Java 9 错误:不在模块源路径上的模块中 [英] Java 9 error: not in a module on the module source path

查看:50
本文介绍了Java 9 错误:不在模块源路径上的模块中的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

项目结构

我有一个用 Java 8 编写的项目,我想将其更新为 Java 9.所以我将这些类分成了 2 个单独的模块.模块:

  • org.ggp.basemodule-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.java

module-info.java文件内容如下:

org.ggp.base/src/main/java/module-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 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:

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;
}

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 path

module 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 path

package 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 path

package 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/src

or 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屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆