Skip to content

Commit

Permalink
(multi-os-engine/multi-os-engine#160) Throw proper exception if same …
Browse files Browse the repository at this point in the history
…ObjC class is preregistered with multiple Java hybrid classes
  • Loading branch information
Noisyfox committed Jan 16, 2022
1 parent 81673f2 commit 8151dec
Showing 1 changed file with 23 additions and 5 deletions.
28 changes: 23 additions & 5 deletions src/main/native/natj/ObjCRuntime.mm
Original file line number Diff line number Diff line change
Expand Up @@ -238,30 +238,48 @@ bool handleObjCStartup(JNIEnv* env, jclass clazz) {

if (objcClass != nil) {
Class objcMetaClass = object_getClass(objcClass);

jstring javaName =
(jstring)env->CallObjectMethod(clazz, gGetClassNameMethod);
const char* javaCName = env->GetStringUTFChars(javaName, NULL);

// Swizzle the initializer
IMP original = class_replaceMethod(objcMetaClass, @selector(initialize),
(IMP)initialize_hybrid, "v@:");
if (original) {
if (original == (IMP)initialize_hybrid) {
// Same class get bind twice!

NSString* existingClassName;
@synchronized(gObjCHybridMap) {
existingClassName = [gObjCHybridMap objectForKey:[NSValue valueWithPointer:objcClass]];
}

@throw [NSException
exceptionWithName:@"IllegalArgumentException"
reason:[NSString stringWithFormat:@"Attempt to preregister ObJC class \"%@\" with Java class \"%@\", which has already been preregistered with Java class \"%@\"",
[NSString stringWithUTF8String:nativeCName],
[[NSString stringWithUTF8String:javaCName] stringByReplacingOccurrencesOfString:@"." withString:@"/"],
existingClassName]
userInfo:nil];
}

class_addMethod(objcMetaClass, gObjCOriginalInitializeSelector, original,
"v@:");
}

// Store Java name
@synchronized(gObjCHybridMap) {
jstring javaName =
(jstring)env->CallObjectMethod(clazz, gGetClassNameMethod);
const char* javaCName = env->GetStringUTFChars(javaName, NULL);
@autoreleasepool {
// We use NSValue to avoid invokation of +initialize
[gObjCHybridMap setObject:[[NSString stringWithUTF8String:javaCName]
stringByReplacingOccurrencesOfString:@"."
withString:@"/"]
forKey:[NSValue valueWithPointer:objcClass]];
}
env->ReleaseStringUTFChars(javaName, javaCName);
env->DeleteLocalRef(javaName);
}
env->ReleaseStringUTFChars(javaName, javaCName);
env->DeleteLocalRef(javaName);
}

env->ReleaseStringUTFChars(nativeName, nativeCName);
Expand Down

0 comments on commit 8151dec

Please sign in to comment.