I started to modularize a Java 11 Gradle project using JPMS modules. For test purposes I created an example project called TestGradleModular. The module configuration looks fine, the modules are found from eclipse and I can use them in my application.
The JVM throws an exception when I launch the application within eclipse:
Error occurred during initialization of boot layer
java.lang.module.FindException: Module org.apache.logging.log4j not found, required by TestGradleModular
I looked up the run configuration of the project and noticed that eclipse included the modules I'm using on the class path instead of the module path on the launch command line:
C:\Program Files\OpenJDK\jdk-11.0.6+10\bin\javaw.exe -Dfile.encoding=UTF-8 -p "C:\Users\user\workspaces\test\TestGradleModular\bin\main" -classpath "C:\Users\user\.gradle\caches\modules-2\files-2.1\org.apache.logging.log4j\log4j-core\2.11.2\6c2fb3f5b7cd27504726aef1b674b542a0c9cf53\log4j-core-2.11.2.jar;C:\Users\user\.gradle\caches\modules-2\files-2.1\org.apache.logging.log4j\log4j-api\2.11.2\f5e9a2ffca496057d6891a3de65128efc636e26e\log4j-api-2.11.2.jar" -m TestGradleModular/TestGradleModular.TestMe
The TestGradleModular project contains this files:
build.gradle:
apply plugin: 'java'
apply plugin: 'eclipse'
apply plugin: 'maven'
sourceCompatibility = 11
targetCompatibility = 11
repositories {
mavenCentral()
mavenLocal()
}
plugins.withType(JavaPlugin).configureEach {
java {
modularity.inferModulePath = true
}
}
ext.isConGradle = {entry ->
entry.kind == 'con' && entry.path == 'org.eclipse.buildship.core.gradleclasspathcontainer'
}
tasks.withType(JavaCompile) {
doFirst {
options.compilerArgs += [
'--module-path', classpath.asPath
]
classpath = files()
options.fork = true
options.encoding = compileEncoding
options.debug = compileDebugging
if(compileDebugging){
options.debugOptions = new DebugOptions()
options.debugOptions.setDebugLevel(compilerDebuggingInformation)
}
}
}
eclipse {
project {
natures 'org.eclipse.buildship.core.gradleprojectnature'
}
classpath {
//Necessary otherwise the library is not raised to the module level.
containers 'org.eclipse.buildship.core.gradleclasspathcontainer'
file {
whenMerged {
entries.findAll { isConGradle(it) }.each {
it.entryAttributes['module'] = 'true'
}
}
}
}
}
dependencies{
implementation group: 'org.apache.logging.log4j', name: 'log4j-core', version: '2.11.2'
}
src/main/java/module-info.java:
module TestGradleModular{
requires org.apache.logging.log4j;
}
src/main/java/TestGradleModular/TestMe.java:
package TestGradleModular;
import org.apache.logging.log4j.LogManager;
import org.apache.logging.log4j.Logger;
public class TestMe{
private static final Logger LOGGER = LogManager.getLogger();
public static void main(String[] args){
LOGGER.error("d'oh!");
}
}
Eclipse Java Build Path > Libraries
Modulepath
|> JRE System Library [JavaSE-11]
|> Project and External Dependencies
|> Access rules: No rules defined
|> External annotations: (None)
|> Native library location: No
|> Is modular
|> log4j-core-2.11.2.jar - C:\Users\user\.gradle\caches\modules-2\files-2.1\org.apache.logging.log4j\log4j-core\2.11.2\6c2fb3f5b7cd27504726aef1b674b542a0c9cf53\log4j-core-2.11.2.jar
|> Is modular - non modifiable
|> Access rules: (no restrictions) - non modifiable
|> Visible only for the test sources: No - non modifiable
|> log4j-api-2.11.2.jar - C:\Users\user\.gradle\caches\modules-2\files-2.1\org.apache.logging.log4j\log4j-api\2.11.2\f5e9a2ffca496057d6891a3de65128efc636e26e\log4j-api-2.11.2.jar
|> Is modular - non modifiable
|> Access rules: (no restrictions) - non modifiable
|> Visible only for the test sources: No - non modifiable
Classpath
Is this an eclipse bug or is the Gradle configuration wrong?
I'm tested it on:
Gradle Version 6.4.1
eclipse 2019-12 (4.14.0) x64 with Buildship 3.1.3
eclipse 2020-06 (4.16.0) x64 with Buildship 3.1.4
AdoptOpenJDK 11.0.6+10 x64
edit:
I opened an issue at Buildship's issue tracker: https://github.com/eclipse/buildship/issues/1002
edit 2:
It's now experimentally possible with Buildship 3.1.5 (and it should be integrated in the upcoming eclipse 2021-03 release).