Java 9 错误:不在模块源路径上的模块中 [英] Java 9 error: not in a module on the module source path
问题描述
项目结构
我有一个用 Java 8 编写的项目,我想将其更新为 Java 9.所以我将这些类分成了 2 个单独的模块.模块:
org.ggp.base
和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/│ └── 主要/│ ├── java/│ │ ├──外部/│ │ │ └── JSON/│ │ │ ├── JSONArray.java│ │ │ └── JSONObject.java│ │ ├── META-INF/│ │ │ └── MANIFEST.MF│ │ ├── module-info.java│ │ └── org/│ │ └── ggp/│ │ └── 基地/│ │ └── util/│ │ ├── 状态机/│ │ │ ├── MachineState.java│ │ │ └── StateMachine.java│ │ └── 符号/│ └── 资源/│ └── 组织/│ └── ggp/│ └── 基地/└── pl.edu.prz.klopusz/└── dolar-app/└── src/└── 主要/└── java/├── 模块信息.java└── pl/└── 教育/└── prz/└── 克洛普兹/└── 公用事业/└── 装饰器└──StateMachineDecorator.javamodule-info.java
文件内容如下:
module org.ggp.base {需要番石榴;需要反思;需要 jdk.httpserver;使用 org.ggp.base.util.statemachine.StateMachine;出口 org.ggp.base;}
pl.edu.prz.klopusz/dolar-app/src/main/java/module-info.java
模块 pl.edu.prz.klopusz {需要 org.ggp.base;提供 org.ggp.base.util.statemachine.StateMachine使用 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) $(找到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;
我想要的
我想摆脱错误并编译项目.我不必保留目录结构,但是当我将它们与 2 个 module-info.java
文件放在一起时,编译器抱怨多个模块.我可以通过 IntelliJ IDEA 完成它,我不介意,我试过了.但我不知道幕后发生了什么,我也不知道如何处理错误(Package is empty: org.ggp.base
).
我已经找到的
在javac
命令中很难找到关于--module-source-path
开关的文档.我发现了这个网站.它说:
如果你在你的模块,这样你就可以将模块的代码放在一个封闭的以模块命名的目录,模块源路径变得更像一个简单的路径,如--module-source-path Users/Me/MyProject/src或者如果它在多个项目中,请使用<前>--module-source-path/Users/Me/MyProject/src:/Users/Me/MyOtherProject/src
对于 Windows 使用反斜杠和分号,但我还是使用 Linux.
还有对问题的评论 在 OpenJDK 错误站点,与我的错误相同,但我想它仍未解决.
更新
-verbose
开关
我在命令末尾添加了 -verbose
开关.这是编译器所说的一部分:
[解析开始 SimpleFileObject[/home/sensitive/org.ggp.base/src/main/java/module-info.java]][解析开始 SimpleFileObject[/home/sensitive/org.ggp.base/src/main/java/org/ggp/base/util/statemachine/MachineState.java]][解析开始 SimpleFileObject[/home/sensitive/pl.edu.prz.klopusz/dolar-app/src/main/java/module-info.java]][解析开始 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: 错误:不在模块源路径上的模块中包 org.ggp.base.util.statemachine;^[加载/modules/jdk.httpserver/module-info.class][加载/modules/java.base/module-info.class][总263ms]100 错误
所以,我认为这不是 --module-source-path
开关中路径的错误(同样的行为发生在 *src/main/java
@StephanHerrmann 指出).它读取它应该读取的所有 Java 源代码.pl.edu.prz.klopusz
模块中的源代码没有问题.这些是 org.ggp.base.util.statemachine.MachineState
的第一行:
package org.ggp.base.util.statemachine;导入 org.ggp.base.util.gdl.grammar.GdlSentence;导入 java.util.HashSet;导入 java.util.Set;公共类 MachineState {//...}
根据 JEP 261--module-source-path
选项(用于在多模块模式"下编译)必须指向一个目录,该目录为每个包含的模块保存一个子目录,其中目录名称必须等于模块名称.
为了适应源不直接包含在模块目录中的布局,该选项支持模式,其中标记 *
可用于表示任何部分中的模块名称路径如"./*/src/main/java/"
,它会在./my.mod1中找到模块
等my.mod1
/src/main/java/module-info.java
JEP 261 没有提到任何关于模式中 *
可能出现的限制,但显然 javac
不喜欢模式 starting<代码>*代码>.这可能是有意的,也可能不是.
稍微相关,我可能会补充说,在之前的讨论中,我被告知 JEP 261 包含过时的信息,但是我的问题在 JEP 完成后是否以及在何处维护此规范,没有产生任何答案.javac 手册输入 不是提供足够详细信息的地方,例如--module-source-path
.
Project structure
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
withmodule-info.java
in the directoryorg.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 inpl.edu.prz.klopusz
module.pl.edu.prz.klopusz
in the directorypl.edu.prz.klopusz/dolar-app/src/main/java
. I want to automate its build using Maven. The module requiresorg.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;
}
Compilation
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)
Errors
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;
What I want
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
).
What I've already found
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
switch
I 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 {
//...
}
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
.
这篇关于Java 9 错误:不在模块源路径上的模块中的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!