0

I am making a project in netbeans and facing a problem similar to the one already asked on this site - How to share package private data between two packages in Java? , with a slight difference of let's say that application developer can see my codebase. What I thought is to make a public class in package B say 'communicator class' with its contructor having default package access and passing its instance in the constructor of classes of package A. Basically I am stopping the developer (using package C) from instantiating any classes inside package A. This would work however this is not good approach SE-wise I guess. Besides that question was asked three years ago. Is there a better approach/technique available to this now which is NEAT and/or involves less coupling between packages A and B.

PS: I am new with java. Any help would be appreciated.

Community
  • 1
  • 1
Maxkiel
  • 88
  • 1
  • 9
  • 1
    You can't. You might be able to when modules are introduced. – aioobe Jul 02 '15 at 07:16
  • Its impossible... Because you already said its package private... – CoderNeji Jul 02 '15 at 07:16
  • 1
    Java does not (yet) have a good, standard mechanism for this kind of thing. There will be something for this in Java 9 (coming in September 2016), it's main new feature will be the Java module system (the Project Jigsaw that the other question is talking about). – Jesper Jul 02 '15 at 07:17
  • I've marked my original answer for deletion, because I didn't fully understand how you were dealing with the communicator class. I believe your approach would work, but you should ask yourself if it's worthwhile. Are you trying to protect against intentional, or accidental misuse of these packages? Are these packages that people outside of your team/company will be using? – Nicholas Daley-Okoye Jul 06 '15 at 18:37

2 Answers2

0

You can introduce a module which has a reference of the other two packages and make this module to act as a bridge. This is one thing that can be done till Java 8

Bukhtawar
  • 85
  • 10
0

I believe your approach would work, but you should ask yourself if it's worthwhile. It will have an effect on the readability of your code.

Are you trying to protect against intentional, or accidental misuse of these packages?

If you're trying to protect against intentional misuse, your approach wouldn't completely solve it; because reflection can be used to override access on methods/constructors/etc. e.g.

Communicator communicator = ...;

Constructor<ObjA> constructor = ObjA.class.getConstructor(Communicator.class);
constructor.setAccessible(true);
ObjA objectFromA = constructor.newInstance(communicator);

If you have control over the Java runtime, then something could be done with a security manager to prevent this kind of thing.

There may also be things that can be done with ClassLoaders to control one module's access to another module. A class loads other classes using its own ClassLoader; a custom ClassLoader could prevent access to private parts of another module. This is (I believe) how OSGi controls access between modules.

Solutions involving a security manager or a class loader would require you to have some control over the java runtime used.

If you're only trying to protect against accidental misuse, you may be better to rely on package naming to make it clear to people they shouldn't use the classes. e.g. package foo.bar.internal;

Are these packages that people outside of your team/company will be using?

If you have some influence over the build environment of the modules that will use your code, you could consider adding tools to the build configuration to ban use of your private packages. For example Checkstyle's Import Control check gives a lot of control over what packages can be imported from where.

Nicholas Daley-Okoye
  • 2,267
  • 1
  • 18
  • 12