Open magreenblatt opened 5 years ago
Original comment by Simon Haisz (Bitbucket: sihaisz, GitHub: sihaisz).
This issue happens because another classloader already loaded jawt.dll for some purpose. We ran into this issue because the Java Access Bridge (used for accessibility) loaded the dll first. Likely IDEA itself that is doing it. The annoying thing is that there is no way to check if a native dll is already loaded apart from trying and catching this exception. This is made more annoying because UnsatisfiedLinkError is used for a variety of errors, some of which should cause your program to crash, so you have to resort to checking the exception message.
This is the work around that we ended up using:
#!java
try {
System.loadLibrary("jawt"); //$NON-NLS-1$
} catch(UnsatisfiedLinkError e) {
String message = e.getMessage();
if(!message.startsWith("Native Library") || !message.endsWith("already loaded in another classloader")) { //$NON-NLS-1$ //$NON-NLS-2$
throw e;
}
System.out.println("Failed loading jawt.dll. It is already loaded by another classloader."); //$NON-NLS-1$
}
Something like this should probably be promoted to master. We didn't create a PR because we have other changes around initialization that only apply to our application. If you are concerned about trusting your program flow to an exception message that could be changed in any release (and you should be...) please note that our workaround has been in production for 3 years and we haven't had to touch it since.
Original comment by Nol Moonen (Bitbucket: nolmoonen, GitHub: nolmoonen).
Hello, I am having the exact same issue with IDEA. However, I stumbled upon a way to check if the library is loaded, without relying on this exception message flow. It basically comes down to:
try {
java.lang.reflect.Field libraryNames;
libraryNames = ClassLoader.class.getDeclaredField("loadedLibraryNames");
libraryNames.setAccessible(true);
Vector<String> libraries = (Vector<String>) libraryNames.get(ClassLoader.getSystemClassLoader());
if (!libraries.contains("jawt")) {
System.loadLibrary("jawt");
}
} catch (NoSuchFieldException | IllegalAccessException e) {
e.printStackTrace();
}
I am quite unsure whether this is something you'd want on the master branch, since it seems like a hack. However, it is still a serious issue to me. Should I make a pull request for this?
Original comment by Max Senft (Bitbucket: Max Senft).
Hmhm, as there’s a pull request (https://bitbucket.org/chromiumembedded/java-cef/pull-requests/39/fix-loading-already-loaded-native-library/diff) now, I wonder if this is actually the correct solution. It looks more like a workaround to me, as the Java documentation states that subsequent calls of loadLibrary()
will be ignored (see https://docs.oracle.com/javase/8/docs/api/java/lang/Runtime.html#loadLibrary-java.lang.String-).
I tested this problem by myself, by loading the "jawt" library immediately in Main()
of my program and did not get an exception later, when loading the JCEF…
I believe applications should now be able to work around this issue with the SystemBootstrap class added in fbfa9202 (bb).
If SystemBootstrap is insufficient we can re-open.
Original report by Leah (Bitbucket: Leah, GitHub: Leah).
I'm trying to write a plugin for IDEA which integrates chromium as a webview, not sure if this error is on me, but any help would be appreciated
It's loaded from here https://bitbucket.org/chromiumembedded/java-cef/src/d64cd6c266d5a9fc485bdfb6d5b672201dc5dfc7/java/org/cef/CefApp.java?at=master#lines-138