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.