项目结构
我有一个用Java 8编写的项目,我想将它更新为Java 9.所以我把这些类分成了两个独立的模块 . 模块:
-
org.ggp.base
,module-info.java
目录为module-info.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
文件的内容如下:
org.ggp.base/src/main/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-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;
}
编译
我尝试使用以下命令编译项目:
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:错误:模块源路径模块上找不到模块org.ggp.base {
和 org.ggp.base
包中的类有99个其他错误,每个错误如下:
org.ggp.base / src / main / java / external / JSON / JSONObject.java:1:错误:不在模块源路径包external.JSON上的模块中;
要么
org.ggp.base / src / main / java / org / ggp / base / validator / OPNFValidator.java:1:错误:不在模块源路径包org.ggp.base.validator上的模块中;
我想要什么
我想摆脱错误并编译项目 . 我没有保留目录结构,但是当我把所有内容放在一起时,编译器抱怨了多个模块 . 我可以通过IntelliJ IDEA完成它,我不知道幕后发生了什么,我也不知道如何处理错误( Package is empty: org.ggp.base
) .
我已经找到了什么
在 javac
命令中很难找到有关 --module-source-path
开关的文档 . This site is what I found . 它说:
如果您在模块中安排代码,以便将模块的代码放在为模块命名的封闭目录中,则模块源路径将变得更像一个简单的路径,如--module-source-path Users / Me / MyProject / src或者如果它在多个项目中,请使用--module-source-path
/用户/ ME / MyProject的/ SRC:/用户/ ME / MyOtherProject / SRC
对于Windows使用反斜杠和分号,但无论如何我都在使用Linux .
还有一个问题on OpenJDK bugs site的评论,与我的错误相同,但我想它仍未解决 .
UPDATE
-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 {
//...
}
2 回答
根据JEP 261,
--module-source-path
选项(用于"multi-module mode"中的编译)必须指向一个目录,该目录包含每个包含模块的一个子目录,其中目录名称必须等于模块名称 .为了适应模块目录中不直接包含源的布局,该选项支持模式,其中令牌
*
可用于表示路径任何部分中的模块名称,例如"./*/src/main/java/"
,它将在./my.mod1/src/main/java/module-info.java
中找到模块my.mod1
等 .JEP 261没有提到任何关于
*
模式可能出现的约束,但显然javac
不喜欢以*
开头的模式 . 这可能是也可能不是故意的 .稍微相关,我可能会补充一点,在之前的讨论中,我被告知JEP 261包含过时的信息,但我的问题是,在JEP完成后是否以及在何处维持此规范,没有产生任何答案 . javac manual entry不是为
--module-source-path
等选项提供足够详细信息的地方 .为了完整起见,完整的
javac
命令如下:基于OpenJDK的official tutorial(稍微修改后的目录结构如下所示)和OpenJDK版本"11.0.1",上面的命令
javac
适用于我: