英文:
gradle Jigsaw module not found
问题
I encountered an issue while trying to run a simple Gradle project that utilizes Java 9 modules. The error I received is as follows:
/home/vadim/IdeaProjects/test_modules/src/main/java/module-info.java:2: error: module not found: HdrHistogram
    requires HdrHistogram;
             ^
Here's the link to the GitHub repository: GitHub Link.
The main class appears to perform minimal tasks:
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);
    }
}
The project relies on the HdrHistogram dependency, and I've included the following command in the build.gradle file, following the official Gradle tutorial:
java {
    modularity.inferModulePath = true
}
The contents of the build.gradle file are as follows:
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'
}
The module-info.java file appears like this:
module test.modules.main {
    requires HdrHistogram;
}
Despite having reviewed multiple Jigsaw tutorials and StackOverflow questions, I'm still struggling to get this simple example to function. How can I resolve this issue? Thank you.
英文:
I try to run a very simple gradle project which uses java 9 modules, but i receive the following error.
/home/vadim/IdeaProjects/test_modules/src/main/java/module-info.java:2: error: module not found: HdrHistogram
    requires HdrHistogram;
             ^
Here is it https://github.com/vad0/test_modules.
The main class does basically nothing.
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);
    }
}
It uses only one dependency: HdrHistogram. I included this magic command in build.gradle according to official gradle tutorial https://docs.gradle.org/current/samples/sample_java_modules_multi_project.html.
java {
    modularity.inferModulePath = true
}
The whole build.gradle looks like this.
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 looks like this
module test.modules.main {
    requires HdrHistogram;
}
I have already read a number of tutorials on Jigsaw and a whole bunch of stackoverflow questions related to it, but still can't make this simple example work. How do i fix it?
Thank you
答案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")
}
英文:
Unfortunately, gradle does not treat every jar as a module (in simple words). If you want to find out how exactly is gradle building the module-path (as opposed to class-path), you probably want to start from here, specifically at the isModuleJar method. It's pretty easy to understand (though it took me almost two days to set-up gradle and debug the problem out) that the dependency that you are trying to use : gradle says that it is not a module (it isn't wrong, but I am not sure it is correct either). To make it very correct, gradle will add your dependency to the CLASSPATH, but in the very next line: it will not add your dependency to the module-path, because if fails the filter in isModuleJar.
I do not know if this is a bug or not, or may be this is on purpose, but the solution is easy:
plugins.withType(JavaPlugin).configureEach {
    java {
        modularity.inferModulePath = true
    }
    tasks.withType(JavaCompile) {
        doFirst {
            options.compilerArgs = [
                '--module-path', classpath.asPath,
            ]
            classpath = files()
        }
    }
}
you add it to the path, on purpose. I will flag this as a defect and let's see what they have to say.
EDIT
Even better, use a plugin that is written by a gradle commiter:
plugins {
    id 'java'
    id 'de.jjohannes.extra-java-module-info' version "0.1"
}
And the easiest option on your case is to do :
extraJavaModuleInfo {
     automaticModule("HdrHistogram-2.1.12.jar", "HdrHistogram")
}
通过集体智慧和协作来改善编程学习和解决问题的方式。致力于成为全球开发者共同参与的知识库,让每个人都能够通过互相帮助和分享经验来进步。


评论