Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How split packages are avoided in Java 9

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?

like image 231
Rahul Vedpathak Avatar asked Aug 13 '18 17:08

Rahul Vedpathak


2 Answers

With the scenario described in the question, you'll start facing an error reading :

Module test.myapp reads package from both test.module1 and test.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 in com.foo.app will not be able to access that type since com.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.

like image 78
Naman Avatar answered Oct 25 '22 09:10

Naman


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.

like image 35
Andy Guibert Avatar answered Oct 25 '22 09:10

Andy Guibert