Close

Java 9 Modules - Split Packages

[Last Updated: Mar 14, 2018]

'Split packages' is an old Java term where two packages having the same name exist in different libraries/applications. Java 9 does not allow split packages in different modules for the reason of the reliable configuration. This restriction is even applied to the packages which are not exported. Only unnamed modules are exempted from this restriction.

Example

In this simple example, we will create two modules having split packages.

The first module

core-parser/src/parser/xml/DefaultParser.java

package parser.xml;

public class DefaultParser {
  public String parse(String data) {
      return "parsed " + data;
  }
}

core-parser/src/module-info.java

module core.parser {
}

The above module is not even exporting parser.xml package.

The second module

parser-app/src/parser/xml/AppMain.java

package parser.xml;

public class AppMain {
  public static void main(String[] args) {
      System.out.println("do something");
  }
}

The above class has the same package name 'parser.xml' which we used for DefaultParser above.

parser-app/src/module-info.java

module parser.app {
  requires core.parser;
}

Compiling and running

We have following directory structure:

D:\simple-split-packages>"tree /A /F"
+---core-parser
| \---src
| | module-info.java
| |
| \---parser
| \---xml
| DefaultParser.java
|
\---parser-app
\---src
| module-info.java
|
\---parser
\---xml
AppMain.java

Compiling the first module:

D:\simple-split-packages\core-parser>javac -d out src\module-info.java src\parser\xml\DefaultParser.java

Compiling the second module:

D:\simple-split-packages\parser-app>javac --module-path ../core-parser/out -d out src\module-info.java src\parser\xml\AppMain.java

Compilation done without any error.

Now we have these files:

D:\simple-split-packages>"tree /A /F"
+---core-parser
| +---out
| | | module-info.class
| | |
| | \---parser
| | \---xml
| | DefaultParser.class
| |
| \---src
| | module-info.java
| |
| \---parser
| \---xml
| DefaultParser.java
|
\---parser-app
+---out
| | module-info.class
| |
| \---parser
| \---xml
| AppMain.class
|
\---src
| module-info.java
|
\---parser
\---xml
AppMain.java

Running the second module's main class

D:\simple-split-packages\parser-app>java --module-path ../core-parser/out;out --module parser.app/parser.xml.ParserApp
Error occurred during initialization of boot layer
java.lang.LayerInstantiationException: Package parser.xml in both module core.parser and module parser.app

The exception is clear about split packages situation.

Running on class path

Let's compile and run the application without modules (no module-info.java). Such application actually runs in the unnamed module in Java 9.

We just need to compile the parser.app without module-info.java (the core.parser one will be ignored):

D:\simple-split-packages\parser-app>javac -cp ../core-parser/out -d out2 src\parser\xml\AppMain.java
D:\simple-split-packages\parser-app>java -cp ../core-parser/out;out2 parser.xml.AppMain
do something

For backward compatibility reason, the split packages are allowed in unnamed modules.

Example Project

Dependencies and Technologies Used:

  • JDK 9
Java 9 Split Packages Example Select All Download
  • simple-split-packages
    • core-parser
      • src
        • parser
          • xml
    • parser-app
      • src
        • parser
          • xml
            • AppMain.java

    See Also