I have a project written in Java 8 and I want to update it to Java 9. So I separated the classes into 2 separate modules. Modules:
org.ggp.base
with module-info.java
in the directory org.ggp.base/src/main/java
. Its build was automated with Gradle before I started the update to Java 9. The module uses an abstract class implementation included in pl.edu.prz.klopusz
module.pl.edu.prz.klopusz
in the directory pl.edu.prz.klopusz/dolar-app/src/main/java
. I want to automate its build using Maven. The module requires org.ggp.base
module.The file tree looks like:
.
├── org.ggp.base/
│ ├── build.gradle
│ └── src/
│ └── main/
│ ├── java/
│ │ ├── external/
│ │ │ └── JSON/
│ │ │ ├── JSONArray.java
│ │ │ └── JSONObject.java
│ │ ├── META-INF/
│ │ │ └── MANIFEST.MF
│ │ ├── module-info.java
│ │ └── org/
│ │ └── ggp/
│ │ └── base/
│ │ └── util/
│ │ ├── statemachine/
│ │ │ ├── MachineState.java
│ │ │ └── StateMachine.java
│ │ └── symbol/
│ └── resources/
│ └── org/
│ └── ggp/
│ └── base/
└── pl.edu.prz.klopusz/
└── dolar-app/
└── src/
└── main/
└── java/
├── module-info.java
└── pl/
└── edu/
└── prz/
└── klopusz/
└── utilities/
└── decorators
└──StateMachineDecorator.java
The contents of module-info.java
files is the following:
module org.ggp.base {
requires guava;
requires reflections;
requires jdk.httpserver;
uses org.ggp.base.util.statemachine.StateMachine;
exports org.ggp.base;
}
pl.edu.prz.klopusz/dolar-app/src/main/java/module-info.java
module pl.edu.prz.klopusz {
requires org.ggp.base;
provides org.ggp.base.util.statemachine.StateMachine
with pl.edu.prz.klopusz.utilities.decorators.StateMachineDecorator;
}
I try to compile the project, using the following command:
javac -d out \
--module-source-path org.ggp.base/src/main/java:pl.edu.prz.klopusz/dolar-app/src/main/java \
$(find org.ggp.base/src/main/java -name *.java) \
$(find pl.edu.prz.klopusz/dolar-app/src/main/java -name *.java)
I get the following error:
org.ggp.base/src/main/java/module-info.java:1:
error: module not found on module source pathmodule org.ggp.base {
And 99 other errors for the classes inside org.ggp.base
package, each is like:
org.ggp.base/src/main/java/external/JSON/JSONObject.java:1:
error: not in a module on the module source pathpackage external.JSON;
or
org.ggp.base/src/main/java/org/ggp/base/validator/OPNFValidator.java:1:
error: not in a module on the module source pathpackage org.ggp.base.validator;
I want to get rid of the errors and compile the project. I don't have to preserve the directory structure, but when I put it all together, with 2 module-info.java
files, the compiler complainted about multiple modules. I can have it done by IntelliJ IDEA, I don't mind and I tried. But I don't know what is happening behind the scenes, and I don't know how to handle the errors either (Package is empty: org.ggp.base
).
It was hard to find a documentation about --module-source-path
switch in javac
command. This site is what I found. It says:
if you arrange the code in your modules such that you put the code for a module in an enclosing directory named for the module, the module source path becomes more like a simple path, as in--module-source-path Users/Me/MyProject/srcor if it is in multiple projects, use--module-source-path /Users/Me/MyProject/src:/Users/Me/MyOtherProject/src
And for Windows use backslashes and semicolons, but I'm using Linux anyway.
There is also a comment to an issue on OpenJDK bugs site, with the same error as mine, but I guess it remains unsolved.
UPDATE
-verbose
switchI added -verbose
switch at the end of command. That is a part of what compiler says:
[parsing started SimpleFileObject[/home/sensitive/org.ggp.base/src/main/java/module-info.java]]
[parsing started SimpleFileObject[/home/sensitive/org.ggp.base/src/main/java/org/ggp/base/util/statemachine/MachineState.java]]
[parsing started SimpleFileObject[/home/sensitive/pl.edu.prz.klopusz/dolar-app/src/main/java/module-info.java]]
[parsing started SimpleFileObject[/home/sensitive/pl.edu.prz.klopusz/dolar-app/src/main/java/pl/edu/prz/klopusz/utilities/decorators/StateMachineDecorator.java]]
org.ggp.base/src/main/java/org/ggp/base/util/statemachine/MachineState.java:1: error: not in a module on the module source path
package org.ggp.base.util.statemachine;
^
[loading /modules/jdk.httpserver/module-info.class]
[loading /modules/java.base/module-info.class]
[total 263ms]
100 errors
So, I think this is not a fault of the path in --module-source-path
switch (the same behavior happens with *src/main/java
pointed out by @StephanHerrmann). It reads all the java sources it should read. There's no problem with sources in the pl.edu.prz.klopusz
module.
These are the first lines of org.ggp.base.util.statemachine.MachineState
:
package org.ggp.base.util.statemachine;
import org.ggp.base.util.gdl.grammar.GdlSentence;
import java.util.HashSet;
import java.util.Set;
public class MachineState {
//...
}
xml module, code in modules that read java. desktop becomes dependent on java. xml . Without the requires transitive directive in java.
Java Module System is a major change in Java 9 version. Java added this feature to collect Java packages and code into a single unit called module. In earlier versions of Java, there was no concept of module to create modular Java applications, that why size of application increased and difficult to move around.
It is that file that defines a module's name, dependencies, and APIs. So there is a strong connection between JARs and modules: JARs are the containers from which the module system creates modules and (at the moment) each JAR can only contain a single module.
As per JEP 261 the --module-source-path
option (for compilation in "multi-module mode") must point to a directory that holds one subdirectory for each contained module, where the directory name must equal the module name.
To accommodate layouts where sources are not directly contained in the module directory, the option supports patterns where the token *
can be used to represent the module name in any part of the path such as in "./*/src/main/java/"
, which will find the module my.mod1
in ./my.mod1/src/main/java/module-info.java
etc.
JEP 261 does not mention any contraints on where in the pattern *
may occur, but apparently javac
doesn't like patterns starting with *
. This may or may not be intentional.
Slightly related, I might add that in a previous discussion I was informed that JEP 261 contains outdated information, but my question whether and where this specification would be maintained after the JEP was completed, produced no answer. The javac manual entry is not the place that gives sufficient details for options like --module-source-path
.
For completeness sake, the complete javac
command is as follows:
javac -d out --module-source-path "./*/src/main/java/" $(find . -name "*.java")
Based on the official tutorial from OpenJDK (slightly modified directory structure shown below), and OpenJDK version "11.0.1", the above command javac
works for me:
.
├── com.greetings
│ └── src
│ └── main
│ └── java
│ ├── com
│ │ └── greetings
│ │ └── Main.java
│ └── module-info.java
├── org.astro
│ └── src
│ └── main
│ └── java
│ ├── module-info.java
│ └── org
│ └── astro
│ └── World.java
├── out
│ ├── classes
│ │ ├── com.greetings
│ │ │ ├── com
│ │ │ │ └── greetings
│ │ │ │ └── Main.class
│ │ │ └── module-info.class
│ │ └── org.astro
│ │ ├── module-info.class
│ │ └── org
│ │ └── astro
│ │ └── World.class
│ └── lib
│ ├── com.greetings.jar
│ └── [email protected]
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