Java 9 个自动模块未找到

Java 9 automatic modules not found

我正在尝试定义一个 Java 9 模块。我定义了类似的东西:

module my.module.name {

}

然后我的许多文件开始给我错误,他们找不到一些包。然后我使用了 IntelliJ 的自动帮助功能,它向我的 module-info.java 添加了几个 "requires" 语句。所以它变成了这样的:

module my.module.name {
    requires spring.web;
    requires sshd.core;
    requires com.fasterxml.jackson.core;
    ....
}

现在 IntelliJ 可以毫无错误地显示我的所有代码。但是当我在 "Maven Projects" window 中单击 "compile" 时(我使用 Maven 3.5.3 和 Oracle JDK 10 进行编译),它告诉我以下内容:

src/main/java/module-info.java:[2,20] module not found: spring.web
src/main/java/module-info.java:[11,18] module not found: sshd.core
src/main/java/module-info.java:[13,35] module not found: com.fasterxml.jackson.core
...
same for the other modules I "require".

据我了解,未定义为模块的第 3 方库会生成 "automatic" 模块。所以我找到了我需要的罐子之一:

C:\Users\<my username>\.m2\repository\org\springframework\spring-web.0.5.RELEASE\spring-web-5.0.5.RELEASE.jar

并想使用以下命令查看 "automatic" 模块的名称:

jar.exe" --file=spring-web-5.0.5.RELEASE.jar --describe-module

No module descriptor found. Derived automatic module.

spring.web@5.0.5.RELEASE automatic
...

所以根据我的调查,我"require"的模块名称是正确的!我错过了什么?为什么我得到

module not found: spring.web

其他模块也一样吗?我是不是遗漏了一些路径之类的?

编辑:根据要求,这是我的pom.xml:

<?xml version="1.0" encoding="UTF-8"?>
<project xmlns="http://maven.apache.org/POM/4.0.0"
     xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
     xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 

http://maven.apache.org/xsd/maven-4.0.0.xsd">
<modelVersion>4.0.0</modelVersion>

<groupId>mygroupid</groupId>
<artifactId>myartifactid</artifactId>
<version>1.0.1-RELEASE</version>

<properties>
    <project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
    <project.reporting.outputEncoding>UTF-8</project.reporting.outputEncoding>
    <java.version>1.9</java.version>
</properties>

<dependencies>
    <!-- https://mvnrepository.com/artifact/org.apache.sshd/apache-sshd -->
    <dependency>
        <groupId>org.apache.sshd</groupId>
        <artifactId>apache-sshd</artifactId>
        <version>1.7.0</version>
        <type>pom</type>
        <exclusions>
            <exclusion>
                <groupId>org.slf4j</groupId>
                <artifactId>slf4j-jdk14</artifactId>
            </exclusion>
        </exclusions>
    </dependency>
    <dependency>
        <groupId>org.slf4j</groupId>
        <artifactId>slf4j-api</artifactId>
        <version>1.7.25</version>
    </dependency>
    <!-- https://mvnrepository.com/artifact/net.java.dev.jna/jna -->
    <dependency>
        <groupId>net.java.dev.jna</groupId>
        <artifactId>jna</artifactId>
        <version>4.5.1</version>
    </dependency>
    <dependency>
        <groupId>net.java.dev.jna</groupId>
        <artifactId>jna-platform</artifactId>
        <version>4.5.1</version>
    </dependency>
    <dependency>
        <groupId>org.springframework</groupId>
        <artifactId>spring-web</artifactId>
        <version>5.0.4.RELEASE</version>
    </dependency>
    <dependency>
        <groupId>org.springframework</groupId>
        <artifactId>spring-context</artifactId>
        <version>5.0.4.RELEASE</version>
    </dependency>
    <dependency>
        <groupId>org.springframework.boot</groupId>
        <artifactId>spring-boot-autoconfigure</artifactId>
        <version>2.0.0.RELEASE</version>
    </dependency>
</dependencies>

<build>
    <plugins>
        <plugin>
            <artifactId>maven-assembly-plugin</artifactId>
            <version>3.1.0</version>
            <configuration>
                <descriptors>
                    <descriptor>assembly.xml</descriptor>
                </descriptors>
            </configuration>
            <executions>
                <execution>
                    <id>make-assembly</id>
                    <phase>package</phase>
                    <goals>
                        <goal>single</goal>
                    </goals>
                </execution>
            </executions>
        </plugin>
        <plugin>
            <groupId>org.apache.maven.plugins</groupId>
            <artifactId>maven-compiler-plugin</artifactId>
            <version>3.7.0</version>
            <configuration>
                <source>1.9</source>
                <target>1.9</target>
            </configuration>
        </plugin>
    </plugins>
</build>

编辑2: 我尝试将以下内容添加到 maven-compiler-plugin 配置中:

<compilerArgs>
    <arg>--add-modules</arg><arg>spring.web</arg>
</compilerArgs>

然后尝试用"mvn compile -X"编译它以获得完整的调试日志,所以我执行了编译命令行:

[INFO] Changes detected - recompiling the module!
[DEBUG] Classpath:
[DEBUG] Source roots:
[DEBUG]  D:\Work\gitrepos\mymoduleproject\src\main\java
[DEBUG]  D:\Work\gitrepos\mymoduleproject\target\generated-sources\annotations
[DEBUG] Command line options:
[DEBUG] -d D:\Work\gitrepos\mymoduleproject\target\classes -sourcepath D:\Work\gitrepos\mymoduleproject\src\main\java;D:\Work\gitrepos\mymoduleproject\target\generated-sources\annotations; -s D:\Work\
gitrepos\mymoduleproject\target\generated-sources\annotations -g -nowarn -target 1.9 -source 1.9 -encoding UTF-8 --add-modules spring.web

但又一次……我明白了

module-info.java:[2,20] module not found: spring.web

所有其他模块也一样...

编辑3:

我创建了一个新项目并且新项目编译正常(但我仍然需要编译原始项目!)。我做了同样的 "mvn compile -X" 命令,这是我得到的:

[INFO] Changes detected - recompiling the module!
[DEBUG] Classpath:
[DEBUG]  C:\Users\myuser\.m2\repository\org\springframework\spring-web.0.4.RELEASE\spring-web-5.0.4.RELEASE.jar
[DEBUG]  C:\Users\myuser\.m2\repository\org\springframework\spring-beans.0.4.RELEASE\spring-beans-5.0.4.RELEASE.jar
[DEBUG]  C:\Users\myuser\.m2\repository\org\springframework\spring-core.0.4.RELEASE\spring-core-5.0.4.RELEASE.jar
[DEBUG]  C:\Users\myuser\.m2\repository\org\springframework\spring-jcl.0.4.RELEASE\spring-jcl-5.0.4.RELEASE.jar
[DEBUG]  C:\Users\myuser\.m2\repository\org\springframework\boot\spring-boot-starter.0.0.RELEASE\spring-boot-starter-2.0.0.RELEASE.jar
[DEBUG]  C:\Users\myuser\.m2\repository\org\springframework\spring-aop.0.4.RELEASE\spring-aop-5.0.4.RELEASE.jar
[DEBUG]  C:\Users\myuser\.m2\repository\org\springframework\spring-expression.0.4.RELEASE\spring-expression-5.0.4.RELEASE.jar
[DEBUG]  C:\Users\myuser\.m2\repository\org\springframework\boot\spring-boot-starter-logging.0.0.RELEASE\spring-boot-starter-logging-2.0.0.RELEASE.jar
[DEBUG]  C:\Users\myuser\.m2\repository\ch\qos\logback\logback-classic.2.3\logback-classic-1.2.3.jar
[DEBUG]  C:\Users\myuser\.m2\repository\ch\qos\logback\logback-core.2.3\logback-core-1.2.3.jar
[DEBUG]  C:\Users\myuser\.m2\repository\org\apache\logging\log4j\log4j-to-slf4j.10.0\log4j-to-slf4j-2.10.0.jar
[DEBUG]  C:\Users\myuser\.m2\repository\org\apache\logging\log4j\log4j-api.10.0\log4j-api-2.10.0.jar
[DEBUG]  C:\Users\myuser\.m2\repository\org\slf4j\jul-to-slf4j.7.25\jul-to-slf4j-1.7.25.jar
[DEBUG]  C:\Users\myuser\.m2\repository\javax\annotation\javax.annotation-api.3.2\javax.annotation-api-1.3.2.jar
[DEBUG]  C:\Users\myuser\.m2\repository\org\slf4j\slf4j-api.7.25\slf4j-api-1.7.25.jar
[DEBUG] Modulepath:
[DEBUG]  C:\Users\myuser\.m2\repository\org\springframework\boot\spring-boot-autoconfigure.0.0.RELEASE\spring-boot-autoconfigure-2.0.0.RELEASE.jar
[DEBUG]  C:\Users\myuser\.m2\repository\org\springframework\boot\spring-boot.0.0.RELEASE\spring-boot-2.0.0.RELEASE.jar
[DEBUG]  D:\Work\gitrepos\demo\javamodules\target\classes
[DEBUG]  C:\Users\myuser\.m2\repository\org\springframework\spring-context.0.4.RELEASE\spring-context-5.0.4.RELEASE.jar
[DEBUG] Source roots:
[DEBUG]  D:\Work\gitrepos\demo\javamodules\src\main\java
[DEBUG]  D:\Work\gitrepos\demo\javamodules\target\generated-sources\annotations
[DEBUG] Command line options:
[DEBUG] -d D:\Work\gitrepos\demo\javamodules\target\classes -classpath C:\Users\myuser\.m2\repository\org\springframework\spring-web.0.4.RELEASE\spring-web-5.0.4.RELEASE.jar;C:\Users\myuser\.m2\repository\
org\springframework\spring-beans.0.4.RELEASE\spring-beans-5.0.4.RELEASE.jar;C:\Users\myuser\.m2\repository\org\springframework\spring-core.0.4.RELEASE\spring-core-5.0.4.RELEASE.jar;C:\Users\myuser\.m2\re
pository\org\springframework\spring-jcl.0.4.RELEASE\spring-jcl-5.0.4.RELEASE.jar;C:\Users\myuser\.m2\repository\org\springframework\boot\spring-boot-starter.0.0.RELEASE\spring-boot-starter-2.0.0.RELEAS
E.jar;C:\Users\myuser\.m2\repository\org\springframework\spring-aop.0.4.RELEASE\spring-aop-5.0.4.RELEASE.jar;C:\Users\myuser\.m2\repository\org\springframework\spring-expression.0.4.RELEASE\spring-expres
sion-5.0.4.RELEASE.jar;C:\Users\myuser\.m2\repository\org\springframework\boot\spring-boot-starter-logging.0.0.RELEASE\spring-boot-starter-logging-2.0.0.RELEASE.jar;C:\Users\myuser\.m2\repository\ch\qos\lo
gback\logback-classic.2.3\logback-classic-1.2.3.jar;C:\Users\myuser\.m2\repository\ch\qos\logback\logback-core.2.3\logback-core-1.2.3.jar;C:\Users\myuser\.m2\repository\org\apache\logging\log4j\log4j-to-
slf4j.10.0\log4j-to-slf4j-2.10.0.jar;C:\Users\myuser\.m2\repository\org\apache\logging\log4j\log4j-api.10.0\log4j-api-2.10.0.jar;C:\Users\myuser\.m2\repository\org\slf4j\jul-to-slf4j.7.25\jul-to-slf4j-
1.7.25.jar;C:\Users\myuser\.m2\repository\javax\annotation\javax.annotation-api.3.2\javax.annotation-api-1.3.2.jar;C:\Users\myuser\.m2\repository\org\slf4j\slf4j-api.7.25\slf4j-api-1.7.25.jar; --module-p
ath C:\Users\myuser\.m2\repository\org\springframework\boot\spring-boot-autoconfigure.0.0.RELEASE\spring-boot-autoconfigure-2.0.0.RELEASE.jar;C:\Users\myuser\.m2\repository\org\springframework\boot\spring-
boot.0.0.RELEASE\spring-boot-2.0.0.RELEASE.jar;D:\Work\gitrepos\demo\javamodules\target\classes;C:\Users\myuser\.m2\repository\org\springframework\spring-context.0.4.RELEASE\spring-context-5.0.4.RELEAS
E.jar; -sourcepath D:\Work\gitrepos\demo\javamodules\src\main\java;D:\Work\gitrepos\demo\javamodules\target\generated-sources\annotations; -s D:\Work\gitrepos\demo\javamodules\target\generated-sources\an
notations -g -parameters -nowarn -target 1.9 -source 1.9 -encoding UTF-8

为什么我在新项目中得到 "Module path" 以及 Maven 命令行中的许多其他选项,而在我的原始项目中却没有得到它们?

好吧,问题出在了pom.xml!我在编译期间收到 "module not found" 错误的原因隐藏在警告后面,我认为这并不重要,所以我没有在日志中粘贴这里。警告是 "zip END header not found"。收到此警告的原因是因为我的依赖项中有一个 "malformed jar",因此编译器在解析 module-info.java 文件时失败并产生上述错误。但是哪个是 "malformed" 罐子?结果是这个(我用的是一一排除的方法……):

    <dependency>
        <groupId>org.apache.sshd</groupId>
        <artifactId>apache-sshd</artifactId>
        <version>1.7.0</version>
        <type>pom</type>
        <exclusions>
            <exclusion>
                <groupId>org.slf4j</groupId>
                <artifactId>slf4j-jdk14</artifactId>
            </exclusion>
        </exclusions>
    </dependency>

我在搜索 apache sshd 时从 https://mvnrepository.com 获得了依赖性,我不确定 "type pom" 是什么意思,但我猜,那是因为 Apache Mina 是一组几个项目,这样你就包括了所有项目......无论如何,我只需要所有项目中的 apache-sshd-core,所以我将依赖项更改为以下内容(Apache Mina Dev 社区建议我这样做,所以谢谢对他们来说很多!!!):

<dependency>
    <groupId>org.apache.sshd</groupId>
    <artifactId>sshd-core</artifactId>
    <version>1.7.0</version>
</dependency>

现在所有编译都正常了!非常感谢大家的评论和帮助!

另一个明显的原因是依赖项 module-info.java 中的模块名称与您尝试要求的不同。

确保两个名称同步,如:

requires foo.bar;

// In dependency:
module foo.bar {

}

我在重构后花了大约 1 小时,想知道为什么我的项目没有编译只是为了弄清楚我在更改 Maven 模块名称后忘记在 module-info.java 中更改模块名称。