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
Advertisement
Answer
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") }