我有一个用Java 8编写的项目,我想将它更新为Java 9.所以我把这些类分成了两个独立的模块。模块:
org.ggp.base
中的{li> module-info.java
org.ggp.base/src/main/java
。在我开始更新Java 9之前,它的构建是使用Gradle自动完成的。该模块使用pl.edu.prz.klopusz
模块中包含的抽象类实现。
目录pl.edu.prz.klopusz
中的pl.edu.prz.klopusz/dolar-app/src/main/java
。我想使用Maven自动化它的构建。该模块需要org.ggp.base
模块。文件树如下所示:
.
├── 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
module-info.java
个文件的内容如下:
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应用内/ SRC /主/爪哇/ 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;
}
我尝试使用以下命令编译项目:
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)
我收到以下错误:
org.ggp.base / src / main / java / module-info.java:1:
error: module not found on module source path模块org.ggp.base {
org.ggp.base
包中的类有99个其他错误,每个错误都是:
org.ggp.base / src / main / java / external / JSON / JSONObject.java:1:
error: not in a module on the module source pathpackage external.JSON;
或
org.ggp.base / src / main / java / org / ggp / base / validator / OPNFValidator.java:1:
error: not in a module on the module source path包org.ggp.base.validator;
我想摆脱错误并编译项目。我不必保留目录结构,但是当我把它们放在一起时,有两个module-info.java
文件,编译器抱怨了多个模块。我可以通过IntelliJ IDEA完成它,我不介意,我尝试过。但我不知道幕后发生了什么,我也不知道如何处理错误(Package is empty: org.ggp.base
)。
很难在--module-source-path
命令中找到有关javac
切换的文档。 This site is what I found。它说:
如果你安排代码 模块,以便您将模块的代码放在一个封闭的模块中 为模块命名的目录,模块源路径变得更像 一条简单的路径,如--module-source-path Users/Me/MyProject/src或者如果它在多个项目中,请使用--module-source-path /Users/Me/MyProject/src:/Users/Me/MyOtherProject/src
对于Windows使用反斜杠和分号,但我还是使用Linux。
还有一个问题on OpenJDK bugs site的评论,与我的错误相同,但我想它仍未解决。
更新
-verbose
切换我在命令末尾添加了-verbose
开关。这是编译器所说的一部分:
[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
所以,我认为这不是--module-source-path
切换中路径的错误(@StephanHerrmann指出*src/main/java
同样的行为)。它读取它应该读取的所有Java源代码。 pl.edu.prz.klopusz
模块中的源代码没有问题。
这些是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 {
//...
}
答案 0 :(得分:7)
根据JEP 261,--module-source-path
选项(用于“多模块模式”中的编译)必须指向一个目录,该目录包含每个包含模块的一个子目录,其中目录名称必须等于模块名。
为了适应模块目录中不直接包含源的布局,该选项支持模式,其中标记*
可用于表示路径任何部分中的模块名称例如在"./*/src/main/java/"
中,它会在my.mod1
等中找到模块./my.mod1/src/main/java/module-info.java
。
JEP 261没有提及关于模式*
可能出现在哪里的任何约束,但显然javac
不喜欢以*
开始的模式。这可能是也可能不是故意的。
稍微相关,我可以补充一点,在之前的讨论中,我被告知JEP 261包含过时的信息,但我的问题是在JEP完成后是否以及在何处维持此规范,没有产生任何答案。 javac manual entry不是为--module-source-path
等选项提供足够详细信息的地方。
答案 1 :(得分:2)
出于完整性考虑,完整的javac
命令如下:
javac -d out --module-source-path "./*/src/main/java/" $(find . -name "*.java")
基于OpenJDK的official tutorial(如下所示的略微修改的目录结构)和OpenJDK版本“ 11.0.1”,以上命令javac
对我有用:
.
├── 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
│ └── org.astro@1.0.jar