macOS: fixed crash when running in WebSwing (issue #826; regression in 3.4)

This commit is contained in:
Karl Tauber
2024-03-26 13:24:05 +01:00
parent 36e4071b7f
commit 5f5c225300
6 changed files with 16 additions and 10 deletions

View File

@@ -22,6 +22,7 @@ FlatLaf Change Log
incompatible native library) and to test whether native methods can be invoked incompatible native library) and to test whether native methods can be invoked
(some security software allows loading native library but blocks method (some security software allows loading native library but blocks method
invocation). invocation).
- macOS: Fixed crash when running in WebSwing. (issue #826; regression in 3.4)
## 3.4 ## 3.4

View File

@@ -42,5 +42,5 @@
jclass findClass( JNIEnv *env, const char* className, bool globalRef ); jclass findClass( JNIEnv *env, const char* className, bool globalRef );
jfieldID getFieldID( JNIEnv *env, const char* className, const char* fieldName, const char* fieldSignature, bool staticField ); jfieldID getFieldID( JNIEnv *env, jclass cls, const char* fieldName, const char* fieldSignature, bool staticField );
jmethodID getMethodID( JNIEnv *env, jclass cls, const char* methodName, const char* methodSignature, bool staticMethod ); jmethodID getMethodID( JNIEnv *env, jclass cls, const char* methodName, const char* methodSignature, bool staticMethod );

View File

@@ -38,10 +38,9 @@ jclass findClass( JNIEnv *env, const char* className, bool globalRef ) {
return cls; return cls;
} }
jfieldID getFieldID( JNIEnv *env, const char* className, const char* fieldName, const char* fieldSignature, bool staticField ) { jfieldID getFieldID( JNIEnv *env, jclass cls, const char* fieldName, const char* fieldSignature, bool staticField ) {
// NSLog( @"getFieldID %s %s %s", className, fieldName, fieldSignature ); // NSLog( @"getFieldID %s %s", fieldName, fieldSignature );
jclass cls = findClass( env, className, false );
if( cls == NULL ) if( cls == NULL )
return NULL; return NULL;
@@ -49,7 +48,7 @@ jfieldID getFieldID( JNIEnv *env, const char* className, const char* fieldName,
? env->GetStaticFieldID( cls, fieldName, fieldSignature ) ? env->GetStaticFieldID( cls, fieldName, fieldSignature )
: env->GetFieldID( cls, fieldName, fieldSignature ); : env->GetFieldID( cls, fieldName, fieldSignature );
if( fieldID == NULL ) { if( fieldID == NULL ) {
NSLog( @"FlatLaf: failed to lookup field '%s' of type '%s' in class '%s'", fieldName, fieldSignature, className ); NSLog( @"FlatLaf: failed to lookup field '%s' of type '%s'", fieldName, fieldSignature );
env->ExceptionDescribe(); // print stack trace env->ExceptionDescribe(); // print stack trace
env->ExceptionClear(); env->ExceptionClear();
return NULL; return NULL;

View File

@@ -52,21 +52,27 @@ NSWindow* getNSWindow( JNIEnv* env, jclass cls, jobject window ) {
if( window == NULL ) if( window == NULL )
return NULL; return NULL;
// initialize class IDs (done only once because variables are static)
static jclass lwWindowPeerClass = findClass( env, "sun/lwawt/LWWindowPeer", true );
static jclass cfRetainedResourceClass = findClass( env, "sun/lwawt/macosx/CFRetainedResource", true );
if( lwWindowPeerClass == NULL || cfRetainedResourceClass == NULL )
return NULL;
// initialize field IDs (done only once because variables are static) // initialize field IDs (done only once because variables are static)
static jfieldID peerID = getFieldID( env, "java/awt/Component", "peer", "Ljava/awt/peer/ComponentPeer;", false ); static jfieldID peerID = getFieldID( env, findClass( env, "java/awt/Component", false ), "peer", "Ljava/awt/peer/ComponentPeer;", false );
static jfieldID platformWindowID = getFieldID( env, "sun/lwawt/LWWindowPeer", "platformWindow", "Lsun/lwawt/PlatformWindow;", false ); static jfieldID platformWindowID = getFieldID( env, lwWindowPeerClass, "platformWindow", "Lsun/lwawt/PlatformWindow;", false );
static jfieldID ptrID = getFieldID( env, "sun/lwawt/macosx/CFRetainedResource", "ptr", "J", false ); static jfieldID ptrID = getFieldID( env, cfRetainedResourceClass, "ptr", "J", false );
if( peerID == NULL || platformWindowID == NULL || ptrID == NULL ) if( peerID == NULL || platformWindowID == NULL || ptrID == NULL )
return NULL; return NULL;
// get field java.awt.Component.peer // get field java.awt.Component.peer
jobject peer = env->GetObjectField( window, peerID ); jobject peer = env->GetObjectField( window, peerID );
if( peer == NULL ) if( peer == NULL || !env->IsInstanceOf( peer, lwWindowPeerClass ) )
return NULL; return NULL;
// get field sun.lwawt.LWWindowPeer.platformWindow // get field sun.lwawt.LWWindowPeer.platformWindow
jobject platformWindow = env->GetObjectField( peer, platformWindowID ); jobject platformWindow = env->GetObjectField( peer, platformWindowID );
if( platformWindow == NULL ) if( platformWindow == NULL || !env->IsInstanceOf( platformWindow, cfRetainedResourceClass ) )
return NULL; return NULL;
// get field sun.lwawt.macosx.CFRetainedResource.ptr // get field sun.lwawt.macosx.CFRetainedResource.ptr