Skip to content

Commit 47915d2

Browse files
committed
use cached DependencyResolver classpath from file
1 parent 9992890 commit 47915d2

File tree

5 files changed

+71
-39
lines changed

5 files changed

+71
-39
lines changed

JavaKit/src/main/java/org/swift/javakit/dependencies/DependencyResolver.java

Lines changed: 33 additions & 32 deletions
Original file line numberDiff line numberDiff line change
@@ -32,7 +32,7 @@
3232
public class DependencyResolver {
3333

3434
private static final String COMMAND_OUTPUT_LINE_PREFIX_CLASSPATH = "CLASSPATH:";
35-
private static final String CLASSPATH_CACHE_FILENAME = "JavaKitDependencyResolver.classpath.swift-java";
35+
private static final String CLASSPATH_CACHE_FILENAME = "JavaKitDependencyResolver.swift-java.classpath";
3636

3737
public static String GRADLE_API_DEPENDENCY = "dev.gradleplugins:gradle-api:8.10.1";
3838
public static String[] BASE_DEPENDENCIES = {
@@ -46,42 +46,42 @@ public class DependencyResolver {
4646
@UsedFromSwift
4747
@SuppressWarnings("unused")
4848
public static String resolveDependenciesToClasspath(String projectBaseDirectoryString, String[] dependencies) throws IOException {
49-
try {
50-
simpleLog("Fetch dependencies: " + Arrays.toString(dependencies));
51-
simpleLog("projectBaseDirectoryString = " + projectBaseDirectoryString);
52-
var projectBasePath = new File(projectBaseDirectoryString).toPath();
53-
54-
File projectDir = Files.createTempDirectory("java-swift-dependencies").toFile();
55-
projectDir.mkdirs();
56-
57-
if (hasDependencyResolverDependenciesLoaded()) {
58-
// === Resolve dependencies using Gradle API in-process
59-
simpleLog("Gradle API runtime dependency is available, resolve dependencies...");
60-
return resolveDependenciesUsingAPI(projectDir, dependencies);
61-
}
49+
try {
50+
simpleLog("Fetch dependencies: " + Arrays.toString(dependencies));
51+
simpleLog("Classpath: " + System.getProperty("java.class.path"));
52+
var projectBasePath = new File(projectBaseDirectoryString).toPath();
6253

63-
// === Bootstrap the resolver dependencies and cache them
64-
simpleLog("Gradle API not available on classpath, bootstrap %s dependencies: %s"
65-
.formatted(DependencyResolver.class.getSimpleName(), Arrays.toString(BASE_DEPENDENCIES)));
66-
String dependencyResolverDependenciesClasspath = bootstrapDependencyResolverClasspath();
67-
writeDependencyResolverClasspath(projectBasePath, dependencyResolverDependenciesClasspath);
68-
69-
// --- Resolve dependencies using sub-process process
70-
// TODO: it would be nice to just add the above classpath to the system classloader and here call the API
71-
// immediately, but that's challenging and not a stable API we can rely on (hacks exist to add paths
72-
// to system classloader but are not reliable).
73-
printBuildFiles(projectDir, dependencies);
74-
return resolveDependenciesWithSubprocess(projectDir);
75-
} catch (Exception e) {
76-
e.printStackTrace();
77-
throw e;
78-
}
54+
File projectDir = Files.createTempDirectory("java-swift-dependencies").toFile();
55+
projectDir.mkdirs();
56+
57+
if (hasDependencyResolverDependenciesLoaded()) {
58+
// === Resolve dependencies using Gradle API in-process
59+
simpleLog("Gradle API runtime dependency is available, resolve dependencies...");
60+
return resolveDependenciesUsingAPI(projectDir, dependencies);
61+
}
62+
63+
// === Bootstrap the resolver dependencies and cache them
64+
simpleLog("Gradle API not available on classpath, bootstrap %s dependencies: %s"
65+
.formatted(DependencyResolver.class.getSimpleName(), Arrays.toString(BASE_DEPENDENCIES)));
66+
String dependencyResolverDependenciesClasspath = bootstrapDependencyResolverClasspath();
67+
writeDependencyResolverClasspath(projectBasePath, dependencyResolverDependenciesClasspath);
68+
69+
// --- Resolve dependencies using sub-process process
70+
// TODO: it would be nice to just add the above classpath to the system classloader and here call the API
71+
// immediately, but that's challenging and not a stable API we can rely on (hacks exist to add paths
72+
// to system classloader but are not reliable).
73+
printBuildFiles(projectDir, dependencies);
74+
return resolveDependenciesWithSubprocess(projectDir);
75+
} catch (Exception e) {
76+
e.printStackTrace();
77+
throw e;
78+
}
7979
}
8080

8181

8282
/**
8383
* Use an external {@code gradle} invocation in order to download dependencies such that we can use `gradle-api`
84-
* next time we want to resolve dependencies. This uses an external process and is sligtly worse than using the API
84+
* next time we want to resolve dependencies. This uses an external process and is slightly worse than using the API
8585
* directly.
8686
*
8787
* @return classpath obtained for the dependencies
@@ -158,7 +158,8 @@ private static void writeDependencyResolverClasspath(Path projectBasePath, Strin
158158
/**
159159
* Detect if we have the necessary dependencies loaded.
160160
*/
161-
private static boolean hasDependencyResolverDependenciesLoaded() {
161+
@UsedFromSwift
162+
public static boolean hasDependencyResolverDependenciesLoaded() {
162163
return hasDependencyResolverDependenciesLoaded(DependencyResolver.class.getClassLoader());
163164
}
164165

Samples/JavaDependencySampleApp/Sources/JavaCommonsCSV/swift-java.config

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -2,7 +2,6 @@
22
"classes" : {
33

44
},
5-
"classpath" : "\/Users\/ktoso\/.gradle\/caches\/modules-2\/files-2.1\/org.apache.commons\/commons-csv\/1.12.0\/c77e053d7189bc0857f8d323ab61cb949965fbd1\/commons-csv-1.12.0.jar:\/Users\/ktoso\/.gradle\/caches\/modules-2\/files-2.1\/commons-io\/commons-io\/2.17.0\/ddcc8433eb019fb48fe25207c0278143f3e1d7e2\/commons-io-2.17.0.jar:\/Users\/ktoso\/.gradle\/caches\/modules-2\/files-2.1\/commons-codec\/commons-codec\/1.17.1\/973638b7149d333563584137ebf13a691bb60579\/commons-codec-1.17.1.jar",
65
"dependencies" : [
76
"org.apache.commons:commons-csv:1.12.0"
87
]

Sources/Java2Swift/JavaToSwift+FetchDependencies.swift

Lines changed: 26 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -23,6 +23,32 @@ import JavaKitConfigurationShared
2323
import JavaKitShared
2424

2525
extension JavaToSwift {
26+
27+
/// Must be the same as `DependencyResolver#CLASSPATH_CACHE_FILENAME` on the java side.
28+
var JavaKitDependencyResolverClasspathCacheFilename: String {
29+
"JavaKitDependencyResolver.swift-java.classpath"
30+
}
31+
var JavaKitDependencyResolverClasspathCacheFilePath: String {
32+
".build/\(JavaKitDependencyResolverClasspathCacheFilename)"
33+
}
34+
35+
func fetchDependenciesCachedClasspath() -> [String]? {
36+
guard let cachedClasspathURL = URL(string: "file://" + FileManager.default.currentDirectoryPath + "/" + JavaKitDependencyResolverClasspathCacheFilePath) else {
37+
return []
38+
}
39+
40+
guard FileManager.default.fileExists(atPath: cachedClasspathURL.path) else {
41+
return []
42+
}
43+
44+
guard let javaKitDependencyResolverCachedClasspath = try? String(contentsOf: cachedClasspathURL) else {
45+
return []
46+
}
47+
48+
print("[debug][swift-java] Cached dependency resolver classpath: \(javaKitDependencyResolverCachedClasspath)")
49+
return javaKitDependencyResolverCachedClasspath.split(separator: ":").map(String.init)
50+
}
51+
2652
func fetchDependencies(moduleName: String,
2753
dependencies: [JavaDependencyDescriptor],
2854
baseClasspath: [String],

Sources/Java2Swift/JavaToSwift.swift

Lines changed: 9 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -222,13 +222,16 @@ struct JavaToSwift: ParsableCommand {
222222
let extraClasspathEntries = extraClasspath.split(separator: ":").map(String.init)
223223
print("[debug][swift-java] Extra classpath: \(extraClasspathEntries)")
224224
classpathEntries += extraClasspathEntries
225-
case .classWrappers/*(let config)*/,
226-
.fetchDependencies/*(let config)*/:
225+
case .fetchDependencies:
226+
// if we have already fetched dependencies for the dependency loader,
227+
// let's use them so we can in-process resolve rather than forking a new
228+
// gradle process.
229+
if let dependencyResolverClasspath = fetchDependenciesCachedClasspath() {
230+
print("[debug][swift-java] Found cached dependency resolver classpath: \(dependencyResolverClasspath)")
231+
classpathEntries += dependencyResolverClasspath
232+
}
233+
case .classWrappers:
227234
break;
228-
// * Classpath specified in the configuration file (if any)
229-
// let extraClasspathEntries = config.classpath?.split(separator: ":").map(String.init) ?? []
230-
// print("[debug][swift-java] Config classpath: \(extraClasspathEntries)")
231-
// classpathEntries += extraClasspathEntries
232235
}
233236

234237
// Add extra classpath entries which are specific to building the JavaKit project and samples

Sources/JavaKitDependencyResolver/DependencyResolver.swift

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -26,4 +26,7 @@ extension JavaClass<DependencyResolver> {
2626
projectBaseDirectory: String,
2727
dependencies: [String]) throws -> String
2828

29+
@JavaStaticMethod
30+
public func hasDependencyResolverDependenciesLoaded() -> Bool
31+
2932
}

0 commit comments

Comments
 (0)