I want to hide the implementation (concrete class) of a service (interface) from the API user. The implementation is provided to the user by a factory which uses the Java API ServiceLoader mechanism. This Loader requires the implementation class to have public visibility. This is OK as long as the implementation is hidden in a different JAR (apart from the API JAR) the user is not directly depending on.
However, for easy distribution the content of the JAR with the default implementation is packed into the API JAR. So effectively the user depends on this prepacked JAR where the default implementation class is available with public visibility. Nothing keeps people from directly instantiating the implementation. I don't want that to be possible.
My bad ideas:
What do you think is the right way? Any compromise?
Using OSGi or other heavy machinery is out of question.
Disappointing maybe but:
<scope>runtime</scope>
.The only other way would be the have @Deprecated
in the javadoc, with as comment how to use the corresponding class using the java service API.
In C# you can create an internal interface that is visible only to relevant friend assemblies, and then explicitly implement the interface. I'm not sure how you would do this in Java, but conceptually this is how I've been able to work around this problem in the .NET world.
EDIT I just looked it up, from what I can tell Java doesn't have explicit implementation for interfaces. As an FYI, an explicit implementation of an interface requires you to make a function call through an interface member, you can't call it as a member of the implementing class. This is why my technique works for me, at least in the .NET world.
Alternatively, I would suggest putting the interface in another JAR, and don't distribute it with the API
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With