Gradle:无法找到Jigsaw模块

4

我尝试运行一个非常简单的Gradle项目,使用Java 9模块,但是我收到了以下错误:

/home/vadim/IdeaProjects/test_modules/src/main/java/module-info.java:2: error: module not found: HdrHistogram
    requires HdrHistogram;
             ^

这是它:https://github.com/vad0/test_modules。 主类基本上什么也没做。

package app;

import org.HdrHistogram.Histogram;

public class RunHdr {
    public static void main(String[] args) {
        final Histogram histogram = new Histogram(5);
        System.out.println(histogram);
    }
}

它仅使用了一个依赖项:HdrHistogram。我按照官方Gradle教程https://docs.gradle.org/current/samples/sample_java_modules_multi_project.html中的指示,在build.gradle文件中添加了这个神奇的命令。

java {
    modularity.inferModulePath = true
}

整个 build.gradle 文件看起来像这样。
plugins {
    id 'java'
}

group 'org.example'
version '1.0-SNAPSHOT'

repositories {
    mavenCentral()
}

java {
    modularity.inferModulePath = true
}

dependencies {
    compile group: 'org.hdrhistogram', name: 'HdrHistogram', version: '2.1.12'
    testCompile group: 'junit', name: 'junit', version: '4.12'
}

module.info 的样子是这样的

module test.modules.main {
    requires HdrHistogram;
}

我已经阅读了关于Jigsaw的许多教程以及大量与之相关的stackoverflow问题,但仍然无法让这个简单的示例工作。我该如何解决它?

谢谢


奇怪!我使用 [tag:maven],并且能够使用相同的构件版本添加模块 HdrHistogram - Naman
转换从gradle到maven对我来说不是一种选择,很遗憾。 - Vadim
@Naman,你知道maven是如何将其转换为自动模块的吗? - Eugene
@Eugene 从构建日志中可以看出,不需要深入了解实际代码,Maven似乎首先识别编译路径上的所有依赖项。然后,基于自身模块化的工件/ JAR(即包括模块描述符或在META-INF中声明Automatic-Module-Name的工件),或者任何其他作为maven模块的module-info.java的一部分的工件被视为在模块路径上而不是类路径上。共享的日志有两个组成部分,以清晰地说明这种差异。 - Naman
@Naman 在这里(https://github.com/jjohannes/extra-java-module-info)是Gradle通过一个Gradle核心作者的插件如何实现的。这真是一件美妙的事情!这个想法并不复杂,但非常好。他们让 为非模块化的JAR定义 module-info.java。我已经说过我喜欢它了吗? - Eugene
显示剩余2条评论
1个回答

6
很不幸,gradle不能将每个jar都视为模块(简单地说)。如果你想了解gradle如何精确构建module-path(与class-path相对),你可能要从这里开始,具体来说是在isModuleJar方法处。很容易理解(尽管我花了将近两天的时间来设置gradle并调试出问题):你试图使用的依赖项,gradle说它不是一个模块(虽然它没错,但我也不确定它是否正确)。为了使它非常正确,gradle将把你的依赖项添加到CLASSPATH中,但在下一行代码中:它不会将你的依赖项添加到module-path,因为它在isModuleJar中没有通过筛选。

我不知道这是不是一个bug,或者它是否是有意的,但解决方案很简单:

plugins.withType(JavaPlugin).configureEach {
    java {
        modularity.inferModulePath = true
    }

    tasks.withType(JavaCompile) {
        doFirst {
            options.compilerArgs = [
                '--module-path', classpath.asPath,
            ]
            classpath = files()
        }
    }
}

你故意将其添加到路径中。我会将此标记为缺陷,让我们看看他们会说什么。
编辑:
更好的方法是使用由Gradle提交者编写的插件。
plugins {
    id 'java'
    id 'de.jjohannes.extra-java-module-info' version "0.1"
}

对于您的情况,最简单的选择是执行以下操作:

extraJavaModuleInfo {
     automaticModule("HdrHistogram-2.1.12.jar", "HdrHistogram")
}

太棒了!非常感谢@Eugene。但总体来看,现在使用模块+Gradle的人很少。 - Vadim

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接