Hi all,
We updated the target platform to 2021-09 for our Eclipse RCP application that uses JOGL (via Jzy3d) and found an issue. When JOGL's SWTAccessor class is loaded (for a NewtCanvasSWT or GLCanvas), it initializes some field to point to methods in SWT's internal classes. The recent release of SWT 4.21 separated some gtk methods off to gtk3 and gtk4 specific bindings. This breaks the initialization code when looking for gtk_widget_get_window. The patch below fixes this. I can provide a PR on https://github.com/sgothel/jogl if that's more convenient. Best regards, Peter ---8<--- --- SWTAccessor.java.orig 2022-02-16 10:22:07.702204475 +0000 +++ SWTAccessor.java 2022-02-16 10:25:38.589674850 +0000 @@ -95,6 +95,7 @@ private static final String str_OS_gtk_class = "org.eclipse.swt.internal.gtk.OS"; // used by earlier versions of SWT private static final String str_GTK_gtk_class = "org.eclipse.swt.internal.gtk.GTK"; // used by later versions of SWT + private static final String str_GTK3_gtk_class = "org.eclipse.swt.internal.gtk3.GTK3"; // used by later versions of SWT (4.21+) private static final String str_GDK_gtk_class = "org.eclipse.swt.internal.gtk.GDK"; // used by later versions of SWT public static final Class<?> OS_gtk_class; private static final String str_OS_gtk_version = "GTK_VERSION"; @@ -124,6 +125,8 @@ private static final String str_gdk_window_set_back_pixmap = "gdk_window_set_back_pixmap"; private static final String str_gdk_window_set_background_pattern = "gdk_window_set_background_pattern"; + private static final int SWT_VERSION_4_21 = 4946; + private static final VersionNumber GTK_VERSION_2_14_0 = new VersionNumber(2, 14, 0); private static final VersionNumber GTK_VERSION_2_24_0 = new VersionNumber(2, 24, 0); private static final VersionNumber GTK_VERSION_2_90_0 = new VersionNumber(2, 90, 0); @@ -261,7 +264,12 @@ _gtk_version = GTK_VERSION(field_OS_gtk_version.getInt(null)); m1 = cGTK.getDeclaredMethod(str_gtk_widget_realize, handleType); if (_gtk_version.compareTo(GTK_VERSION_2_14_0) >= 0) { - m4 = cGTK.getDeclaredMethod(str_gtk_widget_get_window, handleType); + if (SWT.getVersion() < SWT_VERSION_4_21) { + m4 = cGTK.getDeclaredMethod(str_gtk_widget_get_window, handleType); + } else { + Class<?> cGTK3 = ReflectionUtil.getClass(str_GTK3_gtk_class, false, cl); + m4 = cGTK3.getDeclaredMethod(str_gtk_widget_get_window, handleType); + } } else { m3 = cGTK.getDeclaredMethod(str_GTK_WIDGET_WINDOW, handleType); } ---8<--- |
Thanks for sharing this.
When I added natives for M1 / ARM64, I also had to add this SWT jar. Were you able to build and run without updating any SWT jar? Without any promise, there is a chance I rebuild JOGL soon. Having your PR on https://github.com/jzy3d/jogl would be helpful to integrate it in this release, so do not hesitate to push your work there. |
This post was updated on .
It works in a simple JUnit test but not in a plugin test owing to the Equinox class loader not finding the gtk3 package. I think the SWT gtk jar needs to export org.eclipse.swt.internal.gtk3.
Edit: here's the upstream bug https://bugs.eclipse.org/bugs/show_bug.cgi?id=577874 |
Hi Peter,
Now that the upstream bug in SWT allows you to test your patch, does it work in a "regular" Equinox plugins scenario ? And if so, have you been able to regenerate JOGL ? Or how do you plan to use your fix ? Any information appreciated as I am facing the exact same issue, and i have not decided yet what to do (wait for an "official" 2.4 release, use an "unofficial build" like the one produced by Martin, build our own versions... ?) Cheers Alexis |
Hi,
Just to report that I have been able to run JOGL on Eclipse 4.23 (2022-03) using the fix posted by Peter. Being in a regular Equinox/OSGI environment, I only had to duplicate SWTAcccessor.java, fix it, add it to the sources of the plugin where the JOGL libraries reside and voila ! this class is loaded by the ClassLoader instead of the one buried in JOGL jars. Obviously a temporary solution, but better than nothing for those who do not want to recompile JOGL or wait for a new version... Thanks guys ! Alexis |
In reply to this post by PeterC-DLS
I had the same error on Ubuntu, Eclipse 4.23 and successfully applied your patch after reading this post.
So a big thank you from my side! |
In reply to this post by Alexis Drogoul
Hi all,
Thanks for the feedback. I've add a PR sgothel/jogl#108.
Best regards,
Peter
|
Administrator
|
It's not the right place to fill bug reports, Github is only used as a mirror. You have to fill a bug report here:
https://jogamp.org/bugzilla/ If you don't have an account, contact me in private, I'll create one for you.
Julien Gouesse | Personal blog | Website
|
In reply to this post by Alexis Drogoul
Seems like SWT strikes again. Testing this solution againstSWT 4.26 (which comes with Eclipse 2022-12) fails with an error in SWTAccessor (either the patched one or the original one) under Linux (works well on Windows and macOS) Anyones has a clue about what has been changed in the access to GTK in this version ? |
Administrator
|
Maybe we have to take into account GTK 4 specific class in SWTAccessor. Moreover, you might have to use --add-opens with Java >= 9.
Julien Gouesse | Personal blog | Website
|
In reply to this post by Alexis Drogoul
Hi Alexis,
I think we should try looking for explanations around this version bump commit in SWT. Could you share the error message you encounter? That would help pointing to SWT classes and identify which class history to read... Behind this, the bad news is that SWTAccessor design does not easily allow to fix JOGL by overriding : most of this class work is triggered in the class initialization without any other caller than the classloader. I think the fix should require a JOGL rebuild. |
Hi Martin and gouessej,
I'm working with Alexis and here's the error stack we're having as requested by Martin: My thoughts is that the problem may, indeed, comes from the new GTK 4, but it also can come from some rework to be compatible with Wayland |
Hi all,
Just a quick update, I did try to compile our software with different version of SWT, and none of them works above Eclipse 2022-03 (SWT 4.21)... So I did a git diff between every files used in the patched SWTAccessor between SWT 4.21 and 4.22 (the problem should comes from here I guess), which is here : https://pastebin.com/miWipQJ3 Most of the modifications are in the file `Display.java`, but I can't really point out what could be breaking... Maybe something about callbacks ? I also made another diff with those same files but comparing SWT 4.21 and 4.26 (current latest release) : https://pastebin.com/xNawYsZs |
Hi,
What I find surprising is that the root cause of your problem is located here according to the stack trace Caused by: java.lang.NoSuchMethodException: org.eclipse.swt.internal.gtk.GDK.gdk_window_set_background_pattern(long,long) at java.base/java.lang.Class.getDeclaredMethod(Class.java:2675) at com.jogamp.nativewindow.swt.SWTAccessor.<clinit>(SWTAccessor.java:382) But there actually nothing related to getDeclaredMethod(..) or gdk_window_set_background_pattern at line 382 of SWTAccessor It should rather be line 281 if you work with Peter's patch, ... same if you are using the non patched SWTAccessor. Anyway, this suggests gdk_window_set_background_pattern disappeared, which is confirmed by reading the diff you made between 4.21 and 4.22. So a fix would be to change if (_gtk_version.compareTo(GTK_VERSION_2_90_0) >= 0) { mb = cGDK.getDeclaredMethod(str_gdk_window_set_background_pattern, handleType, handleType); } else { ma = cGTK.getDeclaredMethod(str_gdk_window_set_back_pixmap, handleType, handleType, boolean.class); } by something like this if (_gtk_version.compareTo(GTK_VERSION_2_90_0) >= 0) { if (_gtk_version.compareTo(GTK_VERSION_2_21_0) <= 0) mb = cGDK.getDeclaredMethod(str_gdk_window_set_background_pattern, handleType, handleType); } else { ma = cGTK.getDeclaredMethod(str_gdk_window_set_back_pixmap, handleType, handleType, boolean.class); } (but you should check wether str_gdk_window_set_back_pixmap is required or not as of 4.22). |
Hi,
Thanks a lot for your quick answer. We are using an adapted version of Peter's patch that you can find here. I did a stupid copy/paste replacing the code you pointed to me by the one you gave me, and it works on X11 !! 🥳 However, as the accessor check if the application is using the X11 backend, it crashes our soft' if ran using Wayland with this error log : It's a bit frustrating, but I guess it's pretty normal as JOGAMP only been dev for X11 compatibility so far 🤔🤔 |
Nice step! Maybe it is worth asking to the developers involved in the changes you pointed in your diff to get sure our change is fully relevant for GTK... they'll probably answer through github ticket! But more importantly Could you share the core dump file (.log) to better understand what's happening? I see no reason for JOGL to fail on wayland. I have seen JOGL working in several remote desktop scenarios... |
Administrator
|
I don't remember the details but Wayland isn't supported out of the box, a contributor did this:
https://github.com/udevbe/wayland-java-bindings
Julien Gouesse | Personal blog | Website
|
In reply to this post by Martin
Here you go : https://pastebin.com/vJTGjVst |
In reply to this post by Alexis Drogoul
Hi Alexis,
I red this message again today and found that it is a very good idea to "override" classes in JOGL that have a static initializer. I did something similar while debugging something in JAWTUtil class. Simply copy pasting JAWTUtil in the project from which the main program is ran ensures my JAWTUtil copy get loaded first, which then prevent JOGL from loading the original JAWTUtil. Do you think this kind of hack could be reliable? Are there scenarios where class loading could happen differently and this trick fail? I am mainly thinking of cases where class loading happens differently on the customer computer :) |
Administrator
|
No
Julien Gouesse | Personal blog | Website
|
Free forum by Nabble | Edit this page |