I'm new to Java. I've discovered, while trying to structure my code, that Java intimately ties source file organisation (directory structure) to package structure and package structure to external visibility of classes (a class is either visible to all other packages, or none).
This makes it quite difficult to organise the internal implementation details of my public library into logical units of related functionality while maintaining good encapsulation. JSR 294 explains it best:
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.
So my question is, what workarounds exist for this limitation, and what are the pros & cons? Two are mentioned in the JSR - use packages for logical grouping (violating encapsulation); place everything in a single package (unwieldy). Are there other pros/cons to these workarounds? Are there other solutions? (I've become vaguely aware of OSGi bundles, but I've found it hard to understand how they work and what the the pros/cons might be (perhaps that's a con). It appears to be very intrusive compared to vanilla packages, to development & deployment.
Note: I'll upvote any good answers, but the the best answer will be one that comprehensively folds in the pros & cons of others (plagiarise!).
Related (but not duplicate!) questions
Anticipating cries of 'Possible duplicate', here are similar questions that I've found on SO; I present them here for reference and also to explain why they don't answer my question.
- Java : Expose only a single package in a jar file: asks how to do it, but given that it's not possible in current releases of Java, doesn't discuss workarounds. Has interesting pointers to forthcoming Modularization (Project Jigsaw) in Java 8.
- Package and visibility - duplicate question of the above, basically.
- Best practice for controlling access to a ".internal" package - question and answers seem to be specific to OSGi or Eclipse plug-ins.