I'd like to have a jar file in which only the API package is accessible. All the other packages (containing implementations) would not be accessible by another jar (nor by any other class).
Is it possible ?
If yes, how ?
I'd like to have a jar file in which only the API package is accessible. All the other packages (containing implementations) would not be accessible by another jar (nor by any other class).
Is it possible ?
If yes, how ?
Currently scheduled for Java 8 (2012?) is JSR 294. This JSR introduces better modularization language constructs into Java.
Today, an implementation can be partitioned into multiple packages. Subparts of such an implementation need to be more tightly coupled to each other than to the surrounding software environment. Today designers are forced to declare elements of the program that are needed by other subparts of the implementation as public - thereby making them globally accessible, which is clearly suboptimal.
Alternately, the entire implementation can be placed in a single package. This resolves the issue above, but is unwieldy, and exposes all internals of all subparts to each other.
The language changes envisioned will resolve these issues. In particular, we expect to introduce a new notion of modules (superpackages) at the language level where existing public access control would apply only within a language level module and access to API's from outside a module would be restricted to API's the module explicitly exports.
Now I believe the expert group is still discussing the details of this concept. But I believe one thing you might be able to do is this (source: Super Packages in Java 7.0):
superpackage com.myorg.myApp.model
{
member package com.myorg.myApp.model.swing;
member package com.myorg.myApp.model.html;
export com.myorg.myApp.model.swing.SEmployee;
export com.myorg.myApp.model.swing.SDepartment;
export package com.myorg.myApp.model.html;
}
In other words, for a given "superpackage" you can define what is and isn't exported, independent from visibility keywords like public
.
If you have classes that should not be used, put them into a subpackage named "internal". While this does not prevent others from using the classes, it is a strong indication that they should not.
Example:
my.library.Stuff
my.library.StuffFactory
my.library.internal.StuffImpl
my.library.internal.MoreStuff
my.library.internal.xml.DataStuff
While this is not an actual solution, I would consider it a best practice.
this isn't really possible in Java 6 unless you're using OSGI which I assume you're not. what I usually end up doing to hide classes is to use package friendly classes for implementations - but you might still need to expose some class-es if you're implementation classes do live in a separate package.
sample:
package com.example;
public class Service { }
assume the API class uses ServiceImpl
as it's implementation
now if ServiceImpl
lives in the same package you might remove it's public class modifier and it won't be accessible outside the package ...
if it lives in a different package (your case) it needs to be public :
package com.example.impl;
public class ServiceImpl { }
but all implementation details (related classes it uses) from the same package need not to be public !
In a "normal" java application that is not possible. Although in OSGi environment you define which packages are exposed by your bundle (slightly modified jar file) to other bundles and which are private (not visible outside your bundle).
Why not simply create a jar with the API classes and a seperated jar with implementations depending of the API one. That way, you can distribute your API classes without distributing your implementation.
KR.
I can see the reason why do you want to do it. It has always troubled me when I try to use someone's library. There are so many classes which I don't know where to start with.
As far as I can see from most libraries, there is no such a library that try to hide unrelated classes. Although, this is not a solid evidence , it must means there is no way to do it. Normally, they budle api and the implementation into seperated jar files.
However, if you are running your application through OSGi framework, it is possible to bundle your jar file in such way that the OSGi frame can see only the API classes you want. But using OSGi might be a bit of work.
You can add an ant-task or a maven-jar-plugin configuration to jar the components you need given your building tool preference.
Another solution is to set default access modifier in implementation classes and put them in the same package as interfaces. Although its a bit dirty way.