IDEA-277709: cache jclass objects

empiric observation: JNI can't find loaded class when
1. class is located in signed jar
2. class was requested from AppKit thread (when JNIEnv is obtained via global JavaVM)

GitOrigin-RevId: 02b275c3696a9903c3805346ae2bbebe863f8449
This commit is contained in:
Artem Bochkarev
2021-10-18 13:48:07 +07:00
committed by intellij-monorepo-bot
parent 67208bb7fa
commit 242bc6167a
3 changed files with 23 additions and 2 deletions

Binary file not shown.

View File

@@ -225,6 +225,15 @@ Java_com_intellij_ui_mac_screenmenu_Menu_nativeRefillMainMenu
(JNIEnv *env, jclass peerClass, jlongArray newItems)
{
JNI_COCOA_ENTER();
if (sjc_Menu == NULL) {
// Cache Menu jclass, because JNI can't find it when:
// 1. class in signed JAR
// 2. class requested in AppKit-thread
sjc_Menu = peerClass;
if (sjc_Menu != NULL) {
sjc_Menu = (*env)->NewGlobalRef(env, sjc_Menu);
}
}
// 1. create copy of array
jsize length = (*env)->GetArrayLength(env, newItems);

View File

@@ -7,6 +7,7 @@
#import "java_awt_event_InputEvent.h"
static JavaVM *g_jvm = NULL;
static jclass sjc_MenuItem = NULL;
void initGlobalVMPtr(JNIEnv * env) {
if (g_jvm == NULL) {
@@ -81,8 +82,8 @@ NSString* JavaStringToNSString(JNIEnv *env, jstring jstr) {
JNI_COCOA_ENTER();
JNIEnv *env = getAppKitEnv();
DECLARE_CLASS(jc_MenuItem, "com/intellij/ui/mac/screenmenu/MenuItem");
DECLARE_METHOD(jm_handleAction, jc_MenuItem, "handleAction", "(I)V");
GET_CLASS(sjc_MenuItem, "com/intellij/ui/mac/screenmenu/MenuItem");
DECLARE_METHOD(jm_handleAction, sjc_MenuItem, "handleAction", "(I)V");
NSEvent *currEvent = [[NSApplication sharedApplication] currentEvent];
NSUInteger modifiers = [currEvent modifierFlags];
@@ -268,6 +269,17 @@ Java_com_intellij_ui_mac_screenmenu_MenuItem_nativeCreate
{
initGlobalVMPtr(env);
if (sjc_MenuItem == NULL) {
// Cache MenuItem jclass, because JNI can't find it when:
// 1. class in signed JAR
// 2. class requested in AppKit-thread
jclass peerClass = (*env)->GetObjectClass(env, peer);
sjc_MenuItem = peerClass;
if (sjc_MenuItem != NULL) {
sjc_MenuItem = (*env)->NewGlobalRef(env, sjc_MenuItem);
}
}
JNI_COCOA_ENTER();
jobject javaPeer = (*env)->NewGlobalRef(env, peer);
const BOOL asSeparator = (isSeparator == JNI_TRUE) ? YES: NO;