How do you create a java library jar that both:
module-info
)commons-exec
)?The dependency is an implementation detail - should not be exported.
Having the following build.gradle
(using gradle-6.8
):
plugins {
id 'java-library'
}
group = 'test'
version = '0.0.1-SNAPSHOT'
sourceCompatibility = '15'
repositories {
mavenCentral()
}
java {
modularity.inferModulePath = true
}
dependencies {
implementation 'org.apache.commons:commons-exec:1.3'
}
and the following module-info.java
:
module test.module {
requires commons.exec;
}
I'm getting the following compile error:
module-info.java:2: error: module not found: commons.exec
requires commons.exec;
^
If I don't include requires commons.exec
then the error becomes:
error: package org.apache.commons.exec is not visible
import org.apache.commons.exec.CommandLine;
^
(package org.apache.commons.exec is declared in the unnamed module,
but module test.module does not read it)
commons.exec
module name?Running jar --file=commons-exec-1.3.jar --describe-module
does output:
No module descriptor found. Derived automatic module.
commons.exec@1.3 automatic
requires java.base mandated
contains org.apache.commons.exec
contains org.apache.commons.exec.environment
contains org.apache.commons.exec.launcher
contains org.apache.commons.exec.util
So commons.exec
looks like a valid module name for commons-exec-1.3.jar
. Intelij Idea seem to agree and does auto-complete it in module-info.java
. Though it fails at build time.
I managed to overcome the same issue using java-module-info plugin.
This plugin allows you to add module information to a Java library that does not have any. If you do that, you can give it a proper module name and Gradle can pick it up to put it on the module path during compilation, testing and execution.
plugins {
id 'java-library'
id("de.jjohannes.extra-java-module-info") version "0.6"
}
Add this section into your build.gradle
to add the commons-exec module information
extraJavaModuleInfo {
module("commons-exec-1.3.jar", "org.apache.commons.exec", "1.3") {
exports("org.apache.commons.exec")
}
}
Add requires org.apache.commons.exec;
to your module-info.java
EDIT 1:
Gradle 7.0 comes with full support for the Java module system. Users can now build, test, and run Java modules via Gradle. The mere presence of module-info.java
will let Gradle infer that your jar is a module and has to be put on the modulepath instead of the traditional classpath.