gradlex-org/extra-java-module-info

Not a module and no mapping defined after installing the plug-in

Closed this issue · 6 comments

Hi,I want to use java.desktop in Gradle. I tried adding JVM startup parameters, but it didn't work, so I installed this plug-in, but when I installed the build, the following error was thrown:

Not a module and no mapping defined: forge-1.20.1-47.2.0_mapped_official_1.20.1-recomp.jar

Execution failed for task ':compileJava'.
> Could not resolve all files for configuration ':compileClasspath'.
   > Failed to transform forge-1.20.1-47.2.0_mapped_official_1.20.1.jar (net.minecraftforge:forge:1.20.1-47.2.0_mapped_official_1.20.1) to match attributes {artifactType=jar, javaModule=true, org.gradle.category=library, org.gradle.libraryelements=jar, org.gradle.status=release, org.gradle.usage=java-api}.
      > Execution failed for ExtraJavaModuleInfoTransform: C:\Users\sss\.gradle\caches\forge_gradle\minecraft_user_repo\net\minecraftforge\forge\1.20.1-47.2.0_mapped_official_1.20.1\forge-1.20.1-47.2.0_mapped_official_1.20.1-recomp.jar.
         > Not a module and no mapping defined: forge-1.20.1-47.2.0_mapped_official_1.20.1-recomp.jar

Mh. You probably do not need this plugin. java.desktop is part of the JDK, i.e. of Java itself. If you use the Java Module System (JPMS) and have a module-info.java, you can add requires java.desktop; to it. If you do not use the Java Module System (do not have a module-info.java), it should just work, because then all classes of the JDK are on the classpath at compile time and runtime.

Mh. You probably do not need this plugin. java.desktop is part of the JDK, i.e. of Java itself. If you use the Java Module System (JPMS) and have a module-info.java, you can add requires java.desktop; to it. If you do not use the Java Module System (do not have a module-info.java), it should just work, because then all classes of the JDK are on the classpath at compile time and runtime.

Thank you for your answer. In fact, I tried to add module-info.java. My IDEA will report errors for some packages and ask me to use the requires packet in module-info.java to add them, but unexpectedly there are one (or more?) package "forge" is marked as undeclared identity during gradle build and I don't know how to declare it

The error indicates that forge-1.20.1-47.2.0_mapped_official_1.20.1-recomp.jar itself does not have a module-info.class and also no Automatic-Module-Name entry in the Manifest. If you want to fully use the Java Module System (JPMS) with a module-info.java you need all Jars to have a module-info.class (or as Fallback a Automatic-Module-Name).

You can try to use this plugin with this configuration:

extraJavaModuleInfo {
    deriveAutomaticModuleNamesFromFileNames = true
}

See this section in the Readme.
Or you add individual "patch" entries for all Jars that need patching (see other parts the Readme).

If you want to learn more about the how and why of all of this, I have a playlist on YouTube on Java Modularity.

The error indicates that forge-1.20.1-47.2.0_mapped_official_1.20.1-recomp.jar itself does not have a module-info.class and also no Automatic-Module-Name entry in the Manifest. If you want to fully use the Java Module System (JPMS) with a module-info.java you need all Jars to have a module-info.class (or as Fallback a Automatic-Module-Name).

You can try to use this plugin with this configuration:

extraJavaModuleInfo {
    deriveAutomaticModuleNamesFromFileNames = true
}

See this section in the Readme. Or you add individual "patch" entries for all Jars that need patching (see other parts the Readme).

If you want to learn more about the how and why of all of this, I have a playlist on YouTube on Java Modularity.

Thank you very much for your answer, when I used

extraJavaModuleInfo {
     deriveAutomaticModuleNamesFromFileNames = true
}

The issue was successfully solved. But I don’t know if I can make a digression. I found that requires("java.desktop") did not solve my original problem. I want to use the classes in sun.awt.image in Gradle using JDK17. How did you solve it?

I understand now what you are trying to achieve @Sywyar. As I suspected initially, this is unrelated to what this plugin does. I think you should not add a module-info.java and use this plugin to fix this. It only makes things more complicated.

Your initial idea was right. You need a JVM argument to export the sun.awt.image package, which is hidden by default in current JDK releases. Ideally, you should avoid using it at all. But if you need it, the following works:

build.gradle.kts example

plugins { id("application") }
application { mainClass = "com.example.demo.HelloWorld" }

val addExportsArgs = listOf("--add-exports", "java.desktop/sun.awt.image=ALL-UNNAMED")

// Make hidden packages visible to the compiler (javac)
tasks.withType<JavaCompile>().configureEach {
    options.compilerArgs = addExportsArgs
}

// Make hidden packages visible to the Java VM (java) when executed through Gradle (e.g. :run task)
tasks.withType<JavaExec>().configureEach {
    jvmArgs(addExportsArgs)
}

Now I understand now what you are trying to achieve @Sywyar. As I suspected initially, this is unrelated to what this plugin does. I think you should not add a module-info.java and use this plugin to fix this. It only makes things more complicated.

Your initial idea was right. You need a JVM argument to export the sun.awt.image package, which is hidden by default in current JDK releases. Ideally, you should avoid using it at all. But if you need it, the following works:

build.gradle.kts example

plugins { id("application") }
application { mainClass = "com.example.demo.HelloWorld" }

val addExportsArgs = listOf("--add-exports", "java.desktop/sun.awt.image=ALL-UNNAMED")

// Make hidden packages visible to the compiler (javac)
tasks.withType<JavaCompile>().configureEach {
    options.compilerArgs = addExportsArgs
}

// Make hidden packages visible to the Java VM (java) when executed through Gradle (e.g. :run task)
tasks.withType<JavaExec>().configureEach {
    jvmArgs(addExportsArgs)
}

Thank you very much