Open damnms opened 1 year ago
Renderer classes are not directly accessed in Java-code, but dynamically loaded "by name" at runtime.
If you have a build-tool that will only pick classes that are "accessed", then these tools will not see the necessity of those extra classes, and thus not include them.
One workaround is, to directly use those Renderer-classes that you appear to need(based on thrown exceptions), in your own code, or maybe you can tell the build tool to add a given list of classes always - regardless of any analyzed need for those classes.
On Wed, Oct 25, 2023 at 10:17 AM damnms @.***> wrote:
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.
(AbstractTextGUI.java:60) at com.googlecode.lanterna.gui2.MultiWindowTextGUI. (MultiWindowTextGUI.java:169) at com.googlecode.lanterna.gui2.MultiWindowTextGUI. (MultiWindowTextGUI.java:76) at com.googlecode.lanterna.gui2.MultiWindowTextGUI. (MultiWindowTextGUI.java:65) at jsfdl.adapters.CursesWindow. (CursesWindow.java:52) at jsfdl.ApplicationConfiguration.getGui(ApplicationConfiguration.java:62) at jsfdl.adapters.GuiApplication.main(GuiApplication.java:10) at @./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. (PropertyTheme.java:66) at com.googlecode.lanterna.bundle.DefaultTheme. @./java.lang.Class.forName(DynamicHub.java:1346) at @./java.lang.Class.forName(DynamicHub.java:1309) at @./java.lang.Class.forName(DynamicHub.java:1302) at com.googlecode.lanterna.graphics.AbstractTheme.instanceByClassName(AbstractTheme.java:152) ... 11 more(DefaultTheme.java:11) at com.googlecode.lanterna.bundle.LanternaThemes. (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 line 52 of CursesWindow is: final WindowBasedTextGUI textGUI = new MultiWindowTextGUI(screen); So i assume its something with MultiWindowTextGUI, but thats just me guessing :)
— Reply to this email directly, view it on GitHub https://github.com/mabe02/lanterna/issues/584, or unsubscribe https://github.com/notifications/unsubscribe-auth/ABIDBMSWK6WMJG2ZHRERL3TYBDDLBAVCNFSM6AAAAAA6O6IQH2VHI2DSMVQWIX3LMV43ASLTON2WKOZRHE3DAOBRHA4DMNI . You are receiving this because you are subscribed to this thread.Message ID: @.***>
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
I'd really suggest adding the classes to some "white-list" of the build tool. That would be the cleanest solution.
If you don't want to deal with the specifics of the build-tool, then you can try the following tricks: To a class that is already included in the build, like e.g. the main class of your project, you add a dummy() method like:
public int pullIn() {
return WindowShadowRenderer.class.toString().length() +
FatWindowDecorationRenderer.class.toString().length() +
...;
}
Try it - I'd think it will already pull in all these classes - don't
forget the import
for each fully qualified classname.
If some tooling complains about the unused method dummy(), you can
call dummy() and compare it's result to
be greater-or-equal to 0, which is a pretty safe bet, so you can make
some parts of your main method dependent
on whether dummy() >= 0
.
Not very nice, sure, so that's why I'd rather suggest manually configuring the build-tool to just unconditionally include those classes.
On Wed, Oct 25, 2023 at 3:04 PM damnms @.***> wrote:
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
— Reply to this email directly, view it on GitHub, or unsubscribe. You are receiving this because you commented.Message ID: @.***>
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...
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.
seems like https://github.com/mabe02/lanterna/issues/521 is the same problem
ah, that's why i had that deja-vu...
so, you still get the same classnotfound exception?
what kind of "executable" does gradle produce? is it still essentially a zipfile, or something completely different? Does such a gradle program thing even support dynamic loading of classes in the first place?
damnms @.***> schrieb am So., 29. Okt. 2023, 09:52:
seems like #521 https://github.com/mabe02/lanterna/issues/521 is the same problem
— Reply to this email directly, view it on GitHub https://github.com/mabe02/lanterna/issues/584#issuecomment-1784038100, or unsubscribe https://github.com/notifications/unsubscribe-auth/ABIDBMQ7IISW3I4C2J5WJYLYBYDL5AVCNFSM6AAAAAA6O6IQH2VHI2DSMVQWIX3LMV43OSLTON2WKQ3PNVWWK3TUHMYTOOBUGAZTQMJQGA . You are receiving this because you commented.Message ID: @.***>
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
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.
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:
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.