Closed beikov closed 1 year ago
I've downloaded https://search.maven.org/artifact/com.blazebit/blaze-persistence-integration-graphql-spqr/1.6.8/jar and trying to index it with these JDKs:
openjdk version "21-beta" 2023-09-19
OpenJDK Runtime Environment Temurin-21+22-202305251619 (build 21-beta+22-202305251619)
OpenJDK 64-Bit Server VM Temurin-21+22-202305251619 (build 21-beta+22-202305251619, mixed mode, sharing)
openjdk version "21-ea" 2023-09-19
OpenJDK Runtime Environment Zulu21+57-CA (build 21-ea+22)
OpenJDK 64-Bit Server VM Zulu21+57-CA (build 21-ea+22, mixed mode, sharing)
They both seem to work just fine (as in, they write an index file and don't fail).
Could you please provide a JAR on which indexing fails? Alternatively, a stack trace might be enough (mvn -X
).
The problem appears when the module is compiled with the Java 21 class file version. I guess it doesn't really matter what the content of the JAR file is, as long as there is one class file compiled with the latest version.
So far, I reproduced this issue locally with Azul Zulu JDK 21-ea build 22. Here is the JAR (added .zip to the end because GitHub doesn't allow uploading JAR files): blaze-persistence-integration-graphql-spqr-1.6.9-SNAPSHOT.jar.zip
Here is the full error:
Caused by: org.apache.maven.plugin.PluginExecutionException: A type incompatibility occurred while executing io.smallrye:jandex-maven-plugin:3.1.1:jandex: class java.lang.Object cannot be cast to class [B (java.lang.Object and [B are in module java.base of loader 'bootstrap')
-----------------------------------------------------
realm = plugin>io.smallrye:jandex-maven-plugin:3.1.1
strategy = org.codehaus.plexus.classworlds.strategy.SelfFirstStrategy
urls[0] = file:/C:/Users/cbeikov/.m2/repository/io/smallrye/jandex-maven-plugin/3.1.1/jandex-maven-plugin-3.1.1.jar
urls[1] = file:/C:/Users/cbeikov/.m2/repository/org/codehaus/plexus/plexus-utils/3.5.0/plexus-utils-3.5.0.jar
urls[2] = file:/C:/Users/cbeikov/.m2/repository/io/smallrye/jandex/3.1.1/jandex-3.1.1.jar
Number of foreign imports: 1
import: Entry[import from realm ClassRealm[maven.api, parent: null]]
-----------------------------------------------------
at org.apache.maven.plugin.DefaultBuildPluginManager.executeMojo (DefaultBuildPluginManager.java:199)
at org.apache.maven.lifecycle.internal.MojoExecutor.execute (MojoExecutor.java:210)
at org.apache.maven.lifecycle.internal.MojoExecutor.execute (MojoExecutor.java:156)
at org.apache.maven.lifecycle.internal.MojoExecutor.execute (MojoExecutor.java:148)
at org.apache.maven.lifecycle.internal.LifecycleModuleBuilder.buildProject (LifecycleModuleBuilder.java:117)
at org.apache.maven.lifecycle.internal.LifecycleModuleBuilder.buildProject (LifecycleModuleBuilder.java:81)
at org.apache.maven.lifecycle.internal.builder.singlethreaded.SingleThreadedBuilder.build (SingleThreadedBuilder.java:56)
at org.apache.maven.lifecycle.internal.LifecycleStarter.execute (LifecycleStarter.java:128)
at org.apache.maven.DefaultMaven.doExecute (DefaultMaven.java:305)
at org.apache.maven.DefaultMaven.doExecute (DefaultMaven.java:192)
at org.apache.maven.DefaultMaven.execute (DefaultMaven.java:105)
at org.apache.maven.cli.MavenCli.execute (MavenCli.java:957)
at org.apache.maven.cli.MavenCli.doMain (MavenCli.java:289)
at org.apache.maven.cli.MavenCli.main (MavenCli.java:193)
at jdk.internal.reflect.DirectMethodHandleAccessor.invoke (DirectMethodHandleAccessor.java:103)
at java.lang.reflect.Method.invoke (Method.java:578)
at org.codehaus.plexus.classworlds.launcher.Launcher.launchEnhanced (Launcher.java:282)
at org.codehaus.plexus.classworlds.launcher.Launcher.launch (Launcher.java:225)
at org.codehaus.plexus.classworlds.launcher.Launcher.mainWithExitCode (Launcher.java:406)
at org.codehaus.plexus.classworlds.launcher.Launcher.main (Launcher.java:347)
at jdk.internal.reflect.DirectMethodHandleAccessor.invoke (DirectMethodHandleAccessor.java:103)
at java.lang.reflect.Method.invoke (Method.java:578)
at org.apache.maven.wrapper.BootstrapMainStarter.start (BootstrapMainStarter.java:39)
at org.apache.maven.wrapper.WrapperExecutor.execute (WrapperExecutor.java:122)
at org.apache.maven.wrapper.MavenWrapperMain.main (MavenWrapperMain.java:61)
Caused by: java.lang.ClassCastException: class java.lang.Object cannot be cast to class [B (java.lang.Object and [B are in module java.base of loader 'bootstrap')
at org.jboss.jandex.StrongInternPool$ByteArrayInternPool.hash (StrongInternPool.java:625)
at org.jboss.jandex.StrongInternPool.intern (StrongInternPool.java:237)
at org.jboss.jandex.NameTable.intern (NameTable.java:101)
at org.jboss.jandex.IndexWriterV2.deepIntern (IndexWriterV2.java:1027)
at org.jboss.jandex.IndexWriterV2.addMethodList (IndexWriterV2.java:1011)
at org.jboss.jandex.IndexWriterV2.addClass (IndexWriterV2.java:932)
at org.jboss.jandex.IndexWriterV2.buildTables (IndexWriterV2.java:888)
at org.jboss.jandex.IndexWriterV2.write (IndexWriterV2.java:199)
at org.jboss.jandex.IndexWriter.write (IndexWriter.java:102)
at org.jboss.jandex.IndexWriter.write (IndexWriter.java:66)
at org.jboss.jandex.maven.JandexGoal.execute (JandexGoal.java:172)
at org.apache.maven.plugin.DefaultBuildPluginManager.executeMojo (DefaultBuildPluginManager.java:137)
at org.apache.maven.lifecycle.internal.MojoExecutor.execute (MojoExecutor.java:210)
at org.apache.maven.lifecycle.internal.MojoExecutor.execute (MojoExecutor.java:156)
at org.apache.maven.lifecycle.internal.MojoExecutor.execute (MojoExecutor.java:148)
at org.apache.maven.lifecycle.internal.LifecycleModuleBuilder.buildProject (LifecycleModuleBuilder.java:117)
at org.apache.maven.lifecycle.internal.LifecycleModuleBuilder.buildProject (LifecycleModuleBuilder.java:81)
at org.apache.maven.lifecycle.internal.builder.singlethreaded.SingleThreadedBuilder.build (SingleThreadedBuilder.java:56)
at org.apache.maven.lifecycle.internal.LifecycleStarter.execute (LifecycleStarter.java:128)
at org.apache.maven.DefaultMaven.doExecute (DefaultMaven.java:305)
at org.apache.maven.DefaultMaven.doExecute (DefaultMaven.java:192)
at org.apache.maven.DefaultMaven.execute (DefaultMaven.java:105)
at org.apache.maven.cli.MavenCli.execute (MavenCli.java:957)
at org.apache.maven.cli.MavenCli.doMain (MavenCli.java:289)
at org.apache.maven.cli.MavenCli.main (MavenCli.java:193)
at jdk.internal.reflect.DirectMethodHandleAccessor.invoke (DirectMethodHandleAccessor.java:103)
at java.lang.reflect.Method.invoke (Method.java:578)
at org.codehaus.plexus.classworlds.launcher.Launcher.launchEnhanced (Launcher.java:282)
at org.codehaus.plexus.classworlds.launcher.Launcher.launch (Launcher.java:225)
at org.codehaus.plexus.classworlds.launcher.Launcher.mainWithExitCode (Launcher.java:406)
at org.codehaus.plexus.classworlds.launcher.Launcher.main (Launcher.java:347)
at jdk.internal.reflect.DirectMethodHandleAccessor.invoke (DirectMethodHandleAccessor.java:103)
at java.lang.reflect.Method.invoke (Method.java:578)
at org.apache.maven.wrapper.BootstrapMainStarter.start (BootstrapMainStarter.java:39)
at org.apache.maven.wrapper.WrapperExecutor.execute (WrapperExecutor.java:122)
at org.apache.maven.wrapper.MavenWrapperMain.main (MavenWrapperMain.java:61)
No, that doesn't seem to reproduce. Do you have a Maven project I can clone and build myself? https://github.com/Blazebit/blaze-persistence doesn't seem to use Jandex 3.1.1 anywhere :thinking:
I do. Checkout the contents of this PR and first build with .\mvnw clean install -P "hibernate-5.6,h2,spring-data-2.7.x,deltaspike-1.9" "-Duser.country=US" "-Duser.language=en" "-Dmaven.javadoc.skip" "-Dmain.java.version=21" "-Dtest.java.version=21" "-Djdk8.home=<PATH_TO_JDK_8>" -DskipTests
It will fail at that module, but then you can build just that single module by appending -pl .\integration\graphql-spqr\
And don't forget to make sure that your JAVA_HOME
env variable points to a JDK 21
OK, reproduced it now. Thanks!
OK, the issue is caused by the performance improvements made in Jandex 3.1.0. As part of those improvements, the hash table used for object interning was refactored to be more type-safe (with one subclass of the hash table per interned type), but the null
marker object was left unchanged (a single new Object()
instance). Replacing that global marker object with a per-subclass marker object solves the problem, but isn't exactly nice. I'll see if I can come up with something better.
I kept digging, because while my last comment is correct, there must be more to it, and indeed I found a really strange behavior of JDK 21.
Say I have these 2 classes:
public class Foo {
public Foo(String... strings) {
}
}
public class Bar {
public Foo getFoo() {
return new Foo() {};
}
}
Then compiling them using javac -g *.java
and then decompiling the inner class using javap -v -p Bar\$1.class
leads to the following results:
JDK 8, 11, 17:
...
Bar$1(Bar, java.lang.String...);
descriptor: (LBar;[Ljava/lang/String;)V
flags: ACC_VARARGS
Code:
stack=2, locals=3, args_size=3
0: aload_0
1: aload_1
2: putfield #1 // Field this$0:LBar;
5: aload_0
6: aload_2
7: invokespecial #2 // Method Foo."<init>":([Ljava/lang/String;)V
10: return
LineNumberTable:
line 3: 0
LocalVariableTable:
Start Length Slot Name Signature
0 11 0 this LBar$1;
0 11 1 this$0 LBar;
0 11 2 strings [Ljava/lang/String;
...
JDK 21-ea:
...
Bar$1(Bar, java.lang.String...);
descriptor: (LBar;[Ljava/lang/String;)V
flags: (0x0080) ACC_VARARGS
Code:
stack=2, locals=3, args_size=3
0: aload_0
1: aload_2
2: invokespecial #1 // Method Foo."<init>":([Ljava/lang/String;)V
5: return
LineNumberTable:
line 3: 0
LocalVariableTable:
Start Length Slot Name Signature
0 6 0 this LBar$1;
0 6 1 this$0 LBar;
0 6 2 strings [Ljava/lang/String;
MethodParameters:
Name Flags
<no name> final mandated
<no name>
...
That is, javac
from JDK 21-ea produces the MethodParameters
attribute even if -parameters
was not used. The attribute has a name_index
of 0
for each parameter, which is valid per the JVMS, but Jandex can't cope with it. So that needs fixing too.
Aside: if -parameters
is passed to javac
, then the MethodParameters
attribute is as-expected on all tested JDKs:
MethodParameters:
Name Flags
this$0 final mandated
strings
For historical reference, here are JDK issues that explain the differences in bytecode demonstrated above:
Trying to run the 3.1.1 Maven plugin with Java 21-ea, I get the following error:
Any idea what the issue could be?
Apache Maven 3.6.3 (cecedd343002696d0abb50b32b541b8a6ba2883f) Maven home: /home/runner/.m2/wrapper/dists/apache-maven-3.6.3-bin/1iopthnavndlasol9gbrbg6bf2/apache-maven-3.6.3 Java version: 21-ea, vendor: Azul Systems, Inc., runtime: /opt/hostedtoolcache/Java_Zulu_jdk/21.0.0-ea.22/x64 Default locale: en, platform encoding: UTF-8 OS name: "linux", version: "5.15.0-1037-azure", arch: "amd64", family: "unix"