I am new to Java 9 and was going though the modular video lectures by Java on YouTube. They mentioned 3 benefits of modularization- 1. No missing dependencies 2. No cyclic dependnpcies 3. No split packages.
As far as I understand about split packages is that let's say an application is dependant on multiple dependncies and let's say package abc.pqr.xyz is present in more that 1 jar. Then there is a chance that some of the classes in that package will be used from jar1 while other classes from jar2. This might lead to some problems at runtime which will be hard to debug.
Video says modularization solves this issue. But how that's what I am trying to understand?
Let's say there is test.module1 which has below module info -
module test.module1{
exports abc.pqr.xyz;
}
Another module2 with below module info-
module test.module2{
exports abc.pqr.xyz;
}
Now let's say in my application I added dependencies of both of these modules-
module test.myapp{
requires test.module1;
requires test.module2;
}
Now again I have 2 modular dependencies where there is a chance that some of the classes will be present in both of these modules. So at runtime how it will be resolved from which module to pick up the class definitions? How Java 9 will avoid split packages problem?
With the scenario described in the question, you'll start facing an error reading :
Module
test.myapp
reads package from bothtest.module1
andtest.module2
Readability of the Modules from The State of the Module System elaborates over the use of Modules as follows and shall interest your use-case(emphasis mine):
The readability relationships defined in a module graph are the basis of reliable configuration: The module system ensures
- that every dependence is fulfilled by precisely one other module
- that the module graph is acyclic
- that every module reads at most one module defining a given package
- and that modules defining identically-named packages do not interfere with each other.
the benefit of implying the same in the module system is detailed as well
Reliable configuration is not just more reliable; it can also be faster. When code in a module refers to a type in a package then that package is guaranteed to be defined either in that module or in precisely one of the modules read by that module.
When looking for the definition of a specific type there is, therefore, no need to search for it in multiple modules or, worse, along the entire class path.
That said, the current solution to your implementation is
if the modules test.module1
and test.module2
are explicit modules, you can choose to implement the package abc.pqr.xyz
in either one of them
OR you pull it out from both into a separate module test.mergeModule
of your own which can thereafter be used as an independent module across its clients.
if these(or any one of them) are automatic modules, you can make use of the bridge extended to the classpath and let such jar remain on the classpath and be treated as the unnamed module, which shall by default export all of its packages. At the same time, any automatic module while reading every other named module is also made to read the unnamed module.
Quoting the document again and to illustrate with an example, so that you can correlate to your question :
If code in the explicit module com.foo.app refers to a public type in
com.foo.bar
, e.g., and the signature of that type refers to a type in one of the JAR files still on the class path, then the code incom.foo.app
will not be able to access that type sincecom.foo.app
cannot depend upon the unnamed module.This can be remedied by treating
com.foo.app
as an automatic module temporarily, so that its code can access types from the class path, until such time as the relevant JAR file on the class path can be treated as an automatic module or converted into an explicit module.
The Java module system resolves the split package problem by rejecting this sort of scenario at JVM startup time. When the JVM starts it will immediately begin resolving the module graph, and when it encounters two modules in test.myapp
's module path, the JVM will throw an error indicating test.module1
and test.module2
are attempting to export the same package.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With