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

Registration for reflection of non-public classes under java. fails silently #28431

Closed
zakkak opened this issue Oct 6, 2022 · 4 comments · Fixed by quarkusio/gizmo#126 or #28508
Closed
Assignees
Labels
area/native-image kind/bug Something isn't working
Milestone

Comments

@zakkak
Copy link
Contributor

zakkak commented Oct 6, 2022

Describe the bug

When registering a non-public class under java. for reflection the registration fails silently. This is happening because gizmo gets the class directly (not through reflection):

    private static void registerClass35(org.graalvm.nativeimage.hosted.Feature.BeforeAnalysisAccess var0) {
        try {
            Collections.EmptyList.class.getDeclaredConstructors();
            Collections.EmptyList.class.getDeclaredMethods();
            Collections.EmptyList.class.getDeclaredFields();
            Class[] var1 = new Class[]{Collections.EmptyList.class};
            RuntimeReflection.register(var1);
            registerSerializationForClass(Collections.EmptyList.class);
        } catch (Throwable var2) {
        }

    } 

However, Collections.EmptyList is private, as a result this is not going to work. Note here that we don't see any error due to #26162. The actual exception is:

java.lang.IllegalAccessError: failed to access class java.util.Collections$EmptyList from class io.quarkus.runner.Feature (java.util.Collections$EmptyList is in module java.base of loader 'bootstrap'; io.quarkus.runner.Feature is in unnamed module of loader com.oracle.svm.hosted.NativeImageClassLoaderSupport$ClassPathClassLoader @6d4b1c02)
	at io.quarkus.runner.Feature.registerClass35(Unknown Source)
	at io.quarkus.runner.Feature.beforeAnalysis(Unknown Source)
	at org.graalvm.nativeimage.builder/com.oracle.svm.hosted.NativeImageGenerator.lambda$runPointsToAnalysis$9(NativeImageGenerator.java:722)
	at org.graalvm.nativeimage.builder/com.oracle.svm.hosted.FeatureHandler.forEachFeature(FeatureHandler.java:78)
	at org.graalvm.nativeimage.builder/com.oracle.svm.hosted.NativeImageGenerator.runPointsToAnalysis(NativeImageGenerator.java:722)
	at org.graalvm.nativeimage.builder/com.oracle.svm.hosted.NativeImageGenerator.doRun(NativeImageGenerator.java:564)
	at org.graalvm.nativeimage.builder/com.oracle.svm.hosted.NativeImageGenerator.run(NativeImageGenerator.java:521)
	at org.graalvm.nativeimage.builder/com.oracle.svm.hosted.NativeImageGeneratorRunner.buildImage(NativeImageGeneratorRunner.java:407)
	at org.graalvm.nativeimage.builder/com.oracle.svm.hosted.NativeImageGeneratorRunner.build(NativeImageGeneratorRunner.java:585)
	at org.graalvm.nativeimage.builder/com.oracle.svm.hosted.NativeImageGeneratorRunner.main(NativeImageGeneratorRunner.java:128)

In contrast when registering a class that is not under java. the register method uses Class.forName which works for non-public methods as well and looks like this:

    private static void registerClass0(org.graalvm.nativeimage.hosted.Feature.BeforeAnalysisAccess var0) {
        try {
            ClassLoader var1 = Thread.currentThread().getContextClassLoader();
            Class var2 = Class.forName("org.apache.commons.pool2.impl.DefaultEvictionPolicy", (boolean)0, var1);
            Constructor[] var4 = var2.getDeclaredConstructors();
            var2.getDeclaredMethods();
            var2.getDeclaredFields();
            Class[] var3 = new Class[]{var2};
            RuntimeReflection.register(var3);
            RuntimeReflection.register((Executable[])var4);
        } catch (Throwable var5) {
        }

    }

Expected behavior

Registration of non-public classes should work.

Actual behavior

Registration of non-public classes fails silently.

How to Reproduce?

git clone git@github.com:jamesnetherton/camel-quarkus.git -b quarkus-main
./mvnw clean install -Dquickly -T1C
cd integration-tests/http
../../mvnw clean verify -Dnative -Ddocker

Thanks to @jamesnetherton

Output of uname -a or ver

No response

Output of java -version

openjdk version "17.0.4" 2022-07-19 OpenJDK Runtime Environment Temurin-17.0.4+8 (build 17.0.4+8) OpenJDK 64-Bit Server VM Temurin-17.0.4+8 (build 17.0.4+8, mixed mode, sharing)

GraalVM version (if different from Java)

22.0

Quarkus version or git rev

2.13.1 and ebb2c7b

Build tool (ie. output of mvnw --version or gradlew --version)

No response

Additional information

IMO the issue is in gizmo and should fixed there. In the meantime we might want to revert #28219 at least in 2.13, as that's the change that unveiled the issue.

cc @Sanne

@Sanne
Copy link
Member

Sanne commented Oct 6, 2022

We could revert #28219 - but as I mentioned in apache/camel-quarkus#4148 (comment) the issue only highlighted a previous issue, and that issue would still apply if someone were to use

  • io.quarkus.gizmo.BytecodeCreatorImpl#loadClass(java.lang.String)
    instead of
  • io.quarkus.gizmo.BytecodeCreatorImpl#loadClassFromTCCL(java.lang.String)

So I'd rather fix gizmo rather than reverting.

@zakkak
Copy link
Contributor Author

zakkak commented Oct 10, 2022

Re-opening as it depends on a new gizmo release and updating the BOM accordingly.

@zakkak zakkak reopened this Oct 10, 2022
@gsmet gsmet removed this from the 2.13.2.Final milestone Oct 11, 2022
@quarkus-bot quarkus-bot bot added this to the 2.14 - main milestone Oct 11, 2022
gsmet pushed a commit to quarkusio/gizmo that referenced this issue Oct 12, 2022
gsmet pushed a commit to quarkusio/gizmo that referenced this issue Oct 12, 2022
@jamesnetherton
Copy link
Contributor

@gsmet Will the fix for this get backported to 2.13? I see the issue got removed from the 2.13.2 milestone.

gsmet added a commit to gsmet/quarkus that referenced this issue Oct 12, 2022
@gsmet gsmet modified the milestones: 2.14 - main, 2.13.2.Final Oct 12, 2022
@gsmet
Copy link
Member

gsmet commented Oct 12, 2022

Yes, it will be in 2.13.2.Final.
I had to do a 1.1.1.Final release of Gizmo specifically, that's why there was some back and forth on the milestones.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
area/native-image kind/bug Something isn't working
Projects
None yet
5 participants