Skip to content

Commit 98038f9

Browse files
authored
Merge branch 'main' into wip-build-cleanup
2 parents 721cb77 + a64f805 commit 98038f9

17 files changed

+88
-42
lines changed

Package.swift

Lines changed: 0 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -53,37 +53,31 @@ let package = Package(
5353
// ==== JavaKit (i.e. calling Java directly Swift utilities)
5454
.library(
5555
name: "JavaKit",
56-
type: .dynamic,
5756
targets: ["JavaKit"]
5857
),
5958

6059
.library(
6160
name: "JavaKitJar",
62-
type: .dynamic,
6361
targets: ["JavaKitReflection"]
6462
),
6563

6664
.library(
6765
name: "JavaKitNetwork",
68-
type: .dynamic,
6966
targets: ["JavaKitReflection"]
7067
),
7168

7269
.library(
7370
name: "JavaKitReflection",
74-
type: .dynamic,
7571
targets: ["JavaKitReflection"]
7672
),
7773

7874
.library(
7975
name: "JavaKitVM",
80-
type: .dynamic,
8176
targets: ["JavaKitVM"]
8277
),
8378

8479
.library(
8580
name: "JavaTypes",
86-
type: .dynamic,
8781
targets: ["JavaTypes"]
8882
),
8983

@@ -108,7 +102,6 @@ let package = Package(
108102

109103
.library(
110104
name: "JExtractSwift",
111-
type: .dynamic,
112105
targets: ["JExtractSwift"]
113106
),
114107

Sources/Java2Swift/JavaToSwift.swift

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -19,7 +19,6 @@ import JavaKitJar
1919
import JavaKitNetwork
2020
import JavaKitReflection
2121
import JavaKitVM
22-
import JavaRuntime
2322
import SwiftSyntax
2423
import SwiftSyntaxBuilder
2524

Sources/JavaKit/AnyJavaObject.swift

Lines changed: 7 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -81,10 +81,12 @@ extension AnyJavaObject {
8181
}
8282

8383
/// Retrieve the Java class for this type.
84-
public static func getJNIClass(in environment: JNIEnvironment) -> jclass? {
85-
return environment.interface.FindClass(
86-
environment,
87-
fullJavaClassNameWithSlashes
88-
)
84+
public static func getJNIClass(in environment: JNIEnvironment) throws -> jclass {
85+
try environment.translatingJNIExceptions {
86+
environment.interface.FindClass(
87+
environment,
88+
fullJavaClassNameWithSlashes
89+
)
90+
}!
8991
}
9092
}

Sources/JavaKit/BridgedValues/JavaValue+Array.swift

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -12,7 +12,6 @@
1212
//
1313
//===----------------------------------------------------------------------===//
1414

15-
import JavaRuntime
1615
import JavaTypes
1716

1817
extension Array: JavaValue where Element: JavaValue {

Sources/JavaKit/BridgedValues/JavaValue+Bool.swift

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -12,7 +12,6 @@
1212
//
1313
//===----------------------------------------------------------------------===//
1414

15-
import JavaRuntime
1615
import JavaTypes
1716

1817
extension Bool: JavaValue {

Sources/JavaKit/BridgedValues/JavaValue+FloatingPoint.swift

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -12,7 +12,6 @@
1212
//
1313
//===----------------------------------------------------------------------===//
1414

15-
import JavaRuntime
1615
import JavaTypes
1716

1817
extension Float: JavaValue {

Sources/JavaKit/BridgedValues/JavaValue+Integers.swift

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -12,7 +12,6 @@
1212
//
1313
//===----------------------------------------------------------------------===//
1414

15-
import JavaRuntime
1615
import JavaTypes
1716

1817
extension Int8: JavaValue {

Sources/JavaKit/BridgedValues/JavaValue+String.swift

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -12,7 +12,6 @@
1212
//
1313
//===----------------------------------------------------------------------===//
1414

15-
import JavaRuntime
1615
import JavaTypes
1716

1817
extension String: JavaValue {

Sources/JavaKit/Exceptions/ExceptionHandling.swift

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -42,7 +42,7 @@ extension JNIEnvironment {
4242
// Otherwise, create a exception with a message.
4343
_ = interface.ThrowNew(
4444
self,
45-
JavaClass<Exception>.getJNIClass(in: self),
45+
try! JavaClass<Exception>.getJNIClass(in: self),
4646
String(describing: error)
4747
)
4848
}

Sources/JavaKit/JavaClass.swift

Lines changed: 9 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -17,4 +17,12 @@ import JavaRuntime
1717
/// Wrapper around a Java class that provides access to the static members of
1818
/// the class.
1919
@JavaClass("java.lang.Class")
20-
public struct JavaClass<ObjectType: AnyJavaObject> { }
20+
public struct JavaClass<ObjectType: AnyJavaObject> {
21+
/// Lookup this Java class within the given environment.
22+
public init(in environment: JNIEnvironment) throws {
23+
self.init(
24+
javaThis: try ObjectType.getJNIClass(in: environment),
25+
environment: environment
26+
)
27+
}
28+
}

Sources/JavaKit/JavaObject+Inheritance.swift

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -27,7 +27,7 @@ extension AnyJavaObject {
2727
private func isInstanceOf<OtherClass: AnyJavaObject>(
2828
_ otherClass: OtherClass.Type
2929
) -> jclass? {
30-
guard let otherJavaClass = otherClass.getJNIClass(in: javaEnvironment) else {
30+
guard let otherJavaClass = try? otherClass.getJNIClass(in: javaEnvironment) else {
3131
return nil
3232
}
3333

Sources/JavaKit/JavaObject+MethodCalls.swift

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -247,7 +247,7 @@ extension AnyJavaObject {
247247
in environment: JNIEnvironment,
248248
arguments: repeat each Param
249249
) throws -> Self {
250-
let thisClass = Self.getJNIClass(in: environment)!
250+
let thisClass = try Self.getJNIClass(in: environment)
251251

252252
// Compute the method signature so we can find the right method, then look up the
253253
// method within the class.
Lines changed: 15 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,15 @@
1+
//===----------------------------------------------------------------------===//
2+
//
3+
// This source file is part of the Swift.org open source project
4+
//
5+
// Copyright (c) 2024 Apple Inc. and the Swift.org project authors
6+
// Licensed under Apache License v2.0
7+
//
8+
// See LICENSE.txt for license information
9+
// See CONTRIBUTORS.txt for the list of Swift.org project authors
10+
//
11+
// SPDX-License-Identifier: Apache-2.0
12+
//
13+
//===----------------------------------------------------------------------===//
14+
15+
@_exported import JavaRuntime

Sources/JavaKit/Optional+JavaObject.swift

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -70,7 +70,7 @@ extension Optional: JavaValue where Wrapped: AnyJavaObject {
7070

7171
public static func jniNewArray(in environment: JNIEnvironment) -> JNINewArray {
7272
return { environment, size in
73-
let jniClass = Wrapped.getJNIClass(in: environment)
73+
let jniClass = try! Wrapped.getJNIClass(in: environment)
7474
return environment.interface.NewObjectArray(environment, size, jniClass, nil)
7575
}
7676
}

Sources/JavaKitVM/JavaVirtualMachine.swift

Lines changed: 27 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -13,7 +13,6 @@
1313
//===----------------------------------------------------------------------===//
1414

1515
import JavaKit
16-
import JavaRuntime
1716

1817
typealias JavaVMPointer = UnsafeMutablePointer<JavaVM?>
1918

@@ -24,19 +23,41 @@ public final class JavaVirtualMachine: @unchecked Sendable {
2423
/// The JNI environment for the JVM.
2524
public let environment: JNIEnvironment
2625

27-
public init(vmOptions: [String] = []) throws {
26+
/// Initialize a new Java virtual machine instance.
27+
///
28+
/// - Parameters:
29+
/// - classPath: The directories, JAR files, and ZIP files in which the JVM
30+
/// should look to find classes. This maps to the VM option
31+
/// `-Djava.class.path=`.
32+
/// - vmOptions: Options that should be passed along to the JVM, which will
33+
/// be prefixed by the class-path argument described above.
34+
/// - ignoreUnrecognized: Whether the JVM should ignore any VM options it
35+
/// does not recognize.
36+
public init(
37+
classPath: [String] = [],
38+
vmOptions: [String] = [],
39+
ignoreUnrecognized: Bool = true
40+
) throws {
2841
var jvm: JavaVMPointer? = nil
2942
var environment: UnsafeMutableRawPointer? = nil
3043
var vmArgs = JavaVMInitArgs()
31-
vmArgs.version = JNI_VERSION_21
32-
vmArgs.ignoreUnrecognized = jboolean(JNI_TRUE)
44+
vmArgs.version = JNI_VERSION_1_6
45+
vmArgs.ignoreUnrecognized = jboolean(ignoreUnrecognized ? JNI_TRUE : JNI_FALSE)
46+
47+
// Construct the complete list of VM options.
48+
var allVMOptions: [String] = []
49+
if !classPath.isEmpty {
50+
let colonSeparatedClassPath = classPath.joined(separator: ":")
51+
allVMOptions.append("-Djava.class.path=\(colonSeparatedClassPath)")
52+
}
53+
allVMOptions.append(contentsOf: vmOptions)
3354

3455
// Convert the options
35-
let optionsBuffer = UnsafeMutableBufferPointer<JavaVMOption>.allocate(capacity: vmOptions.count)
56+
let optionsBuffer = UnsafeMutableBufferPointer<JavaVMOption>.allocate(capacity: allVMOptions.count)
3657
defer {
3758
optionsBuffer.deallocate()
3859
}
39-
for (index, vmOption) in vmOptions.enumerated() {
60+
for (index, vmOption) in allVMOptions.enumerated() {
4061
let optionString = vmOption.utf8CString.withUnsafeBufferPointer { buffer in
4162
let cString = UnsafeMutableBufferPointer<CChar>.allocate(capacity: buffer.count + 1)
4263
_ = cString.initialize(from: buffer)

Tests/JavaKitTests/BasicRuntimeTests.swift

Lines changed: 26 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -15,7 +15,6 @@
1515
import JavaKit
1616
import JavaKitNetwork
1717
import JavaKitVM
18-
import JavaRuntime
1918
import Testing
2019

2120
@MainActor
@@ -24,8 +23,7 @@ let jvm = try! JavaVirtualMachine(vmOptions: [])
2423
@Suite
2524
@MainActor
2625
struct BasicRuntimeTests {
27-
28-
@Test("Object management")
26+
@Test("Object management", .disabled(if: isLinux, "Attempts to refcount a null pointer on Linux"))
2927
func javaObjectManagement() throws {
3028
let sneakyJavaThis: jobject
3129
do {
@@ -51,8 +49,8 @@ struct BasicRuntimeTests {
5149
#expect(url.javaHolder === urlAgain.javaHolder)
5250
}
5351

54-
@Test("Java exceptions")
55-
func javaExceptionsInSwift() async throws {
52+
@Test("Java exceptions", .disabled(if: isLinux, "Attempts to refcount a null pointer on Linux"))
53+
func javaExceptionsInSwift() throws {
5654
do {
5755
_ = try URL("bad url", environment: jvm.environment)
5856
} catch {
@@ -61,12 +59,29 @@ struct BasicRuntimeTests {
6159
}
6260

6361
@Test("Static methods", .disabled("Fails on macOS command line"))
64-
func staticMethods() {
65-
let urlConnectionClass = JavaClass<URLConnection>(
66-
javaThis: URLConnection.getJNIClass(in: jvm.environment)!,
67-
environment: jvm.environment
68-
)
69-
62+
func staticMethods() throws {
63+
let urlConnectionClass = try JavaClass<URLConnection>(in: jvm.environment)
7064
#expect(urlConnectionClass.getDefaultAllowUserInteraction() == false)
7165
}
66+
67+
@Test("Class instance lookup")
68+
func classInstanceLookup() throws {
69+
do {
70+
_ = try JavaClass<Nonexistent>(in: jvm.environment)
71+
} catch {
72+
#expect(String(describing: error) == "org/swift/javakit/Nonexistent")
73+
}
74+
}
75+
}
76+
77+
@JavaClass("org.swift.javakit.Nonexistent")
78+
struct Nonexistent { }
79+
80+
/// Whether we're running on Linux.
81+
var isLinux: Bool {
82+
#if os(Linux)
83+
return true
84+
#else
85+
return false
86+
#endif
7287
}

USER_GUIDE.md

Lines changed: 0 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -57,7 +57,6 @@ Now, in the `HelloSwift` Swift library, define a `struct` that provides the `mai
5757

5858
```swift
5959
import JavaKit
60-
import JavaRuntime
6160

6261
@JavaClass("org.swift.javakit.HelloSwiftMain")
6362
struct HelloSwiftMain {
@@ -87,7 +86,6 @@ The easiest way to build a command-line program in Swift is with the [Swift argu
8786
```swift
8887
import ArgumentParser
8988
import JavaKit
90-
import JavaRuntime
9189

9290
@JavaClass("org.swift.javakit.HelloSwiftMain")
9391
struct HelloSwiftMain: ParsableCommand {

0 commit comments

Comments
 (0)