Skip to content

Commit fd2925f

Browse files
committed
fallback to application class loader if available
1 parent 4931115 commit fd2925f

File tree

4 files changed

+40
-20
lines changed

4 files changed

+40
-20
lines changed

Sources/SwiftJava/AnyJavaObject.swift

Lines changed: 32 additions & 17 deletions
Original file line numberDiff line numberDiff line change
@@ -102,23 +102,39 @@ extension AnyJavaObject {
102102
in environment: JNIEnvironment,
103103
_ body: (jclass) throws -> Result
104104
) throws -> Result {
105-
let resolvedClass = try environment.translatingJNIExceptions {
106-
environment.interface.FindClass(
107-
environment,
108-
fullJavaClassNameWithSlashes
109-
)
110-
}!
111-
return try body(resolvedClass)
105+
do {
106+
let resolvedClass = try environment.translatingJNIExceptions {
107+
environment.interface.FindClass(
108+
environment,
109+
fullJavaClassNameWithSlashes
110+
)
111+
}!
112+
return try body(resolvedClass)
113+
} catch {
114+
// If we are in a Java environment where we have loaded
115+
// SwiftJava dynamically, we have access to the application class loader
116+
// so lets try that as as a fallback
117+
if let applicationClassLoader = JNI.shared?.applicationClassLoader {
118+
return try _withJNIClassFromCustomClassLoader(
119+
applicationClassLoader,
120+
in: environment
121+
) { applicationLoadedClass in
122+
return try body(applicationLoadedClass)
123+
}
124+
} else {
125+
throw error
126+
}
127+
}
112128
}
113129

114130
/// Retrieve the Java class for this type using a specific class loader.
115131
private static func _withJNIClassFromCustomClassLoader<Result>(
116132
_ classLoader: JavaClassLoader,
117133
in environment: JNIEnvironment,
118-
_ body: (jclass?) throws -> Result
134+
_ body: (jclass) throws -> Result
119135
) throws -> Result {
120-
let resolvedClass = try? classLoader.findClass(fullJavaClassName)
121-
return try body(resolvedClass?.javaThis)
136+
let resolvedClass = try classLoader.findClass(fullJavaClassName)
137+
return try body(resolvedClass!.javaThis)
122138
}
123139

124140
/// Retrieve the Java class for this type and execute body().
@@ -129,16 +145,15 @@ extension AnyJavaObject {
129145
) throws -> Result {
130146
if let AnyJavaObjectWithCustomClassLoader = self as? AnyJavaObjectWithCustomClassLoader.Type,
131147
let customClassLoader = try AnyJavaObjectWithCustomClassLoader.getJavaClassLoader(in: environment) {
132-
try _withJNIClassFromCustomClassLoader(customClassLoader, in: environment) { clazz in
133-
guard let clazz else {
134-
// If the custom class loader did not find the class
135-
// let's look in the default class loader.
136-
return try _withJNIClassFromDefaultClassLoader(in: environment, body)
148+
do {
149+
return try _withJNIClassFromCustomClassLoader(customClassLoader, in: environment) { clazz in
150+
return try body(clazz)
137151
}
138-
return try body(clazz)
152+
} catch {
153+
return try _withJNIClassFromDefaultClassLoader(in: environment, body)
139154
}
140155
} else {
141-
try _withJNIClassFromDefaultClassLoader(in: environment, body)
156+
return try _withJNIClassFromDefaultClassLoader(in: environment, body)
142157
}
143158
}
144159
}

Sources/SwiftJava/JNI.swift

Lines changed: 4 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -22,7 +22,10 @@ import CSwiftJavaJNI
2222
/// from Java.
2323
package final class JNI {
2424
/// The shared JNI object, initialized by `JNI_OnLoad`
25-
package fileprivate(set) static var shared: JNI!
25+
///
26+
/// This may be `nil` in the case where `SwiftJava` is not loaded as a dynamic lib
27+
/// by the Java sources.
28+
package fileprivate(set) static var shared: JNI?
2629

2730
/// The default application class loader
2831
package let applicationClassLoader: JavaClassLoader

Sources/SwiftJavaRuntimeSupport/_JNIMethodIDCache.swift

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -55,7 +55,8 @@ public final class _JNIMethodIDCache: Sendable {
5555
// Clear any ClassNotFound exceptions from FindClass
5656
environment.interface.ExceptionClear(environment)
5757

58-
if let javaClass = try? JNI.shared.applicationClassLoader.loadClass(
58+
// OK to force unwrap, we are in a jextract environment.
59+
if let javaClass = try? JNI.shared!.applicationClassLoader.loadClass(
5960
className.replacingOccurrences(of: "/", with: ".")
6061
) {
6162
clazz = javaClass.javaThis

Sources/SwiftJavaRuntimeSupport/generated/JavaJNISwiftInstance.swift

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -20,6 +20,7 @@ public struct JavaJNISwiftInstance: AnyJavaObjectWithCustomClassLoader {
2020
public func memoryAddress() -> Int64
2121

2222
public static func getJavaClassLoader(in environment: JNIEnvironment) throws -> JavaClassLoader! {
23-
JNI.shared.applicationClassLoader
23+
// OK to force unwrap, we are in a jextract environment.
24+
JNI.shared!.applicationClassLoader
2425
}
2526
}

0 commit comments

Comments
 (0)