hyperxpro/Brotli4j

Invalid module name: 'native' is not a Java identifier

kamenik opened this issue · 3 comments

Could you please add Automatic-Module-Name to manifest? Thanx;).

Can you explain in detail, please?

I'm running in the same issue.
This happens when trying to load a brotli4j native (e.g. native-linux-x86_64) in a modular context.
The JMPS needs to assign a module name to the jar, and since no module-info is present, it tries to give the jar a generated name. Here is where the problem happens: Module names can contain restricted keywords (static, abstract, native, public, etc), but because the jar starts with "native", the automatic name starts with "native" as well, which is not allowed and causes the JPMS to crash later.
You can see an example crash here:

Exception in thread "main" java.lang.module.FindException: Unable to derive module descriptor for /home/tobias/.gradle/caches/modules-2/files-2.1/com.aayushatharva.brotli4j/native-linux-x86_64/1.8.0/add74b11206e3a6ff14c7405718a0b61abae9a75/native-linux-x86_64-1.8.0.jar
	at java.base/jdk.internal.module.ModulePath.readJar(ModulePath.java:648)
	at java.base/jdk.internal.module.ModulePath.readModule(ModulePath.java:331)
	at java.base/jdk.internal.module.ModulePath.scan(ModulePath.java:237)
	at java.base/jdk.internal.module.ModulePath.scanNextEntry(ModulePath.java:190)
	at java.base/jdk.internal.module.ModulePath.find(ModulePath.java:154)
	at java.base/java.lang.module.Resolver.findWithBeforeFinder(Resolver.java:842)
	at java.base/java.lang.module.Resolver.resolve(Resolver.java:182)
	at java.base/java.lang.module.Resolver.resolve(Resolver.java:141)
	at java.base/java.lang.module.Configuration.resolveAndBind(Configuration.java:492)
	at java.base/java.lang.module.Configuration.resolveAndBind(Configuration.java:298)
Caused by: java.lang.IllegalArgumentException: native.linux.x86.64: Invalid module name: 'native' is not a Java identifier
	at java.base/jdk.internal.module.Checks.requireModuleName(Checks.java:52)
	at java.base/java.lang.module.ModuleDescriptor$Builder.<init>(ModuleDescriptor.java:1515)
	at java.base/java.lang.module.ModuleDescriptor.newAutomaticModule(ModuleDescriptor.java:2395)
	at java.base/jdk.internal.module.ModulePath.deriveModuleDescriptor(ModulePath.java:508)
	at java.base/jdk.internal.module.ModulePath.readJar(ModulePath.java:644)
	... 10 more

The authors of the java module system put a system in place that allows you to work around this issue without the need of including full module support via module-info: The Automatic-Module-Name.
The Automatic-Module-Name is a property read from the manifest that determines the name of the automatic module when loading in a modular context.
See jaxen-xpath/jaxen@ecf4282 for an example of how to do this with maven.

Small followup: Both this (Automatic-Module-Name) and #26 are not sufficient. I've tried both locally in my setup, but both fail to find the native lib. This is because the native lib is in a different jar (which means a different module for the JPMS), causing the Brotli4jLoader.class.getResourceAsStream to fail.