Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Multi-Release JAR is not recognized as such #2495

Open
eitan-rosenberg opened this issue May 25, 2024 · 6 comments
Open

Multi-Release JAR is not recognized as such #2495

eitan-rosenberg opened this issue May 25, 2024 · 6 comments

Comments

@eitan-rosenberg
Copy link

Recently, I update com.google.code.gson:gson to version 2.11.0 from version 2.10.1.

The project use module-info.java and use "requires com.google.gson;"

gson-2.11.0.jar is a Multi-Release JAR and the module declaration is at META-INF/versions/9/module-info.class

I open an issue and it got the full details.
Also included in that issue a small project to demonstrate the problem.(https://github.com/google/gson/files/15412480/ModuleTest.zip)

When using pure maven build "mvn clean test" it is compiled successfully.
Also I can run it using "mvn compile exec:java -Dexec.mainClass="main.Main"" .

I use:
M2E Maven Integration for Eclipse Core 2.6.0.20240220-1109
Eclipse 2024-03 (4.31)
Java openjdk version "22.0.1" 2024-04-16

Thanks in advance for any response.

@eitan-rosenberg
Copy link
Author

Hi there...
Anyone at home ?

@eitan-rosenberg
Copy link
Author

Solved for me by recompile with java 22

@howlger
Copy link

howlger commented Jul 8, 2024

Steps to reproduce this issue

  1. Create a new Java project name Sample of Java 9 or higher with the option Create module-info.java
  2. Add the com.networknt:json-schema-validator:1.4.3 JAR to the build path
  3. Edit the module-info.java as follows:
    module Sample {
    
    	requires json.schema.validator; // module name mistakenly derived from the file name "json-schema-validator-1.4.3.jar"
    
    	// ... instead of from "META-INF/versions/9/module-info.class" as follows:
    	requires com.networknt.schema;
    	//       ~~~~~~~~~~~~~~~~~~~~
    	//       com.networknt.schema cannot be resolved to a module
    
    }

Expected: requires json.schema.validator; should give an error and requires com.networknt.schema; should work instead.

Workarounds

As a workaround, do one of the following:

  • In the json-schema-validator-1.4.3.jar copy module-info.class from META-INF/versions/9/ to the root
  • In META-INF/MANIFEST.MF add the line Automatic-Module-Name: com.networknt.schema

See also

@iloveeclipse iloveeclipse reopened this Jul 8, 2024
@Marcono1234
Copy link

Marcono1234 commented Jul 28, 2024

It seems this is related to the moditect-maven-plugin. For Gson and json-schema-validator it looks like this issue started occurring when they updated moditect-maven-plugin to 1.2.0.Final (for Gson 2.10.1 → 2.11.0; for json-schema-validator 1.4.0 → 1.4.1).

I am not completely sure where exactly the issue is within jdt.core and if there are multiple classes affected (please double check!), but I could at least find one location:

String name = META_INF_VERSIONS + (i - 44);
ZipEntry entry = zipFile.getEntry(name);
if (entry != null) {

Here is an example for testing this:

public static void main(String[] args) throws Exception {
    System.out.println(getModuleName("gson-2.10.1.jar"));
    System.out.println(getModuleName("gson-2.11.0.jar"));

    System.out.println(getModuleName("json-schema-validator-1.4.0.jar"));
    System.out.println(getModuleName("json-schema-validator-1.4.1.jar"));
}

static String getModuleName(String path) throws Exception {
    AccessRuleSet accessRuleSet = new AccessRuleSet(new AccessRule[0], AccessRestriction.LIBRARY, "test");
    ClasspathJar classpathJar = new ClasspathMultiReleaseJar(new ZipFile(path), accessRuleSet, true, "9");
    // Initialize module information
    new ModulePathEntry(new Path(path), classpathJar);
    return new String(classpathJar.getModule().name());
}

(tested with org.eclipse.jdt:org.eclipse.jdt.core:3.38.0)

The code in ClasspathMultiReleaseJar assumes that for multi-release JARs a (directory) entry exists, e.g. META-INF/versions/9/. However, moditect/moditect#230 (accidentally?) changed the JAR modification code to not generate that entry anymore, but only the META-INF/versions/9/module-info.class entry.

It is not completely clear if that directory entry is required. The JAR specification talks about the "directory" but it does not explicitly say that this directory must exist as ZIP entry.

javac does not seem to care whether the ZIP directory entry exists or not.


There seems to be some duplication regarding multi-release handling in jdt.core, at least these classes all have logic for META-INF/versions:

  • org.eclipse.jdt.internal.compiler.batch.ClasspathMultiReleaseJar
  • org.eclipse.jdt.internal.core.builder.ClasspathJar
  • org.eclipse.jdt.internal.core.builder.ClasspathMultiReleaseJar
  • org.eclipse.jdt.internal.core.JarPackageFragmentRoot
  • org.eclipse.jdt.internal.compiler.batch.ModuleFinder

Confusingly though org.eclipse.jdt.core.JavaCore.getModuleNameFromJar(File) and getRequiredModulesFromJar have no handling for multi-release JARs.

And I think so far I also haven't seen any Multi-Release: true check, despite the JAR specification requiring this for JARs to be recognized as multi-release JARs.

@Marcono1234
Copy link

Marcono1234 commented Jul 29, 2024

As side note: This only affects JDT within the Eclipse IDE. The ECJ batch compiler does not properly support modular multi-release JARs at all, see https://bugs.eclipse.org/bugs/show_bug.cgi?id=577790 / #2778 and #61.

@gv2011
Copy link

gv2011 commented Oct 10, 2024

Probably related: Bugzilla – Bug 534624 Support module-info.java in multi-release JAR files

I have the same problem AndreasWBartels described.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

5 participants