Skip to content

Commit 9ba3255

Browse files
authored
Dynamically load libjvm rather than requiring it at build time (#8)
* Dynamically load libjvm rather than requiring it at build time * Update formatting * Add amazonlinux2 back to CI and formatting fix * Update CI to include macOS and Windows and not pre-install Java on Linux * Update dynamic library loading to support Windows * Add imports for Windows * Cleanup and compact * Fix fomatting and cleanup symbol loading
1 parent 6d4b196 commit 9ba3255

File tree

7 files changed

+629
-330
lines changed

7 files changed

+629
-330
lines changed

.github/workflows/pull_request.yml

Lines changed: 4 additions & 20 deletions
Original file line numberDiff line numberDiff line change
@@ -12,29 +12,13 @@ jobs:
1212
name: Test
1313
uses: swiftlang/github-workflows/.github/workflows/swift_package_test.yml@main
1414
with:
15-
# TODO: need to pre-install Java
16-
enable_windows_checks: false
17-
# TODO: need to pre-install Java
18-
enable_macos_checks: false
15+
enable_windows_checks: true
16+
windows_swift_versions: '["nightly-main"]'
17+
enable_macos_checks: true
1918
enable_ios_checks: false
2019
enable_linux_checks: true
21-
linux_os_versions: '["bookworm", "jammy", "noble", "rhel-ubi9"]'
20+
linux_os_versions: '["amazonlinux2", "bookworm", "noble", "jammy", "rhel-ubi9"]'
2221
linux_exclude_swift_versions: "[{\"swift_version\": \"5.9\"}, {\"swift_version\": \"5.10\"}]"
23-
linux_pre_build_command: |
24-
if command -v apt-get >/dev/null 2>&1 ; then # bookworm, noble, jammy
25-
if command -v sudo &> /dev/null && [ "$EUID" -ne 0 ]; then
26-
sudo apt-get update -y
27-
sudo apt-get install -y default-jdk
28-
else
29-
apt-get update -y
30-
apt-get install -y default-jdk
31-
fi
32-
elif command -v yum >/dev/null 2>&1 ; then # amazonlinux2, rhel-ubi9
33-
# TODO: amazonlinux2 needs more help finding JAVA_HOME
34-
yum update -y
35-
yum install -y java-devel
36-
fi
37-
3822
enable_android_sdk_build: true
3923
enable_android_sdk_checks: true
4024
soundness:

Package.swift

Lines changed: 1 addition & 164 deletions
Original file line numberDiff line numberDiff line change
@@ -1,133 +1,7 @@
11
// swift-tools-version: 6.0
22
// The swift-tools-version declares the minimum version of Swift required to build this package.
3-
4-
import Foundation
53
import PackageDescription
64

7-
// Note: the JAVA_HOME environment variable must be set to point to where
8-
// Java is installed, e.g.,
9-
// Library/Java/JavaVirtualMachines/openjdk-21.jdk/Contents/Home.
10-
func findJavaHome() -> String {
11-
if let home = ProcessInfo.processInfo.environment["JAVA_HOME"] {
12-
return home
13-
}
14-
15-
// This is a workaround for envs (some IDEs) which have trouble with
16-
// picking up env variables during the build process
17-
let path = "\(FileManager.default.homeDirectoryForCurrentUser.path()).java_home"
18-
if let home = try? String(contentsOfFile: path, encoding: .utf8) {
19-
if let lastChar = home.last, lastChar.isNewline {
20-
return String(home.dropLast())
21-
}
22-
23-
return home
24-
}
25-
26-
if let home = getJavaHomeFromLibexecJavaHome(),
27-
!home.isEmpty
28-
{
29-
return home
30-
}
31-
32-
if let home = getJavaHomeFromSDKMAN() {
33-
return home
34-
}
35-
36-
if let home = getJavaHomeFromPath() {
37-
return home
38-
}
39-
40-
if ProcessInfo.processInfo.environment["SPI_PROCESSING"] == "1"
41-
&& ProcessInfo.processInfo.environment["SPI_BUILD"] == nil
42-
{
43-
return ""
44-
}
45-
fatalError("Please set the JAVA_HOME environment variable to point to where Java is installed.")
46-
}
47-
48-
/// On MacOS we can use the java_home tool as a fallback if we can't find JAVA_HOME environment variable.
49-
func getJavaHomeFromLibexecJavaHome() -> String? {
50-
let task = Process()
51-
task.executableURL = URL(fileURLWithPath: "/usr/libexec/java_home")
52-
53-
guard FileManager.default.fileExists(atPath: task.executableURL!.path) else {
54-
return nil
55-
}
56-
57-
let pipe = Pipe()
58-
task.standardOutput = pipe
59-
task.standardError = pipe
60-
61-
do {
62-
try task.run()
63-
task.waitUntilExit()
64-
65-
let data = pipe.fileHandleForReading.readDataToEndOfFile()
66-
let output = String(data: data, encoding: .utf8)?.trimmingCharacters(in: .whitespacesAndNewlines)
67-
68-
if task.terminationStatus == 0 {
69-
return output
70-
} else {
71-
return nil
72-
}
73-
} catch {
74-
return nil
75-
}
76-
}
77-
78-
func getJavaHomeFromSDKMAN() -> String? {
79-
let home = FileManager.default.homeDirectoryForCurrentUser
80-
.appendingPathComponent(".sdkman/candidates/java/current")
81-
82-
let javaBin = home.appendingPathComponent("bin/java").path
83-
if FileManager.default.isExecutableFile(atPath: javaBin) {
84-
return home.path
85-
}
86-
return nil
87-
}
88-
89-
func getJavaHomeFromPath() -> String? {
90-
let task = Process()
91-
task.executableURL = URL(fileURLWithPath: "/usr/bin/which")
92-
task.arguments = ["java"]
93-
94-
let pipe = Pipe()
95-
task.standardOutput = pipe
96-
97-
do {
98-
try task.run()
99-
task.waitUntilExit()
100-
guard task.terminationStatus == 0 else { return nil }
101-
102-
let data = pipe.fileHandleForReading.readDataToEndOfFile()
103-
guard
104-
let javaPath = String(data: data, encoding: .utf8)?
105-
.trimmingCharacters(in: .whitespacesAndNewlines),
106-
!javaPath.isEmpty
107-
else { return nil }
108-
109-
let resolved = URL(fileURLWithPath: javaPath).resolvingSymlinksInPath()
110-
return
111-
resolved
112-
.deletingLastPathComponent()
113-
.deletingLastPathComponent()
114-
.path
115-
} catch {
116-
return nil
117-
}
118-
}
119-
120-
let javaHome = findJavaHome()
121-
122-
let javaIncludePath = "\(javaHome)/include"
123-
#if os(Linux)
124-
let javaPlatformIncludePath = "\(javaIncludePath)/linux"
125-
#elseif os(macOS)
126-
let javaPlatformIncludePath = "\(javaIncludePath)/darwin"
127-
#elseif os(Windows)
128-
let javaPlatformIncludePath = "\(javaIncludePath)/win32"
129-
#endif
130-
1315
let package = Package(
1326
name: "swift-java-jni-core",
1337
products: [
@@ -138,57 +12,20 @@ let package = Package(
13812
],
13913
targets: [
14014
.target(
141-
name: "CSwiftJavaJNI",
142-
cSettings: [
143-
.unsafeFlags(["-I\(javaIncludePath)", "-I\(javaPlatformIncludePath)"], .when(platforms: [.macOS, .linux, .windows]))
144-
],
145-
swiftSettings: [
146-
.unsafeFlags(["-I\(javaIncludePath)", "-I\(javaPlatformIncludePath)"], .when(platforms: [.macOS, .linux, .windows]))
147-
],
148-
linkerSettings: [
149-
.linkedLibrary("log", .when(platforms: [.android]))
150-
]
15+
name: "CSwiftJavaJNI"
15116
),
15217

15318
.target(
15419
name: "SwiftJavaJNICore",
15520
dependencies: [
15621
"CSwiftJavaJNI"
157-
],
158-
swiftSettings: [
159-
.swiftLanguageMode(.v5),
160-
.unsafeFlags(["-I\(javaIncludePath)", "-I\(javaPlatformIncludePath)"], .when(platforms: [.macOS, .linux, .windows])),
161-
],
162-
linkerSettings: [
163-
.unsafeFlags(
164-
[
165-
"-L\(javaHome)/lib/server",
166-
"-Xlinker", "-rpath",
167-
"-Xlinker", "\(javaHome)/lib/server",
168-
],
169-
.when(platforms: [.linux, .macOS])
170-
),
171-
.unsafeFlags(
172-
[
173-
"-L\(javaHome)/lib"
174-
],
175-
.when(platforms: [.windows])
176-
),
177-
.linkedLibrary(
178-
"jvm",
179-
.when(platforms: [.linux, .macOS, .windows])
180-
),
18122
]
18223
),
18324

18425
.testTarget(
18526
name: "SwiftJavaJNICoreTests",
18627
dependencies: [
18728
"SwiftJavaJNICore"
188-
],
189-
swiftSettings: [
190-
.swiftLanguageMode(.v5),
191-
.unsafeFlags(["-I\(javaIncludePath)", "-I\(javaPlatformIncludePath)"], .when(platforms: [.macOS, .linux, .windows])),
19229
]
19330
),
19431
]

Sources/CSwiftJavaJNI/AndroidSupport.cpp

Lines changed: 0 additions & 98 deletions
This file was deleted.

0 commit comments

Comments
 (0)