Problem
How do you create a java library jar that both:
- is java module (has
module-info
) - has a depending legacy (non-module) jar. (like
commons-exec
)?
The dependency is an implementation detail - should not be exported.
Sources
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;
}
Errors
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.
[email protected] 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.
Add this section into your
build.gradle
to add the commons-exec module informationAdd
requires org.apache.commons.exec;
to yourmodule-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.Using libraries that are not modules