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

GraalVM: ClassNotFoundException: com.googlecode.lanterna.gui2.WindowShadowRenderer #584

Open
damnms opened this issue Oct 25, 2023 · 9 comments

Comments

@damnms
Copy link

damnms commented Oct 25, 2023

Hi, i have a little application and would love to create native images with graalvm.
Unfortunately, when i run the built native-image, i get:

Exception in thread "main" java.lang.ExceptionInInitializerError
        at com.googlecode.lanterna.gui2.AbstractTextGUI.<init>(AbstractTextGUI.java:60)
        at com.googlecode.lanterna.gui2.MultiWindowTextGUI.<init>(MultiWindowTextGUI.java:169)
        at com.googlecode.lanterna.gui2.MultiWindowTextGUI.<init>(MultiWindowTextGUI.java:76)
        at com.googlecode.lanterna.gui2.MultiWindowTextGUI.<init>(MultiWindowTextGUI.java:65)
        at jsfdl.adapters.CursesWindow.<init>(CursesWindow.java:52)
        at jsfdl.ApplicationConfiguration.getGui(ApplicationConfiguration.java:62)
        at jsfdl.adapters.GuiApplication.main(GuiApplication.java:10)
        at java.base@21.0.1/java.lang.invoke.LambdaForm$DMH/sa346b79c.invokeStaticInit(LambdaForm$DMH)
Caused by: java.lang.RuntimeException: java.lang.ClassNotFoundException: com.googlecode.lanterna.gui2.WindowShadowRenderer
        at com.googlecode.lanterna.graphics.AbstractTheme.instanceByClassName(AbstractTheme.java:154)
        at com.googlecode.lanterna.graphics.PropertyTheme.<init>(PropertyTheme.java:66)
        at com.googlecode.lanterna.bundle.DefaultTheme.<init>(DefaultTheme.java:11)
        at com.googlecode.lanterna.bundle.LanternaThemes.<clinit>(LanternaThemes.java:52)
        ... 8 more
Caused by: java.lang.ClassNotFoundException: com.googlecode.lanterna.gui2.WindowShadowRenderer
        at org.graalvm.nativeimage.builder/com.oracle.svm.core.hub.ClassForNameSupport.forName(ClassForNameSupport.java:122)
        at org.graalvm.nativeimage.builder/com.oracle.svm.core.hub.ClassForNameSupport.forName(ClassForNameSupport.java:86)
        at java.base@21.0.1/java.lang.Class.forName(DynamicHub.java:1346)
        at java.base@21.0.1/java.lang.Class.forName(DynamicHub.java:1309)
        at java.base@21.0.1/java.lang.Class.forName(DynamicHub.java:1302)
        at com.googlecode.lanterna.graphics.AbstractTheme.instanceByClassName(AbstractTheme.java:152)
        ... 11 more

line 52 of CursesWindow is: final WindowBasedTextGUI textGUI = new MultiWindowTextGUI(screen);

I assume its because of the dynamic loading in AbstractTheme.java:152, wondering if i can somehow manually "add" those classes that are required (for linux/windows/mac) to graalvm, so they are packaged.

@avl42
Copy link
Contributor

avl42 commented Oct 25, 2023 via email

@damnms
Copy link
Author

damnms commented Oct 25, 2023

all classes thare are instantiated by reflection are:
com.googlecode.lanterna.gui2.WindowShadowRenderer
com.googlecode.lanterna.gui2.FatWindowDecorationRenderer
com.googlecode.lanterna.gui2.Button$DefaultButtonRenderer

any idea how to use the direct renderer classes? guess thats the easiest workaround/solution

@avl42
Copy link
Contributor

avl42 commented Oct 26, 2023 via email

@damnms
Copy link
Author

damnms commented Oct 28, 2023

my build tool is gradle, i dont know how i can "whitelist" some classes. i guess that has to be done in the graalvm native image task.

i tried adding those classes that i need in my code, but that did not work:
i added System.out.println(GuiApplication.pullIn());//TODO: so nasty... :P in my static main, and the method contains:

       private static String pullIn() {
        return com.googlecode.lanterna.gui2.WindowShadowRenderer.class.toString() +
                com.googlecode.lanterna.gui2.FatWindowDecorationRenderer.class.toString() +
                com.googlecode.lanterna.gui2.Button.DefaultButtonRenderer.class.toString();
    }

when i run the compiled image, it says:

oli@fedora:~/IdeaProjects/jsfdlloader/build/native/nativeCompile$ ./jsfdlloader 
class com.googlecode.lanterna.gui2.WindowShadowRendererclass com.googlecode.lanterna.gui2.FatWindowDecorationRendererclass com.googlecode.lanterna.gui2.Button$DefaultButtonRenderer
Exception in thread "main" java.lang.ExceptionInInitializerError
        at com.googlecode.lanterna.gui2.AbstractTextGUI.<init>(AbstractTextGUI.java:60)
        at com.googlecode.lanterna.gui2.MultiWindowTextGUI.<init>(MultiWindowTextGUI.java:169)
        at com.googlecode.lanterna.gui2.MultiWindowTextGUI.<init>(MultiWindowTextGUI.java:76)
        at com.googlecode.lanterna.gui2.MultiWindowTextGUI.<init>(MultiWindowTextGUI.java:65)
        at org.gitlab.jsfdl.adapters.CursesWindow.<init>(CursesWindow.java:52)
        at org.gitlab.jsfdl.ApplicationConfiguration.getGui(ApplicationConfiguration.java:62)
        at org.gitlab.jsfdl.adapters.GuiApplication.main(GuiApplication.java:16)
        at java.base@21.0.1/java.lang.invoke.LambdaForm$DMH/sa346b79c.invokeStaticInit(LambdaForm$DMH)
Caused by: java.lang.RuntimeException: java.lang.ClassNotFoundException: com.googlecode.lanterna.gui2.WindowShadowRenderer
        at com.googlecode.lanterna.graphics.AbstractTheme.instanceByClassName(AbstractTheme.java:154)
        at com.googlecode.lanterna.graphics.PropertyTheme.<init>(PropertyTheme.java:66)
        at com.googlecode.lanterna.bundle.DefaultTheme.<init>(DefaultTheme.java:11)
        at com.googlecode.lanterna.bundle.LanternaThemes.<clinit>(LanternaThemes.java:52)
        ... 8 more
Caused by: java.lang.ClassNotFoundException: com.googlecode.lanterna.gui2.WindowShadowRenderer
        at org.graalvm.nativeimage.builder/com.oracle.svm.core.hub.ClassForNameSupport.forName(ClassForNameSupport.java:122)
        at org.graalvm.nativeimage.builder/com.oracle.svm.core.hub.ClassForNameSupport.forName(ClassForNameSupport.java:86)
        at java.base@21.0.1/java.lang.Class.forName(DynamicHub.java:1346)
        at java.base@21.0.1/java.lang.Class.forName(DynamicHub.java:1309)
        at java.base@21.0.1/java.lang.Class.forName(DynamicHub.java:1302)
        at com.googlecode.lanterna.graphics.AbstractTheme.instanceByClassName(AbstractTheme.java:152)
        ... 11 more

so i guess something is not working correctly. maybe the compiler removes that by some sort of optimization algorithm, no idea...

@damnms
Copy link
Author

damnms commented Oct 28, 2023

to make sure its not optimized away i used real instances and got the following outpu:
oli@fedora:~/IdeaProjects/jsfdlloader/build/native/nativeCompile$ ./jsfdlloader
com.googlecode.lanterna.gui2.WindowShadowRenderer@366774a6com.googlecode.lanterna.gui2.FatWindowDecorationRenderer@747e2db8com.googlecode.lanterna.gui2.Button$DefaultButtonRenderer@25ba116b
then the exceptions... as above

so the classes are there, they can be instantiated. seems like this is something else thats not working.

@damnms
Copy link
Author

damnms commented Oct 29, 2023

seems like #521 is the same problem

@avl42
Copy link
Contributor

avl42 commented Oct 29, 2023 via email

@damnms
Copy link
Author

damnms commented Oct 29, 2023

gradle does not really produce an executable, its just like maven. it has some addons/plugins that can e.g. create a shadowjar (aka fatjar). and gradle can handle graalvm - which really produces a standalone application.
so the problem is in graalvm's plugin for gradle, not gradle itself. at least for me it looks like that.

oli@fedora:~/IdeaProjects/jsfdlloader/build/native/nativeCompile$ file jsfdlloader 
jsfdlloader: ELF 64-bit LSB executable, x86-64, version 1 (SYSV), dynamically linked, interpreter /lib64/ld-linux-x86-64.so.2, BuildID[sha1]=c93142e2698f5f940ea91930f8b350512ebecb86, for GNU/Linux 3.2.0, with debug_info, not stripped

its a real executable and yes, graalvm supports reflection: https://www.graalvm.org/22.2/reference-manual/native-image/guides/build-with-reflection/

when i grep that binary or search with vim, i find some of those WindowShadowRenderer, so i am really lost whats going on

@damnms
Copy link
Author

damnms commented Nov 5, 2023

i think i got it working...
i was not sure if the tutorial also works with jar files, but it does
https://www.graalvm.org/22.2/reference-manual/native-image/guides/build-with-reflection/

first i created the shadow jar, which produces the mentioned errors above (classnotfound etc.).
so i executed the command like in the tutorial but a bit different.
i went into my $PROJECTROOT/build/libs and created a META-INF/native-image directory, then:
graalvm-jdk-21.0.1+12.1/bin/java -agentlib:native-image-agent=config-output-dir=META-INF/native-image -jar myapplication-all.jar
that produces some files in META-INF/native-image, which i moved then to $PROJECT_ROOT/src/main/resources.
With those, i re-created the shadowJar and checked that those files are inside the .jar under META-INF/native-image.
Then i was able to run graalvm-jdk-21.0.1+12.1/bin/native-image -jar myapplication-all.jar which produces the native-image.
so seems like, its a must have to have those configuration generated by graalvm. not sure if there is another way.

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

2 participants