In the comparison of JSR 277 and JSR 291 features, I caused some confusion by saying the default export granularity was 'class' for JSR 277 and 'package' for JSR 291. I'll try to explain.
The primitive unit of export in JSR 277 is the class. You can use a wildcard to export all of a module's classes in a specified package, but that's just syntactic sugar. The wildcard will be expanded to a list of classes in the binary file representing the module's superpackage. There is no runtime notion of an exported package.
The primitive unit of export in JSR 291, on the other hand, is the package. You can filter the set of classes available to importers, but the runtime deals in exported packages rather than classes.
I hope that's a bit clearer. Also, try not to confuse default export granularity with import semantics. JSR 277 supports only module import whereas JSR 291 supports package and module imports.
I'm curious ... how does one filter out classes from an export package?
ReplyDeleteUsing 'include' and 'exclude' directives, e.g.
ReplyDeleteExport-Package: org.foo.p; exclude:="*Impl"
thanks, that's much clearer
ReplyDeletebtw, is it possible for different modules to export a different (but potentially overlapping) set of classes from the same package?
Distinct modules can certainly export arbitrary sets of classes sharing a common package name and these sets could overlap. This is true in JSR 277 and JSR 291.
ReplyDeleteA so-called 'split' package occurs when two or more such sets of classes are imported by another module. JSR prohibits split packages whereas JSR 291 accommodates them (but only via require-bundle - never via import-package).
Since each module has its own class loader, two classes sharing a common package name but belonging to distinct modules do not belong to the same runtime package. In particular, they couldn't access each other's package private members.
For this and other reasons split packages need handling with some care. The main reason to support split packages in JSR 291 was the requirement to be able to refactor large 'legacy' packages comprising two or more relatively independent pieces but without impacting code using the packages.