From d8a215c9a2823bfa897834c1318bd81fededc735 Mon Sep 17 00:00:00 2001 From: Konrad `ktoso` Malawski Date: Fri, 29 Nov 2024 22:25:45 +0900 Subject: [PATCH 01/25] implemented resolving --- JavaKit/build.gradle | 44 +++ .../javakit/annotations/UsedFromSwift.java | 28 ++ .../dependencies/DependencyResolver.java | 252 ++++++++++++++++ .../SwiftJavaBootstrapException.java | 25 ++ .../dependencies/SystemClassLoaderUnsafe.java | 46 +++ Package.swift | 24 +- .../PluginsShared/JavaKitConfigurationShared | 1 + .../JavaToSwift+EmitConfiguration.swift | 64 ++++ .../JavaToSwift+FetchDependencies.swift | 56 ++++ .../JavaToSwift+GenerateWrappers.swift | 145 +++++++++ Sources/Java2Swift/JavaToSwift.swift | 275 ++++-------------- Sources/Java2Swift/MiniTerminalColors.swift | 26 ++ Sources/Java2Swift/String+Extensions.swift | 62 ++++ Sources/Java2SwiftLib/Configuration.swift | 45 --- .../JavaTranslator+Configuration.swift | 7 +- Sources/Java2SwiftLib/JavaTranslator.swift | 1 + .../JavaKitVM/JavaVirtualMachine.swift | 72 ++++- .../Configuration.swift | 67 ++++- .../DependencyResolver.swift | 29 ++ .../swift-java.config | 9 + .../contents.xcworkspacedata | 23 ++ .../xcshareddata/WorkspaceSettings.xcsettings | 5 + settings.gradle | 1 + 23 files changed, 1016 insertions(+), 291 deletions(-) create mode 100644 JavaKit/build.gradle create mode 100644 JavaKit/src/main/java/org/swift/javakit/annotations/UsedFromSwift.java create mode 100644 JavaKit/src/main/java/org/swift/javakit/dependencies/DependencyResolver.java create mode 100644 JavaKit/src/main/java/org/swift/javakit/dependencies/SwiftJavaBootstrapException.java create mode 100644 JavaKit/src/main/java/org/swift/javakit/dependencies/SystemClassLoaderUnsafe.java create mode 120000 Plugins/PluginsShared/JavaKitConfigurationShared create mode 100644 Sources/Java2Swift/JavaToSwift+EmitConfiguration.swift create mode 100644 Sources/Java2Swift/JavaToSwift+FetchDependencies.swift create mode 100644 Sources/Java2Swift/JavaToSwift+GenerateWrappers.swift create mode 100644 Sources/Java2Swift/MiniTerminalColors.swift create mode 100644 Sources/Java2Swift/String+Extensions.swift delete mode 100644 Sources/Java2SwiftLib/Configuration.swift rename {Plugins/PluginsShared => Sources/JavaKitConfigurationShared}/Configuration.swift (50%) create mode 100644 Sources/JavaKitDependencyResolver/DependencyResolver.swift create mode 100644 Sources/JavaKitDependencyResolver/swift-java.config create mode 100644 SwiftJava.xcworkspace/contents.xcworkspacedata create mode 100644 SwiftJava.xcworkspace/xcshareddata/WorkspaceSettings.xcsettings diff --git a/JavaKit/build.gradle b/JavaKit/build.gradle new file mode 100644 index 00000000..80050c7a --- /dev/null +++ b/JavaKit/build.gradle @@ -0,0 +1,44 @@ +//===----------------------------------------------------------------------===// + // + // This source file is part of the Swift.org open source project + // + // Copyright (c) 2024 Apple Inc. and the Swift.org project authors + // Licensed under Apache License v2.0 + // + // See LICENSE.txt for license information + // See CONTRIBUTORS.txt for the list of Swift.org project authors + // + // SPDX-License-Identifier: Apache-2.0 + // + //===----------------------------------------------------------------------===// + + plugins { + id("build-logic.java-application-conventions") + } + + group = "org.swift.javakit" + version = "1.0-SNAPSHOT" + + repositories { + mavenCentral() + } + + java { + toolchain { + languageVersion.set(JavaLanguageVersion.of(22)) + } + } + + dependencies { + implementation("dev.gradleplugins:gradle-api:8.10.1") + + testImplementation(platform("org.junit:junit-bom:5.10.0")) + testImplementation("org.junit.jupiter:junit-jupiter") + } + + tasks.test { + useJUnitPlatform() + testLogging { + events("passed", "skipped", "failed") + } + } \ No newline at end of file diff --git a/JavaKit/src/main/java/org/swift/javakit/annotations/UsedFromSwift.java b/JavaKit/src/main/java/org/swift/javakit/annotations/UsedFromSwift.java new file mode 100644 index 00000000..ad9e7918 --- /dev/null +++ b/JavaKit/src/main/java/org/swift/javakit/annotations/UsedFromSwift.java @@ -0,0 +1,28 @@ +//===----------------------------------------------------------------------===// +// +// This source file is part of the Swift.org open source project +// +// Copyright (c) 2024 Apple Inc. and the Swift.org project authors +// Licensed under Apache License v2.0 +// +// See LICENSE.txt for license information +// See CONTRIBUTORS.txt for the list of Swift.org project authors +// +// SPDX-License-Identifier: Apache-2.0 +// +//===----------------------------------------------------------------------===// + +package org.swift.javakit.annotations; + +import java.lang.annotation.Retention; +import java.lang.annotation.RetentionPolicy; + +/** + * Since some public methods may not appear as used in Java source code, but are used by Swift, + * we can use this source annotation to mark such entry points to not accidentally remove them with + * "safe delete" refactorings in Java IDEs which would be unaware of the usages from Swift. + */ +@SuppressWarnings("unused") // used from Swift +@Retention(RetentionPolicy.SOURCE) +public @interface UsedFromSwift { +} diff --git a/JavaKit/src/main/java/org/swift/javakit/dependencies/DependencyResolver.java b/JavaKit/src/main/java/org/swift/javakit/dependencies/DependencyResolver.java new file mode 100644 index 00000000..14c2a519 --- /dev/null +++ b/JavaKit/src/main/java/org/swift/javakit/dependencies/DependencyResolver.java @@ -0,0 +1,252 @@ +//===----------------------------------------------------------------------===// +// +// This source file is part of the Swift.org open source project +// +// Copyright (c) 2024 Apple Inc. and the Swift.org project authors +// Licensed under Apache License v2.0 +// +// See LICENSE.txt for license information +// See CONTRIBUTORS.txt for the list of Swift.org project authors +// +// SPDX-License-Identifier: Apache-2.0 +// +//===----------------------------------------------------------------------===// + +package org.swift.javakit.dependencies; + +import org.gradle.tooling.GradleConnector; +import org.swift.javakit.annotations.UsedFromSwift; + +import java.io.*; +import java.nio.file.Files; +import java.nio.file.Path; +import java.nio.file.StandardOpenOption; +import java.util.Arrays; +import java.util.concurrent.TimeUnit; +import java.util.stream.Stream; + +/** + * Fetches dependencies using the Gradle resolver and returns the resulting classpath which includes + * the fetched dependency and all of its dependencies. + */ +public class DependencyResolver { + + private static final String COMMAND_OUTPUT_LINE_PREFIX_CLASSPATH = "CLASSPATH:"; + private static final String CLASSPATH_CACHE_FILENAME = "JavaKitDependencyResolver.classpath.swift-java"; + + public static String GRADLE_API_DEPENDENCY = "dev.gradleplugins:gradle-api:8.10.1"; + public static String[] BASE_DEPENDENCIES = { + GRADLE_API_DEPENDENCY + }; + + /** + * May throw runtime exceptions including {@link org.gradle.api.internal.artifacts.ivyservice.TypedResolveException} + * if unable to resolve a dependency. + */ + @UsedFromSwift + @SuppressWarnings("unused") + public static String resolveDependenciesToClasspath(String projectBaseDirectoryString, String[] dependencies) throws IOException { +try { + simpleLog("Fetch dependencies: " + Arrays.toString(dependencies)); + simpleLog("projectBaseDirectoryString = " + projectBaseDirectoryString); + var projectBasePath = new File(projectBaseDirectoryString).toPath(); + + File projectDir = Files.createTempDirectory("java-swift-dependencies").toFile(); + projectDir.mkdirs(); + + if (hasDependencyResolverDependenciesLoaded()) { + // === Resolve dependencies using Gradle API in-process + simpleLog("Gradle API runtime dependency is available, resolve dependencies..."); + return resolveDependenciesUsingAPI(projectDir, dependencies); + } + + // === Bootstrap the resolver dependencies and cache them + simpleLog("Gradle API not available on classpath, bootstrap %s dependencies: %s" + .formatted(DependencyResolver.class.getSimpleName(), Arrays.toString(BASE_DEPENDENCIES))); + String dependencyResolverDependenciesClasspath = bootstrapDependencyResolverClasspath(); + writeDependencyResolverClasspath(projectBasePath, dependencyResolverDependenciesClasspath); + + // --- Resolve dependencies using sub-process process + // TODO: it would be nice to just add the above classpath to the system classloader and here call the API + // immediately, but that's challenging and not a stable API we can rely on (hacks exist to add paths + // to system classloader but are not reliable). + printBuildFiles(projectDir, dependencies); + return resolveDependenciesWithSubprocess(projectDir); +} catch (Exception e) { + e.printStackTrace(); + throw e; +} + } + + + /** + * Use an external {@code gradle} invocation in order to download dependencies such that we can use `gradle-api` + * next time we want to resolve dependencies. This uses an external process and is sligtly worse than using the API + * directly. + * + * @return classpath obtained for the dependencies + * @throws IOException if file IO failed during mock project creation + * @throws SwiftJavaBootstrapException if the resolve failed for some other reason + */ + private static String bootstrapDependencyResolverClasspath() throws IOException, SwiftJavaBootstrapException { + var dependencies = BASE_DEPENDENCIES; + simpleLog("Bootstrap gradle-api for DependencyResolver: " + Arrays.toString(dependencies)); + + File bootstrapDir = Files.createTempDirectory("swift-java-dependency-resolver").toFile(); + bootstrapDir.mkdirs(); + simpleLog("Bootstrap dependencies using project at: %s".formatted(bootstrapDir)); + + printBuildFiles(bootstrapDir, dependencies); + + var bootstrapClasspath = resolveDependenciesWithSubprocess(bootstrapDir); + simpleLog("Prepared dependency resolver bootstrap classpath: " + bootstrapClasspath.split(":").length + " entries"); + + return bootstrapClasspath; + + } + + private static String resolveDependenciesWithSubprocess(File gradleProjectDir) throws IOException { + if (!gradleProjectDir.isDirectory()) { + throw new IllegalArgumentException("Gradle project directory is not a directory: " + gradleProjectDir); + } + + File stdoutFile = File.createTempFile("swift-java-bootstrap", ".stdout", gradleProjectDir); + stdoutFile.deleteOnExit(); + File stderrFile = File.createTempFile("swift-java-bootstrap", ".stderr", gradleProjectDir); + stderrFile.deleteOnExit(); + + try { + ProcessBuilder gradleBuilder = new ProcessBuilder("gradle", ":printRuntimeClasspath"); + gradleBuilder.directory(gradleProjectDir); + gradleBuilder.redirectOutput(stdoutFile); + gradleBuilder.redirectError(stderrFile); + Process gradleProcess = gradleBuilder.start(); + gradleProcess.waitFor(10, TimeUnit.MINUTES); // TODO: must be configurable + + if (gradleProcess.exitValue() != 0) { + throw new SwiftJavaBootstrapException("Failed to resolve bootstrap dependencies, exit code: " + gradleProcess.exitValue()); + } + + Stream lines = Files.readAllLines(stdoutFile.toPath()).stream(); + var bootstrapClasspath = getClasspathFromGradleCommandOutput(lines); + return bootstrapClasspath; + } catch (Exception ex) { + simpleLog("stdoutFile = " + stdoutFile); + simpleLog("stderrFile = " + stderrFile); + + ex.printStackTrace(); + throw new SwiftJavaBootstrapException("Failed to bootstrap dependencies necessary for " + + DependencyResolver.class.getCanonicalName() + "!", ex); + } + } + + private static void writeDependencyResolverClasspath(Path projectBasePath, String dependencyResolverDependenciesClasspath) throws IOException { + File swiftBuildDirectory = new File(String.valueOf(projectBasePath), ".build"); + swiftBuildDirectory.mkdirs(); + + File dependencyResolverClasspathCacheFile = new File(swiftBuildDirectory, CLASSPATH_CACHE_FILENAME); + dependencyResolverClasspathCacheFile.createNewFile(); + simpleLog("Cache %s dependencies classpath at: '%s'. Subsequent dependency resolutions will use gradle-api." + .formatted(DependencyResolver.class.getSimpleName(), dependencyResolverClasspathCacheFile.toPath())); + + Files.writeString( + dependencyResolverClasspathCacheFile.toPath(), + dependencyResolverDependenciesClasspath, + StandardOpenOption.WRITE, StandardOpenOption.TRUNCATE_EXISTING); + } + + /** + * Detect if we have the necessary dependencies loaded. + */ + private static boolean hasDependencyResolverDependenciesLoaded() { + return hasDependencyResolverDependenciesLoaded(DependencyResolver.class.getClassLoader()); + } + + /** + * Resolve dependencies in the passed project directory and return the resulting classpath. + * + * @return classpath which was resolved for the dependencies + */ + private static String resolveDependenciesUsingAPI(File projectDir, String[] dependencies) throws FileNotFoundException { + printBuildFiles(projectDir, dependencies); + + var connection = GradleConnector.newConnector() + .forProjectDirectory(projectDir) + .connect(); + + try (connection) { + ByteArrayOutputStream outputStream = new ByteArrayOutputStream(); + PrintStream printStream = new PrintStream(outputStream); + + connection.newBuild().forTasks(":printRuntimeClasspath") + .setStandardError(new NoopOutputStream()) + .setStandardOutput(printStream) + .run(); + + var all = outputStream.toString(); + var classpath = Arrays.stream(all.split("\n")) + .filter(s -> s.startsWith(COMMAND_OUTPUT_LINE_PREFIX_CLASSPATH)) + .map(s -> s.substring(COMMAND_OUTPUT_LINE_PREFIX_CLASSPATH.length())) + .findFirst().orElseThrow(() -> new RuntimeException("Could not find classpath output from ':printRuntimeClasspath' task.")); + return classpath; + } + } + + private static String getClasspathFromGradleCommandOutput(Stream lines) { + return lines.filter(s -> s.startsWith(COMMAND_OUTPUT_LINE_PREFIX_CLASSPATH)) + .map(s -> s.substring(COMMAND_OUTPUT_LINE_PREFIX_CLASSPATH.length())) + .findFirst().orElseThrow(() -> new RuntimeException("Could not find classpath output from gradle command output task.")); + } + + + private static boolean hasDependencyResolverDependenciesLoaded(ClassLoader classLoader) { + try { + classLoader.loadClass("org.gradle.tooling.GradleConnector"); + return true; + } catch (ClassNotFoundException e) { + return false; + } + } + + private static void printBuildFiles(File projectDir, String[] dependencies) throws FileNotFoundException { + File buildFile = new File(projectDir, "build.gradle"); + try (PrintWriter writer = new PrintWriter(buildFile)) { + writer.println("plugins { id 'java-library' }"); + writer.println("repositories { mavenCentral() }"); + + writer.println("dependencies {"); + for (String dependency : dependencies) { + writer.println("implementation(\"" + dependency + "\")"); + } + writer.println("}"); + + writer.println(""" + task printRuntimeClasspath { + def runtimeClasspath = sourceSets.main.runtimeClasspath + inputs.files(runtimeClasspath) + doLast { + println("CLASSPATH:${runtimeClasspath.asPath}") + } + } + """); + } + + File settingsFile = new File(projectDir, "settings.gradle.kts"); + try (PrintWriter writer = new PrintWriter(settingsFile)) { + writer.println(""" + rootProject.name = "swift-java-resolve-temp-project" + """); + } + } + + private static void simpleLog(String message) { + System.err.println("[info][swift-java/" + DependencyResolver.class.getSimpleName() + "] " + message); + } + + private static class NoopOutputStream extends OutputStream { + @Override + public void write(int b) throws IOException { + // ignore + } + } +} diff --git a/JavaKit/src/main/java/org/swift/javakit/dependencies/SwiftJavaBootstrapException.java b/JavaKit/src/main/java/org/swift/javakit/dependencies/SwiftJavaBootstrapException.java new file mode 100644 index 00000000..3c8d475a --- /dev/null +++ b/JavaKit/src/main/java/org/swift/javakit/dependencies/SwiftJavaBootstrapException.java @@ -0,0 +1,25 @@ +//===----------------------------------------------------------------------===// +// +// This source file is part of the Swift.org open source project +// +// Copyright (c) 2024 Apple Inc. and the Swift.org project authors +// Licensed under Apache License v2.0 +// +// See LICENSE.txt for license information +// See CONTRIBUTORS.txt for the list of Swift.org project authors +// +// SPDX-License-Identifier: Apache-2.0 +// +//===----------------------------------------------------------------------===// + +package org.swift.javakit.dependencies; + +public class SwiftJavaBootstrapException extends RuntimeException { + public SwiftJavaBootstrapException(String message) { + super(message); + } + + public SwiftJavaBootstrapException(String message, Exception ex) { + super(message, ex); + } +} diff --git a/JavaKit/src/main/java/org/swift/javakit/dependencies/SystemClassLoaderUnsafe.java b/JavaKit/src/main/java/org/swift/javakit/dependencies/SystemClassLoaderUnsafe.java new file mode 100644 index 00000000..d8d4f64a --- /dev/null +++ b/JavaKit/src/main/java/org/swift/javakit/dependencies/SystemClassLoaderUnsafe.java @@ -0,0 +1,46 @@ +//===----------------------------------------------------------------------===// +// +// This source file is part of the Swift.org open source project +// +// Copyright (c) 2024 Apple Inc. and the Swift.org project authors +// Licensed under Apache License v2.0 +// +// See LICENSE.txt for license information +// See CONTRIBUTORS.txt for the list of Swift.org project authors +// +// SPDX-License-Identifier: Apache-2.0 +// +//===----------------------------------------------------------------------===// + +package org.swift.javakit.dependencies; + +import java.io.File; +import java.net.URL; +import java.net.URLClassLoader; + +public final class SystemClassLoaderUnsafe { + + private SystemClassLoaderUnsafe() {} + + /** + * Use internal methods to add a path to the system classloader. + * If this ever starts throwing in new JDK versions, we may need to abandon this technique. + * + * @param path path to add to the current system classloader. + */ + public static void addPath(String path) { + try { + var url = new File(path).toURI().toURL(); + var urlClassLoader = (URLClassLoader) ClassLoader.getSystemClassLoader(); + var method = URLClassLoader.class.getDeclaredMethod("addURL", URL.class); + method.setAccessible(true); + method.invoke(urlClassLoader, url); + } catch (Throwable ex) { + throw new RuntimeException("Unable to add path to system class loader! " + + "This is not supported API and may indeed start failing in the future. " + + "If/when this happens, we have to change the bootstrap logic to instead " + + "create a new JVM with the new bootstrap classpath, " + + "rather than add paths to the existing one.", ex); + } + } +} diff --git a/Package.swift b/Package.swift index 119aca6e..58a0c946 100644 --- a/Package.swift +++ b/Package.swift @@ -40,7 +40,7 @@ let javaIncludePath = "\(javaHome)/include" #endif let package = Package( - name: "JavaKit", + name: "SwiftJava", platforms: [ .macOS(.v10_15) ], @@ -171,6 +171,21 @@ let package = Package( .swiftLanguageMode(.v5) ] ), + + .target( + name: "JavaKitDependencyResolver", + dependencies: [ + "JavaKit", + ], + exclude: [ + "swift-java.config", + ], + swiftSettings: [ + .swiftLanguageMode(.v5), + .unsafeFlags(["-I\(javaIncludePath)", "-I\(javaPlatformIncludePath)"]), + ] + ), + .target( name: "JavaKit", dependencies: ["JavaRuntime", "JavaKitMacros", "JavaTypes"], @@ -282,6 +297,10 @@ let package = Package( ] ), + .target( + name: "JavaKitConfigurationShared" + ), + .target( name: "Java2SwiftLib", dependencies: [ @@ -293,6 +312,8 @@ let package = Package( "JavaKitReflection", "JavaKitNetwork", "JavaTypes", + "JavaKitConfigurationShared", + "JavaKitDependencyResolver", ], swiftSettings: [ .swiftLanguageMode(.v5), @@ -312,6 +333,7 @@ let package = Package( "JavaKitJar", "JavaKitNetwork", "Java2SwiftLib", + "JavaKitDependencyResolver", ], swiftSettings: [ diff --git a/Plugins/PluginsShared/JavaKitConfigurationShared b/Plugins/PluginsShared/JavaKitConfigurationShared new file mode 120000 index 00000000..d5c765df --- /dev/null +++ b/Plugins/PluginsShared/JavaKitConfigurationShared @@ -0,0 +1 @@ +../../Sources/JavaKitConfigurationShared \ No newline at end of file diff --git a/Sources/Java2Swift/JavaToSwift+EmitConfiguration.swift b/Sources/Java2Swift/JavaToSwift+EmitConfiguration.swift new file mode 100644 index 00000000..6caca8fe --- /dev/null +++ b/Sources/Java2Swift/JavaToSwift+EmitConfiguration.swift @@ -0,0 +1,64 @@ +//===----------------------------------------------------------------------===// +// +// This source file is part of the Swift.org open source project +// +// Copyright (c) 2024 Apple Inc. and the Swift.org project authors +// Licensed under Apache License v2.0 +// +// See LICENSE.txt for license information +// See CONTRIBUTORS.txt for the list of Swift.org project authors +// +// SPDX-License-Identifier: Apache-2.0 +// +//===----------------------------------------------------------------------===// + +import Foundation +import ArgumentParser +import Java2SwiftLib +import JavaKit +import JavaKitJar +import Java2SwiftLib +import JavaKitDependencyResolver +import JavaKitConfigurationShared + +extension JavaToSwift { + mutating func emitConfiguration( + forJarFile jarFileName: String, + classPath: String, + environment: JNIEnvironment + ) throws { + var configuration = Configuration() + configuration.classPath = classPath + + let jarFile = try JarFile(jarFileName, false, environment: environment) + for entry in jarFile.entries()! { + // We only look at class files in the Jar file. + guard entry.getName().hasSuffix(".class") else { + continue + } + + // If this is a local class, it cannot be mapped into Swift. + if entry.getName().isLocalJavaClass { + continue + } + + let javaCanonicalName = String(entry.getName().replacing("/", with: ".") + .dropLast(".class".count)) + configuration.classes?[javaCanonicalName] = + javaCanonicalName.defaultSwiftNameForJavaClass + } + + // Encode the configuration. + let encoder = JSONEncoder() + encoder.outputFormatting = [.prettyPrinted, .sortedKeys] + var contents = String(data: try encoder.encode(configuration), encoding: .utf8)! + contents.append("\n") + + // Write the file. + try writeContents( + contents, + to: "swift-java.config", + description: "swift-java configuration file" + ) + } +} \ No newline at end of file diff --git a/Sources/Java2Swift/JavaToSwift+FetchDependencies.swift b/Sources/Java2Swift/JavaToSwift+FetchDependencies.swift new file mode 100644 index 00000000..ca9b1269 --- /dev/null +++ b/Sources/Java2Swift/JavaToSwift+FetchDependencies.swift @@ -0,0 +1,56 @@ +//===----------------------------------------------------------------------===// +// +// This source file is part of the Swift.org open source project +// +// Copyright (c) 2024 Apple Inc. and the Swift.org project authors +// Licensed under Apache License v2.0 +// +// See LICENSE.txt for license information +// See CONTRIBUTORS.txt for the list of Swift.org project authors +// +// SPDX-License-Identifier: Apache-2.0 +// +//===----------------------------------------------------------------------===// + +import ArgumentParser +import Java2SwiftLib +import JavaKit +import Foundation +import JavaKitJar +import Java2SwiftLib +import JavaKitDependencyResolver +import JavaKitConfigurationShared + +extension JavaToSwift { + func fetchDependencies(projectName: String, + dependencies: [JavaDependencyDescriptor], + baseClasspath: [String]) throws -> JavaClasspath { + let deps = dependencies.map { $0.descriptionGradleStyle } + print("[debug][swift-java] Fetch dependencies: \(deps)") + + let jvm = try JavaVirtualMachine.shared(classPath: baseClasspath) + // let jvm = try ensureDependencyResolverDependenciesLoaded(baseClasspath: baseClasspath) + + let resolverClass = try JavaClass(environment: jvm.environment()) + let classpath = try resolverClass.resolveDependenciesToClasspath( + projectBaseDirectory: URL(fileURLWithPath: ".").path, + dependencies: deps) + + let entryCount = classpath.split(separator: ":").count + print("[debug][swift-java] Resolved classpath for \(deps.count) dependencies: classpath entries: \(entryCount)... ", terminator: "") + print("done.".green) + return .init(classpath) + } +} + +struct JavaClasspath: CustomStringConvertible { + let value: String + + init(_ value: String) { + self.value = value + } + + var description: String { + "JavaClasspath(value: \(value))" + } +} diff --git a/Sources/Java2Swift/JavaToSwift+GenerateWrappers.swift b/Sources/Java2Swift/JavaToSwift+GenerateWrappers.swift new file mode 100644 index 00000000..e53678b6 --- /dev/null +++ b/Sources/Java2Swift/JavaToSwift+GenerateWrappers.swift @@ -0,0 +1,145 @@ +//===----------------------------------------------------------------------===// +// +// This source file is part of the Swift.org open source project +// +// Copyright (c) 2024 Apple Inc. and the Swift.org project authors +// Licensed under Apache License v2.0 +// +// See LICENSE.txt for license information +// See CONTRIBUTORS.txt for the list of Swift.org project authors +// +// SPDX-License-Identifier: Apache-2.0 +// +//===----------------------------------------------------------------------===// + +import Foundation +import ArgumentParser +import Java2SwiftLib +import JavaKit +import JavaKitJar +import Java2SwiftLib +import JavaKitDependencyResolver +import JavaKitConfigurationShared + +extension JavaToSwift { + mutating func generateWrappers( + config: Configuration, + classPath: String, + dependentConfigs: [(String, Configuration)], + environment: JNIEnvironment + ) throws { + guard let moduleName else { + fatalError("--module-name must be set in 'generate wrappers' mode!") + } + let translator = JavaTranslator( + swiftModuleName: moduleName, + environment: environment, + translateAsClass: true + ) + + // Keep track of all of the Java classes that will have + // Swift-native implementations. + translator.swiftNativeImplementations = Set(swiftNativeImplementation) + + // Note all of the dependent configurations. + for (swiftModuleName, dependentConfig) in dependentConfigs { + translator.addConfiguration( + dependentConfig, + forSwiftModule: swiftModuleName + ) + } + + // Add the configuration for this module. + translator.addConfiguration(config, forSwiftModule: moduleName) + + // Load all of the explicitly-requested classes. + let classLoader = try JavaClass(environment: environment) + .getSystemClassLoader()! + var javaClasses: [JavaClass] = [] + for (javaClassName, _) in config.classes ?? [:] { + guard let javaClass = try classLoader.loadClass(javaClassName) else { + print("warning: could not find Java class '\(javaClassName)'") + continue + } + + // Add this class to the list of classes we'll translate. + javaClasses.append(javaClass) + } + + // Find all of the nested classes for each class, adding them to the list + // of classes to be translated if they were already specified. + var allClassesToVisit = javaClasses + var currentClassIndex: Int = 0 + while currentClassIndex < allClassesToVisit.count { + defer { + currentClassIndex += 1 + } + + // The current class we're in. + let currentClass = allClassesToVisit[currentClassIndex] + guard let currentSwiftName = translator.translatedClasses[currentClass.getName()]?.swiftType else { + continue + } + + // Find all of the nested classes that weren't explicitly translated + // already. + let nestedClasses: [JavaClass] = currentClass.getClasses().compactMap { nestedClass in + guard let nestedClass else { return nil } + + // If this is a local class, we're done. + let javaClassName = nestedClass.getName() + if javaClassName.isLocalJavaClass { + return nil + } + + // If this class has been explicitly mentioned, we're done. + if translator.translatedClasses[javaClassName] != nil { + return nil + } + + // Record this as a translated class. + let swiftUnqualifiedName = javaClassName.javaClassNameToCanonicalName + .defaultSwiftNameForJavaClass + + + let swiftName = "\(currentSwiftName).\(swiftUnqualifiedName)" + translator.translatedClasses[javaClassName] = (swiftName, nil) + return nestedClass + } + + // If there were no new nested classes, there's nothing to do. + if nestedClasses.isEmpty { + continue + } + + // Record all of the nested classes that we will visit. + translator.nestedClasses[currentClass.getName()] = nestedClasses + allClassesToVisit.append(contentsOf: nestedClasses) + } + + // Validate configurations before writing any files + try translator.validateClassConfiguration() + + // Translate all of the Java classes into Swift classes. + for javaClass in javaClasses { + translator.startNewFile() + let swiftClassDecls = try translator.translateClass(javaClass) + let importDecls = translator.getImportDecls() + + let swiftFileText = """ + // Auto-generated by Java-to-Swift wrapper generator. + \(importDecls.map { $0.description }.joined()) + \(swiftClassDecls.map { $0.description }.joined(separator: "\n")) + + """ + + let swiftFileName = try! translator.getSwiftTypeName(javaClass, preferValueTypes: false) + .swiftName.replacing(".", with: "+") + ".swift" + try writeContents( + swiftFileText, + to: swiftFileName, + description: "Java class '\(javaClass.getName())' translation" + ) + } + } +} \ No newline at end of file diff --git a/Sources/Java2Swift/JavaToSwift.swift b/Sources/Java2Swift/JavaToSwift.swift index 35bffc74..98d34ae8 100644 --- a/Sources/Java2Swift/JavaToSwift.swift +++ b/Sources/Java2Swift/JavaToSwift.swift @@ -21,6 +21,7 @@ import JavaKitNetwork import JavaKitReflection import SwiftSyntax import SwiftSyntaxBuilder +import JavaKitConfigurationShared /// Command-line utility to drive the export of Java classes into Swift types. @main @@ -28,7 +29,7 @@ struct JavaToSwift: ParsableCommand { static var _commandName: String { "Java2Swift" } @Option(help: "The name of the Swift module into which the resulting Swift types will be generated.") - var moduleName: String + var moduleName: String? @Option( help: @@ -62,6 +63,9 @@ struct JavaToSwift: ParsableCommand { ) var input: String + @Flag(help: "Fetch dependencies from given target (containing swift-java configuration) or dependency string") + var fetch: Bool = false + /// Whether we have ensured that the output directory exists. var createdOutputDirectory: Bool = false @@ -79,6 +83,10 @@ struct JavaToSwift: ParsableCommand { return URL(fileURLWithPath: outputDirectory) } + guard let moduleName else { + fatalError("--module-name must be set!") + } + // Put the result into Sources/\(moduleName). let baseDir = URL(fileURLWithPath: ".") .appendingPathComponent("Sources", isDirectory: true) @@ -97,25 +105,36 @@ struct JavaToSwift: ParsableCommand { return outputDir } - /// Describes what kind of generation action is being performed by - /// Java2Swift. - enum GenerationMode { + /// Describes what kind of generation action is being performed by swift-java. + enum ToolMode { /// Generate a configuration file given a Jar file. case configuration(jarFile: String) /// Generate Swift wrappers for Java classes based on the given /// configuration. case classWrappers(Configuration) + + /// Fetch dependencies for a module + case fetchDependencies(Configuration) + // FIXME each mode should have its own config? } mutating func run() throws { // Determine the mode in which we'll execute. - let generationMode: GenerationMode + let toolMode: ToolMode if jar { - generationMode = .configuration(jarFile: input) + toolMode = .configuration(jarFile: input) + } else if fetch { + let config = try JavaTranslator.readConfiguration(from: URL(fileURLWithPath: input)) + guard let dependencies = config.dependencies else { + print("[swift-java] Running in 'fetch dependencies' mode but dependencies list was empty!") + print("[swift-java] Nothing to do: done.") + return + } + toolMode = .fetchDependencies(config) } else { let config = try JavaTranslator.readConfiguration(from: URL(fileURLWithPath: input)) - generationMode = .classWrappers(config) + toolMode = .classWrappers(config) } // Load all of the dependent configurations and associate them with Swift @@ -136,160 +155,58 @@ struct JavaToSwift: ParsableCommand { // Form a class path from all of our input sources: // * Command-line option --classpath - var classpathPieces: [String] = classpath - switch generationMode { + var classPathPieces: [String] = classpath.flatMap { $0.split(separator: ":").map(String.init) } + switch toolMode { case .configuration(jarFile: let jarFile): // * Jar file (in `-jar` mode) - classpathPieces.append(jarFile) - case .classWrappers(let config): - // * Class path specified in the configuration file (if any) - config.classpath.map { classpathPieces.append($0) } + classPathPieces.append(jarFile) + case .classWrappers(let config), + .fetchDependencies(let config): + // * Classpath specified in the configuration file (if any) + if let classpath = config.classPath { + for part in classpath.split(separator: ":") { + classPathPieces.append(String(part)) + } + } } - // * Classes paths from all dependent configuration files + // * Classespaths from all dependent configuration files for (_, config) in dependentConfigs { - config.classpath.map { classpathPieces.append($0) } + config.classPath.map { element in + print("[swift-java] Add dependent config classpath element: \(element)") + classPathPieces.append(element) + } } // Bring up the Java VM. - let jvm = try JavaVirtualMachine.shared(classpath: classpathPieces) + let classpath = classPathPieces.joined(separator: ":") + // TODO: print only in verbose mode + print("[swift-java] Initialize JVM with classpath: \(classpath)") + - // Run the generation step. - let classpath = classpathPieces.joined(separator: ":") - switch generationMode { + // Run the task. + let jvm: JavaVirtualMachine + switch toolMode { case .configuration(jarFile: let jarFile): + jvm = try JavaVirtualMachine.shared(classPath: classPathPieces) try emitConfiguration( forJarFile: jarFile, - classpath: classpath, + classPath: classpath, environment: jvm.environment() ) case .classWrappers(let config): + jvm = try JavaVirtualMachine.shared(classPath: classPathPieces) try generateWrappers( config: config, - classpath: classpath, + classPath: classpath, dependentConfigs: dependentConfigs, environment: jvm.environment() ) - } - } - - /// Generate wrapper - mutating func generateWrappers( - config: Configuration, - classpath: String, - dependentConfigs: [(String, Configuration)], - environment: JNIEnvironment - ) throws { - let translator = JavaTranslator( - swiftModuleName: moduleName, - environment: environment, - translateAsClass: true - ) - - // Keep track of all of the Java classes that will have - // Swift-native implementations. - translator.swiftNativeImplementations = Set(swiftNativeImplementation) - - // Note all of the dependent configurations. - for (swiftModuleName, dependentConfig) in dependentConfigs { - translator.addConfiguration( - dependentConfig, - forSwiftModule: swiftModuleName - ) - } - - // Add the configuration for this module. - translator.addConfiguration(config, forSwiftModule: moduleName) - - // Load all of the explicitly-requested classes. - let classLoader = try JavaClass(environment: environment) - .getSystemClassLoader()! - var javaClasses: [JavaClass] = [] - for (javaClassName, swiftName) in config.classes { - guard let javaClass = try classLoader.loadClass(javaClassName) else { - print("warning: could not find Java class '\(javaClassName)'") - continue - } - - // Add this class to the list of classes we'll translate. - javaClasses.append(javaClass) - } - - // Find all of the nested classes for each class, adding them to the list - // of classes to be translated if they were already specified. - var allClassesToVisit = javaClasses - var currentClassIndex: Int = 0 - while currentClassIndex < allClassesToVisit.count { - defer { - currentClassIndex += 1 - } - - // The current class we're in. - let currentClass = allClassesToVisit[currentClassIndex] - guard let currentSwiftName = translator.translatedClasses[currentClass.getName()]?.swiftType else { - continue - } - - // Find all of the nested classes that weren't explicitly translated - // already. - let nestedClasses: [JavaClass] = currentClass.getClasses().compactMap { nestedClass in - guard let nestedClass else { return nil } - - // If this is a local class, we're done. - let javaClassName = nestedClass.getName() - if javaClassName.isLocalJavaClass { - return nil - } - - // If this class has been explicitly mentioned, we're done. - if translator.translatedClasses[javaClassName] != nil { - return nil - } - - // Record this as a translated class. - let swiftUnqualifiedName = javaClassName.javaClassNameToCanonicalName - .defaultSwiftNameForJavaClass - - - let swiftName = "\(currentSwiftName).\(swiftUnqualifiedName)" - translator.translatedClasses[javaClassName] = (swiftName, nil) - return nestedClass - } - // If there were no new nested classes, there's nothing to do. - if nestedClasses.isEmpty { - continue - } - - // Record all of the nested classes that we will visit. - translator.nestedClasses[currentClass.getName()] = nestedClasses - allClassesToVisit.append(contentsOf: nestedClasses) - } - - // Validate configurations before writing any files - try translator.validateClassConfiguration() - - // Translate all of the Java classes into Swift classes. - for javaClass in javaClasses { - translator.startNewFile() - let swiftClassDecls = try translator.translateClass(javaClass) - let importDecls = translator.getImportDecls() - - let swiftFileText = """ - // Auto-generated by Java-to-Swift wrapper generator. - \(importDecls.map { $0.description }.joined()) - \(swiftClassDecls.map { $0.description }.joined(separator: "\n")) - - """ - - let swiftFileName = try! translator.getSwiftTypeName(javaClass, preferValueTypes: false) - .swiftName.replacing(".", with: "+") + ".swift" - try writeContents( - swiftFileText, - to: swiftFileName, - description: "Java class '\(javaClass.getName())' translation" - ) + case .fetchDependencies(let config): + let dependencies = config.dependencies! // TODO: cleanup how we do config + try fetchDependencies(dependencies: dependencies, baseClasspath: classPathPieces) } } @@ -333,49 +250,10 @@ struct JavaToSwift: ParsableCommand { // Write the file: let file = outputDir.appendingPathComponent(filename) - print("Writing \(description) to '\(file.path)'...", terminator: "") + print("[swift-java] Writing \(description) to '\(file.path)'...", terminator: "") try contents.write(to: file, atomically: true, encoding: .utf8) print(" done.") } - - mutating func emitConfiguration( - forJarFile jarFileName: String, - classpath: String, - environment: JNIEnvironment - ) throws { - var configuration = Configuration(classpath: classpath) - - let jarFile = try JarFile(jarFileName, false, environment: environment) - for entry in jarFile.entries()! { - // We only look at class files in the Jar file. - guard entry.getName().hasSuffix(".class") else { - continue - } - - // If this is a local class, it cannot be mapped into Swift. - if entry.getName().isLocalJavaClass { - continue - } - - let javaCanonicalName = String(entry.getName().replacing("/", with: ".") - .dropLast(".class".count)) - configuration.classes[javaCanonicalName] = - javaCanonicalName.defaultSwiftNameForJavaClass - } - - // Encode the configuration. - let encoder = JSONEncoder() - encoder.outputFormatting = [.prettyPrinted, .sortedKeys] - var contents = String(data: try encoder.encode(configuration), encoding: .utf8)! - contents.append("\n") - - // Write the file. - try writeContents( - contents, - to: "swift-java.config", - description: "swift-java configuration file" - ) - } } enum JavaToSwiftError: Error { @@ -391,19 +269,6 @@ extension JavaToSwiftError: CustomStringConvertible { } } -extension String { - /// For a String that's of the form java.util.Vector, return the "Vector" - /// part. - fileprivate var defaultSwiftNameForJavaClass: String { - if let dotLoc = lastIndex(of: ".") { - let afterDot = index(after: dotLoc) - return String(self[afterDot...]).javaClassNameToCanonicalName.adjustedSwiftTypeName - } - - return javaClassNameToCanonicalName.adjustedSwiftTypeName - } -} - @JavaClass("java.lang.ClassLoader") public struct ClassLoader { @JavaMethod @@ -415,29 +280,3 @@ extension JavaClass { public func getSystemClassLoader() -> ClassLoader? } -extension String { - /// Replace all of the $'s for nested names with "." to turn a Java class - /// name into a Java canonical class name, - fileprivate var javaClassNameToCanonicalName: String { - return replacing("$", with: ".") - } - - /// Whether this is the name of an anonymous class. - fileprivate var isLocalJavaClass: Bool { - for segment in split(separator: "$") { - if let firstChar = segment.first, firstChar.isNumber { - return true - } - } - - return false - } - - /// Adjust type name for "bad" type names that don't work well in Swift. - fileprivate var adjustedSwiftTypeName: String { - switch self { - case "Type": return "JavaType" - default: return self - } - } -} diff --git a/Sources/Java2Swift/MiniTerminalColors.swift b/Sources/Java2Swift/MiniTerminalColors.swift new file mode 100644 index 00000000..7a9d6087 --- /dev/null +++ b/Sources/Java2Swift/MiniTerminalColors.swift @@ -0,0 +1,26 @@ +//===----------------------------------------------------------------------===// +// +// This source file is part of the Swift.org open source project +// +// Copyright (c) 2024 Apple Inc. and the Swift.org project authors +// Licensed under Apache License v2.0 +// +// See LICENSE.txt for license information +// See CONTRIBUTORS.txt for the list of Swift.org project authors +// +// SPDX-License-Identifier: Apache-2.0 +// +//===----------------------------------------------------------------------===// + +// TODO: Share TerminalColors.swift + +// Mini coloring helper, since we cannot have dependencies we keep it minimal here +extension String { + var red: String { + "\u{001B}[0;31m" + "\(self)" + "\u{001B}[0;0m" + } + var green: String { + "\u{001B}[0;32m" + "\(self)" + "\u{001B}[0;0m" + } +} + diff --git a/Sources/Java2Swift/String+Extensions.swift b/Sources/Java2Swift/String+Extensions.swift new file mode 100644 index 00000000..ba26f892 --- /dev/null +++ b/Sources/Java2Swift/String+Extensions.swift @@ -0,0 +1,62 @@ +//===----------------------------------------------------------------------===// +// +// This source file is part of the Swift.org open source project +// +// Copyright (c) 2024 Apple Inc. and the Swift.org project authors +// Licensed under Apache License v2.0 +// +// See LICENSE.txt for license information +// See CONTRIBUTORS.txt for the list of Swift.org project authors +// +// SPDX-License-Identifier: Apache-2.0 +// +//===----------------------------------------------------------------------===// + +import Foundation +import ArgumentParser +import Java2SwiftLib +import JavaKit +import JavaKitJar +import Java2SwiftLib +import JavaKitDependencyResolver +import JavaKitConfigurationShared + +extension String { + /// For a String that's of the form java.util.Vector, return the "Vector" + /// part. + var defaultSwiftNameForJavaClass: String { + if let dotLoc = lastIndex(of: ".") { + let afterDot = index(after: dotLoc) + return String(self[afterDot...]).javaClassNameToCanonicalName.adjustedSwiftTypeName + } + + return javaClassNameToCanonicalName.adjustedSwiftTypeName + } +} + +extension String { + /// Replace all of the $'s for nested names with "." to turn a Java class + /// name into a Java canonical class name, + var javaClassNameToCanonicalName: String { + return replacing("$", with: ".") + } + + /// Whether this is the name of an anonymous class. + var isLocalJavaClass: Bool { + for segment in split(separator: "$") { + if let firstChar = segment.first, firstChar.isNumber { + return true + } + } + + return false + } + + /// Adjust type name for "bad" type names that don't work well in Swift. + var adjustedSwiftTypeName: String { + switch self { + case "Type": return "JavaType" + default: return self + } + } +} diff --git a/Sources/Java2SwiftLib/Configuration.swift b/Sources/Java2SwiftLib/Configuration.swift deleted file mode 100644 index 2cda8476..00000000 --- a/Sources/Java2SwiftLib/Configuration.swift +++ /dev/null @@ -1,45 +0,0 @@ -//===----------------------------------------------------------------------===// -// -// This source file is part of the Swift.org open source project -// -// Copyright (c) 2024 Apple Inc. and the Swift.org project authors -// Licensed under Apache License v2.0 -// -// See LICENSE.txt for license information -// See CONTRIBUTORS.txt for the list of Swift.org project authors -// -// SPDX-License-Identifier: Apache-2.0 -// -//===----------------------------------------------------------------------===// - -package typealias JavaVersion = Int - -/// Configuration for the Java2Swift translation tool, provided on a per-target -/// basis. -/// -/// Note: there is a copy of this struct in the Java2Swift plugin. They -/// must be kept in sync. -package struct Configuration: Codable { - /// The Java class path that should be passed along to the Java2Swift tool. - package var classpath: String? = nil - - /// The Java classes that should be translated to Swift. The keys are - /// canonical Java class names (e.g., java.util.Vector) and the values are - /// the corresponding Swift names (e.g., JavaVector). - package var classes: [String: String] = [:] - - package var sourceCompatibility: JavaVersion? - package var targetCompatibility: JavaVersion? - - package init( - classpath: String? = nil, - classes: [String : String] = [:], - sourceCompatibility: JavaVersion? = nil, - targetCompatibility: JavaVersion? = nil - ) { - self.classpath = classpath - self.classes = classes - self.sourceCompatibility = sourceCompatibility - self.targetCompatibility = targetCompatibility - } -} diff --git a/Sources/Java2SwiftLib/JavaTranslator+Configuration.swift b/Sources/Java2SwiftLib/JavaTranslator+Configuration.swift index b84d7a1e..e0f6d0cb 100644 --- a/Sources/Java2SwiftLib/JavaTranslator+Configuration.swift +++ b/Sources/Java2SwiftLib/JavaTranslator+Configuration.swift @@ -13,6 +13,7 @@ //===----------------------------------------------------------------------===// import Foundation +import JavaKitConfigurationShared extension JavaTranslator { /// Read a configuration file from the given URL. @@ -24,7 +25,11 @@ extension JavaTranslator { /// Load the configuration file with the given name to populate the known set of /// translated Java classes. package func addConfiguration(_ config: Configuration, forSwiftModule swiftModule: String) { - for (javaClassName, swiftName) in config.classes { + guard let classes = config.classes else { + return + } + + for (javaClassName, swiftName) in classes { translatedClasses[javaClassName] = ( swiftType: swiftName, swiftModule: swiftModule diff --git a/Sources/Java2SwiftLib/JavaTranslator.swift b/Sources/Java2SwiftLib/JavaTranslator.swift index 69edac6c..225d3868 100644 --- a/Sources/Java2SwiftLib/JavaTranslator.swift +++ b/Sources/Java2SwiftLib/JavaTranslator.swift @@ -17,6 +17,7 @@ import JavaKitReflection import JavaTypes import SwiftBasicFormat import SwiftSyntax +import JavaKitConfigurationShared import SwiftSyntaxBuilder /// Utility that translates Java classes into Swift source code to access diff --git a/Sources/JavaKit/JavaKitVM/JavaVirtualMachine.swift b/Sources/JavaKit/JavaKitVM/JavaVirtualMachine.swift index 61f01f51..436870a6 100644 --- a/Sources/JavaKit/JavaKitVM/JavaVirtualMachine.swift +++ b/Sources/JavaKit/JavaKitVM/JavaVirtualMachine.swift @@ -32,13 +32,16 @@ public final class JavaVirtualMachine: @unchecked Sendable { /// The Java virtual machine instance. private let jvm: JavaVMPointer + let classPath: [String] + /// Whether to destroy the JVM on deinit. - private let destroyOnDeinit: Bool + private let destroyOnDeinit: LockedState // FIXME: we should require macOS 15 and then use Synchronization /// Adopt an existing JVM pointer. public init(adoptingJVM jvm: JavaVMPointer) { self.jvm = jvm - self.destroyOnDeinit = false + self.classPath = [] // FIXME: bad... + self.destroyOnDeinit = .init(initialState: false) } /// Initialize a new Java virtual machine instance. @@ -56,6 +59,7 @@ public final class JavaVirtualMachine: @unchecked Sendable { vmOptions: [String] = [], ignoreUnrecognized: Bool = false ) throws { + self.classPath = classPath var jvm: JavaVMPointer? = nil var environment: UnsafeMutableRawPointer? = nil var vmArgs = JavaVMInitArgs() @@ -68,7 +72,9 @@ public final class JavaVirtualMachine: @unchecked Sendable { let fileManager = FileManager.default for path in classpath { if !fileManager.fileExists(atPath: path) { - throw JavaKitError.classpathEntryNotFound(entry: path, classpath: classpath) + // FIXME: this should be configurable, a classpath missing a directory isn't reason to blow up + print("[warning][swift-java][JavaVirtualMachine] Missing classpath element: \(path)") // TODO: stderr + // throw JavaKitError.classPathEntryNotFound(entry: path, classPath: classPath) } } let colonSeparatedClassPath = classpath.joined(separator: ":") @@ -104,20 +110,41 @@ public final class JavaVirtualMachine: @unchecked Sendable { } self.jvm = jvm! - self.destroyOnDeinit = true + self.destroyOnDeinit = .init(initialState: true) + print("[trace][swift-java][JavaVirtualMachine] init complete \(self)") + } + + public func destroyJVM() throws { + try self.detachCurrentThread() + if let error = VMError(fromJNIError: jvm.pointee!.pointee.DestroyJavaVM(jvm)) { + throw error + } + + _ = destroyOnDeinit.withLock { $0 = false } // we destroyed explicitly, disable destroy in deinit + print("[trace][swift-java][JavaVirtualMachine] destroy complete \(self)") } deinit { - if destroyOnDeinit { - // Destroy the JVM. - if let resultError = VMError(fromJNIError: jvm.pointee!.pointee.DestroyJavaVM(jvm)) { - fatalError("Failed to destroy the JVM: \(resultError)") + if destroyOnDeinit.withLock { $0 } { + do { + try destroyJVM() + } catch { + fatalError("Failed to destroy the JVM: \(error)") } } + print("[trace][swift-java][JavaVirtualMachine] Deinit complete \(self)") + } +} + +extension JavaVirtualMachine: CustomStringConvertible { + public var description: String { + "\(Self.self)(\(jvm))" } } +// ==== ------------------------------------------------------------------------ // MARK: Java thread management. + extension JavaVirtualMachine { /// Produce the JNI environment for the active thread, attaching this /// thread to the JVM if it isn't already. @@ -148,6 +175,7 @@ extension JavaVirtualMachine { // If we failed to attach, report that. if let attachError = VMError(fromJNIError: attachResult) { + fatalError("JVM Error: \(attachError)") throw attachError } @@ -164,8 +192,9 @@ extension JavaVirtualMachine { } } } - +// ==== ------------------------------------------------------------------------ // MARK: Shared Java Virtual Machine management. + extension JavaVirtualMachine { /// The globally shared JavaVirtualMachine instance, behind a lock. /// @@ -190,15 +219,26 @@ extension JavaVirtualMachine { /// be prefixed by the class-path argument described above. /// - ignoreUnrecognized: Whether the JVM should ignore any VM options it /// does not recognize. + /// - replace: replace the existing shared JVM instance public static func shared( classpath: [String] = [], vmOptions: [String] = [], - ignoreUnrecognized: Bool = false + ignoreUnrecognized: Bool = false, + replace: Bool = false ) throws -> JavaVirtualMachine { - try sharedJVM.withLock { (sharedJVMPointer: inout JavaVirtualMachine?) in + precondition(!classPath.contains(where: { $0.contains(":") }), "Classpath element must not contain `:`! Split the path into elements! Was: \(classPath)") + + return try sharedJVM.withLock { (sharedJVMPointer: inout JavaVirtualMachine?) in // If we already have a JavaVirtualMachine instance, return it. - if let existingInstance = sharedJVMPointer { - return existingInstance + if replace { + print("[swift-java] Replace JVM instance!") + try sharedJVMPointer?.destroyJVM() + sharedJVMPointer = nil + } else { + if let existingInstance = sharedJVMPointer { + // FIXME: this isn't ideal; we silently ignored that we may have requested a different classpath or options + return existingInstance + } } while true { @@ -273,9 +313,9 @@ extension JavaVirtualMachine { case invalidArguments /// Unknown JNI error. - case unknown(jint) + case unknown(jint, file: String, line: UInt) - init?(fromJNIError error: jint) { + init?(fromJNIError error: jint, file: String = #fileID, line: UInt = #line) { switch error { case JNI_OK: return nil case JNI_EDETACHED: self = .threadDetached @@ -283,7 +323,7 @@ extension JavaVirtualMachine { case JNI_ENOMEM: self = .outOfMemory case JNI_EEXIST: self = .existingVM case JNI_EINVAL: self = .invalidArguments - default: self = .unknown(error) + default: self = .unknown(error, file: file, line: line) } } } diff --git a/Plugins/PluginsShared/Configuration.swift b/Sources/JavaKitConfigurationShared/Configuration.swift similarity index 50% rename from Plugins/PluginsShared/Configuration.swift rename to Sources/JavaKitConfigurationShared/Configuration.swift index 769eef70..4bc34698 100644 --- a/Plugins/PluginsShared/Configuration.swift +++ b/Sources/JavaKitConfigurationShared/Configuration.swift @@ -14,32 +14,79 @@ import Foundation -typealias JavaVersion = Int +//////////////////////////////////////////////////////////////////////////////// +// This file is only supposed to be edited in `Shared/` and must be symlinked // +// from everywhere else! We cannot share dependencies with or between plugins // +//////////////////////////////////////////////////////////////////////////////// + +public typealias JavaVersion = Int /// Configuration for the SwiftJava plugins, provided on a per-target basis. -struct Configuration: Codable { +public struct Configuration: Codable { // ==== swift 2 java --------------------------------------------------------- - var javaPackage: String? + public var javaPackage: String? // ==== java 2 swift --------------------------------------------------------- /// The Java class path that should be passed along to the Java2Swift tool. - var classPath: String? = nil + public var classPath: String? = nil /// The Java classes that should be translated to Swift. The keys are /// canonical Java class names (e.g., java.util.Vector) and the values are /// the corresponding Swift names (e.g., JavaVector). - var classes: [String: String]? = [:] + public var classes: [String: String]? = [:] // Compile for the specified Java SE release. - var sourceCompatibility: JavaVersion? + public var sourceCompatibility: JavaVersion? // Generate class files suitable for the specified Java SE release. - var targetCompatibility: JavaVersion? + public var targetCompatibility: JavaVersion? + + // ==== dependencies --------------------------------------------------------- + + // Java dependencies we need to fetch for this target. + public var dependencies: [JavaDependencyDescriptor]? + + public init() { + } + +} + +/// Represents a maven-style Java dependency. +public struct JavaDependencyDescriptor: Codable { + public var groupID: String + public var artifactID: String + public var version: String + + public init(from decoder: any Decoder) throws { + let container = try decoder.singleValueContainer() + let string = try container.decode(String.self) + let parts = string.split(separator: ":") + guard parts.count == 3 else { + throw JavaDependencyDescriptorError(message: "Illegal dependency, did not match: `groupID:artifactID:version`") + } + self.groupID = String(parts[0]) + self.artifactID = String(parts[1]) + self.version = String(parts[2]) + } + + public var descriptionGradleStyle: String { + [groupID, artifactID, version].joined(separator: ":") + } + + public func encode(to encoder: any Encoder) throws { + var container = encoder.singleValueContainer() + try container.encode("\(self.groupID):\(self.artifactID):\(self.version)") + } + + struct JavaDependencyDescriptorError: Error { + let message: String + } } -func readConfiguration(sourceDir: String, file: String = #fileID, line: UInt = #line) throws -> Configuration { +@available(macOS 13.0, *) +public func readConfiguration(sourceDir: String, file: String = #fileID, line: UInt = #line) throws -> Configuration { let configFile = URL(filePath: sourceDir).appending(path: "swift-java.config") do { let configData = try Data(contentsOf: configFile) @@ -51,7 +98,7 @@ func readConfiguration(sourceDir: String, file: String = #fileID, line: UInt = # } extension Configuration { - var compilerVersionArgs: [String] { + public var compilerVersionArgs: [String] { var compilerVersionArgs = [String]() if let sourceCompatibility { @@ -65,7 +112,7 @@ extension Configuration { } } -struct ConfigurationError: Error { +public struct ConfigurationError: Error { let message: String let error: any Error diff --git a/Sources/JavaKitDependencyResolver/DependencyResolver.swift b/Sources/JavaKitDependencyResolver/DependencyResolver.swift new file mode 100644 index 00000000..4b7d9edd --- /dev/null +++ b/Sources/JavaKitDependencyResolver/DependencyResolver.swift @@ -0,0 +1,29 @@ +//===----------------------------------------------------------------------===// +// +// This source file is part of the Swift.org open source project +// +// Copyright (c) 2024 Apple Inc. and the Swift.org project authors +// Licensed under Apache License v2.0 +// +// See LICENSE.txt for license information +// See CONTRIBUTORS.txt for the list of Swift.org project authors +// +// SPDX-License-Identifier: Apache-2.0 +// +//===----------------------------------------------------------------------===// + +import JavaKit +import JavaRuntime + +@JavaInterface("org.swift.javakit.dependencies.DependencyResolver") +public struct DependencyResolver { +} + +extension JavaClass { + + @JavaStaticMethod + public func resolveDependenciesToClasspath( + projectBaseDirectory: String, + dependencies: [String]) throws -> String + +} \ No newline at end of file diff --git a/Sources/JavaKitDependencyResolver/swift-java.config b/Sources/JavaKitDependencyResolver/swift-java.config new file mode 100644 index 00000000..3f095312 --- /dev/null +++ b/Sources/JavaKitDependencyResolver/swift-java.config @@ -0,0 +1,9 @@ +{ + "dependencies": [ + "dev.gradleplugins:gradle-api:8.10.1" + ], + "classPath": "JavaKit/build/classes/java/main", + "classes": { + "org.swift.javakit.dependencies.DependencyResolver": "DependencyResolver" + } + } \ No newline at end of file diff --git a/SwiftJava.xcworkspace/contents.xcworkspacedata b/SwiftJava.xcworkspace/contents.xcworkspacedata new file mode 100644 index 00000000..6e4db1f6 --- /dev/null +++ b/SwiftJava.xcworkspace/contents.xcworkspacedata @@ -0,0 +1,23 @@ + + + + + + + + + + + + + + + diff --git a/SwiftJava.xcworkspace/xcshareddata/WorkspaceSettings.xcsettings b/SwiftJava.xcworkspace/xcshareddata/WorkspaceSettings.xcsettings new file mode 100644 index 00000000..0c67376e --- /dev/null +++ b/SwiftJava.xcworkspace/xcshareddata/WorkspaceSettings.xcsettings @@ -0,0 +1,5 @@ + + + + + diff --git a/settings.gradle b/settings.gradle index fa0fa5bd..c1168a68 100644 --- a/settings.gradle +++ b/settings.gradle @@ -18,6 +18,7 @@ pluginManagement { rootProject.name = "swift-java" +include "JavaKit" include "SwiftKit" // Include sample apps -- you can run them via `gradle Name:run` From cb115ba07d966ff2e72442e297627944f144596a Mon Sep 17 00:00:00 2001 From: Konrad `ktoso` Malawski Date: Fri, 29 Nov 2024 22:36:29 +0900 Subject: [PATCH 02/25] add a sample --- Samples/JavaDependencySampleApp/Package.swift | 80 +++++++++++++++++ .../JavaKitExample/JavaKitExample.swift | 89 +++++++++++++++++++ .../Sources/JavaKitExample/swift-java.config | 7 ++ .../JavaDependencySampleApp/ci-validate.sh | 7 ++ .../JavaToSwift+FetchDependencies.swift | 13 ++- Sources/Java2Swift/JavaToSwift.swift | 6 +- 6 files changed, 198 insertions(+), 4 deletions(-) create mode 100644 Samples/JavaDependencySampleApp/Package.swift create mode 100644 Samples/JavaDependencySampleApp/Sources/JavaKitExample/JavaKitExample.swift create mode 100644 Samples/JavaDependencySampleApp/Sources/JavaKitExample/swift-java.config create mode 100755 Samples/JavaDependencySampleApp/ci-validate.sh diff --git a/Samples/JavaDependencySampleApp/Package.swift b/Samples/JavaDependencySampleApp/Package.swift new file mode 100644 index 00000000..8a9eb064 --- /dev/null +++ b/Samples/JavaDependencySampleApp/Package.swift @@ -0,0 +1,80 @@ +// swift-tools-version: 6.0 +// The swift-tools-version declares the minimum version of Swift required to build this package. + +import CompilerPluginSupport +import PackageDescription + +import class Foundation.FileManager +import class Foundation.ProcessInfo + +// Note: the JAVA_HOME environment variable must be set to point to where +// Java is installed, e.g., +// Library/Java/JavaVirtualMachines/openjdk-21.jdk/Contents/Home. +func findJavaHome() -> String { + if let home = ProcessInfo.processInfo.environment["JAVA_HOME"] { + return home + } + + // This is a workaround for envs (some IDEs) which have trouble with + // picking up env variables during the build process + let path = "\(FileManager.default.homeDirectoryForCurrentUser.path()).java_home" + if let home = try? String(contentsOfFile: path, encoding: .utf8) { + if let lastChar = home.last, lastChar.isNewline { + return String(home.dropLast()) + } + + return home + } + + fatalError("Please set the JAVA_HOME environment variable to point to where Java is installed.") +} +let javaHome = findJavaHome() + +let javaIncludePath = "\(javaHome)/include" +#if os(Linux) + let javaPlatformIncludePath = "\(javaIncludePath)/linux" +#elseif os(macOS) + let javaPlatformIncludePath = "\(javaIncludePath)/darwin" +#else + // TODO: Handle windows as well + #error("Currently only macOS and Linux platforms are supported, this may change in the future.") +#endif + +let package = Package( + name: "JavaKitSampleApp", + platforms: [ + .macOS(.v13), + .iOS(.v13), + .tvOS(.v13), + .watchOS(.v6), + .macCatalyst(.v13), + ], + + products: [ + .library( + name: "JavaKitExample", + type: .dynamic, + targets: ["JavaKitExample"] + ), + ], + + dependencies: [ + .package(name: "swift-java", path: "../../") + ], + + targets: [ + .target( + name: "JavaKitExample", + dependencies: [ + .product(name: "JavaKit", package: "swift-java"), + .product(name: "JavaKitFunction", package: "swift-java"), + ], + swiftSettings: [ + .unsafeFlags(["-I\(javaIncludePath)", "-I\(javaPlatformIncludePath)"]) + ], + plugins: [ + .plugin(name: "SwiftJavaPlugin", package: "swift-java"), + ] + ), + ] +) diff --git a/Samples/JavaDependencySampleApp/Sources/JavaKitExample/JavaKitExample.swift b/Samples/JavaDependencySampleApp/Sources/JavaKitExample/JavaKitExample.swift new file mode 100644 index 00000000..366e8894 --- /dev/null +++ b/Samples/JavaDependencySampleApp/Sources/JavaKitExample/JavaKitExample.swift @@ -0,0 +1,89 @@ +//===----------------------------------------------------------------------===// +// +// This source file is part of the Swift.org open source project +// +// Copyright (c) 2024 Apple Inc. and the Swift.org project authors +// Licensed under Apache License v2.0 +// +// See LICENSE.txt for license information +// See CONTRIBUTORS.txt for the list of Swift.org project authors +// +// SPDX-License-Identifier: Apache-2.0 +// +//===----------------------------------------------------------------------===// + +import JavaKit +import JavaKitFunction + +enum SwiftWrappedError: Error { + case message(String) +} + +@JavaImplementation("com.example.swift.HelloSwift") +extension HelloSwift: HelloSwiftNativeMethods { + @JavaMethod + func sayHello(_ i: Int32, _ j: Int32) -> Int32 { + print("Hello from Swift!") + let answer = self.sayHelloBack(i + j) + print("Swift got back \(answer) from Java") + + print("We expect the above value to be the initial value, \(self.javaClass.initialValue)") + + print("Updating Java field value to something different") + self.value = 2.71828 + + let newAnswer = self.sayHelloBack(17) + print("Swift got back updated \(newAnswer) from Java") + + let newHello = HelloSwift(environment: javaEnvironment) + print("Swift created a new Java instance with the value \(newHello.value)") + + let name = newHello.name + print("Hello to \(name)") + newHello.greet("Swift 👋🏽 How's it going") + + self.name = "a 🗑️-collected language" + _ = self.sayHelloBack(42) + + let predicate: JavaPredicate = self.lessThanTen()! + let value = predicate.test(JavaInteger(3).as(JavaObject.self)) + print("Running a JavaPredicate from swift 3 < 10 = \(value)") + + let strings = doublesToStrings([3.14159, 2.71828]) + print("Converting doubles to strings: \(strings)") + + // Try downcasting + if let helloSub = self.as(HelloSubclass.self) { + print("Hello from the subclass!") + helloSub.greetMe() + + assert(helloSub.value == 2.71828) + } else { + fatalError("Expected subclass here") + } + + // Check "is" behavior + assert(newHello.is(HelloSwift.self)) + assert(!newHello.is(HelloSubclass.self)) + + // Create a new instance. + let helloSubFromSwift = HelloSubclass("Hello from Swift", environment: javaEnvironment) + helloSubFromSwift.greetMe() + + do { + try throwMessage("I am an error") + } catch { + print("Caught Java error: \(error)") + } + + // Make sure that the thread safe class is sendable + let threadSafe: Sendable = ThreadSafeHelperClass(environment: javaEnvironment) + + return i * j + } + + @JavaMethod + func throwMessageFromSwift(_ message: String) throws -> String { + throw SwiftWrappedError.message(message) + } +} diff --git a/Samples/JavaDependencySampleApp/Sources/JavaKitExample/swift-java.config b/Samples/JavaDependencySampleApp/Sources/JavaKitExample/swift-java.config new file mode 100644 index 00000000..4dca6264 --- /dev/null +++ b/Samples/JavaDependencySampleApp/Sources/JavaKitExample/swift-java.config @@ -0,0 +1,7 @@ +{ + "dependencies": [ + "org.reactivestreams:reactive-streams:1.0.4" + ], + "__FIXME": "we should not need to express this classpath!", + "classPath": "JavaKit/build/classes/java/main", +} diff --git a/Samples/JavaDependencySampleApp/ci-validate.sh b/Samples/JavaDependencySampleApp/ci-validate.sh new file mode 100755 index 00000000..eff61551 --- /dev/null +++ b/Samples/JavaDependencySampleApp/ci-validate.sh @@ -0,0 +1,7 @@ +#!/bin/sh + +swift build +"$JAVA_HOME/bin/java" \ + -cp .build/plugins/outputs/javakitsampleapp/JavaKitExample/destination/JavaCompilerPlugin/Java \ + -Djava.library.path=.build/debug \ + "com.example.swift.JavaKitSampleMain" diff --git a/Sources/Java2Swift/JavaToSwift+FetchDependencies.swift b/Sources/Java2Swift/JavaToSwift+FetchDependencies.swift index ca9b1269..80c8d9b0 100644 --- a/Sources/Java2Swift/JavaToSwift+FetchDependencies.swift +++ b/Sources/Java2Swift/JavaToSwift+FetchDependencies.swift @@ -22,7 +22,7 @@ import JavaKitDependencyResolver import JavaKitConfigurationShared extension JavaToSwift { - func fetchDependencies(projectName: String, + func fetchDependencies(moduleName: String, dependencies: [JavaDependencyDescriptor], baseClasspath: [String]) throws -> JavaClasspath { let deps = dependencies.map { $0.descriptionGradleStyle } @@ -36,9 +36,16 @@ extension JavaToSwift { projectBaseDirectory: URL(fileURLWithPath: ".").path, dependencies: deps) - let entryCount = classpath.split(separator: ":").count - print("[debug][swift-java] Resolved classpath for \(deps.count) dependencies: classpath entries: \(entryCount)... ", terminator: "") + let entries = classpath.split(separator: ":") + let entryCount = entries.count + + print("[info][swift-java] Resolved classpath for \(deps.count) dependencies of '\(moduleName)': classpath entries: \(entryCount)... ", terminator: "") print("done.".green) + + for entry in entries { + print("[debug][swift-java] Classpath entry: \(entry)") + } + return .init(classpath) } } diff --git a/Sources/Java2Swift/JavaToSwift.swift b/Sources/Java2Swift/JavaToSwift.swift index 98d34ae8..31e86faa 100644 --- a/Sources/Java2Swift/JavaToSwift.swift +++ b/Sources/Java2Swift/JavaToSwift.swift @@ -137,6 +137,10 @@ struct JavaToSwift: ParsableCommand { toolMode = .classWrappers(config) } + let moduleName = self.moduleName ?? + input.split(separator: "/").dropLast().last.map(String.init) ?? + "__UnknownModule" + // Load all of the dependent configurations and associate them with Swift // modules. let dependentConfigs = try dependsOn.map { dependentConfig in @@ -206,7 +210,7 @@ struct JavaToSwift: ParsableCommand { case .fetchDependencies(let config): let dependencies = config.dependencies! // TODO: cleanup how we do config - try fetchDependencies(dependencies: dependencies, baseClasspath: classPathPieces) + try fetchDependencies(moduleName: moduleName, dependencies: dependencies, baseClasspath: classPathPieces) } } From 3254f8bca21944a4086de5f250315a1e8a6a38fa Mon Sep 17 00:00:00 2001 From: Konrad `ktoso` Malawski Date: Mon, 2 Dec 2024 12:03:22 +0900 Subject: [PATCH 03/25] work on sample such that we download and use the dependencies --- Package.swift | 5 ++ Samples/JavaDependencySampleApp/Package.swift | 4 +- .../Sources/JavaDependencySample/main.swift | 16 ++++ .../swift-java.config | 2 +- .../JavaKitExample/JavaKitExample.swift | 89 ------------------- .../Sources/ReactiveStreams/.gitkeep | 0 .../Sources/ReactiveStreams/swift-java.config | 18 ++++ .../JavaDependencySampleApp/ci-validate.sh | 6 +- Sources/JExtractSwift/Swift2Java.swift | 1 + Sources/Java2Swift/JavaToSwift.swift | 4 + .../TerminalColors.swift | 0 Sources/ReactiveStreams/swift-java.config | 18 ++++ 12 files changed, 70 insertions(+), 93 deletions(-) create mode 100644 Samples/JavaDependencySampleApp/Sources/JavaDependencySample/main.swift rename Samples/JavaDependencySampleApp/Sources/{JavaKitExample => JavaDependencySample}/swift-java.config (61%) delete mode 100644 Samples/JavaDependencySampleApp/Sources/JavaKitExample/JavaKitExample.swift create mode 100644 Samples/JavaDependencySampleApp/Sources/ReactiveStreams/.gitkeep create mode 100644 Samples/JavaDependencySampleApp/Sources/ReactiveStreams/swift-java.config rename Sources/{JExtractSwift => JavaKitShared}/TerminalColors.swift (100%) create mode 100644 Sources/ReactiveStreams/swift-java.config diff --git a/Package.swift b/Package.swift index 58a0c946..d8b637c4 100644 --- a/Package.swift +++ b/Package.swift @@ -301,6 +301,10 @@ let package = Package( name: "JavaKitConfigurationShared" ), + .target( + name: "JavaKitShared" + ), + .target( name: "Java2SwiftLib", dependencies: [ @@ -351,6 +355,7 @@ let package = Package( .product(name: "SwiftSyntaxBuilder", package: "swift-syntax"), .product(name: "ArgumentParser", package: "swift-argument-parser"), "JavaTypes", + "JavaKitShared", ], swiftSettings: [ .swiftLanguageMode(.v5), diff --git a/Samples/JavaDependencySampleApp/Package.swift b/Samples/JavaDependencySampleApp/Package.swift index 8a9eb064..465abb07 100644 --- a/Samples/JavaDependencySampleApp/Package.swift +++ b/Samples/JavaDependencySampleApp/Package.swift @@ -41,7 +41,7 @@ let javaIncludePath = "\(javaHome)/include" #endif let package = Package( - name: "JavaKitSampleApp", + name: "JavaDependencySampleApp", platforms: [ .macOS(.v13), .iOS(.v13), @@ -64,7 +64,7 @@ let package = Package( targets: [ .target( - name: "JavaKitExample", + name: "JavaDependencySample", dependencies: [ .product(name: "JavaKit", package: "swift-java"), .product(name: "JavaKitFunction", package: "swift-java"), diff --git a/Samples/JavaDependencySampleApp/Sources/JavaDependencySample/main.swift b/Samples/JavaDependencySampleApp/Sources/JavaDependencySample/main.swift new file mode 100644 index 00000000..59b887e2 --- /dev/null +++ b/Samples/JavaDependencySampleApp/Sources/JavaDependencySample/main.swift @@ -0,0 +1,16 @@ +//===----------------------------------------------------------------------===// +// +// This source file is part of the Swift.org open source project +// +// Copyright (c) 2024 Apple Inc. and the Swift.org project authors +// Licensed under Apache License v2.0 +// +// See LICENSE.txt for license information +// See CONTRIBUTORS.txt for the list of Swift.org project authors +// +// SPDX-License-Identifier: Apache-2.0 +// +//===----------------------------------------------------------------------===// + +import JavaKit +import JavaKitFunction diff --git a/Samples/JavaDependencySampleApp/Sources/JavaKitExample/swift-java.config b/Samples/JavaDependencySampleApp/Sources/JavaDependencySample/swift-java.config similarity index 61% rename from Samples/JavaDependencySampleApp/Sources/JavaKitExample/swift-java.config rename to Samples/JavaDependencySampleApp/Sources/JavaDependencySample/swift-java.config index 4dca6264..2d610d2e 100644 --- a/Samples/JavaDependencySampleApp/Sources/JavaKitExample/swift-java.config +++ b/Samples/JavaDependencySampleApp/Sources/JavaDependencySample/swift-java.config @@ -3,5 +3,5 @@ "org.reactivestreams:reactive-streams:1.0.4" ], "__FIXME": "we should not need to express this classpath!", - "classPath": "JavaKit/build/classes/java/main", + "classPath": "JavaKit/build/classes/java/main:../../JavaKit/build/classes/java/main", } diff --git a/Samples/JavaDependencySampleApp/Sources/JavaKitExample/JavaKitExample.swift b/Samples/JavaDependencySampleApp/Sources/JavaKitExample/JavaKitExample.swift deleted file mode 100644 index 366e8894..00000000 --- a/Samples/JavaDependencySampleApp/Sources/JavaKitExample/JavaKitExample.swift +++ /dev/null @@ -1,89 +0,0 @@ -//===----------------------------------------------------------------------===// -// -// This source file is part of the Swift.org open source project -// -// Copyright (c) 2024 Apple Inc. and the Swift.org project authors -// Licensed under Apache License v2.0 -// -// See LICENSE.txt for license information -// See CONTRIBUTORS.txt for the list of Swift.org project authors -// -// SPDX-License-Identifier: Apache-2.0 -// -//===----------------------------------------------------------------------===// - -import JavaKit -import JavaKitFunction - -enum SwiftWrappedError: Error { - case message(String) -} - -@JavaImplementation("com.example.swift.HelloSwift") -extension HelloSwift: HelloSwiftNativeMethods { - @JavaMethod - func sayHello(_ i: Int32, _ j: Int32) -> Int32 { - print("Hello from Swift!") - let answer = self.sayHelloBack(i + j) - print("Swift got back \(answer) from Java") - - print("We expect the above value to be the initial value, \(self.javaClass.initialValue)") - - print("Updating Java field value to something different") - self.value = 2.71828 - - let newAnswer = self.sayHelloBack(17) - print("Swift got back updated \(newAnswer) from Java") - - let newHello = HelloSwift(environment: javaEnvironment) - print("Swift created a new Java instance with the value \(newHello.value)") - - let name = newHello.name - print("Hello to \(name)") - newHello.greet("Swift 👋🏽 How's it going") - - self.name = "a 🗑️-collected language" - _ = self.sayHelloBack(42) - - let predicate: JavaPredicate = self.lessThanTen()! - let value = predicate.test(JavaInteger(3).as(JavaObject.self)) - print("Running a JavaPredicate from swift 3 < 10 = \(value)") - - let strings = doublesToStrings([3.14159, 2.71828]) - print("Converting doubles to strings: \(strings)") - - // Try downcasting - if let helloSub = self.as(HelloSubclass.self) { - print("Hello from the subclass!") - helloSub.greetMe() - - assert(helloSub.value == 2.71828) - } else { - fatalError("Expected subclass here") - } - - // Check "is" behavior - assert(newHello.is(HelloSwift.self)) - assert(!newHello.is(HelloSubclass.self)) - - // Create a new instance. - let helloSubFromSwift = HelloSubclass("Hello from Swift", environment: javaEnvironment) - helloSubFromSwift.greetMe() - - do { - try throwMessage("I am an error") - } catch { - print("Caught Java error: \(error)") - } - - // Make sure that the thread safe class is sendable - let threadSafe: Sendable = ThreadSafeHelperClass(environment: javaEnvironment) - - return i * j - } - - @JavaMethod - func throwMessageFromSwift(_ message: String) throws -> String { - throw SwiftWrappedError.message(message) - } -} diff --git a/Samples/JavaDependencySampleApp/Sources/ReactiveStreams/.gitkeep b/Samples/JavaDependencySampleApp/Sources/ReactiveStreams/.gitkeep new file mode 100644 index 00000000..e69de29b diff --git a/Samples/JavaDependencySampleApp/Sources/ReactiveStreams/swift-java.config b/Samples/JavaDependencySampleApp/Sources/ReactiveStreams/swift-java.config new file mode 100644 index 00000000..bf679e9b --- /dev/null +++ b/Samples/JavaDependencySampleApp/Sources/ReactiveStreams/swift-java.config @@ -0,0 +1,18 @@ +{ + "classPath" : "/Users/ktoso/.gradle/caches/modules-2/files-2.1/org.reactivestreams/reactive-streams/1.0.4/3864a1320d97d7b045f729a326e1e077661f31b7/reactive-streams-1.0.4.jar", + "classes" : { + "org.reactivestreams.FlowAdapters" : "FlowAdapters", + "org.reactivestreams.FlowAdapters$FlowPublisherFromReactive" : "FlowAdapters.FlowPublisherFromReactive", + "org.reactivestreams.FlowAdapters$FlowToReactiveProcessor" : "FlowAdapters.FlowToReactiveProcessor", + "org.reactivestreams.FlowAdapters$FlowToReactiveSubscriber" : "FlowAdapters.FlowToReactiveSubscriber", + "org.reactivestreams.FlowAdapters$FlowToReactiveSubscription" : "FlowAdapters.FlowToReactiveSubscription", + "org.reactivestreams.FlowAdapters$ReactivePublisherFromFlow" : "FlowAdapters.ReactivePublisherFromFlow", + "org.reactivestreams.FlowAdapters$ReactiveToFlowProcessor" : "FlowAdapters.ReactiveToFlowProcessor", + "org.reactivestreams.FlowAdapters$ReactiveToFlowSubscriber" : "FlowAdapters.ReactiveToFlowSubscriber", + "org.reactivestreams.FlowAdapters$ReactiveToFlowSubscription" : "FlowAdapters.ReactiveToFlowSubscription", + "org.reactivestreams.Processor" : "Processor", + "org.reactivestreams.Publisher" : "Publisher", + "org.reactivestreams.Subscriber" : "Subscriber", + "org.reactivestreams.Subscription" : "Subscription" + } +} diff --git a/Samples/JavaDependencySampleApp/ci-validate.sh b/Samples/JavaDependencySampleApp/ci-validate.sh index eff61551..10cd317a 100755 --- a/Samples/JavaDependencySampleApp/ci-validate.sh +++ b/Samples/JavaDependencySampleApp/ci-validate.sh @@ -1,6 +1,10 @@ #!/bin/sh -swift build +# TODO: + +# downloads all the dependencies +../../.build/debug/Java2Swift --fetch Sources/JavaDependencySample/swift-java.config + "$JAVA_HOME/bin/java" \ -cp .build/plugins/outputs/javakitsampleapp/JavaKitExample/destination/JavaCompilerPlugin/Java \ -Djava.library.path=.build/debug \ diff --git a/Sources/JExtractSwift/Swift2Java.swift b/Sources/JExtractSwift/Swift2Java.swift index 2167c391..a46d1ab4 100644 --- a/Sources/JExtractSwift/Swift2Java.swift +++ b/Sources/JExtractSwift/Swift2Java.swift @@ -16,6 +16,7 @@ import ArgumentParser import Foundation import SwiftSyntax import SwiftSyntaxBuilder +import JavaKitShared /// Command-line utility, similar to `jextract` to export Swift types to Java. public struct SwiftToJava: ParsableCommand { diff --git a/Sources/Java2Swift/JavaToSwift.swift b/Sources/Java2Swift/JavaToSwift.swift index 31e86faa..cfe1913a 100644 --- a/Sources/Java2Swift/JavaToSwift.swift +++ b/Sources/Java2Swift/JavaToSwift.swift @@ -66,6 +66,10 @@ struct JavaToSwift: ParsableCommand { @Flag(help: "Fetch dependencies from given target (containing swift-java configuration) or dependency string") var fetch: Bool = false + // TODO: Need a better name, this follows up a fetch with creating modules for each of the dependencies + @Flag(help: "Fetch dependencies for given ") + var fetchMakeModules: Bool = false + /// Whether we have ensured that the output directory exists. var createdOutputDirectory: Bool = false diff --git a/Sources/JExtractSwift/TerminalColors.swift b/Sources/JavaKitShared/TerminalColors.swift similarity index 100% rename from Sources/JExtractSwift/TerminalColors.swift rename to Sources/JavaKitShared/TerminalColors.swift diff --git a/Sources/ReactiveStreams/swift-java.config b/Sources/ReactiveStreams/swift-java.config new file mode 100644 index 00000000..600885b2 --- /dev/null +++ b/Sources/ReactiveStreams/swift-java.config @@ -0,0 +1,18 @@ +{ + "classPath" : "\/Users\/ktoso\/.gradle\/caches\/modules-2\/files-2.1\/org.reactivestreams\/reactive-streams\/1.0.4\/3864a1320d97d7b045f729a326e1e077661f31b7\/reactive-streams-1.0.4.jar", + "classes" : { + "org.reactivestreams.FlowAdapters" : "FlowAdapters", + "org.reactivestreams.FlowAdapters$FlowPublisherFromReactive" : "FlowAdapters.FlowPublisherFromReactive", + "org.reactivestreams.FlowAdapters$FlowToReactiveProcessor" : "FlowAdapters.FlowToReactiveProcessor", + "org.reactivestreams.FlowAdapters$FlowToReactiveSubscriber" : "FlowAdapters.FlowToReactiveSubscriber", + "org.reactivestreams.FlowAdapters$FlowToReactiveSubscription" : "FlowAdapters.FlowToReactiveSubscription", + "org.reactivestreams.FlowAdapters$ReactivePublisherFromFlow" : "FlowAdapters.ReactivePublisherFromFlow", + "org.reactivestreams.FlowAdapters$ReactiveToFlowProcessor" : "FlowAdapters.ReactiveToFlowProcessor", + "org.reactivestreams.FlowAdapters$ReactiveToFlowSubscriber" : "FlowAdapters.ReactiveToFlowSubscriber", + "org.reactivestreams.FlowAdapters$ReactiveToFlowSubscription" : "FlowAdapters.ReactiveToFlowSubscription", + "org.reactivestreams.Processor" : "Processor", + "org.reactivestreams.Publisher" : "Publisher", + "org.reactivestreams.Subscriber" : "Subscriber", + "org.reactivestreams.Subscription" : "Subscription" + } +} From 1d4d25fc469ee9a96f7a5aff3e20f9392ba5cdd0 Mon Sep 17 00:00:00 2001 From: Konrad `ktoso` Malawski Date: Tue, 3 Dec 2024 16:26:27 +0900 Subject: [PATCH 04/25] sample is now generating config from pulled dependency --- Package.swift | 2 + Samples/JavaDependencySampleApp/Package.swift | 26 +++++- .../Sources/Guava/swift-java.config | 8 ++ .../Sources/JavaDependencySample/main.swift | 6 ++ .../JavaDependencySample/swift-java.config | 4 +- .../Sources/ReactiveStreams/.gitkeep | 0 .../Sources/ReactiveStreams/swift-java.config | 18 ---- .../JavaDependencySampleApp/ci-validate.sh | 27 ++++-- .../JavaToSwift+EmitConfiguration.swift | 32 +++++-- .../JavaToSwift+FetchDependencies.swift | 76 ++++++++++----- .../JavaToSwift+GenerateWrappers.swift | 2 +- Sources/Java2Swift/JavaToSwift.swift | 92 ++++++++++++++----- Sources/Java2Swift/MiniTerminalColors.swift | 26 ------ .../JavaKitVM/JavaVirtualMachine.swift | 13 +-- .../Configuration.swift | 20 +++- .../swift-java.config | 2 +- Sources/ReactiveStreams/swift-java.config | 18 ---- 17 files changed, 229 insertions(+), 143 deletions(-) create mode 100644 Samples/JavaDependencySampleApp/Sources/Guava/swift-java.config delete mode 100644 Samples/JavaDependencySampleApp/Sources/ReactiveStreams/.gitkeep delete mode 100644 Samples/JavaDependencySampleApp/Sources/ReactiveStreams/swift-java.config delete mode 100644 Sources/Java2Swift/MiniTerminalColors.swift delete mode 100644 Sources/ReactiveStreams/swift-java.config diff --git a/Package.swift b/Package.swift index d8b637c4..706da53f 100644 --- a/Package.swift +++ b/Package.swift @@ -316,6 +316,7 @@ let package = Package( "JavaKitReflection", "JavaKitNetwork", "JavaTypes", + "JavaKitShared", "JavaKitConfigurationShared", "JavaKitDependencyResolver", ], @@ -338,6 +339,7 @@ let package = Package( "JavaKitNetwork", "Java2SwiftLib", "JavaKitDependencyResolver", + "JavaKitShared", ], swiftSettings: [ diff --git a/Samples/JavaDependencySampleApp/Package.swift b/Samples/JavaDependencySampleApp/Package.swift index 465abb07..d084f781 100644 --- a/Samples/JavaDependencySampleApp/Package.swift +++ b/Samples/JavaDependencySampleApp/Package.swift @@ -51,10 +51,9 @@ let package = Package( ], products: [ - .library( - name: "JavaKitExample", - type: .dynamic, - targets: ["JavaKitExample"] + .executable( + name: "JavaDependencySample", + targets: ["JavaDependencySample"] ), ], @@ -63,11 +62,13 @@ let package = Package( ], targets: [ - .target( + .executableTarget( name: "JavaDependencySample", dependencies: [ .product(name: "JavaKit", package: "swift-java"), + .product(name: "JavaRuntime", package: "swift-java"), .product(name: "JavaKitFunction", package: "swift-java"), + "ReactiveStreams" ], swiftSettings: [ .unsafeFlags(["-I\(javaIncludePath)", "-I\(javaPlatformIncludePath)"]) @@ -76,5 +77,20 @@ let package = Package( .plugin(name: "SwiftJavaPlugin", package: "swift-java"), ] ), + + .target( + name: "ReactiveStreams", + dependencies: [ + .product(name: "JavaKit", package: "swift-java"), + .product(name: "JavaRuntime", package: "swift-java"), + ], + swiftSettings: [ + .unsafeFlags(["-I\(javaIncludePath)", "-I\(javaPlatformIncludePath)"]) + ], + plugins: [ + .plugin(name: "SwiftJavaPlugin", package: "swift-java"), + ] + ), + ] ) diff --git a/Samples/JavaDependencySampleApp/Sources/Guava/swift-java.config b/Samples/JavaDependencySampleApp/Sources/Guava/swift-java.config new file mode 100644 index 00000000..bc508bdb --- /dev/null +++ b/Samples/JavaDependencySampleApp/Sources/Guava/swift-java.config @@ -0,0 +1,8 @@ +{ + "classes" : { + }, + "classpath" : "\/Users\/ktoso\/.gradle\/caches\/modules-2\/files-2.1\/com.google.guava\/guava\/33.3.1-jre\/852f8b363da0111e819460021ca693cacca3e8db\/guava-33.3.1-jre.jar:\/Users\/ktoso\/.gradle\/caches\/modules-2\/files-2.1\/com.google.guava\/failureaccess\/1.0.2\/c4a06a64e650562f30b7bf9aaec1bfed43aca12b\/failureaccess-1.0.2.jar:\/Users\/ktoso\/.gradle\/caches\/modules-2\/files-2.1\/com.google.guava\/listenablefuture\/9999.0-empty-to-avoid-conflict-with-guava\/b421526c5f297295adef1c886e5246c39d4ac629\/listenablefuture-9999.0-empty-to-avoid-conflict-with-guava.jar:\/Users\/ktoso\/.gradle\/caches\/modules-2\/files-2.1\/com.google.code.findbugs\/jsr305\/3.0.2\/25ea2e8b0c338a877313bd4672d3fe056ea78f0d\/jsr305-3.0.2.jar:\/Users\/ktoso\/.gradle\/caches\/modules-2\/files-2.1\/org.checkerframework\/checker-qual\/3.43.0\/9425eee39e56b116d2b998b7c2cebcbd11a3c98b\/checker-qual-3.43.0.jar:\/Users\/ktoso\/.gradle\/caches\/modules-2\/files-2.1\/com.google.errorprone\/error_prone_annotations\/2.28.0\/59fc00087ce372de42e394d2c789295dff2d19f0\/error_prone_annotations-2.28.0.jar:\/Users\/ktoso\/.gradle\/caches\/modules-2\/files-2.1\/com.google.j2objc\/j2objc-annotations\/3.0.0\/7399e65dd7e9ff3404f4535b2f017093bdb134c7\/j2objc-annotations-3.0.0.jar", + "dependencies" : [ + "com.google.guava:guava:33.3.1-jre" + ] +} diff --git a/Samples/JavaDependencySampleApp/Sources/JavaDependencySample/main.swift b/Samples/JavaDependencySampleApp/Sources/JavaDependencySample/main.swift index 59b887e2..84bc07b0 100644 --- a/Samples/JavaDependencySampleApp/Sources/JavaDependencySample/main.swift +++ b/Samples/JavaDependencySampleApp/Sources/JavaDependencySample/main.swift @@ -14,3 +14,9 @@ import JavaKit import JavaKitFunction +import ReactiveStreams + +// Just showcasing that we imported the module +let s: Subscriber? = nil + +print("Done.") \ No newline at end of file diff --git a/Samples/JavaDependencySampleApp/Sources/JavaDependencySample/swift-java.config b/Samples/JavaDependencySampleApp/Sources/JavaDependencySample/swift-java.config index 2d610d2e..b7f52945 100644 --- a/Samples/JavaDependencySampleApp/Sources/JavaDependencySample/swift-java.config +++ b/Samples/JavaDependencySampleApp/Sources/JavaDependencySample/swift-java.config @@ -1,7 +1,7 @@ { "dependencies": [ - "org.reactivestreams:reactive-streams:1.0.4" + "com.google.guava:guava:33.3.1-jre" ], "__FIXME": "we should not need to express this classpath!", - "classPath": "JavaKit/build/classes/java/main:../../JavaKit/build/classes/java/main", + "classpath": "JavaKit/build/classes/java/main:../../JavaKit/build/classes/java/main", } diff --git a/Samples/JavaDependencySampleApp/Sources/ReactiveStreams/.gitkeep b/Samples/JavaDependencySampleApp/Sources/ReactiveStreams/.gitkeep deleted file mode 100644 index e69de29b..00000000 diff --git a/Samples/JavaDependencySampleApp/Sources/ReactiveStreams/swift-java.config b/Samples/JavaDependencySampleApp/Sources/ReactiveStreams/swift-java.config deleted file mode 100644 index bf679e9b..00000000 --- a/Samples/JavaDependencySampleApp/Sources/ReactiveStreams/swift-java.config +++ /dev/null @@ -1,18 +0,0 @@ -{ - "classPath" : "/Users/ktoso/.gradle/caches/modules-2/files-2.1/org.reactivestreams/reactive-streams/1.0.4/3864a1320d97d7b045f729a326e1e077661f31b7/reactive-streams-1.0.4.jar", - "classes" : { - "org.reactivestreams.FlowAdapters" : "FlowAdapters", - "org.reactivestreams.FlowAdapters$FlowPublisherFromReactive" : "FlowAdapters.FlowPublisherFromReactive", - "org.reactivestreams.FlowAdapters$FlowToReactiveProcessor" : "FlowAdapters.FlowToReactiveProcessor", - "org.reactivestreams.FlowAdapters$FlowToReactiveSubscriber" : "FlowAdapters.FlowToReactiveSubscriber", - "org.reactivestreams.FlowAdapters$FlowToReactiveSubscription" : "FlowAdapters.FlowToReactiveSubscription", - "org.reactivestreams.FlowAdapters$ReactivePublisherFromFlow" : "FlowAdapters.ReactivePublisherFromFlow", - "org.reactivestreams.FlowAdapters$ReactiveToFlowProcessor" : "FlowAdapters.ReactiveToFlowProcessor", - "org.reactivestreams.FlowAdapters$ReactiveToFlowSubscriber" : "FlowAdapters.ReactiveToFlowSubscriber", - "org.reactivestreams.FlowAdapters$ReactiveToFlowSubscription" : "FlowAdapters.ReactiveToFlowSubscription", - "org.reactivestreams.Processor" : "Processor", - "org.reactivestreams.Publisher" : "Publisher", - "org.reactivestreams.Subscriber" : "Subscriber", - "org.reactivestreams.Subscription" : "Subscription" - } -} diff --git a/Samples/JavaDependencySampleApp/ci-validate.sh b/Samples/JavaDependencySampleApp/ci-validate.sh index 10cd317a..56a72754 100755 --- a/Samples/JavaDependencySampleApp/ci-validate.sh +++ b/Samples/JavaDependencySampleApp/ci-validate.sh @@ -1,11 +1,24 @@ #!/bin/sh -# TODO: +JAVASWIFT="../../.build/debug/Java2Swift" -# downloads all the dependencies -../../.build/debug/Java2Swift --fetch Sources/JavaDependencySample/swift-java.config +MODULE_NAME=Guava +MODULE_CONFIG_DIR=$(pwd)/Sources/$MODULE_NAME/ +MODULE_CONFIG_PATH="$MODULE_CONFIG_DIR/swift-java.config" -"$JAVA_HOME/bin/java" \ - -cp .build/plugins/outputs/javakitsampleapp/JavaKitExample/destination/JavaCompilerPlugin/Java \ - -Djava.library.path=.build/debug \ - "com.example.swift.JavaKitSampleMain" +### 1) downloads all the dependencies +"$JAVASWIFT" --fetch Sources/JavaDependencySample/swift-java.config \ + --module-name "$MODULE_NAME" \ + --output-directory "$MODULE_CONFIG_DIR" + +### 2) extract the config for the fetched dependency +DEP_JAR_CP=$(jq .classpath "$MODULE_CONFIG_PATH") +DEP_JAR_CP=$(echo "$DEP_JAR_CP" | tr -d '"') # trim the "..." +# FIXME: "jar" is the wrong word for it +# shellcheck disable=SC2086 +"$JAVASWIFT" --jar $DEP_JAR_CP \ + --module-name "$MODULE_NAME" \ + --existing-config amend + +### 3) make wrappers for the module +"$JAVASWIFT" "$MODULE_CONFIG_PATH" --module-name "$MODULE_NAME" diff --git a/Sources/Java2Swift/JavaToSwift+EmitConfiguration.swift b/Sources/Java2Swift/JavaToSwift+EmitConfiguration.swift index 6caca8fe..251c8ae2 100644 --- a/Sources/Java2Swift/JavaToSwift+EmitConfiguration.swift +++ b/Sources/Java2Swift/JavaToSwift+EmitConfiguration.swift @@ -22,13 +22,20 @@ import JavaKitDependencyResolver import JavaKitConfigurationShared extension JavaToSwift { + + // TODO: make this perhaps "emit type mappings" mutating func emitConfiguration( forJarFile jarFileName: String, - classPath: String, + classpath: String, environment: JNIEnvironment ) throws { - var configuration = Configuration() - configuration.classPath = classPath + // Get a fresh or existing configuration we'll amend + var (amendExistingConfig, configuration) = try getBaseConfigurationForWrite() + if amendExistingConfig { + print("[java-swift] Amend existing swift-java.config file...") + } else { + configuration.classpath = classpath // TODO: is this correct? + } let jarFile = try JarFile(jarFileName, false, environment: environment) for entry in jarFile.entries()! { @@ -44,15 +51,26 @@ extension JavaToSwift { let javaCanonicalName = String(entry.getName().replacing("/", with: ".") .dropLast(".class".count)) + + if let javaPackageFilter { + if !javaCanonicalName.hasPrefix(javaPackageFilter) { + // Skip classes which don't match our expected prefix + continue + } + } + + if amendExistingConfig && configuration.classes?[javaCanonicalName] != nil { + // If we're amending an existing config, we never overwrite an existing + // class configuration. E.g. the user may have configured a custom name + // for a type. + continue + } configuration.classes?[javaCanonicalName] = javaCanonicalName.defaultSwiftNameForJavaClass } // Encode the configuration. - let encoder = JSONEncoder() - encoder.outputFormatting = [.prettyPrinted, .sortedKeys] - var contents = String(data: try encoder.encode(configuration), encoding: .utf8)! - contents.append("\n") + let contents = try configuration.renderJSON() // Write the file. try writeContents( diff --git a/Sources/Java2Swift/JavaToSwift+FetchDependencies.swift b/Sources/Java2Swift/JavaToSwift+FetchDependencies.swift index 80c8d9b0..a1749230 100644 --- a/Sources/Java2Swift/JavaToSwift+FetchDependencies.swift +++ b/Sources/Java2Swift/JavaToSwift+FetchDependencies.swift @@ -12,7 +12,7 @@ // //===----------------------------------------------------------------------===// -import ArgumentParser +import Foundation import Java2SwiftLib import JavaKit import Foundation @@ -20,44 +20,76 @@ import JavaKitJar import Java2SwiftLib import JavaKitDependencyResolver import JavaKitConfigurationShared +import JavaKitShared extension JavaToSwift { func fetchDependencies(moduleName: String, dependencies: [JavaDependencyDescriptor], - baseClasspath: [String]) throws -> JavaClasspath { + baseClasspath: [String], + environment: JNIEnvironment) throws -> ResolvedDependencyClasspath { let deps = dependencies.map { $0.descriptionGradleStyle } - print("[debug][swift-java] Fetch dependencies: \(deps)") - - let jvm = try JavaVirtualMachine.shared(classPath: baseClasspath) - // let jvm = try ensureDependencyResolverDependenciesLoaded(baseClasspath: baseClasspath) + print("[debug][swift-java] Resolve and fetch dependencies for: \(deps)") + let resolverClass = try JavaClass(environment: environment) - let resolverClass = try JavaClass(environment: jvm.environment()) - let classpath = try resolverClass.resolveDependenciesToClasspath( - projectBaseDirectory: URL(fileURLWithPath: ".").path, - dependencies: deps) + let fullClasspath = try resolverClass.resolveDependenciesToClasspath( + projectBaseDirectory: URL(fileURLWithPath: ".").path, + dependencies: deps) + .split(separator: ":") - let entries = classpath.split(separator: ":") - let entryCount = entries.count + let classpathEntries = fullClasspath.filter { + $0.hasSuffix(".jar") + } + let classpath = classpathEntries.joined(separator: ":") - print("[info][swift-java] Resolved classpath for \(deps.count) dependencies of '\(moduleName)': classpath entries: \(entryCount)... ", terminator: "") + print("[info][swift-java] Resolved classpath for \(deps.count) dependencies of '\(moduleName)', classpath entries: \(classpathEntries.count), ", terminator: "") print("done.".green) - for entry in entries { - print("[debug][swift-java] Classpath entry: \(entry)") - } + return ResolvedDependencyClasspath(for: dependencies, classpath: classpath) + } +} - return .init(classpath) +extension JavaToSwift { + mutating func writeFetchDependencies(resolvedClasspath: ResolvedDependencyClasspath) throws { + var configuration = Configuration() + configuration.dependencies = resolvedClasspath.rootDependencies + configuration.classpath = resolvedClasspath.classpath + + // Convert the artifact name to a module name + // e.g. reactive-streams -> ReactiveStreams + // TODO: Should we prefix them with `Java...`? + let targetModule = artifactIDAsModuleID(resolvedClasspath.rootDependencies.first!.artifactID) + + // Encode the configuration. + let contents = try configuration.renderJSON() + + // Write the file + try writeContents( + contents, + to: "swift-java.config", + description: "swift-java configuration file" + ) + } + + public func artifactIDAsModuleID(_ artifactID: String) -> String { + let components = artifactID.split(whereSeparator: { $0 == "-" }) + let camelCased = components.map { $0.capitalized }.joined() + return camelCased } } -struct JavaClasspath: CustomStringConvertible { - let value: String +struct ResolvedDependencyClasspath: CustomStringConvertible { + /// The dependency identifiers this is the classpath for. + let rootDependencies: [JavaDependencyDescriptor] + + /// Plain string representation of a Java classpath + let classpath: String - init(_ value: String) { - self.value = value + init(for rootDependencies: [JavaDependencyDescriptor], classpath: String) { + self.rootDependencies = rootDependencies + self.classpath = classpath } var description: String { - "JavaClasspath(value: \(value))" + "JavaClasspath(for: \(rootDependencies), classpath: \(classpath))" } } diff --git a/Sources/Java2Swift/JavaToSwift+GenerateWrappers.swift b/Sources/Java2Swift/JavaToSwift+GenerateWrappers.swift index e53678b6..99f83b4e 100644 --- a/Sources/Java2Swift/JavaToSwift+GenerateWrappers.swift +++ b/Sources/Java2Swift/JavaToSwift+GenerateWrappers.swift @@ -24,7 +24,7 @@ import JavaKitConfigurationShared extension JavaToSwift { mutating func generateWrappers( config: Configuration, - classPath: String, + classpath: String, dependentConfigs: [(String, Configuration)], environment: JNIEnvironment ) throws { diff --git a/Sources/Java2Swift/JavaToSwift.swift b/Sources/Java2Swift/JavaToSwift.swift index cfe1913a..c0d9a706 100644 --- a/Sources/Java2Swift/JavaToSwift.swift +++ b/Sources/Java2Swift/JavaToSwift.swift @@ -22,6 +22,7 @@ import JavaKitReflection import SwiftSyntax import SwiftSyntaxBuilder import JavaKitConfigurationShared +import JavaKitShared /// Command-line utility to drive the export of Java classes into Swift types. @main @@ -37,12 +38,16 @@ struct JavaToSwift: ParsableCommand { ) var dependsOn: [String] = [] + // TODO: This should be a "make wrappers" option that just detects when we give it a jar @Flag( help: "Specifies that the input is a Jar file whose public classes will be loaded. The output of Java2Swift will be a configuration file (Java2Swift.config) that can be used as input to a subsequent Java2Swift invocation to generate wrappers for those public classes." ) var jar: Bool = false + @Flag(help: "Fetch dependencies from given target (containing swift-java configuration) or dependency string") + var fetch: Bool = false + @Option( name: [.customLong("cp"), .customLong("classpath")], help: "Class search path of directories and zip/jar files from which Java classes can be loaded." @@ -57,19 +62,22 @@ struct JavaToSwift: ParsableCommand { @Option(name: .shortAndLong, help: "The directory in which to output the generated Swift files or the Java2Swift configuration file.") var outputDirectory: String? = nil + @Option(name: .shortAndLong, help: "How to handle an existing swift-java.config; by default 'overwrite' by can be changed to amending a configuration") + var existingConfig: ExistingConfigFileMode = .overwrite + public enum ExistingConfigFileMode: String, ExpressibleByArgument, Codable { + case overwrite + case amend + } + + @Option(name: .shortAndLong, help: "While scanning a classpath, inspect only types included in this package") + var javaPackageFilter: String? = nil + @Argument( help: "The input file, which is either a Java2Swift configuration file or (if '-jar' was specified) a Jar file." ) var input: String - @Flag(help: "Fetch dependencies from given target (containing swift-java configuration) or dependency string") - var fetch: Bool = false - - // TODO: Need a better name, this follows up a fetch with creating modules for each of the dependencies - @Flag(help: "Fetch dependencies for given ") - var fetchMakeModules: Bool = false - /// Whether we have ensured that the output directory exists. var createdOutputDirectory: Bool = false @@ -112,7 +120,7 @@ struct JavaToSwift: ParsableCommand { /// Describes what kind of generation action is being performed by swift-java. enum ToolMode { /// Generate a configuration file given a Jar file. - case configuration(jarFile: String) + case configuration(jarFile: String) // FIXME: this is more like "extract" configuration from classpath /// Generate Swift wrappers for Java classes based on the given /// configuration. @@ -163,58 +171,64 @@ struct JavaToSwift: ParsableCommand { // Form a class path from all of our input sources: // * Command-line option --classpath - var classPathPieces: [String] = classpath.flatMap { $0.split(separator: ":").map(String.init) } + var classpathPieces: [String] = classpath.flatMap { $0.split(separator: ":").map(String.init) } switch toolMode { case .configuration(jarFile: let jarFile): // * Jar file (in `-jar` mode) - classPathPieces.append(jarFile) + classpathPieces.append(jarFile) case .classWrappers(let config), .fetchDependencies(let config): // * Classpath specified in the configuration file (if any) - if let classpath = config.classPath { + if let classpath = config.classpath { for part in classpath.split(separator: ":") { - classPathPieces.append(String(part)) + classpathPieces.append(String(part)) } } } // * Classespaths from all dependent configuration files for (_, config) in dependentConfigs { - config.classPath.map { element in + config.classpath.map { element in print("[swift-java] Add dependent config classpath element: \(element)") - classPathPieces.append(element) + classpathPieces.append(element) } } // Bring up the Java VM. - let classpath = classPathPieces.joined(separator: ":") + let classpath = classpathPieces.joined(separator: ":") // TODO: print only in verbose mode print("[swift-java] Initialize JVM with classpath: \(classpath)") // Run the task. - let jvm: JavaVirtualMachine + let jvm = try JavaVirtualMachine.shared(classpath: classpathPieces) switch toolMode { case .configuration(jarFile: let jarFile): - jvm = try JavaVirtualMachine.shared(classPath: classPathPieces) + try emitConfiguration( forJarFile: jarFile, - classPath: classpath, + classpath: classpath, environment: jvm.environment() ) case .classWrappers(let config): - jvm = try JavaVirtualMachine.shared(classPath: classPathPieces) try generateWrappers( config: config, - classPath: classpath, + classpath: classpath, dependentConfigs: dependentConfigs, environment: jvm.environment() ) case .fetchDependencies(let config): let dependencies = config.dependencies! // TODO: cleanup how we do config - try fetchDependencies(moduleName: moduleName, dependencies: dependencies, baseClasspath: classPathPieces) + let dependencyClasspath = try fetchDependencies( + moduleName: moduleName, + dependencies: dependencies, + baseClasspath: classpathPieces, + environment: jvm.environment() + ) + + try writeFetchDependencies(resolvedClasspath: dependencyClasspath) } } @@ -239,7 +253,20 @@ struct JavaToSwift: ParsableCommand { return (javaClassName, swiftName.javaClassNameToCanonicalName) } - mutating func writeContents(_ contents: String, to filename: String, description: String) throws { + mutating func writeContents( + _ contents: String, + to filename: String, description: String) throws { + try writeContents( + contents, + outputDirectoryOverride: self.actualOutputDirectory, + to: filename, + description: description) + } + + mutating func writeContents( + _ contents: String, + outputDirectoryOverride: Foundation.URL?, + to filename: String, description: String) throws { guard let outputDir = actualOutputDirectory else { print("// \(filename) - \(description)") print(contents) @@ -260,7 +287,26 @@ struct JavaToSwift: ParsableCommand { let file = outputDir.appendingPathComponent(filename) print("[swift-java] Writing \(description) to '\(file.path)'...", terminator: "") try contents.write(to: file, atomically: true, encoding: .utf8) - print(" done.") + print(" done.".green) + } +} + +extension JavaToSwift { + /// Get base configuration, depending on if we are to 'amend' or 'overwrite' the existing configuration. + package func getBaseConfigurationForWrite() throws -> (Bool, Configuration) { + guard let actualOutputDirectory = self.actualOutputDirectory else { + // If output has no path there's nothing to amend + return (false, .init()) + } + + switch self.existingConfig { + case .overwrite: + // always make up a fresh instance if we're overwriting + return (false, .init()) + case .amend: + let configPath = actualOutputDirectory + return (true, try readConfiguration(sourceDir: "file://" + configPath.path)) + } } } diff --git a/Sources/Java2Swift/MiniTerminalColors.swift b/Sources/Java2Swift/MiniTerminalColors.swift deleted file mode 100644 index 7a9d6087..00000000 --- a/Sources/Java2Swift/MiniTerminalColors.swift +++ /dev/null @@ -1,26 +0,0 @@ -//===----------------------------------------------------------------------===// -// -// This source file is part of the Swift.org open source project -// -// Copyright (c) 2024 Apple Inc. and the Swift.org project authors -// Licensed under Apache License v2.0 -// -// See LICENSE.txt for license information -// See CONTRIBUTORS.txt for the list of Swift.org project authors -// -// SPDX-License-Identifier: Apache-2.0 -// -//===----------------------------------------------------------------------===// - -// TODO: Share TerminalColors.swift - -// Mini coloring helper, since we cannot have dependencies we keep it minimal here -extension String { - var red: String { - "\u{001B}[0;31m" + "\(self)" + "\u{001B}[0;0m" - } - var green: String { - "\u{001B}[0;32m" + "\(self)" + "\u{001B}[0;0m" - } -} - diff --git a/Sources/JavaKit/JavaKitVM/JavaVirtualMachine.swift b/Sources/JavaKit/JavaKitVM/JavaVirtualMachine.swift index 436870a6..27243586 100644 --- a/Sources/JavaKit/JavaKitVM/JavaVirtualMachine.swift +++ b/Sources/JavaKit/JavaKitVM/JavaVirtualMachine.swift @@ -32,7 +32,7 @@ public final class JavaVirtualMachine: @unchecked Sendable { /// The Java virtual machine instance. private let jvm: JavaVMPointer - let classPath: [String] + let classpath: [String] /// Whether to destroy the JVM on deinit. private let destroyOnDeinit: LockedState // FIXME: we should require macOS 15 and then use Synchronization @@ -40,7 +40,7 @@ public final class JavaVirtualMachine: @unchecked Sendable { /// Adopt an existing JVM pointer. public init(adoptingJVM jvm: JavaVMPointer) { self.jvm = jvm - self.classPath = [] // FIXME: bad... + self.classpath = [] // FIXME: bad... self.destroyOnDeinit = .init(initialState: false) } @@ -59,7 +59,7 @@ public final class JavaVirtualMachine: @unchecked Sendable { vmOptions: [String] = [], ignoreUnrecognized: Bool = false ) throws { - self.classPath = classPath + self.classpath = classpath var jvm: JavaVMPointer? = nil var environment: UnsafeMutableRawPointer? = nil var vmArgs = JavaVMInitArgs() @@ -74,7 +74,7 @@ public final class JavaVirtualMachine: @unchecked Sendable { if !fileManager.fileExists(atPath: path) { // FIXME: this should be configurable, a classpath missing a directory isn't reason to blow up print("[warning][swift-java][JavaVirtualMachine] Missing classpath element: \(path)") // TODO: stderr - // throw JavaKitError.classPathEntryNotFound(entry: path, classPath: classPath) + // throw JavaKitError.classpathEntryNotFound(entry: path, classpath: classpath) } } let colonSeparatedClassPath = classpath.joined(separator: ":") @@ -111,7 +111,6 @@ public final class JavaVirtualMachine: @unchecked Sendable { self.jvm = jvm! self.destroyOnDeinit = .init(initialState: true) - print("[trace][swift-java][JavaVirtualMachine] init complete \(self)") } public func destroyJVM() throws { @@ -121,7 +120,6 @@ public final class JavaVirtualMachine: @unchecked Sendable { } _ = destroyOnDeinit.withLock { $0 = false } // we destroyed explicitly, disable destroy in deinit - print("[trace][swift-java][JavaVirtualMachine] destroy complete \(self)") } deinit { @@ -132,7 +130,6 @@ public final class JavaVirtualMachine: @unchecked Sendable { fatalError("Failed to destroy the JVM: \(error)") } } - print("[trace][swift-java][JavaVirtualMachine] Deinit complete \(self)") } } @@ -226,7 +223,7 @@ extension JavaVirtualMachine { ignoreUnrecognized: Bool = false, replace: Bool = false ) throws -> JavaVirtualMachine { - precondition(!classPath.contains(where: { $0.contains(":") }), "Classpath element must not contain `:`! Split the path into elements! Was: \(classPath)") + precondition(!classpath.contains(where: { $0.contains(":") }), "Classpath element must not contain `:`! Split the path into elements! Was: \(classpath)") return try sharedJVM.withLock { (sharedJVMPointer: inout JavaVirtualMachine?) in // If we already have a JavaVirtualMachine instance, return it. diff --git a/Sources/JavaKitConfigurationShared/Configuration.swift b/Sources/JavaKitConfigurationShared/Configuration.swift index 4bc34698..ddb75a50 100644 --- a/Sources/JavaKitConfigurationShared/Configuration.swift +++ b/Sources/JavaKitConfigurationShared/Configuration.swift @@ -30,7 +30,7 @@ public struct Configuration: Codable { // ==== java 2 swift --------------------------------------------------------- /// The Java class path that should be passed along to the Java2Swift tool. - public var classPath: String? = nil + public var classpath: String? = nil /// The Java classes that should be translated to Swift. The keys are /// canonical Java class names (e.g., java.util.Vector) and the values are @@ -54,7 +54,7 @@ public struct Configuration: Codable { } /// Represents a maven-style Java dependency. -public struct JavaDependencyDescriptor: Codable { +public struct JavaDependencyDescriptor: Hashable, Codable { public var groupID: String public var artifactID: String public var version: String @@ -85,14 +85,13 @@ public struct JavaDependencyDescriptor: Codable { } } -@available(macOS 13.0, *) public func readConfiguration(sourceDir: String, file: String = #fileID, line: UInt = #line) throws -> Configuration { - let configFile = URL(filePath: sourceDir).appending(path: "swift-java.config") + let configFile = URL(string: sourceDir)!.appendingPathComponent("swift-java.config", isDirectory: false) do { let configData = try Data(contentsOf: configFile) return try JSONDecoder().decode(Configuration.self, from: configData) } catch { - throw ConfigurationError(message: "Failed to parse SwiftJava configuration at '\(configFile)!'", error: error, + throw ConfigurationError(message: "Failed to parse SwiftJava configuration at '\(configFile)'!", error: error, file: file, line: line) } } @@ -112,6 +111,17 @@ extension Configuration { } } +extension Configuration { + /// Render the configuration as JSON text. + public func renderJSON() throws -> String { + let encoder = JSONEncoder() + encoder.outputFormatting = [.prettyPrinted, .sortedKeys] + var contents = String(data: try encoder.encode(self), encoding: .utf8)! + contents.append("\n") + return contents + } +} + public struct ConfigurationError: Error { let message: String let error: any Error diff --git a/Sources/JavaKitDependencyResolver/swift-java.config b/Sources/JavaKitDependencyResolver/swift-java.config index 3f095312..0f44aecb 100644 --- a/Sources/JavaKitDependencyResolver/swift-java.config +++ b/Sources/JavaKitDependencyResolver/swift-java.config @@ -2,7 +2,7 @@ "dependencies": [ "dev.gradleplugins:gradle-api:8.10.1" ], - "classPath": "JavaKit/build/classes/java/main", + "classpath": "JavaKit/build/classes/java/main", "classes": { "org.swift.javakit.dependencies.DependencyResolver": "DependencyResolver" } diff --git a/Sources/ReactiveStreams/swift-java.config b/Sources/ReactiveStreams/swift-java.config deleted file mode 100644 index 600885b2..00000000 --- a/Sources/ReactiveStreams/swift-java.config +++ /dev/null @@ -1,18 +0,0 @@ -{ - "classPath" : "\/Users\/ktoso\/.gradle\/caches\/modules-2\/files-2.1\/org.reactivestreams\/reactive-streams\/1.0.4\/3864a1320d97d7b045f729a326e1e077661f31b7\/reactive-streams-1.0.4.jar", - "classes" : { - "org.reactivestreams.FlowAdapters" : "FlowAdapters", - "org.reactivestreams.FlowAdapters$FlowPublisherFromReactive" : "FlowAdapters.FlowPublisherFromReactive", - "org.reactivestreams.FlowAdapters$FlowToReactiveProcessor" : "FlowAdapters.FlowToReactiveProcessor", - "org.reactivestreams.FlowAdapters$FlowToReactiveSubscriber" : "FlowAdapters.FlowToReactiveSubscriber", - "org.reactivestreams.FlowAdapters$FlowToReactiveSubscription" : "FlowAdapters.FlowToReactiveSubscription", - "org.reactivestreams.FlowAdapters$ReactivePublisherFromFlow" : "FlowAdapters.ReactivePublisherFromFlow", - "org.reactivestreams.FlowAdapters$ReactiveToFlowProcessor" : "FlowAdapters.ReactiveToFlowProcessor", - "org.reactivestreams.FlowAdapters$ReactiveToFlowSubscriber" : "FlowAdapters.ReactiveToFlowSubscriber", - "org.reactivestreams.FlowAdapters$ReactiveToFlowSubscription" : "FlowAdapters.ReactiveToFlowSubscription", - "org.reactivestreams.Processor" : "Processor", - "org.reactivestreams.Publisher" : "Publisher", - "org.reactivestreams.Subscriber" : "Subscriber", - "org.reactivestreams.Subscription" : "Subscription" - } -} From cb9e72941baa71bef8180dc11d35bc9e2fa96348 Mon Sep 17 00:00:00 2001 From: Konrad `ktoso` Malawski Date: Wed, 4 Dec 2024 15:45:12 +0900 Subject: [PATCH 05/25] importing all classes from a classpath --- .../Sources/Guava/swift-java.config | 1503 ++++++++++++++++- .../JavaDependencySampleApp/ci-validate.sh | 2 +- .../JavaToSwift+EmitConfiguration.swift | 75 +- .../JavaToSwift+FetchDependencies.swift | 4 + Sources/Java2Swift/JavaToSwift.swift | 127 +- 5 files changed, 1655 insertions(+), 56 deletions(-) diff --git a/Samples/JavaDependencySampleApp/Sources/Guava/swift-java.config b/Samples/JavaDependencySampleApp/Sources/Guava/swift-java.config index bc508bdb..be0d3af1 100644 --- a/Samples/JavaDependencySampleApp/Sources/Guava/swift-java.config +++ b/Samples/JavaDependencySampleApp/Sources/Guava/swift-java.config @@ -1,7 +1,1508 @@ { "classes" : { + "com.google.common.annotations.Beta" : "Beta", + "com.google.common.annotations.GwtCompatible" : "GwtCompatible", + "com.google.common.annotations.GwtIncompatible" : "GwtIncompatible", + "com.google.common.annotations.J2ktIncompatible" : "J2ktIncompatible", + "com.google.common.annotations.VisibleForTesting" : "VisibleForTesting", + "com.google.common.annotations.package-info" : "package-info", + "com.google.common.base.Absent" : "Absent", + "com.google.common.base.AbstractIterator" : "AbstractIterator", + "com.google.common.base.AbstractIterator$State" : "AbstractIterator.State", + "com.google.common.base.Ascii" : "Ascii", + "com.google.common.base.CaseFormat" : "CaseFormat", + "com.google.common.base.CaseFormat$StringConverter" : "CaseFormat.StringConverter", + "com.google.common.base.CharMatcher" : "CharMatcher", + "com.google.common.base.CharMatcher$And" : "CharMatcher.And", + "com.google.common.base.CharMatcher$Any" : "CharMatcher.Any", + "com.google.common.base.CharMatcher$AnyOf" : "CharMatcher.AnyOf", + "com.google.common.base.CharMatcher$Ascii" : "CharMatcher.Ascii", + "com.google.common.base.CharMatcher$BitSetMatcher" : "CharMatcher.BitSetMatcher", + "com.google.common.base.CharMatcher$BreakingWhitespace" : "CharMatcher.BreakingWhitespace", + "com.google.common.base.CharMatcher$Digit" : "CharMatcher.Digit", + "com.google.common.base.CharMatcher$FastMatcher" : "CharMatcher.FastMatcher", + "com.google.common.base.CharMatcher$ForPredicate" : "CharMatcher.ForPredicate", + "com.google.common.base.CharMatcher$InRange" : "CharMatcher.InRange", + "com.google.common.base.CharMatcher$Invisible" : "CharMatcher.Invisible", + "com.google.common.base.CharMatcher$Is" : "CharMatcher.Is", + "com.google.common.base.CharMatcher$IsEither" : "CharMatcher.IsEither", + "com.google.common.base.CharMatcher$IsNot" : "CharMatcher.IsNot", + "com.google.common.base.CharMatcher$JavaDigit" : "CharMatcher.JavaDigit", + "com.google.common.base.CharMatcher$JavaIsoControl" : "CharMatcher.JavaIsoControl", + "com.google.common.base.CharMatcher$JavaLetter" : "CharMatcher.JavaLetter", + "com.google.common.base.CharMatcher$JavaLetterOrDigit" : "CharMatcher.JavaLetterOrDigit", + "com.google.common.base.CharMatcher$JavaLowerCase" : "CharMatcher.JavaLowerCase", + "com.google.common.base.CharMatcher$JavaUpperCase" : "CharMatcher.JavaUpperCase", + "com.google.common.base.CharMatcher$NamedFastMatcher" : "CharMatcher.NamedFastMatcher", + "com.google.common.base.CharMatcher$Negated" : "CharMatcher.Negated", + "com.google.common.base.CharMatcher$NegatedFastMatcher" : "CharMatcher.NegatedFastMatcher", + "com.google.common.base.CharMatcher$None" : "CharMatcher.None", + "com.google.common.base.CharMatcher$Or" : "CharMatcher.Or", + "com.google.common.base.CharMatcher$RangesMatcher" : "CharMatcher.RangesMatcher", + "com.google.common.base.CharMatcher$SingleWidth" : "CharMatcher.SingleWidth", + "com.google.common.base.CharMatcher$Whitespace" : "CharMatcher.Whitespace", + "com.google.common.base.Charsets" : "Charsets", + "com.google.common.base.CommonMatcher" : "CommonMatcher", + "com.google.common.base.CommonPattern" : "CommonPattern", + "com.google.common.base.Converter" : "Converter", + "com.google.common.base.Converter$ConverterComposition" : "Converter.ConverterComposition", + "com.google.common.base.Converter$FunctionBasedConverter" : "Converter.FunctionBasedConverter", + "com.google.common.base.Converter$IdentityConverter" : "Converter.IdentityConverter", + "com.google.common.base.Converter$ReverseConverter" : "Converter.ReverseConverter", + "com.google.common.base.Defaults" : "Defaults", + "com.google.common.base.ElementTypesAreNonnullByDefault" : "ElementTypesAreNonnullByDefault", + "com.google.common.base.Enums" : "Enums", + "com.google.common.base.Enums$StringConverter" : "Enums.StringConverter", + "com.google.common.base.Equivalence" : "Equivalence", + "com.google.common.base.Equivalence$Equals" : "Equivalence.Equals", + "com.google.common.base.Equivalence$EquivalentToPredicate" : "Equivalence.EquivalentToPredicate", + "com.google.common.base.Equivalence$Identity" : "Equivalence.Identity", + "com.google.common.base.Equivalence$Wrapper" : "Equivalence.Wrapper", + "com.google.common.base.ExtraObjectsMethodsForWeb" : "ExtraObjectsMethodsForWeb", + "com.google.common.base.FinalizablePhantomReference" : "FinalizablePhantomReference", + "com.google.common.base.FinalizableReference" : "FinalizableReference", + "com.google.common.base.FinalizableReferenceQueue" : "FinalizableReferenceQueue", + "com.google.common.base.FinalizableReferenceQueue$DecoupledLoader" : "FinalizableReferenceQueue.DecoupledLoader", + "com.google.common.base.FinalizableReferenceQueue$DirectLoader" : "FinalizableReferenceQueue.DirectLoader", + "com.google.common.base.FinalizableReferenceQueue$FinalizerLoader" : "FinalizableReferenceQueue.FinalizerLoader", + "com.google.common.base.FinalizableReferenceQueue$SystemLoader" : "FinalizableReferenceQueue.SystemLoader", + "com.google.common.base.FinalizableSoftReference" : "FinalizableSoftReference", + "com.google.common.base.FinalizableWeakReference" : "FinalizableWeakReference", + "com.google.common.base.Function" : "Function", + "com.google.common.base.FunctionalEquivalence" : "FunctionalEquivalence", + "com.google.common.base.Functions" : "Functions", + "com.google.common.base.Functions$ConstantFunction" : "Functions.ConstantFunction", + "com.google.common.base.Functions$ForMapWithDefault" : "Functions.ForMapWithDefault", + "com.google.common.base.Functions$FunctionComposition" : "Functions.FunctionComposition", + "com.google.common.base.Functions$FunctionForMapNoDefault" : "Functions.FunctionForMapNoDefault", + "com.google.common.base.Functions$IdentityFunction" : "Functions.IdentityFunction", + "com.google.common.base.Functions$PredicateFunction" : "Functions.PredicateFunction", + "com.google.common.base.Functions$SupplierFunction" : "Functions.SupplierFunction", + "com.google.common.base.Functions$ToStringFunction" : "Functions.ToStringFunction", + "com.google.common.base.IgnoreJRERequirement" : "IgnoreJRERequirement", + "com.google.common.base.Internal" : "Internal", + "com.google.common.base.Java8Compatibility" : "Java8Compatibility", + "com.google.common.base.JdkPattern" : "JdkPattern", + "com.google.common.base.JdkPattern$JdkMatcher" : "JdkPattern.JdkMatcher", + "com.google.common.base.Joiner" : "Joiner", + "com.google.common.base.Joiner$MapJoiner" : "Joiner.MapJoiner", + "com.google.common.base.MoreObjects" : "MoreObjects", + "com.google.common.base.MoreObjects$ToStringHelper" : "MoreObjects.ToStringHelper", + "com.google.common.base.MoreObjects$ToStringHelper$UnconditionalValueHolder" : "MoreObjects.ToStringHelper.UnconditionalValueHolder", + "com.google.common.base.MoreObjects$ToStringHelper$ValueHolder" : "MoreObjects.ToStringHelper.ValueHolder", + "com.google.common.base.NullnessCasts" : "NullnessCasts", + "com.google.common.base.Objects" : "Objects", + "com.google.common.base.Optional" : "Optional", + "com.google.common.base.PairwiseEquivalence" : "PairwiseEquivalence", + "com.google.common.base.ParametricNullness" : "ParametricNullness", + "com.google.common.base.PatternCompiler" : "PatternCompiler", + "com.google.common.base.Platform" : "Platform", + "com.google.common.base.Platform$JdkPatternCompiler" : "Platform.JdkPatternCompiler", + "com.google.common.base.Preconditions" : "Preconditions", + "com.google.common.base.Predicate" : "Predicate", + "com.google.common.base.Predicates" : "Predicates", + "com.google.common.base.Predicates$AndPredicate" : "Predicates.AndPredicate", + "com.google.common.base.Predicates$CompositionPredicate" : "Predicates.CompositionPredicate", + "com.google.common.base.Predicates$ContainsPatternFromStringPredicate" : "Predicates.ContainsPatternFromStringPredicate", + "com.google.common.base.Predicates$ContainsPatternPredicate" : "Predicates.ContainsPatternPredicate", + "com.google.common.base.Predicates$InPredicate" : "Predicates.InPredicate", + "com.google.common.base.Predicates$InstanceOfPredicate" : "Predicates.InstanceOfPredicate", + "com.google.common.base.Predicates$IsEqualToPredicate" : "Predicates.IsEqualToPredicate", + "com.google.common.base.Predicates$NotPredicate" : "Predicates.NotPredicate", + "com.google.common.base.Predicates$ObjectPredicate" : "Predicates.ObjectPredicate", + "com.google.common.base.Predicates$OrPredicate" : "Predicates.OrPredicate", + "com.google.common.base.Predicates$SubtypeOfPredicate" : "Predicates.SubtypeOfPredicate", + "com.google.common.base.Present" : "Present", + "com.google.common.base.SmallCharMatcher" : "SmallCharMatcher", + "com.google.common.base.Splitter" : "Splitter", + "com.google.common.base.Splitter$MapSplitter" : "Splitter.MapSplitter", + "com.google.common.base.Splitter$SplittingIterator" : "Splitter.SplittingIterator", + "com.google.common.base.Splitter$Strategy" : "Splitter.Strategy", + "com.google.common.base.StandardSystemProperty" : "StandardSystemProperty", + "com.google.common.base.Stopwatch" : "Stopwatch", + "com.google.common.base.Strings" : "Strings", + "com.google.common.base.Supplier" : "Supplier", + "com.google.common.base.Suppliers" : "Suppliers", + "com.google.common.base.Suppliers$ExpiringMemoizingSupplier" : "Suppliers.ExpiringMemoizingSupplier", + "com.google.common.base.Suppliers$MemoizingSupplier" : "Suppliers.MemoizingSupplier", + "com.google.common.base.Suppliers$NonSerializableMemoizingSupplier" : "Suppliers.NonSerializableMemoizingSupplier", + "com.google.common.base.Suppliers$SupplierComposition" : "Suppliers.SupplierComposition", + "com.google.common.base.Suppliers$SupplierFunction" : "Suppliers.SupplierFunction", + "com.google.common.base.Suppliers$SupplierFunctionImpl" : "Suppliers.SupplierFunctionImpl", + "com.google.common.base.Suppliers$SupplierOfInstance" : "Suppliers.SupplierOfInstance", + "com.google.common.base.Suppliers$ThreadSafeSupplier" : "Suppliers.ThreadSafeSupplier", + "com.google.common.base.Throwables" : "Throwables", + "com.google.common.base.Ticker" : "Ticker", + "com.google.common.base.Utf8" : "Utf8", + "com.google.common.base.Verify" : "Verify", + "com.google.common.base.VerifyException" : "VerifyException", + "com.google.common.base.internal.Finalizer" : "Finalizer", + "com.google.common.base.package-info" : "package-info", + "com.google.common.cache.AbstractCache" : "AbstractCache", + "com.google.common.cache.AbstractCache$SimpleStatsCounter" : "AbstractCache.SimpleStatsCounter", + "com.google.common.cache.AbstractCache$StatsCounter" : "AbstractCache.StatsCounter", + "com.google.common.cache.AbstractLoadingCache" : "AbstractLoadingCache", + "com.google.common.cache.Cache" : "Cache", + "com.google.common.cache.CacheBuilder" : "CacheBuilder", + "com.google.common.cache.CacheBuilder$LoggerHolder" : "CacheBuilder.LoggerHolder", + "com.google.common.cache.CacheBuilder$NullListener" : "CacheBuilder.NullListener", + "com.google.common.cache.CacheBuilder$OneWeigher" : "CacheBuilder.OneWeigher", + "com.google.common.cache.CacheBuilderSpec" : "CacheBuilderSpec", + "com.google.common.cache.CacheBuilderSpec$AccessDurationParser" : "CacheBuilderSpec.AccessDurationParser", + "com.google.common.cache.CacheBuilderSpec$ConcurrencyLevelParser" : "CacheBuilderSpec.ConcurrencyLevelParser", + "com.google.common.cache.CacheBuilderSpec$DurationParser" : "CacheBuilderSpec.DurationParser", + "com.google.common.cache.CacheBuilderSpec$InitialCapacityParser" : "CacheBuilderSpec.InitialCapacityParser", + "com.google.common.cache.CacheBuilderSpec$IntegerParser" : "CacheBuilderSpec.IntegerParser", + "com.google.common.cache.CacheBuilderSpec$KeyStrengthParser" : "CacheBuilderSpec.KeyStrengthParser", + "com.google.common.cache.CacheBuilderSpec$LongParser" : "CacheBuilderSpec.LongParser", + "com.google.common.cache.CacheBuilderSpec$MaximumSizeParser" : "CacheBuilderSpec.MaximumSizeParser", + "com.google.common.cache.CacheBuilderSpec$MaximumWeightParser" : "CacheBuilderSpec.MaximumWeightParser", + "com.google.common.cache.CacheBuilderSpec$RecordStatsParser" : "CacheBuilderSpec.RecordStatsParser", + "com.google.common.cache.CacheBuilderSpec$RefreshDurationParser" : "CacheBuilderSpec.RefreshDurationParser", + "com.google.common.cache.CacheBuilderSpec$ValueParser" : "CacheBuilderSpec.ValueParser", + "com.google.common.cache.CacheBuilderSpec$ValueStrengthParser" : "CacheBuilderSpec.ValueStrengthParser", + "com.google.common.cache.CacheBuilderSpec$WriteDurationParser" : "CacheBuilderSpec.WriteDurationParser", + "com.google.common.cache.CacheLoader" : "CacheLoader", + "com.google.common.cache.CacheLoader$FunctionToCacheLoader" : "CacheLoader.FunctionToCacheLoader", + "com.google.common.cache.CacheLoader$InvalidCacheLoadException" : "CacheLoader.InvalidCacheLoadException", + "com.google.common.cache.CacheLoader$SupplierToCacheLoader" : "CacheLoader.SupplierToCacheLoader", + "com.google.common.cache.CacheLoader$UnsupportedLoadingOperationException" : "CacheLoader.UnsupportedLoadingOperationException", + "com.google.common.cache.CacheStats" : "CacheStats", + "com.google.common.cache.ElementTypesAreNonnullByDefault" : "ElementTypesAreNonnullByDefault", + "com.google.common.cache.ForwardingCache" : "ForwardingCache", + "com.google.common.cache.ForwardingCache$SimpleForwardingCache" : "ForwardingCache.SimpleForwardingCache", + "com.google.common.cache.ForwardingLoadingCache" : "ForwardingLoadingCache", + "com.google.common.cache.ForwardingLoadingCache$SimpleForwardingLoadingCache" : "ForwardingLoadingCache.SimpleForwardingLoadingCache", + "com.google.common.cache.IgnoreJRERequirement" : "IgnoreJRERequirement", + "com.google.common.cache.LoadingCache" : "LoadingCache", + "com.google.common.cache.LocalCache" : "LocalCache", + "com.google.common.cache.LocalCache$AbstractCacheSet" : "LocalCache.AbstractCacheSet", + "com.google.common.cache.LocalCache$AbstractReferenceEntry" : "LocalCache.AbstractReferenceEntry", + "com.google.common.cache.LocalCache$AccessQueue" : "LocalCache.AccessQueue", + "com.google.common.cache.LocalCache$ComputingValueReference" : "LocalCache.ComputingValueReference", + "com.google.common.cache.LocalCache$EntryFactory" : "LocalCache.EntryFactory", + "com.google.common.cache.LocalCache$EntryIterator" : "LocalCache.EntryIterator", + "com.google.common.cache.LocalCache$EntrySet" : "LocalCache.EntrySet", + "com.google.common.cache.LocalCache$HashIterator" : "LocalCache.HashIterator", + "com.google.common.cache.LocalCache$KeyIterator" : "LocalCache.KeyIterator", + "com.google.common.cache.LocalCache$KeySet" : "LocalCache.KeySet", + "com.google.common.cache.LocalCache$LoadingSerializationProxy" : "LocalCache.LoadingSerializationProxy", + "com.google.common.cache.LocalCache$LoadingValueReference" : "LocalCache.LoadingValueReference", + "com.google.common.cache.LocalCache$LocalLoadingCache" : "LocalCache.LocalLoadingCache", + "com.google.common.cache.LocalCache$LocalManualCache" : "LocalCache.LocalManualCache", + "com.google.common.cache.LocalCache$ManualSerializationProxy" : "LocalCache.ManualSerializationProxy", + "com.google.common.cache.LocalCache$NullEntry" : "LocalCache.NullEntry", + "com.google.common.cache.LocalCache$Segment" : "LocalCache.Segment", + "com.google.common.cache.LocalCache$SoftValueReference" : "LocalCache.SoftValueReference", + "com.google.common.cache.LocalCache$Strength" : "LocalCache.Strength", + "com.google.common.cache.LocalCache$StrongAccessEntry" : "LocalCache.StrongAccessEntry", + "com.google.common.cache.LocalCache$StrongAccessWriteEntry" : "LocalCache.StrongAccessWriteEntry", + "com.google.common.cache.LocalCache$StrongEntry" : "LocalCache.StrongEntry", + "com.google.common.cache.LocalCache$StrongValueReference" : "LocalCache.StrongValueReference", + "com.google.common.cache.LocalCache$StrongWriteEntry" : "LocalCache.StrongWriteEntry", + "com.google.common.cache.LocalCache$ValueIterator" : "LocalCache.ValueIterator", + "com.google.common.cache.LocalCache$ValueReference" : "LocalCache.ValueReference", + "com.google.common.cache.LocalCache$Values" : "LocalCache.Values", + "com.google.common.cache.LocalCache$WeakAccessEntry" : "LocalCache.WeakAccessEntry", + "com.google.common.cache.LocalCache$WeakAccessWriteEntry" : "LocalCache.WeakAccessWriteEntry", + "com.google.common.cache.LocalCache$WeakEntry" : "LocalCache.WeakEntry", + "com.google.common.cache.LocalCache$WeakValueReference" : "LocalCache.WeakValueReference", + "com.google.common.cache.LocalCache$WeakWriteEntry" : "LocalCache.WeakWriteEntry", + "com.google.common.cache.LocalCache$WeightedSoftValueReference" : "LocalCache.WeightedSoftValueReference", + "com.google.common.cache.LocalCache$WeightedStrongValueReference" : "LocalCache.WeightedStrongValueReference", + "com.google.common.cache.LocalCache$WeightedWeakValueReference" : "LocalCache.WeightedWeakValueReference", + "com.google.common.cache.LocalCache$WriteQueue" : "LocalCache.WriteQueue", + "com.google.common.cache.LocalCache$WriteThroughEntry" : "LocalCache.WriteThroughEntry", + "com.google.common.cache.LongAddable" : "LongAddable", + "com.google.common.cache.LongAddables" : "LongAddables", + "com.google.common.cache.LongAddables$PureJavaLongAddable" : "LongAddables.PureJavaLongAddable", + "com.google.common.cache.LongAdder" : "LongAdder", + "com.google.common.cache.ParametricNullness" : "ParametricNullness", + "com.google.common.cache.ReferenceEntry" : "ReferenceEntry", + "com.google.common.cache.RemovalCause" : "RemovalCause", + "com.google.common.cache.RemovalListener" : "RemovalListener", + "com.google.common.cache.RemovalListeners" : "RemovalListeners", + "com.google.common.cache.RemovalNotification" : "RemovalNotification", + "com.google.common.cache.Striped64" : "Striped64", + "com.google.common.cache.Striped64$Cell" : "Striped64.Cell", + "com.google.common.cache.Weigher" : "Weigher", + "com.google.common.cache.package-info" : "package-info", + "com.google.common.collect.AbstractBiMap" : "AbstractBiMap", + "com.google.common.collect.AbstractBiMap$BiMapEntry" : "AbstractBiMap.BiMapEntry", + "com.google.common.collect.AbstractBiMap$EntrySet" : "AbstractBiMap.EntrySet", + "com.google.common.collect.AbstractBiMap$Inverse" : "AbstractBiMap.Inverse", + "com.google.common.collect.AbstractBiMap$KeySet" : "AbstractBiMap.KeySet", + "com.google.common.collect.AbstractBiMap$ValueSet" : "AbstractBiMap.ValueSet", + "com.google.common.collect.AbstractIndexedListIterator" : "AbstractIndexedListIterator", + "com.google.common.collect.AbstractIterator" : "AbstractIterator", + "com.google.common.collect.AbstractIterator$State" : "AbstractIterator.State", + "com.google.common.collect.AbstractListMultimap" : "AbstractListMultimap", + "com.google.common.collect.AbstractMapBasedMultimap" : "AbstractMapBasedMultimap", + "com.google.common.collect.AbstractMapBasedMultimap$AsMap" : "AbstractMapBasedMultimap.AsMap", + "com.google.common.collect.AbstractMapBasedMultimap$AsMap$AsMapEntries" : "AbstractMapBasedMultimap.AsMap.AsMapEntries", + "com.google.common.collect.AbstractMapBasedMultimap$AsMap$AsMapIterator" : "AbstractMapBasedMultimap.AsMap.AsMapIterator", + "com.google.common.collect.AbstractMapBasedMultimap$Itr" : "AbstractMapBasedMultimap.Itr", + "com.google.common.collect.AbstractMapBasedMultimap$KeySet" : "AbstractMapBasedMultimap.KeySet", + "com.google.common.collect.AbstractMapBasedMultimap$NavigableAsMap" : "AbstractMapBasedMultimap.NavigableAsMap", + "com.google.common.collect.AbstractMapBasedMultimap$NavigableKeySet" : "AbstractMapBasedMultimap.NavigableKeySet", + "com.google.common.collect.AbstractMapBasedMultimap$RandomAccessWrappedList" : "AbstractMapBasedMultimap.RandomAccessWrappedList", + "com.google.common.collect.AbstractMapBasedMultimap$SortedAsMap" : "AbstractMapBasedMultimap.SortedAsMap", + "com.google.common.collect.AbstractMapBasedMultimap$SortedKeySet" : "AbstractMapBasedMultimap.SortedKeySet", + "com.google.common.collect.AbstractMapBasedMultimap$WrappedCollection" : "AbstractMapBasedMultimap.WrappedCollection", + "com.google.common.collect.AbstractMapBasedMultimap$WrappedCollection$WrappedIterator" : "AbstractMapBasedMultimap.WrappedCollection.WrappedIterator", + "com.google.common.collect.AbstractMapBasedMultimap$WrappedList" : "AbstractMapBasedMultimap.WrappedList", + "com.google.common.collect.AbstractMapBasedMultimap$WrappedList$WrappedListIterator" : "AbstractMapBasedMultimap.WrappedList.WrappedListIterator", + "com.google.common.collect.AbstractMapBasedMultimap$WrappedNavigableSet" : "AbstractMapBasedMultimap.WrappedNavigableSet", + "com.google.common.collect.AbstractMapBasedMultimap$WrappedSet" : "AbstractMapBasedMultimap.WrappedSet", + "com.google.common.collect.AbstractMapBasedMultimap$WrappedSortedSet" : "AbstractMapBasedMultimap.WrappedSortedSet", + "com.google.common.collect.AbstractMapBasedMultiset" : "AbstractMapBasedMultiset", + "com.google.common.collect.AbstractMapBasedMultiset$MapBasedMultisetIterator" : "AbstractMapBasedMultiset.MapBasedMultisetIterator", + "com.google.common.collect.AbstractMapEntry" : "AbstractMapEntry", + "com.google.common.collect.AbstractMultimap" : "AbstractMultimap", + "com.google.common.collect.AbstractMultimap$Entries" : "AbstractMultimap.Entries", + "com.google.common.collect.AbstractMultimap$EntrySet" : "AbstractMultimap.EntrySet", + "com.google.common.collect.AbstractMultimap$Values" : "AbstractMultimap.Values", + "com.google.common.collect.AbstractMultiset" : "AbstractMultiset", + "com.google.common.collect.AbstractMultiset$ElementSet" : "AbstractMultiset.ElementSet", + "com.google.common.collect.AbstractMultiset$EntrySet" : "AbstractMultiset.EntrySet", + "com.google.common.collect.AbstractNavigableMap" : "AbstractNavigableMap", + "com.google.common.collect.AbstractNavigableMap$DescendingMap" : "AbstractNavigableMap.DescendingMap", + "com.google.common.collect.AbstractRangeSet" : "AbstractRangeSet", + "com.google.common.collect.AbstractSequentialIterator" : "AbstractSequentialIterator", + "com.google.common.collect.AbstractSetMultimap" : "AbstractSetMultimap", + "com.google.common.collect.AbstractSortedKeySortedSetMultimap" : "AbstractSortedKeySortedSetMultimap", + "com.google.common.collect.AbstractSortedMultiset" : "AbstractSortedMultiset", + "com.google.common.collect.AbstractSortedSetMultimap" : "AbstractSortedSetMultimap", + "com.google.common.collect.AbstractTable" : "AbstractTable", + "com.google.common.collect.AbstractTable$CellSet" : "AbstractTable.CellSet", + "com.google.common.collect.AbstractTable$Values" : "AbstractTable.Values", + "com.google.common.collect.AllEqualOrdering" : "AllEqualOrdering", + "com.google.common.collect.ArrayListMultimap" : "ArrayListMultimap", + "com.google.common.collect.ArrayListMultimapGwtSerializationDependencies" : "ArrayListMultimapGwtSerializationDependencies", + "com.google.common.collect.ArrayTable" : "ArrayTable", + "com.google.common.collect.ArrayTable$ArrayMap" : "ArrayTable.ArrayMap", + "com.google.common.collect.ArrayTable$Column" : "ArrayTable.Column", + "com.google.common.collect.ArrayTable$ColumnMap" : "ArrayTable.ColumnMap", + "com.google.common.collect.ArrayTable$Row" : "ArrayTable.Row", + "com.google.common.collect.ArrayTable$RowMap" : "ArrayTable.RowMap", + "com.google.common.collect.BaseImmutableMultimap" : "BaseImmutableMultimap", + "com.google.common.collect.BiMap" : "BiMap", + "com.google.common.collect.BoundType" : "BoundType", + "com.google.common.collect.ByFunctionOrdering" : "ByFunctionOrdering", + "com.google.common.collect.CartesianList" : "CartesianList", + "com.google.common.collect.ClassToInstanceMap" : "ClassToInstanceMap", + "com.google.common.collect.CollectCollectors" : "CollectCollectors", + "com.google.common.collect.CollectCollectors$EnumMapAccumulator" : "CollectCollectors.EnumMapAccumulator", + "com.google.common.collect.CollectCollectors$EnumSetAccumulator" : "CollectCollectors.EnumSetAccumulator", + "com.google.common.collect.CollectPreconditions" : "CollectPreconditions", + "com.google.common.collect.CollectSpliterators" : "CollectSpliterators", + "com.google.common.collect.CollectSpliterators$FlatMapSpliterator" : "CollectSpliterators.FlatMapSpliterator", + "com.google.common.collect.CollectSpliterators$FlatMapSpliterator$Factory" : "CollectSpliterators.FlatMapSpliterator.Factory", + "com.google.common.collect.CollectSpliterators$FlatMapSpliteratorOfDouble" : "CollectSpliterators.FlatMapSpliteratorOfDouble", + "com.google.common.collect.CollectSpliterators$FlatMapSpliteratorOfInt" : "CollectSpliterators.FlatMapSpliteratorOfInt", + "com.google.common.collect.CollectSpliterators$FlatMapSpliteratorOfLong" : "CollectSpliterators.FlatMapSpliteratorOfLong", + "com.google.common.collect.CollectSpliterators$FlatMapSpliteratorOfObject" : "CollectSpliterators.FlatMapSpliteratorOfObject", + "com.google.common.collect.CollectSpliterators$FlatMapSpliteratorOfPrimitive" : "CollectSpliterators.FlatMapSpliteratorOfPrimitive", + "com.google.common.collect.Collections2" : "Collections2", + "com.google.common.collect.Collections2$FilteredCollection" : "Collections2.FilteredCollection", + "com.google.common.collect.Collections2$OrderedPermutationCollection" : "Collections2.OrderedPermutationCollection", + "com.google.common.collect.Collections2$OrderedPermutationIterator" : "Collections2.OrderedPermutationIterator", + "com.google.common.collect.Collections2$PermutationCollection" : "Collections2.PermutationCollection", + "com.google.common.collect.Collections2$PermutationIterator" : "Collections2.PermutationIterator", + "com.google.common.collect.Collections2$TransformedCollection" : "Collections2.TransformedCollection", + "com.google.common.collect.CompactHashMap" : "CompactHashMap", + "com.google.common.collect.CompactHashMap$EntrySetView" : "CompactHashMap.EntrySetView", + "com.google.common.collect.CompactHashMap$Itr" : "CompactHashMap.Itr", + "com.google.common.collect.CompactHashMap$KeySetView" : "CompactHashMap.KeySetView", + "com.google.common.collect.CompactHashMap$MapEntry" : "CompactHashMap.MapEntry", + "com.google.common.collect.CompactHashMap$ValuesView" : "CompactHashMap.ValuesView", + "com.google.common.collect.CompactHashSet" : "CompactHashSet", + "com.google.common.collect.CompactHashing" : "CompactHashing", + "com.google.common.collect.CompactLinkedHashMap" : "CompactLinkedHashMap", + "com.google.common.collect.CompactLinkedHashSet" : "CompactLinkedHashSet", + "com.google.common.collect.ComparatorOrdering" : "ComparatorOrdering", + "com.google.common.collect.Comparators" : "Comparators", + "com.google.common.collect.ComparisonChain" : "ComparisonChain", + "com.google.common.collect.ComparisonChain$InactiveComparisonChain" : "ComparisonChain.InactiveComparisonChain", + "com.google.common.collect.CompoundOrdering" : "CompoundOrdering", + "com.google.common.collect.ComputationException" : "ComputationException", + "com.google.common.collect.ConcurrentHashMultiset" : "ConcurrentHashMultiset", + "com.google.common.collect.ConcurrentHashMultiset$EntrySet" : "ConcurrentHashMultiset.EntrySet", + "com.google.common.collect.ConcurrentHashMultiset$FieldSettersHolder" : "ConcurrentHashMultiset.FieldSettersHolder", + "com.google.common.collect.ConsumingQueueIterator" : "ConsumingQueueIterator", + "com.google.common.collect.ContiguousSet" : "ContiguousSet", + "com.google.common.collect.Count" : "Count", + "com.google.common.collect.Cut" : "Cut", + "com.google.common.collect.Cut$AboveAll" : "Cut.AboveAll", + "com.google.common.collect.Cut$AboveValue" : "Cut.AboveValue", + "com.google.common.collect.Cut$BelowAll" : "Cut.BelowAll", + "com.google.common.collect.Cut$BelowValue" : "Cut.BelowValue", + "com.google.common.collect.DenseImmutableTable" : "DenseImmutableTable", + "com.google.common.collect.DenseImmutableTable$Column" : "DenseImmutableTable.Column", + "com.google.common.collect.DenseImmutableTable$ColumnMap" : "DenseImmutableTable.ColumnMap", + "com.google.common.collect.DenseImmutableTable$ImmutableArrayMap" : "DenseImmutableTable.ImmutableArrayMap", + "com.google.common.collect.DenseImmutableTable$Row" : "DenseImmutableTable.Row", + "com.google.common.collect.DenseImmutableTable$RowMap" : "DenseImmutableTable.RowMap", + "com.google.common.collect.DescendingImmutableSortedMultiset" : "DescendingImmutableSortedMultiset", + "com.google.common.collect.DescendingImmutableSortedSet" : "DescendingImmutableSortedSet", + "com.google.common.collect.DescendingMultiset" : "DescendingMultiset", + "com.google.common.collect.DiscreteDomain" : "DiscreteDomain", + "com.google.common.collect.DiscreteDomain$BigIntegerDomain" : "DiscreteDomain.BigIntegerDomain", + "com.google.common.collect.DiscreteDomain$IntegerDomain" : "DiscreteDomain.IntegerDomain", + "com.google.common.collect.DiscreteDomain$LongDomain" : "DiscreteDomain.LongDomain", + "com.google.common.collect.ElementTypesAreNonnullByDefault" : "ElementTypesAreNonnullByDefault", + "com.google.common.collect.EmptyContiguousSet" : "EmptyContiguousSet", + "com.google.common.collect.EmptyContiguousSet$SerializedForm" : "EmptyContiguousSet.SerializedForm", + "com.google.common.collect.EmptyImmutableListMultimap" : "EmptyImmutableListMultimap", + "com.google.common.collect.EmptyImmutableSetMultimap" : "EmptyImmutableSetMultimap", + "com.google.common.collect.EnumBiMap" : "EnumBiMap", + "com.google.common.collect.EnumHashBiMap" : "EnumHashBiMap", + "com.google.common.collect.EnumMultiset" : "EnumMultiset", + "com.google.common.collect.EnumMultiset$Itr" : "EnumMultiset.Itr", + "com.google.common.collect.EvictingQueue" : "EvictingQueue", + "com.google.common.collect.ExplicitOrdering" : "ExplicitOrdering", + "com.google.common.collect.FilteredEntryMultimap" : "FilteredEntryMultimap", + "com.google.common.collect.FilteredEntryMultimap$AsMap" : "FilteredEntryMultimap.AsMap", + "com.google.common.collect.FilteredEntryMultimap$Keys" : "FilteredEntryMultimap.Keys", + "com.google.common.collect.FilteredEntryMultimap$ValuePredicate" : "FilteredEntryMultimap.ValuePredicate", + "com.google.common.collect.FilteredEntrySetMultimap" : "FilteredEntrySetMultimap", + "com.google.common.collect.FilteredKeyListMultimap" : "FilteredKeyListMultimap", + "com.google.common.collect.FilteredKeyMultimap" : "FilteredKeyMultimap", + "com.google.common.collect.FilteredKeyMultimap$AddRejectingList" : "FilteredKeyMultimap.AddRejectingList", + "com.google.common.collect.FilteredKeyMultimap$AddRejectingSet" : "FilteredKeyMultimap.AddRejectingSet", + "com.google.common.collect.FilteredKeyMultimap$Entries" : "FilteredKeyMultimap.Entries", + "com.google.common.collect.FilteredKeySetMultimap" : "FilteredKeySetMultimap", + "com.google.common.collect.FilteredKeySetMultimap$EntrySet" : "FilteredKeySetMultimap.EntrySet", + "com.google.common.collect.FilteredMultimap" : "FilteredMultimap", + "com.google.common.collect.FilteredMultimapValues" : "FilteredMultimapValues", + "com.google.common.collect.FilteredSetMultimap" : "FilteredSetMultimap", + "com.google.common.collect.FluentIterable" : "FluentIterable", + "com.google.common.collect.FluentIterable$FromIterableFunction" : "FluentIterable.FromIterableFunction", + "com.google.common.collect.ForwardingBlockingDeque" : "ForwardingBlockingDeque", + "com.google.common.collect.ForwardingCollection" : "ForwardingCollection", + "com.google.common.collect.ForwardingConcurrentMap" : "ForwardingConcurrentMap", + "com.google.common.collect.ForwardingDeque" : "ForwardingDeque", + "com.google.common.collect.ForwardingImmutableCollection" : "ForwardingImmutableCollection", + "com.google.common.collect.ForwardingImmutableList" : "ForwardingImmutableList", + "com.google.common.collect.ForwardingImmutableMap" : "ForwardingImmutableMap", + "com.google.common.collect.ForwardingImmutableSet" : "ForwardingImmutableSet", + "com.google.common.collect.ForwardingIterator" : "ForwardingIterator", + "com.google.common.collect.ForwardingList" : "ForwardingList", + "com.google.common.collect.ForwardingListIterator" : "ForwardingListIterator", + "com.google.common.collect.ForwardingListMultimap" : "ForwardingListMultimap", + "com.google.common.collect.ForwardingMap" : "ForwardingMap", + "com.google.common.collect.ForwardingMap$StandardEntrySet" : "ForwardingMap.StandardEntrySet", + "com.google.common.collect.ForwardingMap$StandardKeySet" : "ForwardingMap.StandardKeySet", + "com.google.common.collect.ForwardingMap$StandardValues" : "ForwardingMap.StandardValues", + "com.google.common.collect.ForwardingMapEntry" : "ForwardingMapEntry", + "com.google.common.collect.ForwardingMultimap" : "ForwardingMultimap", + "com.google.common.collect.ForwardingMultiset" : "ForwardingMultiset", + "com.google.common.collect.ForwardingMultiset$StandardElementSet" : "ForwardingMultiset.StandardElementSet", + "com.google.common.collect.ForwardingNavigableMap" : "ForwardingNavigableMap", + "com.google.common.collect.ForwardingNavigableMap$StandardDescendingMap" : "ForwardingNavigableMap.StandardDescendingMap", + "com.google.common.collect.ForwardingNavigableMap$StandardNavigableKeySet" : "ForwardingNavigableMap.StandardNavigableKeySet", + "com.google.common.collect.ForwardingNavigableSet" : "ForwardingNavigableSet", + "com.google.common.collect.ForwardingNavigableSet$StandardDescendingSet" : "ForwardingNavigableSet.StandardDescendingSet", + "com.google.common.collect.ForwardingObject" : "ForwardingObject", + "com.google.common.collect.ForwardingQueue" : "ForwardingQueue", + "com.google.common.collect.ForwardingSet" : "ForwardingSet", + "com.google.common.collect.ForwardingSetMultimap" : "ForwardingSetMultimap", + "com.google.common.collect.ForwardingSortedMap" : "ForwardingSortedMap", + "com.google.common.collect.ForwardingSortedMap$StandardKeySet" : "ForwardingSortedMap.StandardKeySet", + "com.google.common.collect.ForwardingSortedMultiset" : "ForwardingSortedMultiset", + "com.google.common.collect.ForwardingSortedMultiset$StandardDescendingMultiset" : "ForwardingSortedMultiset.StandardDescendingMultiset", + "com.google.common.collect.ForwardingSortedMultiset$StandardElementSet" : "ForwardingSortedMultiset.StandardElementSet", + "com.google.common.collect.ForwardingSortedSet" : "ForwardingSortedSet", + "com.google.common.collect.ForwardingSortedSetMultimap" : "ForwardingSortedSetMultimap", + "com.google.common.collect.ForwardingTable" : "ForwardingTable", + "com.google.common.collect.GeneralRange" : "GeneralRange", + "com.google.common.collect.GwtTransient" : "GwtTransient", + "com.google.common.collect.HashBasedTable" : "HashBasedTable", + "com.google.common.collect.HashBasedTable$Factory" : "HashBasedTable.Factory", + "com.google.common.collect.HashBiMap" : "HashBiMap", + "com.google.common.collect.HashBiMap$BiEntry" : "HashBiMap.BiEntry", + "com.google.common.collect.HashBiMap$Inverse" : "HashBiMap.Inverse", + "com.google.common.collect.HashBiMap$Inverse$InverseKeySet" : "HashBiMap.Inverse.InverseKeySet", + "com.google.common.collect.HashBiMap$InverseSerializedForm" : "HashBiMap.InverseSerializedForm", + "com.google.common.collect.HashBiMap$Itr" : "HashBiMap.Itr", + "com.google.common.collect.HashBiMap$KeySet" : "HashBiMap.KeySet", + "com.google.common.collect.HashMultimap" : "HashMultimap", + "com.google.common.collect.HashMultimapGwtSerializationDependencies" : "HashMultimapGwtSerializationDependencies", + "com.google.common.collect.HashMultiset" : "HashMultiset", + "com.google.common.collect.Hashing" : "Hashing", + "com.google.common.collect.IgnoreJRERequirement" : "IgnoreJRERequirement", + "com.google.common.collect.ImmutableAsList" : "ImmutableAsList", + "com.google.common.collect.ImmutableAsList$SerializedForm" : "ImmutableAsList.SerializedForm", + "com.google.common.collect.ImmutableBiMap" : "ImmutableBiMap", + "com.google.common.collect.ImmutableBiMap$Builder" : "ImmutableBiMap.Builder", + "com.google.common.collect.ImmutableBiMap$SerializedForm" : "ImmutableBiMap.SerializedForm", + "com.google.common.collect.ImmutableClassToInstanceMap" : "ImmutableClassToInstanceMap", + "com.google.common.collect.ImmutableClassToInstanceMap$Builder" : "ImmutableClassToInstanceMap.Builder", + "com.google.common.collect.ImmutableCollection" : "ImmutableCollection", + "com.google.common.collect.ImmutableCollection$Builder" : "ImmutableCollection.Builder", + "com.google.common.collect.ImmutableEntry" : "ImmutableEntry", + "com.google.common.collect.ImmutableEnumMap" : "ImmutableEnumMap", + "com.google.common.collect.ImmutableEnumMap$EnumSerializedForm" : "ImmutableEnumMap.EnumSerializedForm", + "com.google.common.collect.ImmutableEnumSet" : "ImmutableEnumSet", + "com.google.common.collect.ImmutableEnumSet$EnumSerializedForm" : "ImmutableEnumSet.EnumSerializedForm", + "com.google.common.collect.ImmutableList" : "ImmutableList", + "com.google.common.collect.ImmutableList$Builder" : "ImmutableList.Builder", + "com.google.common.collect.ImmutableList$ReverseImmutableList" : "ImmutableList.ReverseImmutableList", + "com.google.common.collect.ImmutableList$SerializedForm" : "ImmutableList.SerializedForm", + "com.google.common.collect.ImmutableList$SubList" : "ImmutableList.SubList", + "com.google.common.collect.ImmutableListMultimap" : "ImmutableListMultimap", + "com.google.common.collect.ImmutableListMultimap$Builder" : "ImmutableListMultimap.Builder", + "com.google.common.collect.ImmutableMap" : "ImmutableMap", + "com.google.common.collect.ImmutableMap$Builder" : "ImmutableMap.Builder", + "com.google.common.collect.ImmutableMap$IteratorBasedImmutableMap" : "ImmutableMap.IteratorBasedImmutableMap", + "com.google.common.collect.ImmutableMap$MapViewOfValuesAsSingletonSets" : "ImmutableMap.MapViewOfValuesAsSingletonSets", + "com.google.common.collect.ImmutableMap$SerializedForm" : "ImmutableMap.SerializedForm", + "com.google.common.collect.ImmutableMapEntry" : "ImmutableMapEntry", + "com.google.common.collect.ImmutableMapEntry$NonTerminalImmutableBiMapEntry" : "ImmutableMapEntry.NonTerminalImmutableBiMapEntry", + "com.google.common.collect.ImmutableMapEntry$NonTerminalImmutableMapEntry" : "ImmutableMapEntry.NonTerminalImmutableMapEntry", + "com.google.common.collect.ImmutableMapEntrySet" : "ImmutableMapEntrySet", + "com.google.common.collect.ImmutableMapEntrySet$EntrySetSerializedForm" : "ImmutableMapEntrySet.EntrySetSerializedForm", + "com.google.common.collect.ImmutableMapEntrySet$RegularEntrySet" : "ImmutableMapEntrySet.RegularEntrySet", + "com.google.common.collect.ImmutableMapKeySet" : "ImmutableMapKeySet", + "com.google.common.collect.ImmutableMapKeySet$KeySetSerializedForm" : "ImmutableMapKeySet.KeySetSerializedForm", + "com.google.common.collect.ImmutableMapValues" : "ImmutableMapValues", + "com.google.common.collect.ImmutableMapValues$SerializedForm" : "ImmutableMapValues.SerializedForm", + "com.google.common.collect.ImmutableMultimap" : "ImmutableMultimap", + "com.google.common.collect.ImmutableMultimap$Builder" : "ImmutableMultimap.Builder", + "com.google.common.collect.ImmutableMultimap$EntryCollection" : "ImmutableMultimap.EntryCollection", + "com.google.common.collect.ImmutableMultimap$FieldSettersHolder" : "ImmutableMultimap.FieldSettersHolder", + "com.google.common.collect.ImmutableMultimap$Keys" : "ImmutableMultimap.Keys", + "com.google.common.collect.ImmutableMultimap$KeysSerializedForm" : "ImmutableMultimap.KeysSerializedForm", + "com.google.common.collect.ImmutableMultimap$Values" : "ImmutableMultimap.Values", + "com.google.common.collect.ImmutableMultiset" : "ImmutableMultiset", + "com.google.common.collect.ImmutableMultiset$Builder" : "ImmutableMultiset.Builder", + "com.google.common.collect.ImmutableMultiset$ElementSet" : "ImmutableMultiset.ElementSet", + "com.google.common.collect.ImmutableMultiset$EntrySet" : "ImmutableMultiset.EntrySet", + "com.google.common.collect.ImmutableMultiset$EntrySetSerializedForm" : "ImmutableMultiset.EntrySetSerializedForm", + "com.google.common.collect.ImmutableMultiset$SerializedForm" : "ImmutableMultiset.SerializedForm", + "com.google.common.collect.ImmutableMultisetGwtSerializationDependencies" : "ImmutableMultisetGwtSerializationDependencies", + "com.google.common.collect.ImmutableRangeMap" : "ImmutableRangeMap", + "com.google.common.collect.ImmutableRangeMap$Builder" : "ImmutableRangeMap.Builder", + "com.google.common.collect.ImmutableRangeMap$SerializedForm" : "ImmutableRangeMap.SerializedForm", + "com.google.common.collect.ImmutableRangeSet" : "ImmutableRangeSet", + "com.google.common.collect.ImmutableRangeSet$AsSet" : "ImmutableRangeSet.AsSet", + "com.google.common.collect.ImmutableRangeSet$AsSetSerializedForm" : "ImmutableRangeSet.AsSetSerializedForm", + "com.google.common.collect.ImmutableRangeSet$Builder" : "ImmutableRangeSet.Builder", + "com.google.common.collect.ImmutableRangeSet$ComplementRanges" : "ImmutableRangeSet.ComplementRanges", + "com.google.common.collect.ImmutableRangeSet$SerializedForm" : "ImmutableRangeSet.SerializedForm", + "com.google.common.collect.ImmutableSet" : "ImmutableSet", + "com.google.common.collect.ImmutableSet$Builder" : "ImmutableSet.Builder", + "com.google.common.collect.ImmutableSet$CachingAsList" : "ImmutableSet.CachingAsList", + "com.google.common.collect.ImmutableSet$EmptySetBuilderImpl" : "ImmutableSet.EmptySetBuilderImpl", + "com.google.common.collect.ImmutableSet$Indexed" : "ImmutableSet.Indexed", + "com.google.common.collect.ImmutableSet$JdkBackedSetBuilderImpl" : "ImmutableSet.JdkBackedSetBuilderImpl", + "com.google.common.collect.ImmutableSet$RegularSetBuilderImpl" : "ImmutableSet.RegularSetBuilderImpl", + "com.google.common.collect.ImmutableSet$SerializedForm" : "ImmutableSet.SerializedForm", + "com.google.common.collect.ImmutableSet$SetBuilderImpl" : "ImmutableSet.SetBuilderImpl", + "com.google.common.collect.ImmutableSetMultimap" : "ImmutableSetMultimap", + "com.google.common.collect.ImmutableSetMultimap$Builder" : "ImmutableSetMultimap.Builder", + "com.google.common.collect.ImmutableSetMultimap$EntrySet" : "ImmutableSetMultimap.EntrySet", + "com.google.common.collect.ImmutableSetMultimap$SetFieldSettersHolder" : "ImmutableSetMultimap.SetFieldSettersHolder", + "com.google.common.collect.ImmutableSortedAsList" : "ImmutableSortedAsList", + "com.google.common.collect.ImmutableSortedMap" : "ImmutableSortedMap", + "com.google.common.collect.ImmutableSortedMap$Builder" : "ImmutableSortedMap.Builder", + "com.google.common.collect.ImmutableSortedMap$SerializedForm" : "ImmutableSortedMap.SerializedForm", + "com.google.common.collect.ImmutableSortedMultiset" : "ImmutableSortedMultiset", + "com.google.common.collect.ImmutableSortedMultiset$Builder" : "ImmutableSortedMultiset.Builder", + "com.google.common.collect.ImmutableSortedMultiset$SerializedForm" : "ImmutableSortedMultiset.SerializedForm", + "com.google.common.collect.ImmutableSortedSet" : "ImmutableSortedSet", + "com.google.common.collect.ImmutableSortedSet$Builder" : "ImmutableSortedSet.Builder", + "com.google.common.collect.ImmutableSortedSet$SerializedForm" : "ImmutableSortedSet.SerializedForm", + "com.google.common.collect.ImmutableTable" : "ImmutableTable", + "com.google.common.collect.ImmutableTable$Builder" : "ImmutableTable.Builder", + "com.google.common.collect.ImmutableTable$SerializedForm" : "ImmutableTable.SerializedForm", + "com.google.common.collect.IndexedImmutableSet" : "IndexedImmutableSet", + "com.google.common.collect.Interner" : "Interner", + "com.google.common.collect.Interners" : "Interners", + "com.google.common.collect.Interners$InternerBuilder" : "Interners.InternerBuilder", + "com.google.common.collect.Interners$InternerFunction" : "Interners.InternerFunction", + "com.google.common.collect.Interners$InternerImpl" : "Interners.InternerImpl", + "com.google.common.collect.Iterables" : "Iterables", + "com.google.common.collect.Iterables$UnmodifiableIterable" : "Iterables.UnmodifiableIterable", + "com.google.common.collect.Iterators" : "Iterators", + "com.google.common.collect.Iterators$ArrayItr" : "Iterators.ArrayItr", + "com.google.common.collect.Iterators$ConcatenatedIterator" : "Iterators.ConcatenatedIterator", + "com.google.common.collect.Iterators$EmptyModifiableIterator" : "Iterators.EmptyModifiableIterator", + "com.google.common.collect.Iterators$MergingIterator" : "Iterators.MergingIterator", + "com.google.common.collect.Iterators$PeekingImpl" : "Iterators.PeekingImpl", + "com.google.common.collect.Iterators$SingletonIterator" : "Iterators.SingletonIterator", + "com.google.common.collect.JdkBackedImmutableBiMap" : "JdkBackedImmutableBiMap", + "com.google.common.collect.JdkBackedImmutableBiMap$InverseEntries" : "JdkBackedImmutableBiMap.InverseEntries", + "com.google.common.collect.JdkBackedImmutableMap" : "JdkBackedImmutableMap", + "com.google.common.collect.JdkBackedImmutableMultiset" : "JdkBackedImmutableMultiset", + "com.google.common.collect.JdkBackedImmutableSet" : "JdkBackedImmutableSet", + "com.google.common.collect.LexicographicalOrdering" : "LexicographicalOrdering", + "com.google.common.collect.LinkedHashMultimap" : "LinkedHashMultimap", + "com.google.common.collect.LinkedHashMultimap$ValueEntry" : "LinkedHashMultimap.ValueEntry", + "com.google.common.collect.LinkedHashMultimap$ValueSet" : "LinkedHashMultimap.ValueSet", + "com.google.common.collect.LinkedHashMultimap$ValueSetLink" : "LinkedHashMultimap.ValueSetLink", + "com.google.common.collect.LinkedHashMultimapGwtSerializationDependencies" : "LinkedHashMultimapGwtSerializationDependencies", + "com.google.common.collect.LinkedHashMultiset" : "LinkedHashMultiset", + "com.google.common.collect.LinkedListMultimap" : "LinkedListMultimap", + "com.google.common.collect.LinkedListMultimap$DistinctKeyIterator" : "LinkedListMultimap.DistinctKeyIterator", + "com.google.common.collect.LinkedListMultimap$KeyList" : "LinkedListMultimap.KeyList", + "com.google.common.collect.LinkedListMultimap$Node" : "LinkedListMultimap.Node", + "com.google.common.collect.LinkedListMultimap$NodeIterator" : "LinkedListMultimap.NodeIterator", + "com.google.common.collect.LinkedListMultimap$ValueForKeyIterator" : "LinkedListMultimap.ValueForKeyIterator", + "com.google.common.collect.ListMultimap" : "ListMultimap", + "com.google.common.collect.Lists" : "Lists", + "com.google.common.collect.Lists$AbstractListWrapper" : "Lists.AbstractListWrapper", + "com.google.common.collect.Lists$CharSequenceAsList" : "Lists.CharSequenceAsList", + "com.google.common.collect.Lists$OnePlusArrayList" : "Lists.OnePlusArrayList", + "com.google.common.collect.Lists$Partition" : "Lists.Partition", + "com.google.common.collect.Lists$RandomAccessListWrapper" : "Lists.RandomAccessListWrapper", + "com.google.common.collect.Lists$RandomAccessPartition" : "Lists.RandomAccessPartition", + "com.google.common.collect.Lists$RandomAccessReverseList" : "Lists.RandomAccessReverseList", + "com.google.common.collect.Lists$ReverseList" : "Lists.ReverseList", + "com.google.common.collect.Lists$StringAsImmutableList" : "Lists.StringAsImmutableList", + "com.google.common.collect.Lists$TransformingRandomAccessList" : "Lists.TransformingRandomAccessList", + "com.google.common.collect.Lists$TransformingSequentialList" : "Lists.TransformingSequentialList", + "com.google.common.collect.Lists$TwoPlusArrayList" : "Lists.TwoPlusArrayList", + "com.google.common.collect.MapDifference" : "MapDifference", + "com.google.common.collect.MapDifference$ValueDifference" : "MapDifference.ValueDifference", + "com.google.common.collect.MapMaker" : "MapMaker", + "com.google.common.collect.MapMaker$Dummy" : "MapMaker.Dummy", + "com.google.common.collect.MapMakerInternalMap" : "MapMakerInternalMap", + "com.google.common.collect.MapMakerInternalMap$AbstractSerializationProxy" : "MapMakerInternalMap.AbstractSerializationProxy", + "com.google.common.collect.MapMakerInternalMap$AbstractStrongKeyEntry" : "MapMakerInternalMap.AbstractStrongKeyEntry", + "com.google.common.collect.MapMakerInternalMap$AbstractWeakKeyEntry" : "MapMakerInternalMap.AbstractWeakKeyEntry", + "com.google.common.collect.MapMakerInternalMap$CleanupMapTask" : "MapMakerInternalMap.CleanupMapTask", + "com.google.common.collect.MapMakerInternalMap$DummyInternalEntry" : "MapMakerInternalMap.DummyInternalEntry", + "com.google.common.collect.MapMakerInternalMap$EntryIterator" : "MapMakerInternalMap.EntryIterator", + "com.google.common.collect.MapMakerInternalMap$EntrySet" : "MapMakerInternalMap.EntrySet", + "com.google.common.collect.MapMakerInternalMap$HashIterator" : "MapMakerInternalMap.HashIterator", + "com.google.common.collect.MapMakerInternalMap$InternalEntry" : "MapMakerInternalMap.InternalEntry", + "com.google.common.collect.MapMakerInternalMap$InternalEntryHelper" : "MapMakerInternalMap.InternalEntryHelper", + "com.google.common.collect.MapMakerInternalMap$KeyIterator" : "MapMakerInternalMap.KeyIterator", + "com.google.common.collect.MapMakerInternalMap$KeySet" : "MapMakerInternalMap.KeySet", + "com.google.common.collect.MapMakerInternalMap$Segment" : "MapMakerInternalMap.Segment", + "com.google.common.collect.MapMakerInternalMap$SerializationProxy" : "MapMakerInternalMap.SerializationProxy", + "com.google.common.collect.MapMakerInternalMap$Strength" : "MapMakerInternalMap.Strength", + "com.google.common.collect.MapMakerInternalMap$StrongKeyDummyValueEntry" : "MapMakerInternalMap.StrongKeyDummyValueEntry", + "com.google.common.collect.MapMakerInternalMap$StrongKeyDummyValueEntry$Helper" : "MapMakerInternalMap.StrongKeyDummyValueEntry.Helper", + "com.google.common.collect.MapMakerInternalMap$StrongKeyDummyValueEntry$LinkedStrongKeyDummyValueEntry" : "MapMakerInternalMap.StrongKeyDummyValueEntry.LinkedStrongKeyDummyValueEntry", + "com.google.common.collect.MapMakerInternalMap$StrongKeyDummyValueSegment" : "MapMakerInternalMap.StrongKeyDummyValueSegment", + "com.google.common.collect.MapMakerInternalMap$StrongKeyStrongValueEntry" : "MapMakerInternalMap.StrongKeyStrongValueEntry", + "com.google.common.collect.MapMakerInternalMap$StrongKeyStrongValueEntry$Helper" : "MapMakerInternalMap.StrongKeyStrongValueEntry.Helper", + "com.google.common.collect.MapMakerInternalMap$StrongKeyStrongValueEntry$LinkedStrongKeyStrongValueEntry" : "MapMakerInternalMap.StrongKeyStrongValueEntry.LinkedStrongKeyStrongValueEntry", + "com.google.common.collect.MapMakerInternalMap$StrongKeyStrongValueSegment" : "MapMakerInternalMap.StrongKeyStrongValueSegment", + "com.google.common.collect.MapMakerInternalMap$StrongKeyWeakValueEntry" : "MapMakerInternalMap.StrongKeyWeakValueEntry", + "com.google.common.collect.MapMakerInternalMap$StrongKeyWeakValueEntry$Helper" : "MapMakerInternalMap.StrongKeyWeakValueEntry.Helper", + "com.google.common.collect.MapMakerInternalMap$StrongKeyWeakValueEntry$LinkedStrongKeyWeakValueEntry" : "MapMakerInternalMap.StrongKeyWeakValueEntry.LinkedStrongKeyWeakValueEntry", + "com.google.common.collect.MapMakerInternalMap$StrongKeyWeakValueSegment" : "MapMakerInternalMap.StrongKeyWeakValueSegment", + "com.google.common.collect.MapMakerInternalMap$StrongValueEntry" : "MapMakerInternalMap.StrongValueEntry", + "com.google.common.collect.MapMakerInternalMap$ValueIterator" : "MapMakerInternalMap.ValueIterator", + "com.google.common.collect.MapMakerInternalMap$Values" : "MapMakerInternalMap.Values", + "com.google.common.collect.MapMakerInternalMap$WeakKeyDummyValueEntry" : "MapMakerInternalMap.WeakKeyDummyValueEntry", + "com.google.common.collect.MapMakerInternalMap$WeakKeyDummyValueEntry$Helper" : "MapMakerInternalMap.WeakKeyDummyValueEntry.Helper", + "com.google.common.collect.MapMakerInternalMap$WeakKeyDummyValueEntry$LinkedWeakKeyDummyValueEntry" : "MapMakerInternalMap.WeakKeyDummyValueEntry.LinkedWeakKeyDummyValueEntry", + "com.google.common.collect.MapMakerInternalMap$WeakKeyDummyValueSegment" : "MapMakerInternalMap.WeakKeyDummyValueSegment", + "com.google.common.collect.MapMakerInternalMap$WeakKeyStrongValueEntry" : "MapMakerInternalMap.WeakKeyStrongValueEntry", + "com.google.common.collect.MapMakerInternalMap$WeakKeyStrongValueEntry$Helper" : "MapMakerInternalMap.WeakKeyStrongValueEntry.Helper", + "com.google.common.collect.MapMakerInternalMap$WeakKeyStrongValueEntry$LinkedWeakKeyStrongValueEntry" : "MapMakerInternalMap.WeakKeyStrongValueEntry.LinkedWeakKeyStrongValueEntry", + "com.google.common.collect.MapMakerInternalMap$WeakKeyStrongValueSegment" : "MapMakerInternalMap.WeakKeyStrongValueSegment", + "com.google.common.collect.MapMakerInternalMap$WeakKeyWeakValueEntry" : "MapMakerInternalMap.WeakKeyWeakValueEntry", + "com.google.common.collect.MapMakerInternalMap$WeakKeyWeakValueEntry$Helper" : "MapMakerInternalMap.WeakKeyWeakValueEntry.Helper", + "com.google.common.collect.MapMakerInternalMap$WeakKeyWeakValueEntry$LinkedWeakKeyWeakValueEntry" : "MapMakerInternalMap.WeakKeyWeakValueEntry.LinkedWeakKeyWeakValueEntry", + "com.google.common.collect.MapMakerInternalMap$WeakKeyWeakValueSegment" : "MapMakerInternalMap.WeakKeyWeakValueSegment", + "com.google.common.collect.MapMakerInternalMap$WeakValueEntry" : "MapMakerInternalMap.WeakValueEntry", + "com.google.common.collect.MapMakerInternalMap$WeakValueReference" : "MapMakerInternalMap.WeakValueReference", + "com.google.common.collect.MapMakerInternalMap$WeakValueReferenceImpl" : "MapMakerInternalMap.WeakValueReferenceImpl", + "com.google.common.collect.MapMakerInternalMap$WriteThroughEntry" : "MapMakerInternalMap.WriteThroughEntry", + "com.google.common.collect.Maps" : "Maps", + "com.google.common.collect.Maps$AbstractFilteredMap" : "Maps.AbstractFilteredMap", + "com.google.common.collect.Maps$AsMapView" : "Maps.AsMapView", + "com.google.common.collect.Maps$BiMapConverter" : "Maps.BiMapConverter", + "com.google.common.collect.Maps$DescendingMap" : "Maps.DescendingMap", + "com.google.common.collect.Maps$EntryFunction" : "Maps.EntryFunction", + "com.google.common.collect.Maps$EntrySet" : "Maps.EntrySet", + "com.google.common.collect.Maps$EntryTransformer" : "Maps.EntryTransformer", + "com.google.common.collect.Maps$FilteredEntryBiMap" : "Maps.FilteredEntryBiMap", + "com.google.common.collect.Maps$FilteredEntryMap" : "Maps.FilteredEntryMap", + "com.google.common.collect.Maps$FilteredEntryMap$EntrySet" : "Maps.FilteredEntryMap.EntrySet", + "com.google.common.collect.Maps$FilteredEntryMap$KeySet" : "Maps.FilteredEntryMap.KeySet", + "com.google.common.collect.Maps$FilteredEntryNavigableMap" : "Maps.FilteredEntryNavigableMap", + "com.google.common.collect.Maps$FilteredEntrySortedMap" : "Maps.FilteredEntrySortedMap", + "com.google.common.collect.Maps$FilteredEntrySortedMap$SortedKeySet" : "Maps.FilteredEntrySortedMap.SortedKeySet", + "com.google.common.collect.Maps$FilteredKeyMap" : "Maps.FilteredKeyMap", + "com.google.common.collect.Maps$FilteredMapValues" : "Maps.FilteredMapValues", + "com.google.common.collect.Maps$IteratorBasedAbstractMap" : "Maps.IteratorBasedAbstractMap", + "com.google.common.collect.Maps$KeySet" : "Maps.KeySet", + "com.google.common.collect.Maps$MapDifferenceImpl" : "Maps.MapDifferenceImpl", + "com.google.common.collect.Maps$NavigableAsMapView" : "Maps.NavigableAsMapView", + "com.google.common.collect.Maps$NavigableKeySet" : "Maps.NavigableKeySet", + "com.google.common.collect.Maps$SortedAsMapView" : "Maps.SortedAsMapView", + "com.google.common.collect.Maps$SortedKeySet" : "Maps.SortedKeySet", + "com.google.common.collect.Maps$SortedMapDifferenceImpl" : "Maps.SortedMapDifferenceImpl", + "com.google.common.collect.Maps$TransformedEntriesMap" : "Maps.TransformedEntriesMap", + "com.google.common.collect.Maps$TransformedEntriesNavigableMap" : "Maps.TransformedEntriesNavigableMap", + "com.google.common.collect.Maps$TransformedEntriesSortedMap" : "Maps.TransformedEntriesSortedMap", + "com.google.common.collect.Maps$UnmodifiableBiMap" : "Maps.UnmodifiableBiMap", + "com.google.common.collect.Maps$UnmodifiableEntries" : "Maps.UnmodifiableEntries", + "com.google.common.collect.Maps$UnmodifiableEntrySet" : "Maps.UnmodifiableEntrySet", + "com.google.common.collect.Maps$UnmodifiableNavigableMap" : "Maps.UnmodifiableNavigableMap", + "com.google.common.collect.Maps$ValueDifferenceImpl" : "Maps.ValueDifferenceImpl", + "com.google.common.collect.Maps$Values" : "Maps.Values", + "com.google.common.collect.Maps$ViewCachingAbstractMap" : "Maps.ViewCachingAbstractMap", + "com.google.common.collect.MinMaxPriorityQueue" : "MinMaxPriorityQueue", + "com.google.common.collect.MinMaxPriorityQueue$Builder" : "MinMaxPriorityQueue.Builder", + "com.google.common.collect.MinMaxPriorityQueue$Heap" : "MinMaxPriorityQueue.Heap", + "com.google.common.collect.MinMaxPriorityQueue$MoveDesc" : "MinMaxPriorityQueue.MoveDesc", + "com.google.common.collect.MinMaxPriorityQueue$QueueIterator" : "MinMaxPriorityQueue.QueueIterator", + "com.google.common.collect.MoreCollectors" : "MoreCollectors", + "com.google.common.collect.MoreCollectors$ToOptionalState" : "MoreCollectors.ToOptionalState", + "com.google.common.collect.Multimap" : "Multimap", + "com.google.common.collect.MultimapBuilder" : "MultimapBuilder", + "com.google.common.collect.MultimapBuilder$ArrayListSupplier" : "MultimapBuilder.ArrayListSupplier", + "com.google.common.collect.MultimapBuilder$EnumSetSupplier" : "MultimapBuilder.EnumSetSupplier", + "com.google.common.collect.MultimapBuilder$HashSetSupplier" : "MultimapBuilder.HashSetSupplier", + "com.google.common.collect.MultimapBuilder$LinkedHashSetSupplier" : "MultimapBuilder.LinkedHashSetSupplier", + "com.google.common.collect.MultimapBuilder$LinkedListSupplier" : "MultimapBuilder.LinkedListSupplier", + "com.google.common.collect.MultimapBuilder$ListMultimapBuilder" : "MultimapBuilder.ListMultimapBuilder", + "com.google.common.collect.MultimapBuilder$MultimapBuilderWithKeys" : "MultimapBuilder.MultimapBuilderWithKeys", + "com.google.common.collect.MultimapBuilder$SetMultimapBuilder" : "MultimapBuilder.SetMultimapBuilder", + "com.google.common.collect.MultimapBuilder$SortedSetMultimapBuilder" : "MultimapBuilder.SortedSetMultimapBuilder", + "com.google.common.collect.MultimapBuilder$TreeSetSupplier" : "MultimapBuilder.TreeSetSupplier", + "com.google.common.collect.Multimaps" : "Multimaps", + "com.google.common.collect.Multimaps$AsMap" : "Multimaps.AsMap", + "com.google.common.collect.Multimaps$AsMap$EntrySet" : "Multimaps.AsMap.EntrySet", + "com.google.common.collect.Multimaps$CustomListMultimap" : "Multimaps.CustomListMultimap", + "com.google.common.collect.Multimaps$CustomMultimap" : "Multimaps.CustomMultimap", + "com.google.common.collect.Multimaps$CustomSetMultimap" : "Multimaps.CustomSetMultimap", + "com.google.common.collect.Multimaps$CustomSortedSetMultimap" : "Multimaps.CustomSortedSetMultimap", + "com.google.common.collect.Multimaps$Entries" : "Multimaps.Entries", + "com.google.common.collect.Multimaps$Keys" : "Multimaps.Keys", + "com.google.common.collect.Multimaps$MapMultimap" : "Multimaps.MapMultimap", + "com.google.common.collect.Multimaps$TransformedEntriesListMultimap" : "Multimaps.TransformedEntriesListMultimap", + "com.google.common.collect.Multimaps$TransformedEntriesMultimap" : "Multimaps.TransformedEntriesMultimap", + "com.google.common.collect.Multimaps$UnmodifiableListMultimap" : "Multimaps.UnmodifiableListMultimap", + "com.google.common.collect.Multimaps$UnmodifiableMultimap" : "Multimaps.UnmodifiableMultimap", + "com.google.common.collect.Multimaps$UnmodifiableSetMultimap" : "Multimaps.UnmodifiableSetMultimap", + "com.google.common.collect.Multimaps$UnmodifiableSortedSetMultimap" : "Multimaps.UnmodifiableSortedSetMultimap", + "com.google.common.collect.Multiset" : "Multiset", + "com.google.common.collect.Multiset$Entry" : "Multiset.Entry", + "com.google.common.collect.Multisets" : "Multisets", + "com.google.common.collect.Multisets$AbstractEntry" : "Multisets.AbstractEntry", + "com.google.common.collect.Multisets$DecreasingCount" : "Multisets.DecreasingCount", + "com.google.common.collect.Multisets$ElementSet" : "Multisets.ElementSet", + "com.google.common.collect.Multisets$EntrySet" : "Multisets.EntrySet", + "com.google.common.collect.Multisets$FilteredMultiset" : "Multisets.FilteredMultiset", + "com.google.common.collect.Multisets$ImmutableEntry" : "Multisets.ImmutableEntry", + "com.google.common.collect.Multisets$MultisetIteratorImpl" : "Multisets.MultisetIteratorImpl", + "com.google.common.collect.Multisets$UnmodifiableMultiset" : "Multisets.UnmodifiableMultiset", + "com.google.common.collect.Multisets$ViewMultiset" : "Multisets.ViewMultiset", + "com.google.common.collect.MutableClassToInstanceMap" : "MutableClassToInstanceMap", + "com.google.common.collect.MutableClassToInstanceMap$SerializedForm" : "MutableClassToInstanceMap.SerializedForm", + "com.google.common.collect.NaturalOrdering" : "NaturalOrdering", + "com.google.common.collect.NullnessCasts" : "NullnessCasts", + "com.google.common.collect.NullsFirstOrdering" : "NullsFirstOrdering", + "com.google.common.collect.NullsLastOrdering" : "NullsLastOrdering", + "com.google.common.collect.ObjectArrays" : "ObjectArrays", + "com.google.common.collect.Ordering" : "Ordering", + "com.google.common.collect.Ordering$ArbitraryOrdering" : "Ordering.ArbitraryOrdering", + "com.google.common.collect.Ordering$ArbitraryOrderingHolder" : "Ordering.ArbitraryOrderingHolder", + "com.google.common.collect.Ordering$IncomparableValueException" : "Ordering.IncomparableValueException", + "com.google.common.collect.ParametricNullness" : "ParametricNullness", + "com.google.common.collect.PeekingIterator" : "PeekingIterator", + "com.google.common.collect.Platform" : "Platform", + "com.google.common.collect.Queues" : "Queues", + "com.google.common.collect.Range" : "Range", + "com.google.common.collect.Range$RangeLexOrdering" : "Range.RangeLexOrdering", + "com.google.common.collect.RangeGwtSerializationDependencies" : "RangeGwtSerializationDependencies", + "com.google.common.collect.RangeMap" : "RangeMap", + "com.google.common.collect.RangeSet" : "RangeSet", + "com.google.common.collect.RegularContiguousSet" : "RegularContiguousSet", + "com.google.common.collect.RegularContiguousSet$SerializedForm" : "RegularContiguousSet.SerializedForm", + "com.google.common.collect.RegularImmutableAsList" : "RegularImmutableAsList", + "com.google.common.collect.RegularImmutableBiMap" : "RegularImmutableBiMap", + "com.google.common.collect.RegularImmutableBiMap$Inverse" : "RegularImmutableBiMap.Inverse", + "com.google.common.collect.RegularImmutableBiMap$Inverse$InverseEntrySet" : "RegularImmutableBiMap.Inverse.InverseEntrySet", + "com.google.common.collect.RegularImmutableBiMap$InverseSerializedForm" : "RegularImmutableBiMap.InverseSerializedForm", + "com.google.common.collect.RegularImmutableList" : "RegularImmutableList", + "com.google.common.collect.RegularImmutableMap" : "RegularImmutableMap", + "com.google.common.collect.RegularImmutableMap$BucketOverflowException" : "RegularImmutableMap.BucketOverflowException", + "com.google.common.collect.RegularImmutableMap$KeySet" : "RegularImmutableMap.KeySet", + "com.google.common.collect.RegularImmutableMap$KeySet$SerializedForm" : "RegularImmutableMap.KeySet.SerializedForm", + "com.google.common.collect.RegularImmutableMap$Values" : "RegularImmutableMap.Values", + "com.google.common.collect.RegularImmutableMap$Values$SerializedForm" : "RegularImmutableMap.Values.SerializedForm", + "com.google.common.collect.RegularImmutableMultiset" : "RegularImmutableMultiset", + "com.google.common.collect.RegularImmutableMultiset$NonTerminalEntry" : "RegularImmutableMultiset.NonTerminalEntry", + "com.google.common.collect.RegularImmutableSet" : "RegularImmutableSet", + "com.google.common.collect.RegularImmutableSortedMultiset" : "RegularImmutableSortedMultiset", + "com.google.common.collect.RegularImmutableSortedSet" : "RegularImmutableSortedSet", + "com.google.common.collect.RegularImmutableTable" : "RegularImmutableTable", + "com.google.common.collect.RegularImmutableTable$CellSet" : "RegularImmutableTable.CellSet", + "com.google.common.collect.RegularImmutableTable$Values" : "RegularImmutableTable.Values", + "com.google.common.collect.ReverseNaturalOrdering" : "ReverseNaturalOrdering", + "com.google.common.collect.ReverseOrdering" : "ReverseOrdering", + "com.google.common.collect.RowSortedTable" : "RowSortedTable", + "com.google.common.collect.Serialization" : "Serialization", + "com.google.common.collect.Serialization$FieldSetter" : "Serialization.FieldSetter", + "com.google.common.collect.SetMultimap" : "SetMultimap", + "com.google.common.collect.Sets" : "Sets", + "com.google.common.collect.Sets$CartesianSet" : "Sets.CartesianSet", + "com.google.common.collect.Sets$DescendingSet" : "Sets.DescendingSet", + "com.google.common.collect.Sets$FilteredNavigableSet" : "Sets.FilteredNavigableSet", + "com.google.common.collect.Sets$FilteredSet" : "Sets.FilteredSet", + "com.google.common.collect.Sets$FilteredSortedSet" : "Sets.FilteredSortedSet", + "com.google.common.collect.Sets$ImprovedAbstractSet" : "Sets.ImprovedAbstractSet", + "com.google.common.collect.Sets$PowerSet" : "Sets.PowerSet", + "com.google.common.collect.Sets$SetView" : "Sets.SetView", + "com.google.common.collect.Sets$SubSet" : "Sets.SubSet", + "com.google.common.collect.Sets$UnmodifiableNavigableSet" : "Sets.UnmodifiableNavigableSet", + "com.google.common.collect.SingletonImmutableBiMap" : "SingletonImmutableBiMap", + "com.google.common.collect.SingletonImmutableList" : "SingletonImmutableList", + "com.google.common.collect.SingletonImmutableSet" : "SingletonImmutableSet", + "com.google.common.collect.SingletonImmutableTable" : "SingletonImmutableTable", + "com.google.common.collect.SortedIterable" : "SortedIterable", + "com.google.common.collect.SortedIterables" : "SortedIterables", + "com.google.common.collect.SortedLists" : "SortedLists", + "com.google.common.collect.SortedLists$KeyAbsentBehavior" : "SortedLists.KeyAbsentBehavior", + "com.google.common.collect.SortedLists$KeyPresentBehavior" : "SortedLists.KeyPresentBehavior", + "com.google.common.collect.SortedMapDifference" : "SortedMapDifference", + "com.google.common.collect.SortedMultiset" : "SortedMultiset", + "com.google.common.collect.SortedMultisetBridge" : "SortedMultisetBridge", + "com.google.common.collect.SortedMultisets" : "SortedMultisets", + "com.google.common.collect.SortedMultisets$ElementSet" : "SortedMultisets.ElementSet", + "com.google.common.collect.SortedMultisets$NavigableElementSet" : "SortedMultisets.NavigableElementSet", + "com.google.common.collect.SortedSetMultimap" : "SortedSetMultimap", + "com.google.common.collect.SparseImmutableTable" : "SparseImmutableTable", + "com.google.common.collect.StandardRowSortedTable" : "StandardRowSortedTable", + "com.google.common.collect.StandardRowSortedTable$RowSortedMap" : "StandardRowSortedTable.RowSortedMap", + "com.google.common.collect.StandardTable" : "StandardTable", + "com.google.common.collect.StandardTable$CellIterator" : "StandardTable.CellIterator", + "com.google.common.collect.StandardTable$Column" : "StandardTable.Column", + "com.google.common.collect.StandardTable$Column$EntrySet" : "StandardTable.Column.EntrySet", + "com.google.common.collect.StandardTable$Column$EntrySetIterator" : "StandardTable.Column.EntrySetIterator", + "com.google.common.collect.StandardTable$Column$KeySet" : "StandardTable.Column.KeySet", + "com.google.common.collect.StandardTable$Column$Values" : "StandardTable.Column.Values", + "com.google.common.collect.StandardTable$ColumnKeyIterator" : "StandardTable.ColumnKeyIterator", + "com.google.common.collect.StandardTable$ColumnKeySet" : "StandardTable.ColumnKeySet", + "com.google.common.collect.StandardTable$ColumnMap" : "StandardTable.ColumnMap", + "com.google.common.collect.StandardTable$ColumnMap$ColumnMapEntrySet" : "StandardTable.ColumnMap.ColumnMapEntrySet", + "com.google.common.collect.StandardTable$ColumnMap$ColumnMapValues" : "StandardTable.ColumnMap.ColumnMapValues", + "com.google.common.collect.StandardTable$Row" : "StandardTable.Row", + "com.google.common.collect.StandardTable$RowMap" : "StandardTable.RowMap", + "com.google.common.collect.StandardTable$RowMap$EntrySet" : "StandardTable.RowMap.EntrySet", + "com.google.common.collect.StandardTable$TableSet" : "StandardTable.TableSet", + "com.google.common.collect.Streams" : "Streams", + "com.google.common.collect.Streams$DoubleFunctionWithIndex" : "Streams.DoubleFunctionWithIndex", + "com.google.common.collect.Streams$FunctionWithIndex" : "Streams.FunctionWithIndex", + "com.google.common.collect.Streams$IntFunctionWithIndex" : "Streams.IntFunctionWithIndex", + "com.google.common.collect.Streams$LongFunctionWithIndex" : "Streams.LongFunctionWithIndex", + "com.google.common.collect.Streams$MapWithIndexSpliterator" : "Streams.MapWithIndexSpliterator", + "com.google.common.collect.Streams$TemporaryPair" : "Streams.TemporaryPair", + "com.google.common.collect.Synchronized" : "Synchronized", + "com.google.common.collect.Synchronized$SynchronizedAsMap" : "Synchronized.SynchronizedAsMap", + "com.google.common.collect.Synchronized$SynchronizedAsMapEntries" : "Synchronized.SynchronizedAsMapEntries", + "com.google.common.collect.Synchronized$SynchronizedAsMapValues" : "Synchronized.SynchronizedAsMapValues", + "com.google.common.collect.Synchronized$SynchronizedBiMap" : "Synchronized.SynchronizedBiMap", + "com.google.common.collect.Synchronized$SynchronizedCollection" : "Synchronized.SynchronizedCollection", + "com.google.common.collect.Synchronized$SynchronizedDeque" : "Synchronized.SynchronizedDeque", + "com.google.common.collect.Synchronized$SynchronizedEntry" : "Synchronized.SynchronizedEntry", + "com.google.common.collect.Synchronized$SynchronizedList" : "Synchronized.SynchronizedList", + "com.google.common.collect.Synchronized$SynchronizedListMultimap" : "Synchronized.SynchronizedListMultimap", + "com.google.common.collect.Synchronized$SynchronizedMap" : "Synchronized.SynchronizedMap", + "com.google.common.collect.Synchronized$SynchronizedMultimap" : "Synchronized.SynchronizedMultimap", + "com.google.common.collect.Synchronized$SynchronizedMultiset" : "Synchronized.SynchronizedMultiset", + "com.google.common.collect.Synchronized$SynchronizedNavigableMap" : "Synchronized.SynchronizedNavigableMap", + "com.google.common.collect.Synchronized$SynchronizedNavigableSet" : "Synchronized.SynchronizedNavigableSet", + "com.google.common.collect.Synchronized$SynchronizedObject" : "Synchronized.SynchronizedObject", + "com.google.common.collect.Synchronized$SynchronizedQueue" : "Synchronized.SynchronizedQueue", + "com.google.common.collect.Synchronized$SynchronizedRandomAccessList" : "Synchronized.SynchronizedRandomAccessList", + "com.google.common.collect.Synchronized$SynchronizedSet" : "Synchronized.SynchronizedSet", + "com.google.common.collect.Synchronized$SynchronizedSetMultimap" : "Synchronized.SynchronizedSetMultimap", + "com.google.common.collect.Synchronized$SynchronizedSortedMap" : "Synchronized.SynchronizedSortedMap", + "com.google.common.collect.Synchronized$SynchronizedSortedSet" : "Synchronized.SynchronizedSortedSet", + "com.google.common.collect.Synchronized$SynchronizedSortedSetMultimap" : "Synchronized.SynchronizedSortedSetMultimap", + "com.google.common.collect.Synchronized$SynchronizedTable" : "Synchronized.SynchronizedTable", + "com.google.common.collect.Table" : "Table", + "com.google.common.collect.Table$Cell" : "Table.Cell", + "com.google.common.collect.TableCollectors" : "TableCollectors", + "com.google.common.collect.TableCollectors$ImmutableTableCollectorState" : "TableCollectors.ImmutableTableCollectorState", + "com.google.common.collect.TableCollectors$MutableCell" : "TableCollectors.MutableCell", + "com.google.common.collect.Tables" : "Tables", + "com.google.common.collect.Tables$AbstractCell" : "Tables.AbstractCell", + "com.google.common.collect.Tables$ImmutableCell" : "Tables.ImmutableCell", + "com.google.common.collect.Tables$TransformedTable" : "Tables.TransformedTable", + "com.google.common.collect.Tables$TransposeTable" : "Tables.TransposeTable", + "com.google.common.collect.Tables$UnmodifiableRowSortedMap" : "Tables.UnmodifiableRowSortedMap", + "com.google.common.collect.Tables$UnmodifiableTable" : "Tables.UnmodifiableTable", + "com.google.common.collect.TopKSelector" : "TopKSelector", + "com.google.common.collect.TransformedIterator" : "TransformedIterator", + "com.google.common.collect.TransformedListIterator" : "TransformedListIterator", + "com.google.common.collect.TreeBasedTable" : "TreeBasedTable", + "com.google.common.collect.TreeBasedTable$Factory" : "TreeBasedTable.Factory", + "com.google.common.collect.TreeBasedTable$TreeRow" : "TreeBasedTable.TreeRow", + "com.google.common.collect.TreeMultimap" : "TreeMultimap", + "com.google.common.collect.TreeMultiset" : "TreeMultiset", + "com.google.common.collect.TreeMultiset$Aggregate" : "TreeMultiset.Aggregate", + "com.google.common.collect.TreeMultiset$AvlNode" : "TreeMultiset.AvlNode", + "com.google.common.collect.TreeMultiset$Reference" : "TreeMultiset.Reference", + "com.google.common.collect.TreeRangeMap" : "TreeRangeMap", + "com.google.common.collect.TreeRangeMap$AsMapOfRanges" : "TreeRangeMap.AsMapOfRanges", + "com.google.common.collect.TreeRangeMap$RangeMapEntry" : "TreeRangeMap.RangeMapEntry", + "com.google.common.collect.TreeRangeMap$SubRangeMap" : "TreeRangeMap.SubRangeMap", + "com.google.common.collect.TreeRangeMap$SubRangeMap$SubRangeMapAsMap" : "TreeRangeMap.SubRangeMap.SubRangeMapAsMap", + "com.google.common.collect.TreeRangeSet" : "TreeRangeSet", + "com.google.common.collect.TreeRangeSet$AsRanges" : "TreeRangeSet.AsRanges", + "com.google.common.collect.TreeRangeSet$Complement" : "TreeRangeSet.Complement", + "com.google.common.collect.TreeRangeSet$ComplementRangesByLowerBound" : "TreeRangeSet.ComplementRangesByLowerBound", + "com.google.common.collect.TreeRangeSet$RangesByUpperBound" : "TreeRangeSet.RangesByUpperBound", + "com.google.common.collect.TreeRangeSet$SubRangeSet" : "TreeRangeSet.SubRangeSet", + "com.google.common.collect.TreeRangeSet$SubRangeSetRangesByLowerBound" : "TreeRangeSet.SubRangeSetRangesByLowerBound", + "com.google.common.collect.TreeTraverser" : "TreeTraverser", + "com.google.common.collect.TreeTraverser$BreadthFirstIterator" : "TreeTraverser.BreadthFirstIterator", + "com.google.common.collect.TreeTraverser$PostOrderIterator" : "TreeTraverser.PostOrderIterator", + "com.google.common.collect.TreeTraverser$PostOrderNode" : "TreeTraverser.PostOrderNode", + "com.google.common.collect.TreeTraverser$PreOrderIterator" : "TreeTraverser.PreOrderIterator", + "com.google.common.collect.UnmodifiableIterator" : "UnmodifiableIterator", + "com.google.common.collect.UnmodifiableListIterator" : "UnmodifiableListIterator", + "com.google.common.collect.UnmodifiableSortedMultiset" : "UnmodifiableSortedMultiset", + "com.google.common.collect.UsingToStringOrdering" : "UsingToStringOrdering", + "com.google.common.collect.package-info" : "package-info", + "com.google.common.escape.ArrayBasedCharEscaper" : "ArrayBasedCharEscaper", + "com.google.common.escape.ArrayBasedEscaperMap" : "ArrayBasedEscaperMap", + "com.google.common.escape.ArrayBasedUnicodeEscaper" : "ArrayBasedUnicodeEscaper", + "com.google.common.escape.CharEscaper" : "CharEscaper", + "com.google.common.escape.CharEscaperBuilder" : "CharEscaperBuilder", + "com.google.common.escape.CharEscaperBuilder$CharArrayDecorator" : "CharEscaperBuilder.CharArrayDecorator", + "com.google.common.escape.ElementTypesAreNonnullByDefault" : "ElementTypesAreNonnullByDefault", + "com.google.common.escape.Escaper" : "Escaper", + "com.google.common.escape.Escapers" : "Escapers", + "com.google.common.escape.Escapers$Builder" : "Escapers.Builder", + "com.google.common.escape.ParametricNullness" : "ParametricNullness", + "com.google.common.escape.Platform" : "Platform", + "com.google.common.escape.UnicodeEscaper" : "UnicodeEscaper", + "com.google.common.escape.package-info" : "package-info", + "com.google.common.eventbus.AllowConcurrentEvents" : "AllowConcurrentEvents", + "com.google.common.eventbus.AsyncEventBus" : "AsyncEventBus", + "com.google.common.eventbus.DeadEvent" : "DeadEvent", + "com.google.common.eventbus.Dispatcher" : "Dispatcher", + "com.google.common.eventbus.Dispatcher$ImmediateDispatcher" : "Dispatcher.ImmediateDispatcher", + "com.google.common.eventbus.Dispatcher$LegacyAsyncDispatcher" : "Dispatcher.LegacyAsyncDispatcher", + "com.google.common.eventbus.Dispatcher$LegacyAsyncDispatcher$EventWithSubscriber" : "Dispatcher.LegacyAsyncDispatcher.EventWithSubscriber", + "com.google.common.eventbus.Dispatcher$PerThreadQueuedDispatcher" : "Dispatcher.PerThreadQueuedDispatcher", + "com.google.common.eventbus.Dispatcher$PerThreadQueuedDispatcher$Event" : "Dispatcher.PerThreadQueuedDispatcher.Event", + "com.google.common.eventbus.ElementTypesAreNonnullByDefault" : "ElementTypesAreNonnullByDefault", + "com.google.common.eventbus.EventBus" : "EventBus", + "com.google.common.eventbus.EventBus$LoggingHandler" : "EventBus.LoggingHandler", + "com.google.common.eventbus.ParametricNullness" : "ParametricNullness", + "com.google.common.eventbus.Subscribe" : "Subscribe", + "com.google.common.eventbus.Subscriber" : "Subscriber", + "com.google.common.eventbus.Subscriber$SynchronizedSubscriber" : "Subscriber.SynchronizedSubscriber", + "com.google.common.eventbus.SubscriberExceptionContext" : "SubscriberExceptionContext", + "com.google.common.eventbus.SubscriberExceptionHandler" : "SubscriberExceptionHandler", + "com.google.common.eventbus.SubscriberRegistry" : "SubscriberRegistry", + "com.google.common.eventbus.SubscriberRegistry$MethodIdentifier" : "SubscriberRegistry.MethodIdentifier", + "com.google.common.eventbus.package-info" : "package-info", + "com.google.common.graph.AbstractBaseGraph" : "AbstractBaseGraph", + "com.google.common.graph.AbstractDirectedNetworkConnections" : "AbstractDirectedNetworkConnections", + "com.google.common.graph.AbstractGraph" : "AbstractGraph", + "com.google.common.graph.AbstractGraphBuilder" : "AbstractGraphBuilder", + "com.google.common.graph.AbstractNetwork" : "AbstractNetwork", + "com.google.common.graph.AbstractUndirectedNetworkConnections" : "AbstractUndirectedNetworkConnections", + "com.google.common.graph.AbstractValueGraph" : "AbstractValueGraph", + "com.google.common.graph.BaseGraph" : "BaseGraph", + "com.google.common.graph.DirectedGraphConnections" : "DirectedGraphConnections", + "com.google.common.graph.DirectedGraphConnections$NodeConnection" : "DirectedGraphConnections.NodeConnection", + "com.google.common.graph.DirectedGraphConnections$NodeConnection$Pred" : "DirectedGraphConnections.NodeConnection.Pred", + "com.google.common.graph.DirectedGraphConnections$NodeConnection$Succ" : "DirectedGraphConnections.NodeConnection.Succ", + "com.google.common.graph.DirectedGraphConnections$PredAndSucc" : "DirectedGraphConnections.PredAndSucc", + "com.google.common.graph.DirectedMultiNetworkConnections" : "DirectedMultiNetworkConnections", + "com.google.common.graph.DirectedNetworkConnections" : "DirectedNetworkConnections", + "com.google.common.graph.EdgesConnecting" : "EdgesConnecting", + "com.google.common.graph.ElementOrder" : "ElementOrder", + "com.google.common.graph.ElementOrder$Type" : "ElementOrder.Type", + "com.google.common.graph.ElementTypesAreNonnullByDefault" : "ElementTypesAreNonnullByDefault", + "com.google.common.graph.EndpointPair" : "EndpointPair", + "com.google.common.graph.EndpointPair$Ordered" : "EndpointPair.Ordered", + "com.google.common.graph.EndpointPair$Unordered" : "EndpointPair.Unordered", + "com.google.common.graph.EndpointPairIterator" : "EndpointPairIterator", + "com.google.common.graph.EndpointPairIterator$Directed" : "EndpointPairIterator.Directed", + "com.google.common.graph.EndpointPairIterator$Undirected" : "EndpointPairIterator.Undirected", + "com.google.common.graph.ForwardingGraph" : "ForwardingGraph", + "com.google.common.graph.ForwardingNetwork" : "ForwardingNetwork", + "com.google.common.graph.ForwardingValueGraph" : "ForwardingValueGraph", + "com.google.common.graph.Graph" : "Graph", + "com.google.common.graph.GraphBuilder" : "GraphBuilder", + "com.google.common.graph.GraphConnections" : "GraphConnections", + "com.google.common.graph.GraphConstants" : "GraphConstants", + "com.google.common.graph.GraphConstants$Presence" : "GraphConstants.Presence", + "com.google.common.graph.Graphs" : "Graphs", + "com.google.common.graph.Graphs$NodeAndRemainingSuccessors" : "Graphs.NodeAndRemainingSuccessors", + "com.google.common.graph.Graphs$NodeVisitState" : "Graphs.NodeVisitState", + "com.google.common.graph.Graphs$TransposedGraph" : "Graphs.TransposedGraph", + "com.google.common.graph.Graphs$TransposedNetwork" : "Graphs.TransposedNetwork", + "com.google.common.graph.Graphs$TransposedValueGraph" : "Graphs.TransposedValueGraph", + "com.google.common.graph.GraphsBridgeMethods" : "GraphsBridgeMethods", + "com.google.common.graph.ImmutableGraph" : "ImmutableGraph", + "com.google.common.graph.ImmutableGraph$Builder" : "ImmutableGraph.Builder", + "com.google.common.graph.ImmutableNetwork" : "ImmutableNetwork", + "com.google.common.graph.ImmutableNetwork$Builder" : "ImmutableNetwork.Builder", + "com.google.common.graph.ImmutableValueGraph" : "ImmutableValueGraph", + "com.google.common.graph.ImmutableValueGraph$Builder" : "ImmutableValueGraph.Builder", + "com.google.common.graph.IncidentEdgeSet" : "IncidentEdgeSet", + "com.google.common.graph.InvalidatableSet" : "InvalidatableSet", + "com.google.common.graph.MapIteratorCache" : "MapIteratorCache", + "com.google.common.graph.MapRetrievalCache" : "MapRetrievalCache", + "com.google.common.graph.MapRetrievalCache$CacheEntry" : "MapRetrievalCache.CacheEntry", + "com.google.common.graph.MultiEdgesConnecting" : "MultiEdgesConnecting", + "com.google.common.graph.MutableGraph" : "MutableGraph", + "com.google.common.graph.MutableNetwork" : "MutableNetwork", + "com.google.common.graph.MutableValueGraph" : "MutableValueGraph", + "com.google.common.graph.Network" : "Network", + "com.google.common.graph.NetworkBuilder" : "NetworkBuilder", + "com.google.common.graph.NetworkConnections" : "NetworkConnections", + "com.google.common.graph.ParametricNullness" : "ParametricNullness", + "com.google.common.graph.PredecessorsFunction" : "PredecessorsFunction", + "com.google.common.graph.StandardMutableGraph" : "StandardMutableGraph", + "com.google.common.graph.StandardMutableNetwork" : "StandardMutableNetwork", + "com.google.common.graph.StandardMutableValueGraph" : "StandardMutableValueGraph", + "com.google.common.graph.StandardNetwork" : "StandardNetwork", + "com.google.common.graph.StandardValueGraph" : "StandardValueGraph", + "com.google.common.graph.SuccessorsFunction" : "SuccessorsFunction", + "com.google.common.graph.Traverser" : "Traverser", + "com.google.common.graph.Traverser$InsertionOrder" : "Traverser.InsertionOrder", + "com.google.common.graph.Traverser$Traversal" : "Traverser.Traversal", + "com.google.common.graph.UndirectedGraphConnections" : "UndirectedGraphConnections", + "com.google.common.graph.UndirectedMultiNetworkConnections" : "UndirectedMultiNetworkConnections", + "com.google.common.graph.UndirectedNetworkConnections" : "UndirectedNetworkConnections", + "com.google.common.graph.ValueGraph" : "ValueGraph", + "com.google.common.graph.ValueGraphBuilder" : "ValueGraphBuilder", + "com.google.common.graph.package-info" : "package-info", + "com.google.common.hash.AbstractByteHasher" : "AbstractByteHasher", + "com.google.common.hash.AbstractCompositeHashFunction" : "AbstractCompositeHashFunction", + "com.google.common.hash.AbstractHashFunction" : "AbstractHashFunction", + "com.google.common.hash.AbstractHasher" : "AbstractHasher", + "com.google.common.hash.AbstractNonStreamingHashFunction" : "AbstractNonStreamingHashFunction", + "com.google.common.hash.AbstractNonStreamingHashFunction$BufferingHasher" : "AbstractNonStreamingHashFunction.BufferingHasher", + "com.google.common.hash.AbstractNonStreamingHashFunction$ExposedByteArrayOutputStream" : "AbstractNonStreamingHashFunction.ExposedByteArrayOutputStream", + "com.google.common.hash.AbstractStreamingHasher" : "AbstractStreamingHasher", + "com.google.common.hash.BloomFilter" : "BloomFilter", + "com.google.common.hash.BloomFilter$SerialForm" : "BloomFilter.SerialForm", + "com.google.common.hash.BloomFilter$Strategy" : "BloomFilter.Strategy", + "com.google.common.hash.BloomFilterStrategies" : "BloomFilterStrategies", + "com.google.common.hash.BloomFilterStrategies$LockFreeBitArray" : "BloomFilterStrategies.LockFreeBitArray", + "com.google.common.hash.ChecksumHashFunction" : "ChecksumHashFunction", + "com.google.common.hash.ChecksumHashFunction$ChecksumHasher" : "ChecksumHashFunction.ChecksumHasher", + "com.google.common.hash.ChecksumHashFunction$ChecksumMethodHandles" : "ChecksumHashFunction.ChecksumMethodHandles", + "com.google.common.hash.Crc32cHashFunction" : "Crc32cHashFunction", + "com.google.common.hash.Crc32cHashFunction$Crc32cHasher" : "Crc32cHashFunction.Crc32cHasher", + "com.google.common.hash.ElementTypesAreNonnullByDefault" : "ElementTypesAreNonnullByDefault", + "com.google.common.hash.FarmHashFingerprint64" : "FarmHashFingerprint64", + "com.google.common.hash.Fingerprint2011" : "Fingerprint2011", + "com.google.common.hash.Funnel" : "Funnel", + "com.google.common.hash.Funnels" : "Funnels", + "com.google.common.hash.Funnels$ByteArrayFunnel" : "Funnels.ByteArrayFunnel", + "com.google.common.hash.Funnels$IntegerFunnel" : "Funnels.IntegerFunnel", + "com.google.common.hash.Funnels$LongFunnel" : "Funnels.LongFunnel", + "com.google.common.hash.Funnels$SequentialFunnel" : "Funnels.SequentialFunnel", + "com.google.common.hash.Funnels$SinkAsStream" : "Funnels.SinkAsStream", + "com.google.common.hash.Funnels$StringCharsetFunnel" : "Funnels.StringCharsetFunnel", + "com.google.common.hash.Funnels$StringCharsetFunnel$SerializedForm" : "Funnels.StringCharsetFunnel.SerializedForm", + "com.google.common.hash.Funnels$UnencodedCharsFunnel" : "Funnels.UnencodedCharsFunnel", + "com.google.common.hash.HashCode" : "HashCode", + "com.google.common.hash.HashCode$BytesHashCode" : "HashCode.BytesHashCode", + "com.google.common.hash.HashCode$IntHashCode" : "HashCode.IntHashCode", + "com.google.common.hash.HashCode$LongHashCode" : "HashCode.LongHashCode", + "com.google.common.hash.HashFunction" : "HashFunction", + "com.google.common.hash.Hasher" : "Hasher", + "com.google.common.hash.Hashing" : "Hashing", + "com.google.common.hash.Hashing$ChecksumType" : "Hashing.ChecksumType", + "com.google.common.hash.Hashing$ConcatenatedHashFunction" : "Hashing.ConcatenatedHashFunction", + "com.google.common.hash.Hashing$Crc32CSupplier" : "Hashing.Crc32CSupplier", + "com.google.common.hash.Hashing$Crc32cMethodHandles" : "Hashing.Crc32cMethodHandles", + "com.google.common.hash.Hashing$LinearCongruentialGenerator" : "Hashing.LinearCongruentialGenerator", + "com.google.common.hash.Hashing$Md5Holder" : "Hashing.Md5Holder", + "com.google.common.hash.Hashing$Sha1Holder" : "Hashing.Sha1Holder", + "com.google.common.hash.Hashing$Sha256Holder" : "Hashing.Sha256Holder", + "com.google.common.hash.Hashing$Sha384Holder" : "Hashing.Sha384Holder", + "com.google.common.hash.Hashing$Sha512Holder" : "Hashing.Sha512Holder", + "com.google.common.hash.HashingInputStream" : "HashingInputStream", + "com.google.common.hash.HashingOutputStream" : "HashingOutputStream", + "com.google.common.hash.IgnoreJRERequirement" : "IgnoreJRERequirement", + "com.google.common.hash.ImmutableSupplier" : "ImmutableSupplier", + "com.google.common.hash.Java8Compatibility" : "Java8Compatibility", + "com.google.common.hash.LittleEndianByteArray" : "LittleEndianByteArray", + "com.google.common.hash.LittleEndianByteArray$JavaLittleEndianBytes" : "LittleEndianByteArray.JavaLittleEndianBytes", + "com.google.common.hash.LittleEndianByteArray$LittleEndianBytes" : "LittleEndianByteArray.LittleEndianBytes", + "com.google.common.hash.LittleEndianByteArray$UnsafeByteArray" : "LittleEndianByteArray.UnsafeByteArray", + "com.google.common.hash.LongAddable" : "LongAddable", + "com.google.common.hash.LongAddables" : "LongAddables", + "com.google.common.hash.LongAddables$PureJavaLongAddable" : "LongAddables.PureJavaLongAddable", + "com.google.common.hash.LongAdder" : "LongAdder", + "com.google.common.hash.MacHashFunction" : "MacHashFunction", + "com.google.common.hash.MacHashFunction$MacHasher" : "MacHashFunction.MacHasher", + "com.google.common.hash.MessageDigestHashFunction" : "MessageDigestHashFunction", + "com.google.common.hash.MessageDigestHashFunction$MessageDigestHasher" : "MessageDigestHashFunction.MessageDigestHasher", + "com.google.common.hash.MessageDigestHashFunction$SerializedForm" : "MessageDigestHashFunction.SerializedForm", + "com.google.common.hash.Murmur3_128HashFunction" : "Murmur3_128HashFunction", + "com.google.common.hash.Murmur3_128HashFunction$Murmur3_128Hasher" : "Murmur3_128HashFunction.Murmur3_128Hasher", + "com.google.common.hash.Murmur3_32HashFunction" : "Murmur3_32HashFunction", + "com.google.common.hash.Murmur3_32HashFunction$Murmur3_32Hasher" : "Murmur3_32HashFunction.Murmur3_32Hasher", + "com.google.common.hash.ParametricNullness" : "ParametricNullness", + "com.google.common.hash.PrimitiveSink" : "PrimitiveSink", + "com.google.common.hash.SipHashFunction" : "SipHashFunction", + "com.google.common.hash.SipHashFunction$SipHasher" : "SipHashFunction.SipHasher", + "com.google.common.hash.Striped64" : "Striped64", + "com.google.common.hash.Striped64$Cell" : "Striped64.Cell", + "com.google.common.hash.package-info" : "package-info", + "com.google.common.html.ElementTypesAreNonnullByDefault" : "ElementTypesAreNonnullByDefault", + "com.google.common.html.HtmlEscapers" : "HtmlEscapers", + "com.google.common.html.ParametricNullness" : "ParametricNullness", + "com.google.common.html.package-info" : "package-info", + "com.google.common.io.AppendableWriter" : "AppendableWriter", + "com.google.common.io.BaseEncoding" : "BaseEncoding", + "com.google.common.io.BaseEncoding$Alphabet" : "BaseEncoding.Alphabet", + "com.google.common.io.BaseEncoding$Base16Encoding" : "BaseEncoding.Base16Encoding", + "com.google.common.io.BaseEncoding$Base64Encoding" : "BaseEncoding.Base64Encoding", + "com.google.common.io.BaseEncoding$DecodingException" : "BaseEncoding.DecodingException", + "com.google.common.io.BaseEncoding$SeparatedBaseEncoding" : "BaseEncoding.SeparatedBaseEncoding", + "com.google.common.io.BaseEncoding$StandardBaseEncoding" : "BaseEncoding.StandardBaseEncoding", + "com.google.common.io.ByteArrayDataInput" : "ByteArrayDataInput", + "com.google.common.io.ByteArrayDataOutput" : "ByteArrayDataOutput", + "com.google.common.io.ByteProcessor" : "ByteProcessor", + "com.google.common.io.ByteSink" : "ByteSink", + "com.google.common.io.ByteSink$AsCharSink" : "ByteSink.AsCharSink", + "com.google.common.io.ByteSource" : "ByteSource", + "com.google.common.io.ByteSource$AsCharSource" : "ByteSource.AsCharSource", + "com.google.common.io.ByteSource$ByteArrayByteSource" : "ByteSource.ByteArrayByteSource", + "com.google.common.io.ByteSource$ConcatenatedByteSource" : "ByteSource.ConcatenatedByteSource", + "com.google.common.io.ByteSource$EmptyByteSource" : "ByteSource.EmptyByteSource", + "com.google.common.io.ByteSource$SlicedByteSource" : "ByteSource.SlicedByteSource", + "com.google.common.io.ByteStreams" : "ByteStreams", + "com.google.common.io.ByteStreams$ByteArrayDataInputStream" : "ByteStreams.ByteArrayDataInputStream", + "com.google.common.io.ByteStreams$ByteArrayDataOutputStream" : "ByteStreams.ByteArrayDataOutputStream", + "com.google.common.io.ByteStreams$LimitedInputStream" : "ByteStreams.LimitedInputStream", + "com.google.common.io.CharSequenceReader" : "CharSequenceReader", + "com.google.common.io.CharSink" : "CharSink", + "com.google.common.io.CharSource" : "CharSource", + "com.google.common.io.CharSource$AsByteSource" : "CharSource.AsByteSource", + "com.google.common.io.CharSource$CharSequenceCharSource" : "CharSource.CharSequenceCharSource", + "com.google.common.io.CharSource$ConcatenatedCharSource" : "CharSource.ConcatenatedCharSource", + "com.google.common.io.CharSource$EmptyCharSource" : "CharSource.EmptyCharSource", + "com.google.common.io.CharSource$StringCharSource" : "CharSource.StringCharSource", + "com.google.common.io.CharStreams" : "CharStreams", + "com.google.common.io.CharStreams$NullWriter" : "CharStreams.NullWriter", + "com.google.common.io.Closeables" : "Closeables", + "com.google.common.io.Closer" : "Closer", + "com.google.common.io.Closer$Suppressor" : "Closer.Suppressor", + "com.google.common.io.CountingInputStream" : "CountingInputStream", + "com.google.common.io.CountingOutputStream" : "CountingOutputStream", + "com.google.common.io.ElementTypesAreNonnullByDefault" : "ElementTypesAreNonnullByDefault", + "com.google.common.io.FileBackedOutputStream" : "FileBackedOutputStream", + "com.google.common.io.FileBackedOutputStream$MemoryOutput" : "FileBackedOutputStream.MemoryOutput", + "com.google.common.io.FileWriteMode" : "FileWriteMode", + "com.google.common.io.Files" : "Files", + "com.google.common.io.Files$FileByteSink" : "Files.FileByteSink", + "com.google.common.io.Files$FileByteSource" : "Files.FileByteSource", + "com.google.common.io.Files$FilePredicate" : "Files.FilePredicate", + "com.google.common.io.Flushables" : "Flushables", + "com.google.common.io.IgnoreJRERequirement" : "IgnoreJRERequirement", + "com.google.common.io.InsecureRecursiveDeleteException" : "InsecureRecursiveDeleteException", + "com.google.common.io.Java8Compatibility" : "Java8Compatibility", + "com.google.common.io.LineBuffer" : "LineBuffer", + "com.google.common.io.LineProcessor" : "LineProcessor", + "com.google.common.io.LineReader" : "LineReader", + "com.google.common.io.LittleEndianDataInputStream" : "LittleEndianDataInputStream", + "com.google.common.io.LittleEndianDataOutputStream" : "LittleEndianDataOutputStream", + "com.google.common.io.MoreFiles" : "MoreFiles", + "com.google.common.io.MoreFiles$PathByteSink" : "MoreFiles.PathByteSink", + "com.google.common.io.MoreFiles$PathByteSource" : "MoreFiles.PathByteSource", + "com.google.common.io.MultiInputStream" : "MultiInputStream", + "com.google.common.io.MultiReader" : "MultiReader", + "com.google.common.io.ParametricNullness" : "ParametricNullness", + "com.google.common.io.PatternFilenameFilter" : "PatternFilenameFilter", + "com.google.common.io.ReaderInputStream" : "ReaderInputStream", + "com.google.common.io.RecursiveDeleteOption" : "RecursiveDeleteOption", + "com.google.common.io.Resources" : "Resources", + "com.google.common.io.Resources$UrlByteSource" : "Resources.UrlByteSource", + "com.google.common.io.TempFileCreator" : "TempFileCreator", + "com.google.common.io.TempFileCreator$JavaIoCreator" : "TempFileCreator.JavaIoCreator", + "com.google.common.io.TempFileCreator$JavaNioCreator" : "TempFileCreator.JavaNioCreator", + "com.google.common.io.TempFileCreator$JavaNioCreator$PermissionSupplier" : "TempFileCreator.JavaNioCreator.PermissionSupplier", + "com.google.common.io.TempFileCreator$ThrowingCreator" : "TempFileCreator.ThrowingCreator", + "com.google.common.io.package-info" : "package-info", + "com.google.common.math.BigDecimalMath" : "BigDecimalMath", + "com.google.common.math.BigDecimalMath$BigDecimalToDoubleRounder" : "BigDecimalMath.BigDecimalToDoubleRounder", + "com.google.common.math.BigIntegerMath" : "BigIntegerMath", + "com.google.common.math.BigIntegerMath$BigIntegerToDoubleRounder" : "BigIntegerMath.BigIntegerToDoubleRounder", + "com.google.common.math.DoubleMath" : "DoubleMath", + "com.google.common.math.DoubleUtils" : "DoubleUtils", + "com.google.common.math.ElementTypesAreNonnullByDefault" : "ElementTypesAreNonnullByDefault", + "com.google.common.math.IntMath" : "IntMath", + "com.google.common.math.LinearTransformation" : "LinearTransformation", + "com.google.common.math.LinearTransformation$LinearTransformationBuilder" : "LinearTransformation.LinearTransformationBuilder", + "com.google.common.math.LinearTransformation$NaNLinearTransformation" : "LinearTransformation.NaNLinearTransformation", + "com.google.common.math.LinearTransformation$RegularLinearTransformation" : "LinearTransformation.RegularLinearTransformation", + "com.google.common.math.LinearTransformation$VerticalLinearTransformation" : "LinearTransformation.VerticalLinearTransformation", + "com.google.common.math.LongMath" : "LongMath", + "com.google.common.math.LongMath$MillerRabinTester" : "LongMath.MillerRabinTester", + "com.google.common.math.MathPreconditions" : "MathPreconditions", + "com.google.common.math.PairedStats" : "PairedStats", + "com.google.common.math.PairedStatsAccumulator" : "PairedStatsAccumulator", + "com.google.common.math.ParametricNullness" : "ParametricNullness", + "com.google.common.math.Quantiles" : "Quantiles", + "com.google.common.math.Quantiles$Scale" : "Quantiles.Scale", + "com.google.common.math.Quantiles$ScaleAndIndex" : "Quantiles.ScaleAndIndex", + "com.google.common.math.Quantiles$ScaleAndIndexes" : "Quantiles.ScaleAndIndexes", + "com.google.common.math.Stats" : "Stats", + "com.google.common.math.StatsAccumulator" : "StatsAccumulator", + "com.google.common.math.ToDoubleRounder" : "ToDoubleRounder", + "com.google.common.math.package-info" : "package-info", + "com.google.common.net.ElementTypesAreNonnullByDefault" : "ElementTypesAreNonnullByDefault", + "com.google.common.net.HostAndPort" : "HostAndPort", + "com.google.common.net.HostSpecifier" : "HostSpecifier", + "com.google.common.net.HttpHeaders" : "HttpHeaders", + "com.google.common.net.HttpHeaders$ReferrerPolicyValues" : "HttpHeaders.ReferrerPolicyValues", + "com.google.common.net.InetAddresses" : "InetAddresses", + "com.google.common.net.InetAddresses$Scope" : "InetAddresses.Scope", + "com.google.common.net.InetAddresses$TeredoInfo" : "InetAddresses.TeredoInfo", + "com.google.common.net.InternetDomainName" : "InternetDomainName", + "com.google.common.net.MediaType" : "MediaType", + "com.google.common.net.MediaType$Tokenizer" : "MediaType.Tokenizer", + "com.google.common.net.ParametricNullness" : "ParametricNullness", + "com.google.common.net.PercentEscaper" : "PercentEscaper", + "com.google.common.net.UrlEscapers" : "UrlEscapers", + "com.google.common.net.package-info" : "package-info", + "com.google.common.primitives.Booleans" : "Booleans", + "com.google.common.primitives.Booleans$BooleanArrayAsList" : "Booleans.BooleanArrayAsList", + "com.google.common.primitives.Booleans$BooleanComparator" : "Booleans.BooleanComparator", + "com.google.common.primitives.Booleans$LexicographicalComparator" : "Booleans.LexicographicalComparator", + "com.google.common.primitives.Bytes" : "Bytes", + "com.google.common.primitives.Bytes$ByteArrayAsList" : "Bytes.ByteArrayAsList", + "com.google.common.primitives.Chars" : "Chars", + "com.google.common.primitives.Chars$CharArrayAsList" : "Chars.CharArrayAsList", + "com.google.common.primitives.Chars$LexicographicalComparator" : "Chars.LexicographicalComparator", + "com.google.common.primitives.Doubles" : "Doubles", + "com.google.common.primitives.Doubles$DoubleArrayAsList" : "Doubles.DoubleArrayAsList", + "com.google.common.primitives.Doubles$DoubleConverter" : "Doubles.DoubleConverter", + "com.google.common.primitives.Doubles$LexicographicalComparator" : "Doubles.LexicographicalComparator", + "com.google.common.primitives.DoublesMethodsForWeb" : "DoublesMethodsForWeb", + "com.google.common.primitives.ElementTypesAreNonnullByDefault" : "ElementTypesAreNonnullByDefault", + "com.google.common.primitives.Floats" : "Floats", + "com.google.common.primitives.Floats$FloatArrayAsList" : "Floats.FloatArrayAsList", + "com.google.common.primitives.Floats$FloatConverter" : "Floats.FloatConverter", + "com.google.common.primitives.Floats$LexicographicalComparator" : "Floats.LexicographicalComparator", + "com.google.common.primitives.FloatsMethodsForWeb" : "FloatsMethodsForWeb", + "com.google.common.primitives.ImmutableDoubleArray" : "ImmutableDoubleArray", + "com.google.common.primitives.ImmutableDoubleArray$AsList" : "ImmutableDoubleArray.AsList", + "com.google.common.primitives.ImmutableDoubleArray$Builder" : "ImmutableDoubleArray.Builder", + "com.google.common.primitives.ImmutableIntArray" : "ImmutableIntArray", + "com.google.common.primitives.ImmutableIntArray$AsList" : "ImmutableIntArray.AsList", + "com.google.common.primitives.ImmutableIntArray$Builder" : "ImmutableIntArray.Builder", + "com.google.common.primitives.ImmutableLongArray" : "ImmutableLongArray", + "com.google.common.primitives.ImmutableLongArray$AsList" : "ImmutableLongArray.AsList", + "com.google.common.primitives.ImmutableLongArray$Builder" : "ImmutableLongArray.Builder", + "com.google.common.primitives.Ints" : "Ints", + "com.google.common.primitives.Ints$IntArrayAsList" : "Ints.IntArrayAsList", + "com.google.common.primitives.Ints$IntConverter" : "Ints.IntConverter", + "com.google.common.primitives.Ints$LexicographicalComparator" : "Ints.LexicographicalComparator", + "com.google.common.primitives.IntsMethodsForWeb" : "IntsMethodsForWeb", + "com.google.common.primitives.Longs" : "Longs", + "com.google.common.primitives.Longs$AsciiDigits" : "Longs.AsciiDigits", + "com.google.common.primitives.Longs$LexicographicalComparator" : "Longs.LexicographicalComparator", + "com.google.common.primitives.Longs$LongArrayAsList" : "Longs.LongArrayAsList", + "com.google.common.primitives.Longs$LongConverter" : "Longs.LongConverter", + "com.google.common.primitives.ParametricNullness" : "ParametricNullness", + "com.google.common.primitives.ParseRequest" : "ParseRequest", + "com.google.common.primitives.Primitives" : "Primitives", + "com.google.common.primitives.Shorts" : "Shorts", + "com.google.common.primitives.Shorts$LexicographicalComparator" : "Shorts.LexicographicalComparator", + "com.google.common.primitives.Shorts$ShortArrayAsList" : "Shorts.ShortArrayAsList", + "com.google.common.primitives.Shorts$ShortConverter" : "Shorts.ShortConverter", + "com.google.common.primitives.ShortsMethodsForWeb" : "ShortsMethodsForWeb", + "com.google.common.primitives.SignedBytes" : "SignedBytes", + "com.google.common.primitives.SignedBytes$LexicographicalComparator" : "SignedBytes.LexicographicalComparator", + "com.google.common.primitives.UnsignedBytes" : "UnsignedBytes", + "com.google.common.primitives.UnsignedBytes$LexicographicalComparatorHolder" : "UnsignedBytes.LexicographicalComparatorHolder", + "com.google.common.primitives.UnsignedBytes$LexicographicalComparatorHolder$PureJavaComparator" : "UnsignedBytes.LexicographicalComparatorHolder.PureJavaComparator", + "com.google.common.primitives.UnsignedBytes$LexicographicalComparatorHolder$UnsafeComparator" : "UnsignedBytes.LexicographicalComparatorHolder.UnsafeComparator", + "com.google.common.primitives.UnsignedInteger" : "UnsignedInteger", + "com.google.common.primitives.UnsignedInts" : "UnsignedInts", + "com.google.common.primitives.UnsignedInts$LexicographicalComparator" : "UnsignedInts.LexicographicalComparator", + "com.google.common.primitives.UnsignedLong" : "UnsignedLong", + "com.google.common.primitives.UnsignedLongs" : "UnsignedLongs", + "com.google.common.primitives.UnsignedLongs$LexicographicalComparator" : "UnsignedLongs.LexicographicalComparator", + "com.google.common.primitives.UnsignedLongs$ParseOverflowDetection" : "UnsignedLongs.ParseOverflowDetection", + "com.google.common.primitives.package-info" : "package-info", + "com.google.common.reflect.AbstractInvocationHandler" : "AbstractInvocationHandler", + "com.google.common.reflect.ClassPath" : "ClassPath", + "com.google.common.reflect.ClassPath$ClassInfo" : "ClassPath.ClassInfo", + "com.google.common.reflect.ClassPath$LocationInfo" : "ClassPath.LocationInfo", + "com.google.common.reflect.ClassPath$ResourceInfo" : "ClassPath.ResourceInfo", + "com.google.common.reflect.ElementTypesAreNonnullByDefault" : "ElementTypesAreNonnullByDefault", + "com.google.common.reflect.IgnoreJRERequirement" : "IgnoreJRERequirement", + "com.google.common.reflect.ImmutableTypeToInstanceMap" : "ImmutableTypeToInstanceMap", + "com.google.common.reflect.ImmutableTypeToInstanceMap$Builder" : "ImmutableTypeToInstanceMap.Builder", + "com.google.common.reflect.Invokable" : "Invokable", + "com.google.common.reflect.Invokable$ConstructorInvokable" : "Invokable.ConstructorInvokable", + "com.google.common.reflect.Invokable$MethodInvokable" : "Invokable.MethodInvokable", + "com.google.common.reflect.MutableTypeToInstanceMap" : "MutableTypeToInstanceMap", + "com.google.common.reflect.MutableTypeToInstanceMap$UnmodifiableEntry" : "MutableTypeToInstanceMap.UnmodifiableEntry", + "com.google.common.reflect.Parameter" : "Parameter", + "com.google.common.reflect.ParametricNullness" : "ParametricNullness", + "com.google.common.reflect.Reflection" : "Reflection", + "com.google.common.reflect.TypeCapture" : "TypeCapture", + "com.google.common.reflect.TypeParameter" : "TypeParameter", + "com.google.common.reflect.TypeResolver" : "TypeResolver", + "com.google.common.reflect.TypeResolver$TypeMappingIntrospector" : "TypeResolver.TypeMappingIntrospector", + "com.google.common.reflect.TypeResolver$TypeTable" : "TypeResolver.TypeTable", + "com.google.common.reflect.TypeResolver$TypeVariableKey" : "TypeResolver.TypeVariableKey", + "com.google.common.reflect.TypeResolver$WildcardCapturer" : "TypeResolver.WildcardCapturer", + "com.google.common.reflect.TypeToInstanceMap" : "TypeToInstanceMap", + "com.google.common.reflect.TypeToken" : "TypeToken", + "com.google.common.reflect.TypeToken$Bounds" : "TypeToken.Bounds", + "com.google.common.reflect.TypeToken$ClassSet" : "TypeToken.ClassSet", + "com.google.common.reflect.TypeToken$InterfaceSet" : "TypeToken.InterfaceSet", + "com.google.common.reflect.TypeToken$SimpleTypeToken" : "TypeToken.SimpleTypeToken", + "com.google.common.reflect.TypeToken$TypeCollector" : "TypeToken.TypeCollector", + "com.google.common.reflect.TypeToken$TypeCollector$ForwardingTypeCollector" : "TypeToken.TypeCollector.ForwardingTypeCollector", + "com.google.common.reflect.TypeToken$TypeFilter" : "TypeToken.TypeFilter", + "com.google.common.reflect.TypeToken$TypeSet" : "TypeToken.TypeSet", + "com.google.common.reflect.TypeVisitor" : "TypeVisitor", + "com.google.common.reflect.Types" : "Types", + "com.google.common.reflect.Types$ClassOwnership" : "Types.ClassOwnership", + "com.google.common.reflect.Types$GenericArrayTypeImpl" : "Types.GenericArrayTypeImpl", + "com.google.common.reflect.Types$JavaVersion" : "Types.JavaVersion", + "com.google.common.reflect.Types$NativeTypeVariableEquals" : "Types.NativeTypeVariableEquals", + "com.google.common.reflect.Types$ParameterizedTypeImpl" : "Types.ParameterizedTypeImpl", + "com.google.common.reflect.Types$TypeVariableImpl" : "Types.TypeVariableImpl", + "com.google.common.reflect.Types$TypeVariableInvocationHandler" : "Types.TypeVariableInvocationHandler", + "com.google.common.reflect.Types$WildcardTypeImpl" : "Types.WildcardTypeImpl", + "com.google.common.reflect.package-info" : "package-info", + "com.google.common.util.concurrent.AbstractCatchingFuture" : "AbstractCatchingFuture", + "com.google.common.util.concurrent.AbstractCatchingFuture$AsyncCatchingFuture" : "AbstractCatchingFuture.AsyncCatchingFuture", + "com.google.common.util.concurrent.AbstractCatchingFuture$CatchingFuture" : "AbstractCatchingFuture.CatchingFuture", + "com.google.common.util.concurrent.AbstractExecutionThreadService" : "AbstractExecutionThreadService", + "com.google.common.util.concurrent.AbstractFuture" : "AbstractFuture", + "com.google.common.util.concurrent.AbstractFuture$AtomicHelper" : "AbstractFuture.AtomicHelper", + "com.google.common.util.concurrent.AbstractFuture$Cancellation" : "AbstractFuture.Cancellation", + "com.google.common.util.concurrent.AbstractFuture$Failure" : "AbstractFuture.Failure", + "com.google.common.util.concurrent.AbstractFuture$Listener" : "AbstractFuture.Listener", + "com.google.common.util.concurrent.AbstractFuture$SafeAtomicHelper" : "AbstractFuture.SafeAtomicHelper", + "com.google.common.util.concurrent.AbstractFuture$SetFuture" : "AbstractFuture.SetFuture", + "com.google.common.util.concurrent.AbstractFuture$SynchronizedHelper" : "AbstractFuture.SynchronizedHelper", + "com.google.common.util.concurrent.AbstractFuture$Trusted" : "AbstractFuture.Trusted", + "com.google.common.util.concurrent.AbstractFuture$TrustedFuture" : "AbstractFuture.TrustedFuture", + "com.google.common.util.concurrent.AbstractFuture$UnsafeAtomicHelper" : "AbstractFuture.UnsafeAtomicHelper", + "com.google.common.util.concurrent.AbstractFuture$Waiter" : "AbstractFuture.Waiter", + "com.google.common.util.concurrent.AbstractIdleService" : "AbstractIdleService", + "com.google.common.util.concurrent.AbstractIdleService$DelegateService" : "AbstractIdleService.DelegateService", + "com.google.common.util.concurrent.AbstractIdleService$ThreadNameSupplier" : "AbstractIdleService.ThreadNameSupplier", + "com.google.common.util.concurrent.AbstractListeningExecutorService" : "AbstractListeningExecutorService", + "com.google.common.util.concurrent.AbstractScheduledService" : "AbstractScheduledService", + "com.google.common.util.concurrent.AbstractScheduledService$Cancellable" : "AbstractScheduledService.Cancellable", + "com.google.common.util.concurrent.AbstractScheduledService$CustomScheduler" : "AbstractScheduledService.CustomScheduler", + "com.google.common.util.concurrent.AbstractScheduledService$CustomScheduler$ReschedulableCallable" : "AbstractScheduledService.CustomScheduler.ReschedulableCallable", + "com.google.common.util.concurrent.AbstractScheduledService$CustomScheduler$Schedule" : "AbstractScheduledService.CustomScheduler.Schedule", + "com.google.common.util.concurrent.AbstractScheduledService$CustomScheduler$SupplantableFuture" : "AbstractScheduledService.CustomScheduler.SupplantableFuture", + "com.google.common.util.concurrent.AbstractScheduledService$FutureAsCancellable" : "AbstractScheduledService.FutureAsCancellable", + "com.google.common.util.concurrent.AbstractScheduledService$Scheduler" : "AbstractScheduledService.Scheduler", + "com.google.common.util.concurrent.AbstractScheduledService$ServiceDelegate" : "AbstractScheduledService.ServiceDelegate", + "com.google.common.util.concurrent.AbstractScheduledService$ServiceDelegate$Task" : "AbstractScheduledService.ServiceDelegate.Task", + "com.google.common.util.concurrent.AbstractService" : "AbstractService", + "com.google.common.util.concurrent.AbstractService$HasReachedRunningGuard" : "AbstractService.HasReachedRunningGuard", + "com.google.common.util.concurrent.AbstractService$IsStartableGuard" : "AbstractService.IsStartableGuard", + "com.google.common.util.concurrent.AbstractService$IsStoppableGuard" : "AbstractService.IsStoppableGuard", + "com.google.common.util.concurrent.AbstractService$IsStoppedGuard" : "AbstractService.IsStoppedGuard", + "com.google.common.util.concurrent.AbstractService$StateSnapshot" : "AbstractService.StateSnapshot", + "com.google.common.util.concurrent.AbstractTransformFuture" : "AbstractTransformFuture", + "com.google.common.util.concurrent.AbstractTransformFuture$AsyncTransformFuture" : "AbstractTransformFuture.AsyncTransformFuture", + "com.google.common.util.concurrent.AbstractTransformFuture$TransformFuture" : "AbstractTransformFuture.TransformFuture", + "com.google.common.util.concurrent.AggregateFuture" : "AggregateFuture", + "com.google.common.util.concurrent.AggregateFuture$ReleaseResourcesReason" : "AggregateFuture.ReleaseResourcesReason", + "com.google.common.util.concurrent.AggregateFutureState" : "AggregateFutureState", + "com.google.common.util.concurrent.AggregateFutureState$AtomicHelper" : "AggregateFutureState.AtomicHelper", + "com.google.common.util.concurrent.AggregateFutureState$SafeAtomicHelper" : "AggregateFutureState.SafeAtomicHelper", + "com.google.common.util.concurrent.AggregateFutureState$SynchronizedAtomicHelper" : "AggregateFutureState.SynchronizedAtomicHelper", + "com.google.common.util.concurrent.AsyncCallable" : "AsyncCallable", + "com.google.common.util.concurrent.AsyncFunction" : "AsyncFunction", + "com.google.common.util.concurrent.AtomicDouble" : "AtomicDouble", + "com.google.common.util.concurrent.AtomicDoubleArray" : "AtomicDoubleArray", + "com.google.common.util.concurrent.AtomicLongMap" : "AtomicLongMap", + "com.google.common.util.concurrent.Atomics" : "Atomics", + "com.google.common.util.concurrent.Callables" : "Callables", + "com.google.common.util.concurrent.ClosingFuture" : "ClosingFuture", + "com.google.common.util.concurrent.ClosingFuture$AsyncClosingCallable" : "ClosingFuture.AsyncClosingCallable", + "com.google.common.util.concurrent.ClosingFuture$AsyncClosingFunction" : "ClosingFuture.AsyncClosingFunction", + "com.google.common.util.concurrent.ClosingFuture$CloseableList" : "ClosingFuture.CloseableList", + "com.google.common.util.concurrent.ClosingFuture$ClosingCallable" : "ClosingFuture.ClosingCallable", + "com.google.common.util.concurrent.ClosingFuture$ClosingFunction" : "ClosingFuture.ClosingFunction", + "com.google.common.util.concurrent.ClosingFuture$Combiner" : "ClosingFuture.Combiner", + "com.google.common.util.concurrent.ClosingFuture$Combiner$AsyncCombiningCallable" : "ClosingFuture.Combiner.AsyncCombiningCallable", + "com.google.common.util.concurrent.ClosingFuture$Combiner$CombiningCallable" : "ClosingFuture.Combiner.CombiningCallable", + "com.google.common.util.concurrent.ClosingFuture$Combiner2" : "ClosingFuture.Combiner2", + "com.google.common.util.concurrent.ClosingFuture$Combiner2$AsyncClosingFunction2" : "ClosingFuture.Combiner2.AsyncClosingFunction2", + "com.google.common.util.concurrent.ClosingFuture$Combiner2$ClosingFunction2" : "ClosingFuture.Combiner2.ClosingFunction2", + "com.google.common.util.concurrent.ClosingFuture$Combiner3" : "ClosingFuture.Combiner3", + "com.google.common.util.concurrent.ClosingFuture$Combiner3$AsyncClosingFunction3" : "ClosingFuture.Combiner3.AsyncClosingFunction3", + "com.google.common.util.concurrent.ClosingFuture$Combiner3$ClosingFunction3" : "ClosingFuture.Combiner3.ClosingFunction3", + "com.google.common.util.concurrent.ClosingFuture$Combiner4" : "ClosingFuture.Combiner4", + "com.google.common.util.concurrent.ClosingFuture$Combiner4$AsyncClosingFunction4" : "ClosingFuture.Combiner4.AsyncClosingFunction4", + "com.google.common.util.concurrent.ClosingFuture$Combiner4$ClosingFunction4" : "ClosingFuture.Combiner4.ClosingFunction4", + "com.google.common.util.concurrent.ClosingFuture$Combiner5" : "ClosingFuture.Combiner5", + "com.google.common.util.concurrent.ClosingFuture$Combiner5$AsyncClosingFunction5" : "ClosingFuture.Combiner5.AsyncClosingFunction5", + "com.google.common.util.concurrent.ClosingFuture$Combiner5$ClosingFunction5" : "ClosingFuture.Combiner5.ClosingFunction5", + "com.google.common.util.concurrent.ClosingFuture$DeferredCloser" : "ClosingFuture.DeferredCloser", + "com.google.common.util.concurrent.ClosingFuture$Peeker" : "ClosingFuture.Peeker", + "com.google.common.util.concurrent.ClosingFuture$State" : "ClosingFuture.State", + "com.google.common.util.concurrent.ClosingFuture$ValueAndCloser" : "ClosingFuture.ValueAndCloser", + "com.google.common.util.concurrent.ClosingFuture$ValueAndCloserConsumer" : "ClosingFuture.ValueAndCloserConsumer", + "com.google.common.util.concurrent.CollectionFuture" : "CollectionFuture", + "com.google.common.util.concurrent.CollectionFuture$ListFuture" : "CollectionFuture.ListFuture", + "com.google.common.util.concurrent.CollectionFuture$Present" : "CollectionFuture.Present", + "com.google.common.util.concurrent.CombinedFuture" : "CombinedFuture", + "com.google.common.util.concurrent.CombinedFuture$AsyncCallableInterruptibleTask" : "CombinedFuture.AsyncCallableInterruptibleTask", + "com.google.common.util.concurrent.CombinedFuture$CallableInterruptibleTask" : "CombinedFuture.CallableInterruptibleTask", + "com.google.common.util.concurrent.CombinedFuture$CombinedFutureInterruptibleTask" : "CombinedFuture.CombinedFutureInterruptibleTask", + "com.google.common.util.concurrent.CycleDetectingLockFactory" : "CycleDetectingLockFactory", + "com.google.common.util.concurrent.CycleDetectingLockFactory$CycleDetectingLock" : "CycleDetectingLockFactory.CycleDetectingLock", + "com.google.common.util.concurrent.CycleDetectingLockFactory$CycleDetectingReentrantLock" : "CycleDetectingLockFactory.CycleDetectingReentrantLock", + "com.google.common.util.concurrent.CycleDetectingLockFactory$CycleDetectingReentrantReadLock" : "CycleDetectingLockFactory.CycleDetectingReentrantReadLock", + "com.google.common.util.concurrent.CycleDetectingLockFactory$CycleDetectingReentrantReadWriteLock" : "CycleDetectingLockFactory.CycleDetectingReentrantReadWriteLock", + "com.google.common.util.concurrent.CycleDetectingLockFactory$CycleDetectingReentrantWriteLock" : "CycleDetectingLockFactory.CycleDetectingReentrantWriteLock", + "com.google.common.util.concurrent.CycleDetectingLockFactory$ExampleStackTrace" : "CycleDetectingLockFactory.ExampleStackTrace", + "com.google.common.util.concurrent.CycleDetectingLockFactory$LockGraphNode" : "CycleDetectingLockFactory.LockGraphNode", + "com.google.common.util.concurrent.CycleDetectingLockFactory$Policies" : "CycleDetectingLockFactory.Policies", + "com.google.common.util.concurrent.CycleDetectingLockFactory$Policy" : "CycleDetectingLockFactory.Policy", + "com.google.common.util.concurrent.CycleDetectingLockFactory$PotentialDeadlockException" : "CycleDetectingLockFactory.PotentialDeadlockException", + "com.google.common.util.concurrent.CycleDetectingLockFactory$WithExplicitOrdering" : "CycleDetectingLockFactory.WithExplicitOrdering", + "com.google.common.util.concurrent.DirectExecutor" : "DirectExecutor", + "com.google.common.util.concurrent.DirectExecutorService" : "DirectExecutorService", + "com.google.common.util.concurrent.ElementTypesAreNonnullByDefault" : "ElementTypesAreNonnullByDefault", + "com.google.common.util.concurrent.ExecutionError" : "ExecutionError", + "com.google.common.util.concurrent.ExecutionList" : "ExecutionList", + "com.google.common.util.concurrent.ExecutionList$RunnableExecutorPair" : "ExecutionList.RunnableExecutorPair", + "com.google.common.util.concurrent.ExecutionSequencer" : "ExecutionSequencer", + "com.google.common.util.concurrent.ExecutionSequencer$RunningState" : "ExecutionSequencer.RunningState", + "com.google.common.util.concurrent.ExecutionSequencer$TaskNonReentrantExecutor" : "ExecutionSequencer.TaskNonReentrantExecutor", + "com.google.common.util.concurrent.ExecutionSequencer$ThreadConfinedTaskQueue" : "ExecutionSequencer.ThreadConfinedTaskQueue", + "com.google.common.util.concurrent.FakeTimeLimiter" : "FakeTimeLimiter", + "com.google.common.util.concurrent.FluentFuture" : "FluentFuture", + "com.google.common.util.concurrent.FluentFuture$TrustedFuture" : "FluentFuture.TrustedFuture", + "com.google.common.util.concurrent.ForwardingBlockingDeque" : "ForwardingBlockingDeque", + "com.google.common.util.concurrent.ForwardingBlockingQueue" : "ForwardingBlockingQueue", + "com.google.common.util.concurrent.ForwardingCondition" : "ForwardingCondition", + "com.google.common.util.concurrent.ForwardingExecutorService" : "ForwardingExecutorService", + "com.google.common.util.concurrent.ForwardingFluentFuture" : "ForwardingFluentFuture", + "com.google.common.util.concurrent.ForwardingFuture" : "ForwardingFuture", + "com.google.common.util.concurrent.ForwardingFuture$SimpleForwardingFuture" : "ForwardingFuture.SimpleForwardingFuture", + "com.google.common.util.concurrent.ForwardingListenableFuture" : "ForwardingListenableFuture", + "com.google.common.util.concurrent.ForwardingListenableFuture$SimpleForwardingListenableFuture" : "ForwardingListenableFuture.SimpleForwardingListenableFuture", + "com.google.common.util.concurrent.ForwardingListeningExecutorService" : "ForwardingListeningExecutorService", + "com.google.common.util.concurrent.ForwardingLock" : "ForwardingLock", + "com.google.common.util.concurrent.FutureCallback" : "FutureCallback", + "com.google.common.util.concurrent.Futures" : "Futures", + "com.google.common.util.concurrent.Futures$CallbackListener" : "Futures.CallbackListener", + "com.google.common.util.concurrent.Futures$FutureCombiner" : "Futures.FutureCombiner", + "com.google.common.util.concurrent.Futures$InCompletionOrderFuture" : "Futures.InCompletionOrderFuture", + "com.google.common.util.concurrent.Futures$InCompletionOrderState" : "Futures.InCompletionOrderState", + "com.google.common.util.concurrent.Futures$NonCancellationPropagatingFuture" : "Futures.NonCancellationPropagatingFuture", + "com.google.common.util.concurrent.FuturesGetChecked" : "FuturesGetChecked", + "com.google.common.util.concurrent.FuturesGetChecked$GetCheckedTypeValidator" : "FuturesGetChecked.GetCheckedTypeValidator", + "com.google.common.util.concurrent.FuturesGetChecked$GetCheckedTypeValidatorHolder" : "FuturesGetChecked.GetCheckedTypeValidatorHolder", + "com.google.common.util.concurrent.FuturesGetChecked$GetCheckedTypeValidatorHolder$ClassValueValidator" : "FuturesGetChecked.GetCheckedTypeValidatorHolder.ClassValueValidator", + "com.google.common.util.concurrent.FuturesGetChecked$GetCheckedTypeValidatorHolder$WeakSetValidator" : "FuturesGetChecked.GetCheckedTypeValidatorHolder.WeakSetValidator", + "com.google.common.util.concurrent.GwtFluentFutureCatchingSpecialization" : "GwtFluentFutureCatchingSpecialization", + "com.google.common.util.concurrent.GwtFuturesCatchingSpecialization" : "GwtFuturesCatchingSpecialization", + "com.google.common.util.concurrent.ImmediateFuture" : "ImmediateFuture", + "com.google.common.util.concurrent.ImmediateFuture$ImmediateCancelledFuture" : "ImmediateFuture.ImmediateCancelledFuture", + "com.google.common.util.concurrent.ImmediateFuture$ImmediateFailedFuture" : "ImmediateFuture.ImmediateFailedFuture", + "com.google.common.util.concurrent.Internal" : "Internal", + "com.google.common.util.concurrent.InterruptibleTask" : "InterruptibleTask", + "com.google.common.util.concurrent.InterruptibleTask$Blocker" : "InterruptibleTask.Blocker", + "com.google.common.util.concurrent.InterruptibleTask$DoNothingRunnable" : "InterruptibleTask.DoNothingRunnable", + "com.google.common.util.concurrent.JdkFutureAdapters" : "JdkFutureAdapters", + "com.google.common.util.concurrent.JdkFutureAdapters$ListenableFutureAdapter" : "JdkFutureAdapters.ListenableFutureAdapter", + "com.google.common.util.concurrent.LazyLogger" : "LazyLogger", + "com.google.common.util.concurrent.ListenableFuture" : "ListenableFuture", + "com.google.common.util.concurrent.ListenableFutureTask" : "ListenableFutureTask", + "com.google.common.util.concurrent.ListenableScheduledFuture" : "ListenableScheduledFuture", + "com.google.common.util.concurrent.ListenerCallQueue" : "ListenerCallQueue", + "com.google.common.util.concurrent.ListenerCallQueue$Event" : "ListenerCallQueue.Event", + "com.google.common.util.concurrent.ListenerCallQueue$PerListenerQueue" : "ListenerCallQueue.PerListenerQueue", + "com.google.common.util.concurrent.ListeningExecutorService" : "ListeningExecutorService", + "com.google.common.util.concurrent.ListeningScheduledExecutorService" : "ListeningScheduledExecutorService", + "com.google.common.util.concurrent.Monitor" : "Monitor", + "com.google.common.util.concurrent.Monitor$Guard" : "Monitor.Guard", + "com.google.common.util.concurrent.MoreExecutors" : "MoreExecutors", + "com.google.common.util.concurrent.MoreExecutors$Application" : "MoreExecutors.Application", + "com.google.common.util.concurrent.MoreExecutors$ListeningDecorator" : "MoreExecutors.ListeningDecorator", + "com.google.common.util.concurrent.MoreExecutors$ScheduledListeningDecorator" : "MoreExecutors.ScheduledListeningDecorator", + "com.google.common.util.concurrent.MoreExecutors$ScheduledListeningDecorator$ListenableScheduledTask" : "MoreExecutors.ScheduledListeningDecorator.ListenableScheduledTask", + "com.google.common.util.concurrent.MoreExecutors$ScheduledListeningDecorator$NeverSuccessfulListenableFutureTask" : "MoreExecutors.ScheduledListeningDecorator.NeverSuccessfulListenableFutureTask", + "com.google.common.util.concurrent.NullnessCasts" : "NullnessCasts", + "com.google.common.util.concurrent.OverflowAvoidingLockSupport" : "OverflowAvoidingLockSupport", + "com.google.common.util.concurrent.ParametricNullness" : "ParametricNullness", + "com.google.common.util.concurrent.Partially" : "Partially", + "com.google.common.util.concurrent.Partially$GwtIncompatible" : "Partially.GwtIncompatible", + "com.google.common.util.concurrent.Platform" : "Platform", + "com.google.common.util.concurrent.RateLimiter" : "RateLimiter", + "com.google.common.util.concurrent.RateLimiter$SleepingStopwatch" : "RateLimiter.SleepingStopwatch", + "com.google.common.util.concurrent.Runnables" : "Runnables", + "com.google.common.util.concurrent.SequentialExecutor" : "SequentialExecutor", + "com.google.common.util.concurrent.SequentialExecutor$QueueWorker" : "SequentialExecutor.QueueWorker", + "com.google.common.util.concurrent.SequentialExecutor$WorkerRunningState" : "SequentialExecutor.WorkerRunningState", + "com.google.common.util.concurrent.Service" : "Service", + "com.google.common.util.concurrent.Service$Listener" : "Service.Listener", + "com.google.common.util.concurrent.Service$State" : "Service.State", + "com.google.common.util.concurrent.ServiceManager" : "ServiceManager", + "com.google.common.util.concurrent.ServiceManager$EmptyServiceManagerWarning" : "ServiceManager.EmptyServiceManagerWarning", + "com.google.common.util.concurrent.ServiceManager$FailedService" : "ServiceManager.FailedService", + "com.google.common.util.concurrent.ServiceManager$Listener" : "ServiceManager.Listener", + "com.google.common.util.concurrent.ServiceManager$NoOpService" : "ServiceManager.NoOpService", + "com.google.common.util.concurrent.ServiceManager$ServiceListener" : "ServiceManager.ServiceListener", + "com.google.common.util.concurrent.ServiceManager$ServiceManagerState" : "ServiceManager.ServiceManagerState", + "com.google.common.util.concurrent.ServiceManager$ServiceManagerState$AwaitHealthGuard" : "ServiceManager.ServiceManagerState.AwaitHealthGuard", + "com.google.common.util.concurrent.ServiceManager$ServiceManagerState$StoppedGuard" : "ServiceManager.ServiceManagerState.StoppedGuard", + "com.google.common.util.concurrent.ServiceManagerBridge" : "ServiceManagerBridge", + "com.google.common.util.concurrent.SettableFuture" : "SettableFuture", + "com.google.common.util.concurrent.SimpleTimeLimiter" : "SimpleTimeLimiter", + "com.google.common.util.concurrent.SmoothRateLimiter" : "SmoothRateLimiter", + "com.google.common.util.concurrent.SmoothRateLimiter$SmoothBursty" : "SmoothRateLimiter.SmoothBursty", + "com.google.common.util.concurrent.SmoothRateLimiter$SmoothWarmingUp" : "SmoothRateLimiter.SmoothWarmingUp", + "com.google.common.util.concurrent.Striped" : "Striped", + "com.google.common.util.concurrent.Striped$CompactStriped" : "Striped.CompactStriped", + "com.google.common.util.concurrent.Striped$LargeLazyStriped" : "Striped.LargeLazyStriped", + "com.google.common.util.concurrent.Striped$PaddedLock" : "Striped.PaddedLock", + "com.google.common.util.concurrent.Striped$PaddedSemaphore" : "Striped.PaddedSemaphore", + "com.google.common.util.concurrent.Striped$PowerOfTwoStriped" : "Striped.PowerOfTwoStriped", + "com.google.common.util.concurrent.Striped$SmallLazyStriped" : "Striped.SmallLazyStriped", + "com.google.common.util.concurrent.Striped$SmallLazyStriped$ArrayReference" : "Striped.SmallLazyStriped.ArrayReference", + "com.google.common.util.concurrent.Striped$WeakSafeCondition" : "Striped.WeakSafeCondition", + "com.google.common.util.concurrent.Striped$WeakSafeLock" : "Striped.WeakSafeLock", + "com.google.common.util.concurrent.Striped$WeakSafeReadWriteLock" : "Striped.WeakSafeReadWriteLock", + "com.google.common.util.concurrent.ThreadFactoryBuilder" : "ThreadFactoryBuilder", + "com.google.common.util.concurrent.TimeLimiter" : "TimeLimiter", + "com.google.common.util.concurrent.TimeoutFuture" : "TimeoutFuture", + "com.google.common.util.concurrent.TimeoutFuture$Fire" : "TimeoutFuture.Fire", + "com.google.common.util.concurrent.TimeoutFuture$TimeoutFutureException" : "TimeoutFuture.TimeoutFutureException", + "com.google.common.util.concurrent.TrustedListenableFutureTask" : "TrustedListenableFutureTask", + "com.google.common.util.concurrent.TrustedListenableFutureTask$TrustedFutureInterruptibleAsyncTask" : "TrustedListenableFutureTask.TrustedFutureInterruptibleAsyncTask", + "com.google.common.util.concurrent.TrustedListenableFutureTask$TrustedFutureInterruptibleTask" : "TrustedListenableFutureTask.TrustedFutureInterruptibleTask", + "com.google.common.util.concurrent.UncaughtExceptionHandlers" : "UncaughtExceptionHandlers", + "com.google.common.util.concurrent.UncaughtExceptionHandlers$Exiter" : "UncaughtExceptionHandlers.Exiter", + "com.google.common.util.concurrent.UncheckedExecutionException" : "UncheckedExecutionException", + "com.google.common.util.concurrent.UncheckedTimeoutException" : "UncheckedTimeoutException", + "com.google.common.util.concurrent.Uninterruptibles" : "Uninterruptibles", + "com.google.common.util.concurrent.WrappingExecutorService" : "WrappingExecutorService", + "com.google.common.util.concurrent.WrappingScheduledExecutorService" : "WrappingScheduledExecutorService", + "com.google.common.util.concurrent.internal.InternalFutureFailureAccess" : "InternalFutureFailureAccess", + "com.google.common.util.concurrent.internal.InternalFutures" : "InternalFutures", + "com.google.common.util.concurrent.package-info" : "package-info", + "com.google.common.xml.ElementTypesAreNonnullByDefault" : "ElementTypesAreNonnullByDefault", + "com.google.common.xml.ParametricNullness" : "ParametricNullness", + "com.google.common.xml.XmlEscapers" : "XmlEscapers", + "com.google.common.xml.package-info" : "package-info" }, - "classpath" : "\/Users\/ktoso\/.gradle\/caches\/modules-2\/files-2.1\/com.google.guava\/guava\/33.3.1-jre\/852f8b363da0111e819460021ca693cacca3e8db\/guava-33.3.1-jre.jar:\/Users\/ktoso\/.gradle\/caches\/modules-2\/files-2.1\/com.google.guava\/failureaccess\/1.0.2\/c4a06a64e650562f30b7bf9aaec1bfed43aca12b\/failureaccess-1.0.2.jar:\/Users\/ktoso\/.gradle\/caches\/modules-2\/files-2.1\/com.google.guava\/listenablefuture\/9999.0-empty-to-avoid-conflict-with-guava\/b421526c5f297295adef1c886e5246c39d4ac629\/listenablefuture-9999.0-empty-to-avoid-conflict-with-guava.jar:\/Users\/ktoso\/.gradle\/caches\/modules-2\/files-2.1\/com.google.code.findbugs\/jsr305\/3.0.2\/25ea2e8b0c338a877313bd4672d3fe056ea78f0d\/jsr305-3.0.2.jar:\/Users\/ktoso\/.gradle\/caches\/modules-2\/files-2.1\/org.checkerframework\/checker-qual\/3.43.0\/9425eee39e56b116d2b998b7c2cebcbd11a3c98b\/checker-qual-3.43.0.jar:\/Users\/ktoso\/.gradle\/caches\/modules-2\/files-2.1\/com.google.errorprone\/error_prone_annotations\/2.28.0\/59fc00087ce372de42e394d2c789295dff2d19f0\/error_prone_annotations-2.28.0.jar:\/Users\/ktoso\/.gradle\/caches\/modules-2\/files-2.1\/com.google.j2objc\/j2objc-annotations\/3.0.0\/7399e65dd7e9ff3404f4535b2f017093bdb134c7\/j2objc-annotations-3.0.0.jar", + "classpath" : "\/Users\/ktoso\/.gradle\/caches\/modules-2\/files-2.1\/com.google.guava\/guava\/33.3.1-jre\/852f8b363da0111e819460021ca693cacca3e8db\/guava-33.3.1-jre.jar:\/Users\/ktoso\/.gradle\/caches\/modules-2\/files-2.1\/com.google.guava\/failureaccess\/1.0.2\/c4a06a64e650562f30b7bf9aaec1bfed43aca12b\/failureaccess-1.0.2.jar:\/Users\/ktoso\/.gradle\/caches\/modules-2\/files-2.1\/com.google.guava\/listenablefuture\/9999.0-empty-to-avoid-conflict-with-guava\/b421526c5f297295adef1c886e5246c39d4ac629\/listenablefuture-9999.0-empty-to-avoid-conflict-with-guava.jar:\/Users\/ktoso\/.gradle\/caches\/modules-2\/files-2.1\/com.google.code.findbugs\/jsr305\/3.0.2\/25ea2e8b0c338a877313bd4672d3fe056ea78f0d\/jsr305-3.0.2.jar:\/Users\/ktoso\/.gradle\/caches\/modules-2\/files-2.1\/org.checkerframework\/checker-qual\/3.43.0\/9425eee39e56b116d2b998b7c2cebcbd11a3c98b\/checker-qual-3.43.0.jar:\/Users\/ktoso\/.gradle\/caches\/modules-2\/files-2.1\/com.google.errorprone\/error_prone_annotations\/2.28.0\/59fc00087ce372de42e394d2c789295dff2d19f0\/error_prone_annotations-2.28.0.jar:\/Users\/ktoso\/.gradle\/caches\/modules-2\/files-2.1\/com.google.j2objc\/j2objc-annotations\/3.0.0\/7399e65dd7e9ff3404f4535b2f017093bdb134c7\/j2objc-annotations-3.0.0.jar:\/Users\/ktoso\/.gradle\/caches\/modules-2\/files-2.1\/com.google.guava\/guava\/33.3.1-jre\/852f8b363da0111e819460021ca693cacca3e8db\/guava-33.3.1-jre.jar:\/Users\/ktoso\/.gradle\/caches\/modules-2\/files-2.1\/com.google.guava\/failureaccess\/1.0.2\/c4a06a64e650562f30b7bf9aaec1bfed43aca12b\/failureaccess-1.0.2.jar:\/Users\/ktoso\/.gradle\/caches\/modules-2\/files-2.1\/com.google.guava\/listenablefuture\/9999.0-empty-to-avoid-conflict-with-guava\/b421526c5f297295adef1c886e5246c39d4ac629\/listenablefuture-9999.0-empty-to-avoid-conflict-with-guava.jar:\/Users\/ktoso\/.gradle\/caches\/modules-2\/files-2.1\/com.google.code.findbugs\/jsr305\/3.0.2\/25ea2e8b0c338a877313bd4672d3fe056ea78f0d\/jsr305-3.0.2.jar:\/Users\/ktoso\/.gradle\/caches\/modules-2\/files-2.1\/org.checkerframework\/checker-qual\/3.43.0\/9425eee39e56b116d2b998b7c2cebcbd11a3c98b\/checker-qual-3.43.0.jar:\/Users\/ktoso\/.gradle\/caches\/modules-2\/files-2.1\/com.google.errorprone\/error_prone_annotations\/2.28.0\/59fc00087ce372de42e394d2c789295dff2d19f0\/error_prone_annotations-2.28.0.jar:\/Users\/ktoso\/.gradle\/caches\/modules-2\/files-2.1\/com.google.j2objc\/j2objc-annotations\/3.0.0\/7399e65dd7e9ff3404f4535b2f017093bdb134c7\/j2objc-annotations-3.0.0.jar:\/Users\/ktoso\/.gradle\/caches\/modules-2\/files-2.1\/com.google.guava\/guava\/33.3.1-jre\/852f8b363da0111e819460021ca693cacca3e8db\/guava-33.3.1-jre.jar:\/Users\/ktoso\/.gradle\/caches\/modules-2\/files-2.1\/com.google.guava\/failureaccess\/1.0.2\/c4a06a64e650562f30b7bf9aaec1bfed43aca12b\/failureaccess-1.0.2.jar:\/Users\/ktoso\/.gradle\/caches\/modules-2\/files-2.1\/com.google.guava\/listenablefuture\/9999.0-empty-to-avoid-conflict-with-guava\/b421526c5f297295adef1c886e5246c39d4ac629\/listenablefuture-9999.0-empty-to-avoid-conflict-with-guava.jar:\/Users\/ktoso\/.gradle\/caches\/modules-2\/files-2.1\/com.google.code.findbugs\/jsr305\/3.0.2\/25ea2e8b0c338a877313bd4672d3fe056ea78f0d\/jsr305-3.0.2.jar:\/Users\/ktoso\/.gradle\/caches\/modules-2\/files-2.1\/org.checkerframework\/checker-qual\/3.43.0\/9425eee39e56b116d2b998b7c2cebcbd11a3c98b\/checker-qual-3.43.0.jar:\/Users\/ktoso\/.gradle\/caches\/modules-2\/files-2.1\/com.google.errorprone\/error_prone_annotations\/2.28.0\/59fc00087ce372de42e394d2c789295dff2d19f0\/error_prone_annotations-2.28.0.jar:\/Users\/ktoso\/.gradle\/caches\/modules-2\/files-2.1\/com.google.j2objc\/j2objc-annotations\/3.0.0\/7399e65dd7e9ff3404f4535b2f017093bdb134c7\/j2objc-annotations-3.0.0.jar", "dependencies" : [ "com.google.guava:guava:33.3.1-jre" ] diff --git a/Samples/JavaDependencySampleApp/ci-validate.sh b/Samples/JavaDependencySampleApp/ci-validate.sh index 56a72754..62e68b0b 100755 --- a/Samples/JavaDependencySampleApp/ci-validate.sh +++ b/Samples/JavaDependencySampleApp/ci-validate.sh @@ -14,10 +14,10 @@ MODULE_CONFIG_PATH="$MODULE_CONFIG_DIR/swift-java.config" ### 2) extract the config for the fetched dependency DEP_JAR_CP=$(jq .classpath "$MODULE_CONFIG_PATH") DEP_JAR_CP=$(echo "$DEP_JAR_CP" | tr -d '"') # trim the "..." -# FIXME: "jar" is the wrong word for it # shellcheck disable=SC2086 "$JAVASWIFT" --jar $DEP_JAR_CP \ --module-name "$MODULE_NAME" \ + --java-package-filter com.google.common \ --existing-config amend ### 3) make wrappers for the module diff --git a/Sources/Java2Swift/JavaToSwift+EmitConfiguration.swift b/Sources/Java2Swift/JavaToSwift+EmitConfiguration.swift index 251c8ae2..7863fae8 100644 --- a/Sources/Java2Swift/JavaToSwift+EmitConfiguration.swift +++ b/Sources/Java2Swift/JavaToSwift+EmitConfiguration.swift @@ -25,25 +25,71 @@ extension JavaToSwift { // TODO: make this perhaps "emit type mappings" mutating func emitConfiguration( - forJarFile jarFileName: String, classpath: String, environment: JNIEnvironment ) throws { + print("[java-swift] Generate Java->Swift type mappings. Active filter: \(javaPackageFilter)") + print("[java-swift] Classpath: \(classpath)") + + if classpath.isEmpty { + print("[warning][java-swift] Classpath is empty!") + } + // Get a fresh or existing configuration we'll amend var (amendExistingConfig, configuration) = try getBaseConfigurationForWrite() if amendExistingConfig { - print("[java-swift] Amend existing swift-java.config file...") - } else { - configuration.classpath = classpath // TODO: is this correct? + print("[swift-java] Amend existing swift-java.config file...") } + configuration.classpath = classpath // TODO: is this correct? + + // Import types from all the classpath entries; + // Note that we use the package level filtering, so users have some control over what gets imported. + for entry in classpath.split(separator: ":").map(String.init) { + print("[debug][swift-java] Importing classpath entry: \(entry)") + if entry.hasSuffix(".jar") { + let jarFile = try JarFile(entry, false, environment: environment) + try addJavaToSwiftMappings( + to: &configuration, + forJar: jarFile, + environment: environment + ) + } else if FileManager.default.fileExists(atPath: entry) { + fatalError("[warning][swift-java] Currently unable handle directory classpath entries for config generation! Skipping: \(entry)") + } else { + print("[warning][swift-java] Classpath entry does not exist, skipping: \(entry)") + } + } + + // Encode the configuration. + let contents = try configuration.renderJSON() + + // Write the file. + try writeContents( + contents, + to: "swift-java.config", + description: "swift-java configuration file" + ) + } - let jarFile = try JarFile(jarFileName, false, environment: environment) + mutating func addJavaToSwiftMappings( + to configuration: inout Configuration, + forJar jarFile: JarFile, + environment: JNIEnvironment + ) throws { for entry in jarFile.entries()! { // We only look at class files in the Jar file. guard entry.getName().hasSuffix(".class") else { continue } + // Skip some "common" files we know that would be duplicated in every jar + guard !entry.getName().hasPrefix("META-INF") else { + continue + } + guard !entry.getName().hasSuffix("package-info") else { + continue + } + // If this is a local class, it cannot be mapped into Swift. if entry.getName().isLocalJavaClass { continue @@ -59,24 +105,15 @@ extension JavaToSwift { } } - if amendExistingConfig && configuration.classes?[javaCanonicalName] != nil { - // If we're amending an existing config, we never overwrite an existing - // class configuration. E.g. the user may have configured a custom name - // for a type. + if configuration.classes?[javaCanonicalName] != nil { + // We never overwrite an existing class mapping configuration. + // E.g. the user may have configured a custom name for a type. continue } + configuration.classes?[javaCanonicalName] = javaCanonicalName.defaultSwiftNameForJavaClass } - - // Encode the configuration. - let contents = try configuration.renderJSON() - - // Write the file. - try writeContents( - contents, - to: "swift-java.config", - description: "swift-java configuration file" - ) } + } \ No newline at end of file diff --git a/Sources/Java2Swift/JavaToSwift+FetchDependencies.swift b/Sources/Java2Swift/JavaToSwift+FetchDependencies.swift index a1749230..779c3a46 100644 --- a/Sources/Java2Swift/JavaToSwift+FetchDependencies.swift +++ b/Sources/Java2Swift/JavaToSwift+FetchDependencies.swift @@ -84,6 +84,10 @@ struct ResolvedDependencyClasspath: CustomStringConvertible { /// Plain string representation of a Java classpath let classpath: String + var classpathEntries: [String] { + classpath.split(separator: ":").map(String.init) + } + init(for rootDependencies: [JavaDependencyDescriptor], classpath: String) { self.rootDependencies = rootDependencies self.classpath = classpath diff --git a/Sources/Java2Swift/JavaToSwift.swift b/Sources/Java2Swift/JavaToSwift.swift index c0d9a706..cc8f51b4 100644 --- a/Sources/Java2Swift/JavaToSwift.swift +++ b/Sources/Java2Swift/JavaToSwift.swift @@ -81,6 +81,27 @@ struct JavaToSwift: ParsableCommand { /// Whether we have ensured that the output directory exists. var createdOutputDirectory: Bool = false + var moduleBaseDir: Foundation.URL? { + if let outputDirectory { + if outputDirectory == "-" { + return nil + } + + return URL(fileURLWithPath: outputDirectory) + } + + guard let moduleName else { + return nil + } + + // Put the result into Sources/\(moduleName). + let baseDir = URL(fileURLWithPath: ".") + .appendingPathComponent("Sources", isDirectory: true) + .appendingPathComponent(moduleName, isDirectory: true) + + return baseDir + } + /// The output directory in which to place the generated files, which will /// be the specified directory (--output-directory or -o option) if given, /// or a default directory derived from the other command-line arguments. @@ -120,33 +141,40 @@ struct JavaToSwift: ParsableCommand { /// Describes what kind of generation action is being performed by swift-java. enum ToolMode { /// Generate a configuration file given a Jar file. - case configuration(jarFile: String) // FIXME: this is more like "extract" configuration from classpath + case configuration(extraClasspath: String) // FIXME: this is more like "extract" configuration from classpath /// Generate Swift wrappers for Java classes based on the given /// configuration. - case classWrappers(Configuration) + case classWrappers // (Configuration) /// Fetch dependencies for a module - case fetchDependencies(Configuration) + case fetchDependencies // (Configuration) // FIXME each mode should have its own config? } mutating func run() throws { + let config: Configuration + // Determine the mode in which we'll execute. let toolMode: ToolMode if jar { - toolMode = .configuration(jarFile: input) + if let moduleBaseDir { + config = try readConfiguration(sourceDir: "file://" + moduleBaseDir.path) + } else { + config = Configuration() + } + toolMode = .configuration(extraClasspath: input) } else if fetch { - let config = try JavaTranslator.readConfiguration(from: URL(fileURLWithPath: input)) + config = try JavaTranslator.readConfiguration(from: URL(fileURLWithPath: input)) guard let dependencies = config.dependencies else { print("[swift-java] Running in 'fetch dependencies' mode but dependencies list was empty!") print("[swift-java] Nothing to do: done.") return } - toolMode = .fetchDependencies(config) + toolMode = .fetchDependencies } else { - let config = try JavaTranslator.readConfiguration(from: URL(fileURLWithPath: input)) - toolMode = .classWrappers(config) + config = try JavaTranslator.readConfiguration(from: URL(fileURLWithPath: input)) + toolMode = .classWrappers } let moduleName = self.moduleName ?? @@ -171,47 +199,73 @@ struct JavaToSwift: ParsableCommand { // Form a class path from all of our input sources: // * Command-line option --classpath - var classpathPieces: [String] = classpath.flatMap { $0.split(separator: ":").map(String.init) } + let classpathOptionEntries: [String] = classpath.flatMap { $0.split(separator: ":").map(String.init) } + let classpathFromEnv = ProcessInfo.processInfo.environment["CLASSPATH"]?.split(separator: ":").map(String.init) ?? [] + var classpathFromConfig: [String] = config.classpath?.split(separator: ":").map(String.init) ?? [] + print("[debug][swift-java] Base classpath from config: \(classpathFromConfig)") + + var classpathEntries: [String] = classpathFromConfig + if !classpathOptionEntries.isEmpty { + print("[debug][swift-java] Classpath from options: \(classpathOptionEntries)") + classpathEntries += classpathOptionEntries + } else { + // * Base classpath from CLASSPATH env variable + print("[debug][swift-java] Classpath from environment: \(classpathFromEnv)") + classpathEntries += classpathFromEnv + } + switch toolMode { - case .configuration(jarFile: let jarFile): + case .configuration(let extraClasspath): // * Jar file (in `-jar` mode) - classpathPieces.append(jarFile) - case .classWrappers(let config), - .fetchDependencies(let config): + let extraClasspathEntries = extraClasspath.split(separator: ":").map(String.init) + print("[debug][swift-java] Extra classpath: \(extraClasspathEntries)") + classpathEntries += extraClasspathEntries + case .classWrappers/*(let config)*/, + .fetchDependencies/*(let config)*/: + break; // * Classpath specified in the configuration file (if any) - if let classpath = config.classpath { - for part in classpath.split(separator: ":") { - classpathPieces.append(String(part)) - } - } +// let extraClasspathEntries = config.classpath?.split(separator: ":").map(String.init) ?? [] +// print("[debug][swift-java] Config classpath: \(extraClasspathEntries)") +// classpathEntries += extraClasspathEntries } + // Bring up the Java VM. + // TODO: print only in verbose mode + let jvm = try JavaVirtualMachine.shared(classpath: classpathEntries) + let classpath = classpathEntries.joined(separator: ":") + print("[debug][swift-java] Initialize JVM with classpath: \(classpath)") + + // FIXME: we should resolve dependencies here perhaps +// if let dependencies = config.dependencies { +// print("[info][swift-java] Resolve dependencies...") +// let dependencyClasspath = try fetchDependencies( +// moduleName: moduleName, +// dependencies: dependencies, +// baseClasspath: classpathOptionEntries, +// environment: jvm.environment() +// ) +// classpathEntries += dependencyClasspath.classpathEntries +// } + // * Classespaths from all dependent configuration files for (_, config) in dependentConfigs { - config.classpath.map { element in - print("[swift-java] Add dependent config classpath element: \(element)") - classpathPieces.append(element) + // TODO: may need to resolve the dependent configs rather than just get their configs + // TODO: We should cache the resolved classpaths as well so we don't do it many times + config.classpath.map { entry in + print("[swift-java] Add dependent config classpath element: \(entry)") + classpathEntries.append(entry) } } - // Bring up the Java VM. - let classpath = classpathPieces.joined(separator: ":") - // TODO: print only in verbose mode - print("[swift-java] Initialize JVM with classpath: \(classpath)") - - // Run the task. - let jvm = try JavaVirtualMachine.shared(classpath: classpathPieces) switch toolMode { - case .configuration(jarFile: let jarFile): - + case .configuration: try emitConfiguration( - forJarFile: jarFile, classpath: classpath, environment: jvm.environment() ) - case .classWrappers(let config): + case .classWrappers/*(let config)*/: try generateWrappers( config: config, classpath: classpath, @@ -219,12 +273,15 @@ struct JavaToSwift: ParsableCommand { environment: jvm.environment() ) - case .fetchDependencies(let config): - let dependencies = config.dependencies! // TODO: cleanup how we do config + case .fetchDependencies/*(let config)*/: + guard let dependencies = config.dependencies else { + fatalError("Configuration for fetching dependencies must have 'dependencies' defined!") + } + let dependencyClasspath = try fetchDependencies( moduleName: moduleName, dependencies: dependencies, - baseClasspath: classpathPieces, + baseClasspath: classpathOptionEntries, environment: jvm.environment() ) From 3005895bda755da92806865652045fb97f27ef05 Mon Sep 17 00:00:00 2001 From: Konrad `ktoso` Malawski Date: Thu, 5 Dec 2024 14:43:51 +0900 Subject: [PATCH 06/25] silence warnings --- Sources/JavaKit/JavaKitVM/JavaVirtualMachine.swift | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/Sources/JavaKit/JavaKitVM/JavaVirtualMachine.swift b/Sources/JavaKit/JavaKitVM/JavaVirtualMachine.swift index 27243586..279eb05c 100644 --- a/Sources/JavaKit/JavaKitVM/JavaVirtualMachine.swift +++ b/Sources/JavaKit/JavaKitVM/JavaVirtualMachine.swift @@ -119,11 +119,11 @@ public final class JavaVirtualMachine: @unchecked Sendable { throw error } - _ = destroyOnDeinit.withLock { $0 = false } // we destroyed explicitly, disable destroy in deinit + destroyOnDeinit.withLock { $0 = false } // we destroyed explicitly, disable destroy in deinit } deinit { - if destroyOnDeinit.withLock { $0 } { + if destroyOnDeinit.withLock({ $0 }) { do { try destroyJVM() } catch { From 366a76c19fb69945a789accff4efb23e628345fc Mon Sep 17 00:00:00 2001 From: Konrad `ktoso` Malawski Date: Thu, 5 Dec 2024 17:10:06 +0900 Subject: [PATCH 07/25] ignore cloned repo in sample --- Samples/JavaSieve/.gitignore | 1 + 1 file changed, 1 insertion(+) diff --git a/Samples/JavaSieve/.gitignore b/Samples/JavaSieve/.gitignore index 0023a534..6e1b4ce3 100644 --- a/Samples/JavaSieve/.gitignore +++ b/Samples/JavaSieve/.gitignore @@ -6,3 +6,4 @@ DerivedData/ .swiftpm/configuration/registries.json .swiftpm/xcode/package.xcworkspace/contents.xcworkspacedata .netrc +quadratic-sieve-Java \ No newline at end of file From 6c3ab5cbaafa08917623026cc5b6a7decd3cdb96 Mon Sep 17 00:00:00 2001 From: Konrad `ktoso` Malawski Date: Thu, 5 Dec 2024 17:41:14 +0900 Subject: [PATCH 08/25] Simplify how we run JavaSieve sample --- Samples/JavaSieve/README.md | 3 +-- Samples/JavaSieve/Sources/JavaSieve/main.swift | 6 +++++- Samples/JavaSieve/Sources/JavaSieve/swift-java.config | 2 +- 3 files changed, 7 insertions(+), 4 deletions(-) diff --git a/Samples/JavaSieve/README.md b/Samples/JavaSieve/README.md index b8dc3c9a..09fbde83 100644 --- a/Samples/JavaSieve/README.md +++ b/Samples/JavaSieve/README.md @@ -12,10 +12,9 @@ This example wraps an [open-source Java library](https://github.com/gazman-sdk/q git clone https://github.com/gazman-sdk/quadratic-sieve-Java cd quadratic-sieve-Java sh ./gradlew jar +cd .. ``` -Then, copy the resulting Jar file (`./build/libs/QuadraticSieve-1.0.jar`) into the `Samples/JavaSieve` directory. - Now we're ready to build and run the Swift program from `Samples/JavaSieve`: ``` diff --git a/Samples/JavaSieve/Sources/JavaSieve/main.swift b/Samples/JavaSieve/Sources/JavaSieve/main.swift index 6d262b9f..e2047713 100644 --- a/Samples/JavaSieve/Sources/JavaSieve/main.swift +++ b/Samples/JavaSieve/Sources/JavaSieve/main.swift @@ -15,7 +15,11 @@ import JavaKit import JavaMath -let jvm = try JavaVirtualMachine.shared(classpath: ["QuadraticSieve-1.0.jar"]) +let jvm = try JavaVirtualMachine.shared(classpath: [ + "quadratic-sieve-Java/build/libs/QuadraticSieve-1.0.jar", + ".", +]) + do { let sieveClass = try JavaClass(environment: jvm.environment()) for prime in sieveClass.findPrimes(100)! { diff --git a/Samples/JavaSieve/Sources/JavaSieve/swift-java.config b/Samples/JavaSieve/Sources/JavaSieve/swift-java.config index 7ef33db9..7e055d1c 100644 --- a/Samples/JavaSieve/Sources/JavaSieve/swift-java.config +++ b/Samples/JavaSieve/Sources/JavaSieve/swift-java.config @@ -1,5 +1,5 @@ { - "classpath" : "QuadraticSieve-1.0.jar", + "classpath" : ".:quadratic-sieve-Java/build/libs/QuadraticSieve-1.0.jar", "classes" : { "com.gazman.quadratic_sieve.QuadraticSieve" : "QuadraticSieve", "com.gazman.quadratic_sieve.core.BaseFact" : "BaseFact", From d65fa596108a2d4d6e5f85ebad6cce75b7c57fe4 Mon Sep 17 00:00:00 2001 From: Konrad `ktoso` Malawski Date: Thu, 5 Dec 2024 17:42:08 +0900 Subject: [PATCH 09/25] validate JavaSieve in CI --- Samples/JavaSieve/ci-validate.sh | 9 ++++++++- 1 file changed, 8 insertions(+), 1 deletion(-) diff --git a/Samples/JavaSieve/ci-validate.sh b/Samples/JavaSieve/ci-validate.sh index 3eebd3ca..2a1fab17 100755 --- a/Samples/JavaSieve/ci-validate.sh +++ b/Samples/JavaSieve/ci-validate.sh @@ -1,3 +1,10 @@ #!/bin/bash -echo "Not validated in CI..." +echo "Prepare the dependency..." +git clone https://github.com/gazman-sdk/quadratic-sieve-Java +cd quadratic-sieve-Java +sh ./gradlew jar +cd .. + +echo "Run the sample..." +swift run JavaSieve From c9d815cbd86d62bfc7c13e9d3d6a1ff4034ec409 Mon Sep 17 00:00:00 2001 From: Konrad `ktoso` Malawski Date: Thu, 5 Dec 2024 21:13:11 +0900 Subject: [PATCH 10/25] wip --- .../Java2SwiftPlugin/Java2SwiftPlugin.swift | 5 +- Samples/JavaDependencySampleApp/Package.swift | 16 +- .../Sources/Guava/swift-java.config | 1509 ----------------- .../Sources/JavaCommonsCSV/dummy.swift | 14 + .../Sources/JavaCommonsCSV/swift-java.config | 9 + .../Sources/JavaDependencySample/main.swift | 2 +- .../JavaDependencySample/swift-java.config | 7 +- .../JavaDependencySampleApp/ci-validate.sh | 6 +- .../JavaToSwift+EmitConfiguration.swift | 5 +- Sources/Java2Swift/JavaToSwift.swift | 256 +-- .../JavaTranslator+Validation.swift | 2 +- .../Configuration.swift | 5 +- 12 files changed, 188 insertions(+), 1648 deletions(-) delete mode 100644 Samples/JavaDependencySampleApp/Sources/Guava/swift-java.config create mode 100644 Samples/JavaDependencySampleApp/Sources/JavaCommonsCSV/dummy.swift create mode 100644 Samples/JavaDependencySampleApp/Sources/JavaCommonsCSV/swift-java.config diff --git a/Plugins/Java2SwiftPlugin/Java2SwiftPlugin.swift b/Plugins/Java2SwiftPlugin/Java2SwiftPlugin.swift index 8c7045e0..16e5f442 100644 --- a/Plugins/Java2SwiftPlugin/Java2SwiftPlugin.swift +++ b/Plugins/Java2SwiftPlugin/Java2SwiftPlugin.swift @@ -140,10 +140,13 @@ struct Java2SwiftBuildToolPlugin: SwiftJavaPluginProtocol, BuildToolPlugin { return [] } + let executable = try context.tool(named: "Java2Swift").url + log("Prepared build command: \(executable) \(arguments)") + return [ .buildCommand( displayName: "Wrapping \(classes.count) Java classes target \(sourceModule.name) in Swift", - executable: try context.tool(named: "Java2Swift").url, + executable: executable, arguments: arguments, inputFiles: [ configFile ] + compiledClassFiles, outputFiles: outputSwiftFiles diff --git a/Samples/JavaDependencySampleApp/Package.swift b/Samples/JavaDependencySampleApp/Package.swift index d084f781..125aea0a 100644 --- a/Samples/JavaDependencySampleApp/Package.swift +++ b/Samples/JavaDependencySampleApp/Package.swift @@ -68,27 +68,31 @@ let package = Package( .product(name: "JavaKit", package: "swift-java"), .product(name: "JavaRuntime", package: "swift-java"), .product(name: "JavaKitFunction", package: "swift-java"), - "ReactiveStreams" + "JavaCommonsCSV" ], swiftSettings: [ - .unsafeFlags(["-I\(javaIncludePath)", "-I\(javaPlatformIncludePath)"]) + .unsafeFlags(["-I\(javaIncludePath)", "-I\(javaPlatformIncludePath)"]), + .swiftLanguageMode(.v5), ], plugins: [ - .plugin(name: "SwiftJavaPlugin", package: "swift-java"), + .plugin(name: "Java2SwiftPlugin", package: "swift-java"), +// .plugin(name: "SwiftJavaPlugin", package: "swift-java"), ] ), .target( - name: "ReactiveStreams", + name: "JavaCommonsCSV", dependencies: [ .product(name: "JavaKit", package: "swift-java"), .product(name: "JavaRuntime", package: "swift-java"), ], swiftSettings: [ - .unsafeFlags(["-I\(javaIncludePath)", "-I\(javaPlatformIncludePath)"]) + .unsafeFlags(["-I\(javaIncludePath)", "-I\(javaPlatformIncludePath)"]), + .swiftLanguageMode(.v5), ], plugins: [ - .plugin(name: "SwiftJavaPlugin", package: "swift-java"), +// .plugin(name: "SwiftJavaPlugin", package: "swift-java"), + .plugin(name: "Java2SwiftPlugin", package: "swift-java"), ] ), diff --git a/Samples/JavaDependencySampleApp/Sources/Guava/swift-java.config b/Samples/JavaDependencySampleApp/Sources/Guava/swift-java.config deleted file mode 100644 index be0d3af1..00000000 --- a/Samples/JavaDependencySampleApp/Sources/Guava/swift-java.config +++ /dev/null @@ -1,1509 +0,0 @@ -{ - "classes" : { - "com.google.common.annotations.Beta" : "Beta", - "com.google.common.annotations.GwtCompatible" : "GwtCompatible", - "com.google.common.annotations.GwtIncompatible" : "GwtIncompatible", - "com.google.common.annotations.J2ktIncompatible" : "J2ktIncompatible", - "com.google.common.annotations.VisibleForTesting" : "VisibleForTesting", - "com.google.common.annotations.package-info" : "package-info", - "com.google.common.base.Absent" : "Absent", - "com.google.common.base.AbstractIterator" : "AbstractIterator", - "com.google.common.base.AbstractIterator$State" : "AbstractIterator.State", - "com.google.common.base.Ascii" : "Ascii", - "com.google.common.base.CaseFormat" : "CaseFormat", - "com.google.common.base.CaseFormat$StringConverter" : "CaseFormat.StringConverter", - "com.google.common.base.CharMatcher" : "CharMatcher", - "com.google.common.base.CharMatcher$And" : "CharMatcher.And", - "com.google.common.base.CharMatcher$Any" : "CharMatcher.Any", - "com.google.common.base.CharMatcher$AnyOf" : "CharMatcher.AnyOf", - "com.google.common.base.CharMatcher$Ascii" : "CharMatcher.Ascii", - "com.google.common.base.CharMatcher$BitSetMatcher" : "CharMatcher.BitSetMatcher", - "com.google.common.base.CharMatcher$BreakingWhitespace" : "CharMatcher.BreakingWhitespace", - "com.google.common.base.CharMatcher$Digit" : "CharMatcher.Digit", - "com.google.common.base.CharMatcher$FastMatcher" : "CharMatcher.FastMatcher", - "com.google.common.base.CharMatcher$ForPredicate" : "CharMatcher.ForPredicate", - "com.google.common.base.CharMatcher$InRange" : "CharMatcher.InRange", - "com.google.common.base.CharMatcher$Invisible" : "CharMatcher.Invisible", - "com.google.common.base.CharMatcher$Is" : "CharMatcher.Is", - "com.google.common.base.CharMatcher$IsEither" : "CharMatcher.IsEither", - "com.google.common.base.CharMatcher$IsNot" : "CharMatcher.IsNot", - "com.google.common.base.CharMatcher$JavaDigit" : "CharMatcher.JavaDigit", - "com.google.common.base.CharMatcher$JavaIsoControl" : "CharMatcher.JavaIsoControl", - "com.google.common.base.CharMatcher$JavaLetter" : "CharMatcher.JavaLetter", - "com.google.common.base.CharMatcher$JavaLetterOrDigit" : "CharMatcher.JavaLetterOrDigit", - "com.google.common.base.CharMatcher$JavaLowerCase" : "CharMatcher.JavaLowerCase", - "com.google.common.base.CharMatcher$JavaUpperCase" : "CharMatcher.JavaUpperCase", - "com.google.common.base.CharMatcher$NamedFastMatcher" : "CharMatcher.NamedFastMatcher", - "com.google.common.base.CharMatcher$Negated" : "CharMatcher.Negated", - "com.google.common.base.CharMatcher$NegatedFastMatcher" : "CharMatcher.NegatedFastMatcher", - "com.google.common.base.CharMatcher$None" : "CharMatcher.None", - "com.google.common.base.CharMatcher$Or" : "CharMatcher.Or", - "com.google.common.base.CharMatcher$RangesMatcher" : "CharMatcher.RangesMatcher", - "com.google.common.base.CharMatcher$SingleWidth" : "CharMatcher.SingleWidth", - "com.google.common.base.CharMatcher$Whitespace" : "CharMatcher.Whitespace", - "com.google.common.base.Charsets" : "Charsets", - "com.google.common.base.CommonMatcher" : "CommonMatcher", - "com.google.common.base.CommonPattern" : "CommonPattern", - "com.google.common.base.Converter" : "Converter", - "com.google.common.base.Converter$ConverterComposition" : "Converter.ConverterComposition", - "com.google.common.base.Converter$FunctionBasedConverter" : "Converter.FunctionBasedConverter", - "com.google.common.base.Converter$IdentityConverter" : "Converter.IdentityConverter", - "com.google.common.base.Converter$ReverseConverter" : "Converter.ReverseConverter", - "com.google.common.base.Defaults" : "Defaults", - "com.google.common.base.ElementTypesAreNonnullByDefault" : "ElementTypesAreNonnullByDefault", - "com.google.common.base.Enums" : "Enums", - "com.google.common.base.Enums$StringConverter" : "Enums.StringConverter", - "com.google.common.base.Equivalence" : "Equivalence", - "com.google.common.base.Equivalence$Equals" : "Equivalence.Equals", - "com.google.common.base.Equivalence$EquivalentToPredicate" : "Equivalence.EquivalentToPredicate", - "com.google.common.base.Equivalence$Identity" : "Equivalence.Identity", - "com.google.common.base.Equivalence$Wrapper" : "Equivalence.Wrapper", - "com.google.common.base.ExtraObjectsMethodsForWeb" : "ExtraObjectsMethodsForWeb", - "com.google.common.base.FinalizablePhantomReference" : "FinalizablePhantomReference", - "com.google.common.base.FinalizableReference" : "FinalizableReference", - "com.google.common.base.FinalizableReferenceQueue" : "FinalizableReferenceQueue", - "com.google.common.base.FinalizableReferenceQueue$DecoupledLoader" : "FinalizableReferenceQueue.DecoupledLoader", - "com.google.common.base.FinalizableReferenceQueue$DirectLoader" : "FinalizableReferenceQueue.DirectLoader", - "com.google.common.base.FinalizableReferenceQueue$FinalizerLoader" : "FinalizableReferenceQueue.FinalizerLoader", - "com.google.common.base.FinalizableReferenceQueue$SystemLoader" : "FinalizableReferenceQueue.SystemLoader", - "com.google.common.base.FinalizableSoftReference" : "FinalizableSoftReference", - "com.google.common.base.FinalizableWeakReference" : "FinalizableWeakReference", - "com.google.common.base.Function" : "Function", - "com.google.common.base.FunctionalEquivalence" : "FunctionalEquivalence", - "com.google.common.base.Functions" : "Functions", - "com.google.common.base.Functions$ConstantFunction" : "Functions.ConstantFunction", - "com.google.common.base.Functions$ForMapWithDefault" : "Functions.ForMapWithDefault", - "com.google.common.base.Functions$FunctionComposition" : "Functions.FunctionComposition", - "com.google.common.base.Functions$FunctionForMapNoDefault" : "Functions.FunctionForMapNoDefault", - "com.google.common.base.Functions$IdentityFunction" : "Functions.IdentityFunction", - "com.google.common.base.Functions$PredicateFunction" : "Functions.PredicateFunction", - "com.google.common.base.Functions$SupplierFunction" : "Functions.SupplierFunction", - "com.google.common.base.Functions$ToStringFunction" : "Functions.ToStringFunction", - "com.google.common.base.IgnoreJRERequirement" : "IgnoreJRERequirement", - "com.google.common.base.Internal" : "Internal", - "com.google.common.base.Java8Compatibility" : "Java8Compatibility", - "com.google.common.base.JdkPattern" : "JdkPattern", - "com.google.common.base.JdkPattern$JdkMatcher" : "JdkPattern.JdkMatcher", - "com.google.common.base.Joiner" : "Joiner", - "com.google.common.base.Joiner$MapJoiner" : "Joiner.MapJoiner", - "com.google.common.base.MoreObjects" : "MoreObjects", - "com.google.common.base.MoreObjects$ToStringHelper" : "MoreObjects.ToStringHelper", - "com.google.common.base.MoreObjects$ToStringHelper$UnconditionalValueHolder" : "MoreObjects.ToStringHelper.UnconditionalValueHolder", - "com.google.common.base.MoreObjects$ToStringHelper$ValueHolder" : "MoreObjects.ToStringHelper.ValueHolder", - "com.google.common.base.NullnessCasts" : "NullnessCasts", - "com.google.common.base.Objects" : "Objects", - "com.google.common.base.Optional" : "Optional", - "com.google.common.base.PairwiseEquivalence" : "PairwiseEquivalence", - "com.google.common.base.ParametricNullness" : "ParametricNullness", - "com.google.common.base.PatternCompiler" : "PatternCompiler", - "com.google.common.base.Platform" : "Platform", - "com.google.common.base.Platform$JdkPatternCompiler" : "Platform.JdkPatternCompiler", - "com.google.common.base.Preconditions" : "Preconditions", - "com.google.common.base.Predicate" : "Predicate", - "com.google.common.base.Predicates" : "Predicates", - "com.google.common.base.Predicates$AndPredicate" : "Predicates.AndPredicate", - "com.google.common.base.Predicates$CompositionPredicate" : "Predicates.CompositionPredicate", - "com.google.common.base.Predicates$ContainsPatternFromStringPredicate" : "Predicates.ContainsPatternFromStringPredicate", - "com.google.common.base.Predicates$ContainsPatternPredicate" : "Predicates.ContainsPatternPredicate", - "com.google.common.base.Predicates$InPredicate" : "Predicates.InPredicate", - "com.google.common.base.Predicates$InstanceOfPredicate" : "Predicates.InstanceOfPredicate", - "com.google.common.base.Predicates$IsEqualToPredicate" : "Predicates.IsEqualToPredicate", - "com.google.common.base.Predicates$NotPredicate" : "Predicates.NotPredicate", - "com.google.common.base.Predicates$ObjectPredicate" : "Predicates.ObjectPredicate", - "com.google.common.base.Predicates$OrPredicate" : "Predicates.OrPredicate", - "com.google.common.base.Predicates$SubtypeOfPredicate" : "Predicates.SubtypeOfPredicate", - "com.google.common.base.Present" : "Present", - "com.google.common.base.SmallCharMatcher" : "SmallCharMatcher", - "com.google.common.base.Splitter" : "Splitter", - "com.google.common.base.Splitter$MapSplitter" : "Splitter.MapSplitter", - "com.google.common.base.Splitter$SplittingIterator" : "Splitter.SplittingIterator", - "com.google.common.base.Splitter$Strategy" : "Splitter.Strategy", - "com.google.common.base.StandardSystemProperty" : "StandardSystemProperty", - "com.google.common.base.Stopwatch" : "Stopwatch", - "com.google.common.base.Strings" : "Strings", - "com.google.common.base.Supplier" : "Supplier", - "com.google.common.base.Suppliers" : "Suppliers", - "com.google.common.base.Suppliers$ExpiringMemoizingSupplier" : "Suppliers.ExpiringMemoizingSupplier", - "com.google.common.base.Suppliers$MemoizingSupplier" : "Suppliers.MemoizingSupplier", - "com.google.common.base.Suppliers$NonSerializableMemoizingSupplier" : "Suppliers.NonSerializableMemoizingSupplier", - "com.google.common.base.Suppliers$SupplierComposition" : "Suppliers.SupplierComposition", - "com.google.common.base.Suppliers$SupplierFunction" : "Suppliers.SupplierFunction", - "com.google.common.base.Suppliers$SupplierFunctionImpl" : "Suppliers.SupplierFunctionImpl", - "com.google.common.base.Suppliers$SupplierOfInstance" : "Suppliers.SupplierOfInstance", - "com.google.common.base.Suppliers$ThreadSafeSupplier" : "Suppliers.ThreadSafeSupplier", - "com.google.common.base.Throwables" : "Throwables", - "com.google.common.base.Ticker" : "Ticker", - "com.google.common.base.Utf8" : "Utf8", - "com.google.common.base.Verify" : "Verify", - "com.google.common.base.VerifyException" : "VerifyException", - "com.google.common.base.internal.Finalizer" : "Finalizer", - "com.google.common.base.package-info" : "package-info", - "com.google.common.cache.AbstractCache" : "AbstractCache", - "com.google.common.cache.AbstractCache$SimpleStatsCounter" : "AbstractCache.SimpleStatsCounter", - "com.google.common.cache.AbstractCache$StatsCounter" : "AbstractCache.StatsCounter", - "com.google.common.cache.AbstractLoadingCache" : "AbstractLoadingCache", - "com.google.common.cache.Cache" : "Cache", - "com.google.common.cache.CacheBuilder" : "CacheBuilder", - "com.google.common.cache.CacheBuilder$LoggerHolder" : "CacheBuilder.LoggerHolder", - "com.google.common.cache.CacheBuilder$NullListener" : "CacheBuilder.NullListener", - "com.google.common.cache.CacheBuilder$OneWeigher" : "CacheBuilder.OneWeigher", - "com.google.common.cache.CacheBuilderSpec" : "CacheBuilderSpec", - "com.google.common.cache.CacheBuilderSpec$AccessDurationParser" : "CacheBuilderSpec.AccessDurationParser", - "com.google.common.cache.CacheBuilderSpec$ConcurrencyLevelParser" : "CacheBuilderSpec.ConcurrencyLevelParser", - "com.google.common.cache.CacheBuilderSpec$DurationParser" : "CacheBuilderSpec.DurationParser", - "com.google.common.cache.CacheBuilderSpec$InitialCapacityParser" : "CacheBuilderSpec.InitialCapacityParser", - "com.google.common.cache.CacheBuilderSpec$IntegerParser" : "CacheBuilderSpec.IntegerParser", - "com.google.common.cache.CacheBuilderSpec$KeyStrengthParser" : "CacheBuilderSpec.KeyStrengthParser", - "com.google.common.cache.CacheBuilderSpec$LongParser" : "CacheBuilderSpec.LongParser", - "com.google.common.cache.CacheBuilderSpec$MaximumSizeParser" : "CacheBuilderSpec.MaximumSizeParser", - "com.google.common.cache.CacheBuilderSpec$MaximumWeightParser" : "CacheBuilderSpec.MaximumWeightParser", - "com.google.common.cache.CacheBuilderSpec$RecordStatsParser" : "CacheBuilderSpec.RecordStatsParser", - "com.google.common.cache.CacheBuilderSpec$RefreshDurationParser" : "CacheBuilderSpec.RefreshDurationParser", - "com.google.common.cache.CacheBuilderSpec$ValueParser" : "CacheBuilderSpec.ValueParser", - "com.google.common.cache.CacheBuilderSpec$ValueStrengthParser" : "CacheBuilderSpec.ValueStrengthParser", - "com.google.common.cache.CacheBuilderSpec$WriteDurationParser" : "CacheBuilderSpec.WriteDurationParser", - "com.google.common.cache.CacheLoader" : "CacheLoader", - "com.google.common.cache.CacheLoader$FunctionToCacheLoader" : "CacheLoader.FunctionToCacheLoader", - "com.google.common.cache.CacheLoader$InvalidCacheLoadException" : "CacheLoader.InvalidCacheLoadException", - "com.google.common.cache.CacheLoader$SupplierToCacheLoader" : "CacheLoader.SupplierToCacheLoader", - "com.google.common.cache.CacheLoader$UnsupportedLoadingOperationException" : "CacheLoader.UnsupportedLoadingOperationException", - "com.google.common.cache.CacheStats" : "CacheStats", - "com.google.common.cache.ElementTypesAreNonnullByDefault" : "ElementTypesAreNonnullByDefault", - "com.google.common.cache.ForwardingCache" : "ForwardingCache", - "com.google.common.cache.ForwardingCache$SimpleForwardingCache" : "ForwardingCache.SimpleForwardingCache", - "com.google.common.cache.ForwardingLoadingCache" : "ForwardingLoadingCache", - "com.google.common.cache.ForwardingLoadingCache$SimpleForwardingLoadingCache" : "ForwardingLoadingCache.SimpleForwardingLoadingCache", - "com.google.common.cache.IgnoreJRERequirement" : "IgnoreJRERequirement", - "com.google.common.cache.LoadingCache" : "LoadingCache", - "com.google.common.cache.LocalCache" : "LocalCache", - "com.google.common.cache.LocalCache$AbstractCacheSet" : "LocalCache.AbstractCacheSet", - "com.google.common.cache.LocalCache$AbstractReferenceEntry" : "LocalCache.AbstractReferenceEntry", - "com.google.common.cache.LocalCache$AccessQueue" : "LocalCache.AccessQueue", - "com.google.common.cache.LocalCache$ComputingValueReference" : "LocalCache.ComputingValueReference", - "com.google.common.cache.LocalCache$EntryFactory" : "LocalCache.EntryFactory", - "com.google.common.cache.LocalCache$EntryIterator" : "LocalCache.EntryIterator", - "com.google.common.cache.LocalCache$EntrySet" : "LocalCache.EntrySet", - "com.google.common.cache.LocalCache$HashIterator" : "LocalCache.HashIterator", - "com.google.common.cache.LocalCache$KeyIterator" : "LocalCache.KeyIterator", - "com.google.common.cache.LocalCache$KeySet" : "LocalCache.KeySet", - "com.google.common.cache.LocalCache$LoadingSerializationProxy" : "LocalCache.LoadingSerializationProxy", - "com.google.common.cache.LocalCache$LoadingValueReference" : "LocalCache.LoadingValueReference", - "com.google.common.cache.LocalCache$LocalLoadingCache" : "LocalCache.LocalLoadingCache", - "com.google.common.cache.LocalCache$LocalManualCache" : "LocalCache.LocalManualCache", - "com.google.common.cache.LocalCache$ManualSerializationProxy" : "LocalCache.ManualSerializationProxy", - "com.google.common.cache.LocalCache$NullEntry" : "LocalCache.NullEntry", - "com.google.common.cache.LocalCache$Segment" : "LocalCache.Segment", - "com.google.common.cache.LocalCache$SoftValueReference" : "LocalCache.SoftValueReference", - "com.google.common.cache.LocalCache$Strength" : "LocalCache.Strength", - "com.google.common.cache.LocalCache$StrongAccessEntry" : "LocalCache.StrongAccessEntry", - "com.google.common.cache.LocalCache$StrongAccessWriteEntry" : "LocalCache.StrongAccessWriteEntry", - "com.google.common.cache.LocalCache$StrongEntry" : "LocalCache.StrongEntry", - "com.google.common.cache.LocalCache$StrongValueReference" : "LocalCache.StrongValueReference", - "com.google.common.cache.LocalCache$StrongWriteEntry" : "LocalCache.StrongWriteEntry", - "com.google.common.cache.LocalCache$ValueIterator" : "LocalCache.ValueIterator", - "com.google.common.cache.LocalCache$ValueReference" : "LocalCache.ValueReference", - "com.google.common.cache.LocalCache$Values" : "LocalCache.Values", - "com.google.common.cache.LocalCache$WeakAccessEntry" : "LocalCache.WeakAccessEntry", - "com.google.common.cache.LocalCache$WeakAccessWriteEntry" : "LocalCache.WeakAccessWriteEntry", - "com.google.common.cache.LocalCache$WeakEntry" : "LocalCache.WeakEntry", - "com.google.common.cache.LocalCache$WeakValueReference" : "LocalCache.WeakValueReference", - "com.google.common.cache.LocalCache$WeakWriteEntry" : "LocalCache.WeakWriteEntry", - "com.google.common.cache.LocalCache$WeightedSoftValueReference" : "LocalCache.WeightedSoftValueReference", - "com.google.common.cache.LocalCache$WeightedStrongValueReference" : "LocalCache.WeightedStrongValueReference", - "com.google.common.cache.LocalCache$WeightedWeakValueReference" : "LocalCache.WeightedWeakValueReference", - "com.google.common.cache.LocalCache$WriteQueue" : "LocalCache.WriteQueue", - "com.google.common.cache.LocalCache$WriteThroughEntry" : "LocalCache.WriteThroughEntry", - "com.google.common.cache.LongAddable" : "LongAddable", - "com.google.common.cache.LongAddables" : "LongAddables", - "com.google.common.cache.LongAddables$PureJavaLongAddable" : "LongAddables.PureJavaLongAddable", - "com.google.common.cache.LongAdder" : "LongAdder", - "com.google.common.cache.ParametricNullness" : "ParametricNullness", - "com.google.common.cache.ReferenceEntry" : "ReferenceEntry", - "com.google.common.cache.RemovalCause" : "RemovalCause", - "com.google.common.cache.RemovalListener" : "RemovalListener", - "com.google.common.cache.RemovalListeners" : "RemovalListeners", - "com.google.common.cache.RemovalNotification" : "RemovalNotification", - "com.google.common.cache.Striped64" : "Striped64", - "com.google.common.cache.Striped64$Cell" : "Striped64.Cell", - "com.google.common.cache.Weigher" : "Weigher", - "com.google.common.cache.package-info" : "package-info", - "com.google.common.collect.AbstractBiMap" : "AbstractBiMap", - "com.google.common.collect.AbstractBiMap$BiMapEntry" : "AbstractBiMap.BiMapEntry", - "com.google.common.collect.AbstractBiMap$EntrySet" : "AbstractBiMap.EntrySet", - "com.google.common.collect.AbstractBiMap$Inverse" : "AbstractBiMap.Inverse", - "com.google.common.collect.AbstractBiMap$KeySet" : "AbstractBiMap.KeySet", - "com.google.common.collect.AbstractBiMap$ValueSet" : "AbstractBiMap.ValueSet", - "com.google.common.collect.AbstractIndexedListIterator" : "AbstractIndexedListIterator", - "com.google.common.collect.AbstractIterator" : "AbstractIterator", - "com.google.common.collect.AbstractIterator$State" : "AbstractIterator.State", - "com.google.common.collect.AbstractListMultimap" : "AbstractListMultimap", - "com.google.common.collect.AbstractMapBasedMultimap" : "AbstractMapBasedMultimap", - "com.google.common.collect.AbstractMapBasedMultimap$AsMap" : "AbstractMapBasedMultimap.AsMap", - "com.google.common.collect.AbstractMapBasedMultimap$AsMap$AsMapEntries" : "AbstractMapBasedMultimap.AsMap.AsMapEntries", - "com.google.common.collect.AbstractMapBasedMultimap$AsMap$AsMapIterator" : "AbstractMapBasedMultimap.AsMap.AsMapIterator", - "com.google.common.collect.AbstractMapBasedMultimap$Itr" : "AbstractMapBasedMultimap.Itr", - "com.google.common.collect.AbstractMapBasedMultimap$KeySet" : "AbstractMapBasedMultimap.KeySet", - "com.google.common.collect.AbstractMapBasedMultimap$NavigableAsMap" : "AbstractMapBasedMultimap.NavigableAsMap", - "com.google.common.collect.AbstractMapBasedMultimap$NavigableKeySet" : "AbstractMapBasedMultimap.NavigableKeySet", - "com.google.common.collect.AbstractMapBasedMultimap$RandomAccessWrappedList" : "AbstractMapBasedMultimap.RandomAccessWrappedList", - "com.google.common.collect.AbstractMapBasedMultimap$SortedAsMap" : "AbstractMapBasedMultimap.SortedAsMap", - "com.google.common.collect.AbstractMapBasedMultimap$SortedKeySet" : "AbstractMapBasedMultimap.SortedKeySet", - "com.google.common.collect.AbstractMapBasedMultimap$WrappedCollection" : "AbstractMapBasedMultimap.WrappedCollection", - "com.google.common.collect.AbstractMapBasedMultimap$WrappedCollection$WrappedIterator" : "AbstractMapBasedMultimap.WrappedCollection.WrappedIterator", - "com.google.common.collect.AbstractMapBasedMultimap$WrappedList" : "AbstractMapBasedMultimap.WrappedList", - "com.google.common.collect.AbstractMapBasedMultimap$WrappedList$WrappedListIterator" : "AbstractMapBasedMultimap.WrappedList.WrappedListIterator", - "com.google.common.collect.AbstractMapBasedMultimap$WrappedNavigableSet" : "AbstractMapBasedMultimap.WrappedNavigableSet", - "com.google.common.collect.AbstractMapBasedMultimap$WrappedSet" : "AbstractMapBasedMultimap.WrappedSet", - "com.google.common.collect.AbstractMapBasedMultimap$WrappedSortedSet" : "AbstractMapBasedMultimap.WrappedSortedSet", - "com.google.common.collect.AbstractMapBasedMultiset" : "AbstractMapBasedMultiset", - "com.google.common.collect.AbstractMapBasedMultiset$MapBasedMultisetIterator" : "AbstractMapBasedMultiset.MapBasedMultisetIterator", - "com.google.common.collect.AbstractMapEntry" : "AbstractMapEntry", - "com.google.common.collect.AbstractMultimap" : "AbstractMultimap", - "com.google.common.collect.AbstractMultimap$Entries" : "AbstractMultimap.Entries", - "com.google.common.collect.AbstractMultimap$EntrySet" : "AbstractMultimap.EntrySet", - "com.google.common.collect.AbstractMultimap$Values" : "AbstractMultimap.Values", - "com.google.common.collect.AbstractMultiset" : "AbstractMultiset", - "com.google.common.collect.AbstractMultiset$ElementSet" : "AbstractMultiset.ElementSet", - "com.google.common.collect.AbstractMultiset$EntrySet" : "AbstractMultiset.EntrySet", - "com.google.common.collect.AbstractNavigableMap" : "AbstractNavigableMap", - "com.google.common.collect.AbstractNavigableMap$DescendingMap" : "AbstractNavigableMap.DescendingMap", - "com.google.common.collect.AbstractRangeSet" : "AbstractRangeSet", - "com.google.common.collect.AbstractSequentialIterator" : "AbstractSequentialIterator", - "com.google.common.collect.AbstractSetMultimap" : "AbstractSetMultimap", - "com.google.common.collect.AbstractSortedKeySortedSetMultimap" : "AbstractSortedKeySortedSetMultimap", - "com.google.common.collect.AbstractSortedMultiset" : "AbstractSortedMultiset", - "com.google.common.collect.AbstractSortedSetMultimap" : "AbstractSortedSetMultimap", - "com.google.common.collect.AbstractTable" : "AbstractTable", - "com.google.common.collect.AbstractTable$CellSet" : "AbstractTable.CellSet", - "com.google.common.collect.AbstractTable$Values" : "AbstractTable.Values", - "com.google.common.collect.AllEqualOrdering" : "AllEqualOrdering", - "com.google.common.collect.ArrayListMultimap" : "ArrayListMultimap", - "com.google.common.collect.ArrayListMultimapGwtSerializationDependencies" : "ArrayListMultimapGwtSerializationDependencies", - "com.google.common.collect.ArrayTable" : "ArrayTable", - "com.google.common.collect.ArrayTable$ArrayMap" : "ArrayTable.ArrayMap", - "com.google.common.collect.ArrayTable$Column" : "ArrayTable.Column", - "com.google.common.collect.ArrayTable$ColumnMap" : "ArrayTable.ColumnMap", - "com.google.common.collect.ArrayTable$Row" : "ArrayTable.Row", - "com.google.common.collect.ArrayTable$RowMap" : "ArrayTable.RowMap", - "com.google.common.collect.BaseImmutableMultimap" : "BaseImmutableMultimap", - "com.google.common.collect.BiMap" : "BiMap", - "com.google.common.collect.BoundType" : "BoundType", - "com.google.common.collect.ByFunctionOrdering" : "ByFunctionOrdering", - "com.google.common.collect.CartesianList" : "CartesianList", - "com.google.common.collect.ClassToInstanceMap" : "ClassToInstanceMap", - "com.google.common.collect.CollectCollectors" : "CollectCollectors", - "com.google.common.collect.CollectCollectors$EnumMapAccumulator" : "CollectCollectors.EnumMapAccumulator", - "com.google.common.collect.CollectCollectors$EnumSetAccumulator" : "CollectCollectors.EnumSetAccumulator", - "com.google.common.collect.CollectPreconditions" : "CollectPreconditions", - "com.google.common.collect.CollectSpliterators" : "CollectSpliterators", - "com.google.common.collect.CollectSpliterators$FlatMapSpliterator" : "CollectSpliterators.FlatMapSpliterator", - "com.google.common.collect.CollectSpliterators$FlatMapSpliterator$Factory" : "CollectSpliterators.FlatMapSpliterator.Factory", - "com.google.common.collect.CollectSpliterators$FlatMapSpliteratorOfDouble" : "CollectSpliterators.FlatMapSpliteratorOfDouble", - "com.google.common.collect.CollectSpliterators$FlatMapSpliteratorOfInt" : "CollectSpliterators.FlatMapSpliteratorOfInt", - "com.google.common.collect.CollectSpliterators$FlatMapSpliteratorOfLong" : "CollectSpliterators.FlatMapSpliteratorOfLong", - "com.google.common.collect.CollectSpliterators$FlatMapSpliteratorOfObject" : "CollectSpliterators.FlatMapSpliteratorOfObject", - "com.google.common.collect.CollectSpliterators$FlatMapSpliteratorOfPrimitive" : "CollectSpliterators.FlatMapSpliteratorOfPrimitive", - "com.google.common.collect.Collections2" : "Collections2", - "com.google.common.collect.Collections2$FilteredCollection" : "Collections2.FilteredCollection", - "com.google.common.collect.Collections2$OrderedPermutationCollection" : "Collections2.OrderedPermutationCollection", - "com.google.common.collect.Collections2$OrderedPermutationIterator" : "Collections2.OrderedPermutationIterator", - "com.google.common.collect.Collections2$PermutationCollection" : "Collections2.PermutationCollection", - "com.google.common.collect.Collections2$PermutationIterator" : "Collections2.PermutationIterator", - "com.google.common.collect.Collections2$TransformedCollection" : "Collections2.TransformedCollection", - "com.google.common.collect.CompactHashMap" : "CompactHashMap", - "com.google.common.collect.CompactHashMap$EntrySetView" : "CompactHashMap.EntrySetView", - "com.google.common.collect.CompactHashMap$Itr" : "CompactHashMap.Itr", - "com.google.common.collect.CompactHashMap$KeySetView" : "CompactHashMap.KeySetView", - "com.google.common.collect.CompactHashMap$MapEntry" : "CompactHashMap.MapEntry", - "com.google.common.collect.CompactHashMap$ValuesView" : "CompactHashMap.ValuesView", - "com.google.common.collect.CompactHashSet" : "CompactHashSet", - "com.google.common.collect.CompactHashing" : "CompactHashing", - "com.google.common.collect.CompactLinkedHashMap" : "CompactLinkedHashMap", - "com.google.common.collect.CompactLinkedHashSet" : "CompactLinkedHashSet", - "com.google.common.collect.ComparatorOrdering" : "ComparatorOrdering", - "com.google.common.collect.Comparators" : "Comparators", - "com.google.common.collect.ComparisonChain" : "ComparisonChain", - "com.google.common.collect.ComparisonChain$InactiveComparisonChain" : "ComparisonChain.InactiveComparisonChain", - "com.google.common.collect.CompoundOrdering" : "CompoundOrdering", - "com.google.common.collect.ComputationException" : "ComputationException", - "com.google.common.collect.ConcurrentHashMultiset" : "ConcurrentHashMultiset", - "com.google.common.collect.ConcurrentHashMultiset$EntrySet" : "ConcurrentHashMultiset.EntrySet", - "com.google.common.collect.ConcurrentHashMultiset$FieldSettersHolder" : "ConcurrentHashMultiset.FieldSettersHolder", - "com.google.common.collect.ConsumingQueueIterator" : "ConsumingQueueIterator", - "com.google.common.collect.ContiguousSet" : "ContiguousSet", - "com.google.common.collect.Count" : "Count", - "com.google.common.collect.Cut" : "Cut", - "com.google.common.collect.Cut$AboveAll" : "Cut.AboveAll", - "com.google.common.collect.Cut$AboveValue" : "Cut.AboveValue", - "com.google.common.collect.Cut$BelowAll" : "Cut.BelowAll", - "com.google.common.collect.Cut$BelowValue" : "Cut.BelowValue", - "com.google.common.collect.DenseImmutableTable" : "DenseImmutableTable", - "com.google.common.collect.DenseImmutableTable$Column" : "DenseImmutableTable.Column", - "com.google.common.collect.DenseImmutableTable$ColumnMap" : "DenseImmutableTable.ColumnMap", - "com.google.common.collect.DenseImmutableTable$ImmutableArrayMap" : "DenseImmutableTable.ImmutableArrayMap", - "com.google.common.collect.DenseImmutableTable$Row" : "DenseImmutableTable.Row", - "com.google.common.collect.DenseImmutableTable$RowMap" : "DenseImmutableTable.RowMap", - "com.google.common.collect.DescendingImmutableSortedMultiset" : "DescendingImmutableSortedMultiset", - "com.google.common.collect.DescendingImmutableSortedSet" : "DescendingImmutableSortedSet", - "com.google.common.collect.DescendingMultiset" : "DescendingMultiset", - "com.google.common.collect.DiscreteDomain" : "DiscreteDomain", - "com.google.common.collect.DiscreteDomain$BigIntegerDomain" : "DiscreteDomain.BigIntegerDomain", - "com.google.common.collect.DiscreteDomain$IntegerDomain" : "DiscreteDomain.IntegerDomain", - "com.google.common.collect.DiscreteDomain$LongDomain" : "DiscreteDomain.LongDomain", - "com.google.common.collect.ElementTypesAreNonnullByDefault" : "ElementTypesAreNonnullByDefault", - "com.google.common.collect.EmptyContiguousSet" : "EmptyContiguousSet", - "com.google.common.collect.EmptyContiguousSet$SerializedForm" : "EmptyContiguousSet.SerializedForm", - "com.google.common.collect.EmptyImmutableListMultimap" : "EmptyImmutableListMultimap", - "com.google.common.collect.EmptyImmutableSetMultimap" : "EmptyImmutableSetMultimap", - "com.google.common.collect.EnumBiMap" : "EnumBiMap", - "com.google.common.collect.EnumHashBiMap" : "EnumHashBiMap", - "com.google.common.collect.EnumMultiset" : "EnumMultiset", - "com.google.common.collect.EnumMultiset$Itr" : "EnumMultiset.Itr", - "com.google.common.collect.EvictingQueue" : "EvictingQueue", - "com.google.common.collect.ExplicitOrdering" : "ExplicitOrdering", - "com.google.common.collect.FilteredEntryMultimap" : "FilteredEntryMultimap", - "com.google.common.collect.FilteredEntryMultimap$AsMap" : "FilteredEntryMultimap.AsMap", - "com.google.common.collect.FilteredEntryMultimap$Keys" : "FilteredEntryMultimap.Keys", - "com.google.common.collect.FilteredEntryMultimap$ValuePredicate" : "FilteredEntryMultimap.ValuePredicate", - "com.google.common.collect.FilteredEntrySetMultimap" : "FilteredEntrySetMultimap", - "com.google.common.collect.FilteredKeyListMultimap" : "FilteredKeyListMultimap", - "com.google.common.collect.FilteredKeyMultimap" : "FilteredKeyMultimap", - "com.google.common.collect.FilteredKeyMultimap$AddRejectingList" : "FilteredKeyMultimap.AddRejectingList", - "com.google.common.collect.FilteredKeyMultimap$AddRejectingSet" : "FilteredKeyMultimap.AddRejectingSet", - "com.google.common.collect.FilteredKeyMultimap$Entries" : "FilteredKeyMultimap.Entries", - "com.google.common.collect.FilteredKeySetMultimap" : "FilteredKeySetMultimap", - "com.google.common.collect.FilteredKeySetMultimap$EntrySet" : "FilteredKeySetMultimap.EntrySet", - "com.google.common.collect.FilteredMultimap" : "FilteredMultimap", - "com.google.common.collect.FilteredMultimapValues" : "FilteredMultimapValues", - "com.google.common.collect.FilteredSetMultimap" : "FilteredSetMultimap", - "com.google.common.collect.FluentIterable" : "FluentIterable", - "com.google.common.collect.FluentIterable$FromIterableFunction" : "FluentIterable.FromIterableFunction", - "com.google.common.collect.ForwardingBlockingDeque" : "ForwardingBlockingDeque", - "com.google.common.collect.ForwardingCollection" : "ForwardingCollection", - "com.google.common.collect.ForwardingConcurrentMap" : "ForwardingConcurrentMap", - "com.google.common.collect.ForwardingDeque" : "ForwardingDeque", - "com.google.common.collect.ForwardingImmutableCollection" : "ForwardingImmutableCollection", - "com.google.common.collect.ForwardingImmutableList" : "ForwardingImmutableList", - "com.google.common.collect.ForwardingImmutableMap" : "ForwardingImmutableMap", - "com.google.common.collect.ForwardingImmutableSet" : "ForwardingImmutableSet", - "com.google.common.collect.ForwardingIterator" : "ForwardingIterator", - "com.google.common.collect.ForwardingList" : "ForwardingList", - "com.google.common.collect.ForwardingListIterator" : "ForwardingListIterator", - "com.google.common.collect.ForwardingListMultimap" : "ForwardingListMultimap", - "com.google.common.collect.ForwardingMap" : "ForwardingMap", - "com.google.common.collect.ForwardingMap$StandardEntrySet" : "ForwardingMap.StandardEntrySet", - "com.google.common.collect.ForwardingMap$StandardKeySet" : "ForwardingMap.StandardKeySet", - "com.google.common.collect.ForwardingMap$StandardValues" : "ForwardingMap.StandardValues", - "com.google.common.collect.ForwardingMapEntry" : "ForwardingMapEntry", - "com.google.common.collect.ForwardingMultimap" : "ForwardingMultimap", - "com.google.common.collect.ForwardingMultiset" : "ForwardingMultiset", - "com.google.common.collect.ForwardingMultiset$StandardElementSet" : "ForwardingMultiset.StandardElementSet", - "com.google.common.collect.ForwardingNavigableMap" : "ForwardingNavigableMap", - "com.google.common.collect.ForwardingNavigableMap$StandardDescendingMap" : "ForwardingNavigableMap.StandardDescendingMap", - "com.google.common.collect.ForwardingNavigableMap$StandardNavigableKeySet" : "ForwardingNavigableMap.StandardNavigableKeySet", - "com.google.common.collect.ForwardingNavigableSet" : "ForwardingNavigableSet", - "com.google.common.collect.ForwardingNavigableSet$StandardDescendingSet" : "ForwardingNavigableSet.StandardDescendingSet", - "com.google.common.collect.ForwardingObject" : "ForwardingObject", - "com.google.common.collect.ForwardingQueue" : "ForwardingQueue", - "com.google.common.collect.ForwardingSet" : "ForwardingSet", - "com.google.common.collect.ForwardingSetMultimap" : "ForwardingSetMultimap", - "com.google.common.collect.ForwardingSortedMap" : "ForwardingSortedMap", - "com.google.common.collect.ForwardingSortedMap$StandardKeySet" : "ForwardingSortedMap.StandardKeySet", - "com.google.common.collect.ForwardingSortedMultiset" : "ForwardingSortedMultiset", - "com.google.common.collect.ForwardingSortedMultiset$StandardDescendingMultiset" : "ForwardingSortedMultiset.StandardDescendingMultiset", - "com.google.common.collect.ForwardingSortedMultiset$StandardElementSet" : "ForwardingSortedMultiset.StandardElementSet", - "com.google.common.collect.ForwardingSortedSet" : "ForwardingSortedSet", - "com.google.common.collect.ForwardingSortedSetMultimap" : "ForwardingSortedSetMultimap", - "com.google.common.collect.ForwardingTable" : "ForwardingTable", - "com.google.common.collect.GeneralRange" : "GeneralRange", - "com.google.common.collect.GwtTransient" : "GwtTransient", - "com.google.common.collect.HashBasedTable" : "HashBasedTable", - "com.google.common.collect.HashBasedTable$Factory" : "HashBasedTable.Factory", - "com.google.common.collect.HashBiMap" : "HashBiMap", - "com.google.common.collect.HashBiMap$BiEntry" : "HashBiMap.BiEntry", - "com.google.common.collect.HashBiMap$Inverse" : "HashBiMap.Inverse", - "com.google.common.collect.HashBiMap$Inverse$InverseKeySet" : "HashBiMap.Inverse.InverseKeySet", - "com.google.common.collect.HashBiMap$InverseSerializedForm" : "HashBiMap.InverseSerializedForm", - "com.google.common.collect.HashBiMap$Itr" : "HashBiMap.Itr", - "com.google.common.collect.HashBiMap$KeySet" : "HashBiMap.KeySet", - "com.google.common.collect.HashMultimap" : "HashMultimap", - "com.google.common.collect.HashMultimapGwtSerializationDependencies" : "HashMultimapGwtSerializationDependencies", - "com.google.common.collect.HashMultiset" : "HashMultiset", - "com.google.common.collect.Hashing" : "Hashing", - "com.google.common.collect.IgnoreJRERequirement" : "IgnoreJRERequirement", - "com.google.common.collect.ImmutableAsList" : "ImmutableAsList", - "com.google.common.collect.ImmutableAsList$SerializedForm" : "ImmutableAsList.SerializedForm", - "com.google.common.collect.ImmutableBiMap" : "ImmutableBiMap", - "com.google.common.collect.ImmutableBiMap$Builder" : "ImmutableBiMap.Builder", - "com.google.common.collect.ImmutableBiMap$SerializedForm" : "ImmutableBiMap.SerializedForm", - "com.google.common.collect.ImmutableClassToInstanceMap" : "ImmutableClassToInstanceMap", - "com.google.common.collect.ImmutableClassToInstanceMap$Builder" : "ImmutableClassToInstanceMap.Builder", - "com.google.common.collect.ImmutableCollection" : "ImmutableCollection", - "com.google.common.collect.ImmutableCollection$Builder" : "ImmutableCollection.Builder", - "com.google.common.collect.ImmutableEntry" : "ImmutableEntry", - "com.google.common.collect.ImmutableEnumMap" : "ImmutableEnumMap", - "com.google.common.collect.ImmutableEnumMap$EnumSerializedForm" : "ImmutableEnumMap.EnumSerializedForm", - "com.google.common.collect.ImmutableEnumSet" : "ImmutableEnumSet", - "com.google.common.collect.ImmutableEnumSet$EnumSerializedForm" : "ImmutableEnumSet.EnumSerializedForm", - "com.google.common.collect.ImmutableList" : "ImmutableList", - "com.google.common.collect.ImmutableList$Builder" : "ImmutableList.Builder", - "com.google.common.collect.ImmutableList$ReverseImmutableList" : "ImmutableList.ReverseImmutableList", - "com.google.common.collect.ImmutableList$SerializedForm" : "ImmutableList.SerializedForm", - "com.google.common.collect.ImmutableList$SubList" : "ImmutableList.SubList", - "com.google.common.collect.ImmutableListMultimap" : "ImmutableListMultimap", - "com.google.common.collect.ImmutableListMultimap$Builder" : "ImmutableListMultimap.Builder", - "com.google.common.collect.ImmutableMap" : "ImmutableMap", - "com.google.common.collect.ImmutableMap$Builder" : "ImmutableMap.Builder", - "com.google.common.collect.ImmutableMap$IteratorBasedImmutableMap" : "ImmutableMap.IteratorBasedImmutableMap", - "com.google.common.collect.ImmutableMap$MapViewOfValuesAsSingletonSets" : "ImmutableMap.MapViewOfValuesAsSingletonSets", - "com.google.common.collect.ImmutableMap$SerializedForm" : "ImmutableMap.SerializedForm", - "com.google.common.collect.ImmutableMapEntry" : "ImmutableMapEntry", - "com.google.common.collect.ImmutableMapEntry$NonTerminalImmutableBiMapEntry" : "ImmutableMapEntry.NonTerminalImmutableBiMapEntry", - "com.google.common.collect.ImmutableMapEntry$NonTerminalImmutableMapEntry" : "ImmutableMapEntry.NonTerminalImmutableMapEntry", - "com.google.common.collect.ImmutableMapEntrySet" : "ImmutableMapEntrySet", - "com.google.common.collect.ImmutableMapEntrySet$EntrySetSerializedForm" : "ImmutableMapEntrySet.EntrySetSerializedForm", - "com.google.common.collect.ImmutableMapEntrySet$RegularEntrySet" : "ImmutableMapEntrySet.RegularEntrySet", - "com.google.common.collect.ImmutableMapKeySet" : "ImmutableMapKeySet", - "com.google.common.collect.ImmutableMapKeySet$KeySetSerializedForm" : "ImmutableMapKeySet.KeySetSerializedForm", - "com.google.common.collect.ImmutableMapValues" : "ImmutableMapValues", - "com.google.common.collect.ImmutableMapValues$SerializedForm" : "ImmutableMapValues.SerializedForm", - "com.google.common.collect.ImmutableMultimap" : "ImmutableMultimap", - "com.google.common.collect.ImmutableMultimap$Builder" : "ImmutableMultimap.Builder", - "com.google.common.collect.ImmutableMultimap$EntryCollection" : "ImmutableMultimap.EntryCollection", - "com.google.common.collect.ImmutableMultimap$FieldSettersHolder" : "ImmutableMultimap.FieldSettersHolder", - "com.google.common.collect.ImmutableMultimap$Keys" : "ImmutableMultimap.Keys", - "com.google.common.collect.ImmutableMultimap$KeysSerializedForm" : "ImmutableMultimap.KeysSerializedForm", - "com.google.common.collect.ImmutableMultimap$Values" : "ImmutableMultimap.Values", - "com.google.common.collect.ImmutableMultiset" : "ImmutableMultiset", - "com.google.common.collect.ImmutableMultiset$Builder" : "ImmutableMultiset.Builder", - "com.google.common.collect.ImmutableMultiset$ElementSet" : "ImmutableMultiset.ElementSet", - "com.google.common.collect.ImmutableMultiset$EntrySet" : "ImmutableMultiset.EntrySet", - "com.google.common.collect.ImmutableMultiset$EntrySetSerializedForm" : "ImmutableMultiset.EntrySetSerializedForm", - "com.google.common.collect.ImmutableMultiset$SerializedForm" : "ImmutableMultiset.SerializedForm", - "com.google.common.collect.ImmutableMultisetGwtSerializationDependencies" : "ImmutableMultisetGwtSerializationDependencies", - "com.google.common.collect.ImmutableRangeMap" : "ImmutableRangeMap", - "com.google.common.collect.ImmutableRangeMap$Builder" : "ImmutableRangeMap.Builder", - "com.google.common.collect.ImmutableRangeMap$SerializedForm" : "ImmutableRangeMap.SerializedForm", - "com.google.common.collect.ImmutableRangeSet" : "ImmutableRangeSet", - "com.google.common.collect.ImmutableRangeSet$AsSet" : "ImmutableRangeSet.AsSet", - "com.google.common.collect.ImmutableRangeSet$AsSetSerializedForm" : "ImmutableRangeSet.AsSetSerializedForm", - "com.google.common.collect.ImmutableRangeSet$Builder" : "ImmutableRangeSet.Builder", - "com.google.common.collect.ImmutableRangeSet$ComplementRanges" : "ImmutableRangeSet.ComplementRanges", - "com.google.common.collect.ImmutableRangeSet$SerializedForm" : "ImmutableRangeSet.SerializedForm", - "com.google.common.collect.ImmutableSet" : "ImmutableSet", - "com.google.common.collect.ImmutableSet$Builder" : "ImmutableSet.Builder", - "com.google.common.collect.ImmutableSet$CachingAsList" : "ImmutableSet.CachingAsList", - "com.google.common.collect.ImmutableSet$EmptySetBuilderImpl" : "ImmutableSet.EmptySetBuilderImpl", - "com.google.common.collect.ImmutableSet$Indexed" : "ImmutableSet.Indexed", - "com.google.common.collect.ImmutableSet$JdkBackedSetBuilderImpl" : "ImmutableSet.JdkBackedSetBuilderImpl", - "com.google.common.collect.ImmutableSet$RegularSetBuilderImpl" : "ImmutableSet.RegularSetBuilderImpl", - "com.google.common.collect.ImmutableSet$SerializedForm" : "ImmutableSet.SerializedForm", - "com.google.common.collect.ImmutableSet$SetBuilderImpl" : "ImmutableSet.SetBuilderImpl", - "com.google.common.collect.ImmutableSetMultimap" : "ImmutableSetMultimap", - "com.google.common.collect.ImmutableSetMultimap$Builder" : "ImmutableSetMultimap.Builder", - "com.google.common.collect.ImmutableSetMultimap$EntrySet" : "ImmutableSetMultimap.EntrySet", - "com.google.common.collect.ImmutableSetMultimap$SetFieldSettersHolder" : "ImmutableSetMultimap.SetFieldSettersHolder", - "com.google.common.collect.ImmutableSortedAsList" : "ImmutableSortedAsList", - "com.google.common.collect.ImmutableSortedMap" : "ImmutableSortedMap", - "com.google.common.collect.ImmutableSortedMap$Builder" : "ImmutableSortedMap.Builder", - "com.google.common.collect.ImmutableSortedMap$SerializedForm" : "ImmutableSortedMap.SerializedForm", - "com.google.common.collect.ImmutableSortedMultiset" : "ImmutableSortedMultiset", - "com.google.common.collect.ImmutableSortedMultiset$Builder" : "ImmutableSortedMultiset.Builder", - "com.google.common.collect.ImmutableSortedMultiset$SerializedForm" : "ImmutableSortedMultiset.SerializedForm", - "com.google.common.collect.ImmutableSortedSet" : "ImmutableSortedSet", - "com.google.common.collect.ImmutableSortedSet$Builder" : "ImmutableSortedSet.Builder", - "com.google.common.collect.ImmutableSortedSet$SerializedForm" : "ImmutableSortedSet.SerializedForm", - "com.google.common.collect.ImmutableTable" : "ImmutableTable", - "com.google.common.collect.ImmutableTable$Builder" : "ImmutableTable.Builder", - "com.google.common.collect.ImmutableTable$SerializedForm" : "ImmutableTable.SerializedForm", - "com.google.common.collect.IndexedImmutableSet" : "IndexedImmutableSet", - "com.google.common.collect.Interner" : "Interner", - "com.google.common.collect.Interners" : "Interners", - "com.google.common.collect.Interners$InternerBuilder" : "Interners.InternerBuilder", - "com.google.common.collect.Interners$InternerFunction" : "Interners.InternerFunction", - "com.google.common.collect.Interners$InternerImpl" : "Interners.InternerImpl", - "com.google.common.collect.Iterables" : "Iterables", - "com.google.common.collect.Iterables$UnmodifiableIterable" : "Iterables.UnmodifiableIterable", - "com.google.common.collect.Iterators" : "Iterators", - "com.google.common.collect.Iterators$ArrayItr" : "Iterators.ArrayItr", - "com.google.common.collect.Iterators$ConcatenatedIterator" : "Iterators.ConcatenatedIterator", - "com.google.common.collect.Iterators$EmptyModifiableIterator" : "Iterators.EmptyModifiableIterator", - "com.google.common.collect.Iterators$MergingIterator" : "Iterators.MergingIterator", - "com.google.common.collect.Iterators$PeekingImpl" : "Iterators.PeekingImpl", - "com.google.common.collect.Iterators$SingletonIterator" : "Iterators.SingletonIterator", - "com.google.common.collect.JdkBackedImmutableBiMap" : "JdkBackedImmutableBiMap", - "com.google.common.collect.JdkBackedImmutableBiMap$InverseEntries" : "JdkBackedImmutableBiMap.InverseEntries", - "com.google.common.collect.JdkBackedImmutableMap" : "JdkBackedImmutableMap", - "com.google.common.collect.JdkBackedImmutableMultiset" : "JdkBackedImmutableMultiset", - "com.google.common.collect.JdkBackedImmutableSet" : "JdkBackedImmutableSet", - "com.google.common.collect.LexicographicalOrdering" : "LexicographicalOrdering", - "com.google.common.collect.LinkedHashMultimap" : "LinkedHashMultimap", - "com.google.common.collect.LinkedHashMultimap$ValueEntry" : "LinkedHashMultimap.ValueEntry", - "com.google.common.collect.LinkedHashMultimap$ValueSet" : "LinkedHashMultimap.ValueSet", - "com.google.common.collect.LinkedHashMultimap$ValueSetLink" : "LinkedHashMultimap.ValueSetLink", - "com.google.common.collect.LinkedHashMultimapGwtSerializationDependencies" : "LinkedHashMultimapGwtSerializationDependencies", - "com.google.common.collect.LinkedHashMultiset" : "LinkedHashMultiset", - "com.google.common.collect.LinkedListMultimap" : "LinkedListMultimap", - "com.google.common.collect.LinkedListMultimap$DistinctKeyIterator" : "LinkedListMultimap.DistinctKeyIterator", - "com.google.common.collect.LinkedListMultimap$KeyList" : "LinkedListMultimap.KeyList", - "com.google.common.collect.LinkedListMultimap$Node" : "LinkedListMultimap.Node", - "com.google.common.collect.LinkedListMultimap$NodeIterator" : "LinkedListMultimap.NodeIterator", - "com.google.common.collect.LinkedListMultimap$ValueForKeyIterator" : "LinkedListMultimap.ValueForKeyIterator", - "com.google.common.collect.ListMultimap" : "ListMultimap", - "com.google.common.collect.Lists" : "Lists", - "com.google.common.collect.Lists$AbstractListWrapper" : "Lists.AbstractListWrapper", - "com.google.common.collect.Lists$CharSequenceAsList" : "Lists.CharSequenceAsList", - "com.google.common.collect.Lists$OnePlusArrayList" : "Lists.OnePlusArrayList", - "com.google.common.collect.Lists$Partition" : "Lists.Partition", - "com.google.common.collect.Lists$RandomAccessListWrapper" : "Lists.RandomAccessListWrapper", - "com.google.common.collect.Lists$RandomAccessPartition" : "Lists.RandomAccessPartition", - "com.google.common.collect.Lists$RandomAccessReverseList" : "Lists.RandomAccessReverseList", - "com.google.common.collect.Lists$ReverseList" : "Lists.ReverseList", - "com.google.common.collect.Lists$StringAsImmutableList" : "Lists.StringAsImmutableList", - "com.google.common.collect.Lists$TransformingRandomAccessList" : "Lists.TransformingRandomAccessList", - "com.google.common.collect.Lists$TransformingSequentialList" : "Lists.TransformingSequentialList", - "com.google.common.collect.Lists$TwoPlusArrayList" : "Lists.TwoPlusArrayList", - "com.google.common.collect.MapDifference" : "MapDifference", - "com.google.common.collect.MapDifference$ValueDifference" : "MapDifference.ValueDifference", - "com.google.common.collect.MapMaker" : "MapMaker", - "com.google.common.collect.MapMaker$Dummy" : "MapMaker.Dummy", - "com.google.common.collect.MapMakerInternalMap" : "MapMakerInternalMap", - "com.google.common.collect.MapMakerInternalMap$AbstractSerializationProxy" : "MapMakerInternalMap.AbstractSerializationProxy", - "com.google.common.collect.MapMakerInternalMap$AbstractStrongKeyEntry" : "MapMakerInternalMap.AbstractStrongKeyEntry", - "com.google.common.collect.MapMakerInternalMap$AbstractWeakKeyEntry" : "MapMakerInternalMap.AbstractWeakKeyEntry", - "com.google.common.collect.MapMakerInternalMap$CleanupMapTask" : "MapMakerInternalMap.CleanupMapTask", - "com.google.common.collect.MapMakerInternalMap$DummyInternalEntry" : "MapMakerInternalMap.DummyInternalEntry", - "com.google.common.collect.MapMakerInternalMap$EntryIterator" : "MapMakerInternalMap.EntryIterator", - "com.google.common.collect.MapMakerInternalMap$EntrySet" : "MapMakerInternalMap.EntrySet", - "com.google.common.collect.MapMakerInternalMap$HashIterator" : "MapMakerInternalMap.HashIterator", - "com.google.common.collect.MapMakerInternalMap$InternalEntry" : "MapMakerInternalMap.InternalEntry", - "com.google.common.collect.MapMakerInternalMap$InternalEntryHelper" : "MapMakerInternalMap.InternalEntryHelper", - "com.google.common.collect.MapMakerInternalMap$KeyIterator" : "MapMakerInternalMap.KeyIterator", - "com.google.common.collect.MapMakerInternalMap$KeySet" : "MapMakerInternalMap.KeySet", - "com.google.common.collect.MapMakerInternalMap$Segment" : "MapMakerInternalMap.Segment", - "com.google.common.collect.MapMakerInternalMap$SerializationProxy" : "MapMakerInternalMap.SerializationProxy", - "com.google.common.collect.MapMakerInternalMap$Strength" : "MapMakerInternalMap.Strength", - "com.google.common.collect.MapMakerInternalMap$StrongKeyDummyValueEntry" : "MapMakerInternalMap.StrongKeyDummyValueEntry", - "com.google.common.collect.MapMakerInternalMap$StrongKeyDummyValueEntry$Helper" : "MapMakerInternalMap.StrongKeyDummyValueEntry.Helper", - "com.google.common.collect.MapMakerInternalMap$StrongKeyDummyValueEntry$LinkedStrongKeyDummyValueEntry" : "MapMakerInternalMap.StrongKeyDummyValueEntry.LinkedStrongKeyDummyValueEntry", - "com.google.common.collect.MapMakerInternalMap$StrongKeyDummyValueSegment" : "MapMakerInternalMap.StrongKeyDummyValueSegment", - "com.google.common.collect.MapMakerInternalMap$StrongKeyStrongValueEntry" : "MapMakerInternalMap.StrongKeyStrongValueEntry", - "com.google.common.collect.MapMakerInternalMap$StrongKeyStrongValueEntry$Helper" : "MapMakerInternalMap.StrongKeyStrongValueEntry.Helper", - "com.google.common.collect.MapMakerInternalMap$StrongKeyStrongValueEntry$LinkedStrongKeyStrongValueEntry" : "MapMakerInternalMap.StrongKeyStrongValueEntry.LinkedStrongKeyStrongValueEntry", - "com.google.common.collect.MapMakerInternalMap$StrongKeyStrongValueSegment" : "MapMakerInternalMap.StrongKeyStrongValueSegment", - "com.google.common.collect.MapMakerInternalMap$StrongKeyWeakValueEntry" : "MapMakerInternalMap.StrongKeyWeakValueEntry", - "com.google.common.collect.MapMakerInternalMap$StrongKeyWeakValueEntry$Helper" : "MapMakerInternalMap.StrongKeyWeakValueEntry.Helper", - "com.google.common.collect.MapMakerInternalMap$StrongKeyWeakValueEntry$LinkedStrongKeyWeakValueEntry" : "MapMakerInternalMap.StrongKeyWeakValueEntry.LinkedStrongKeyWeakValueEntry", - "com.google.common.collect.MapMakerInternalMap$StrongKeyWeakValueSegment" : "MapMakerInternalMap.StrongKeyWeakValueSegment", - "com.google.common.collect.MapMakerInternalMap$StrongValueEntry" : "MapMakerInternalMap.StrongValueEntry", - "com.google.common.collect.MapMakerInternalMap$ValueIterator" : "MapMakerInternalMap.ValueIterator", - "com.google.common.collect.MapMakerInternalMap$Values" : "MapMakerInternalMap.Values", - "com.google.common.collect.MapMakerInternalMap$WeakKeyDummyValueEntry" : "MapMakerInternalMap.WeakKeyDummyValueEntry", - "com.google.common.collect.MapMakerInternalMap$WeakKeyDummyValueEntry$Helper" : "MapMakerInternalMap.WeakKeyDummyValueEntry.Helper", - "com.google.common.collect.MapMakerInternalMap$WeakKeyDummyValueEntry$LinkedWeakKeyDummyValueEntry" : "MapMakerInternalMap.WeakKeyDummyValueEntry.LinkedWeakKeyDummyValueEntry", - "com.google.common.collect.MapMakerInternalMap$WeakKeyDummyValueSegment" : "MapMakerInternalMap.WeakKeyDummyValueSegment", - "com.google.common.collect.MapMakerInternalMap$WeakKeyStrongValueEntry" : "MapMakerInternalMap.WeakKeyStrongValueEntry", - "com.google.common.collect.MapMakerInternalMap$WeakKeyStrongValueEntry$Helper" : "MapMakerInternalMap.WeakKeyStrongValueEntry.Helper", - "com.google.common.collect.MapMakerInternalMap$WeakKeyStrongValueEntry$LinkedWeakKeyStrongValueEntry" : "MapMakerInternalMap.WeakKeyStrongValueEntry.LinkedWeakKeyStrongValueEntry", - "com.google.common.collect.MapMakerInternalMap$WeakKeyStrongValueSegment" : "MapMakerInternalMap.WeakKeyStrongValueSegment", - "com.google.common.collect.MapMakerInternalMap$WeakKeyWeakValueEntry" : "MapMakerInternalMap.WeakKeyWeakValueEntry", - "com.google.common.collect.MapMakerInternalMap$WeakKeyWeakValueEntry$Helper" : "MapMakerInternalMap.WeakKeyWeakValueEntry.Helper", - "com.google.common.collect.MapMakerInternalMap$WeakKeyWeakValueEntry$LinkedWeakKeyWeakValueEntry" : "MapMakerInternalMap.WeakKeyWeakValueEntry.LinkedWeakKeyWeakValueEntry", - "com.google.common.collect.MapMakerInternalMap$WeakKeyWeakValueSegment" : "MapMakerInternalMap.WeakKeyWeakValueSegment", - "com.google.common.collect.MapMakerInternalMap$WeakValueEntry" : "MapMakerInternalMap.WeakValueEntry", - "com.google.common.collect.MapMakerInternalMap$WeakValueReference" : "MapMakerInternalMap.WeakValueReference", - "com.google.common.collect.MapMakerInternalMap$WeakValueReferenceImpl" : "MapMakerInternalMap.WeakValueReferenceImpl", - "com.google.common.collect.MapMakerInternalMap$WriteThroughEntry" : "MapMakerInternalMap.WriteThroughEntry", - "com.google.common.collect.Maps" : "Maps", - "com.google.common.collect.Maps$AbstractFilteredMap" : "Maps.AbstractFilteredMap", - "com.google.common.collect.Maps$AsMapView" : "Maps.AsMapView", - "com.google.common.collect.Maps$BiMapConverter" : "Maps.BiMapConverter", - "com.google.common.collect.Maps$DescendingMap" : "Maps.DescendingMap", - "com.google.common.collect.Maps$EntryFunction" : "Maps.EntryFunction", - "com.google.common.collect.Maps$EntrySet" : "Maps.EntrySet", - "com.google.common.collect.Maps$EntryTransformer" : "Maps.EntryTransformer", - "com.google.common.collect.Maps$FilteredEntryBiMap" : "Maps.FilteredEntryBiMap", - "com.google.common.collect.Maps$FilteredEntryMap" : "Maps.FilteredEntryMap", - "com.google.common.collect.Maps$FilteredEntryMap$EntrySet" : "Maps.FilteredEntryMap.EntrySet", - "com.google.common.collect.Maps$FilteredEntryMap$KeySet" : "Maps.FilteredEntryMap.KeySet", - "com.google.common.collect.Maps$FilteredEntryNavigableMap" : "Maps.FilteredEntryNavigableMap", - "com.google.common.collect.Maps$FilteredEntrySortedMap" : "Maps.FilteredEntrySortedMap", - "com.google.common.collect.Maps$FilteredEntrySortedMap$SortedKeySet" : "Maps.FilteredEntrySortedMap.SortedKeySet", - "com.google.common.collect.Maps$FilteredKeyMap" : "Maps.FilteredKeyMap", - "com.google.common.collect.Maps$FilteredMapValues" : "Maps.FilteredMapValues", - "com.google.common.collect.Maps$IteratorBasedAbstractMap" : "Maps.IteratorBasedAbstractMap", - "com.google.common.collect.Maps$KeySet" : "Maps.KeySet", - "com.google.common.collect.Maps$MapDifferenceImpl" : "Maps.MapDifferenceImpl", - "com.google.common.collect.Maps$NavigableAsMapView" : "Maps.NavigableAsMapView", - "com.google.common.collect.Maps$NavigableKeySet" : "Maps.NavigableKeySet", - "com.google.common.collect.Maps$SortedAsMapView" : "Maps.SortedAsMapView", - "com.google.common.collect.Maps$SortedKeySet" : "Maps.SortedKeySet", - "com.google.common.collect.Maps$SortedMapDifferenceImpl" : "Maps.SortedMapDifferenceImpl", - "com.google.common.collect.Maps$TransformedEntriesMap" : "Maps.TransformedEntriesMap", - "com.google.common.collect.Maps$TransformedEntriesNavigableMap" : "Maps.TransformedEntriesNavigableMap", - "com.google.common.collect.Maps$TransformedEntriesSortedMap" : "Maps.TransformedEntriesSortedMap", - "com.google.common.collect.Maps$UnmodifiableBiMap" : "Maps.UnmodifiableBiMap", - "com.google.common.collect.Maps$UnmodifiableEntries" : "Maps.UnmodifiableEntries", - "com.google.common.collect.Maps$UnmodifiableEntrySet" : "Maps.UnmodifiableEntrySet", - "com.google.common.collect.Maps$UnmodifiableNavigableMap" : "Maps.UnmodifiableNavigableMap", - "com.google.common.collect.Maps$ValueDifferenceImpl" : "Maps.ValueDifferenceImpl", - "com.google.common.collect.Maps$Values" : "Maps.Values", - "com.google.common.collect.Maps$ViewCachingAbstractMap" : "Maps.ViewCachingAbstractMap", - "com.google.common.collect.MinMaxPriorityQueue" : "MinMaxPriorityQueue", - "com.google.common.collect.MinMaxPriorityQueue$Builder" : "MinMaxPriorityQueue.Builder", - "com.google.common.collect.MinMaxPriorityQueue$Heap" : "MinMaxPriorityQueue.Heap", - "com.google.common.collect.MinMaxPriorityQueue$MoveDesc" : "MinMaxPriorityQueue.MoveDesc", - "com.google.common.collect.MinMaxPriorityQueue$QueueIterator" : "MinMaxPriorityQueue.QueueIterator", - "com.google.common.collect.MoreCollectors" : "MoreCollectors", - "com.google.common.collect.MoreCollectors$ToOptionalState" : "MoreCollectors.ToOptionalState", - "com.google.common.collect.Multimap" : "Multimap", - "com.google.common.collect.MultimapBuilder" : "MultimapBuilder", - "com.google.common.collect.MultimapBuilder$ArrayListSupplier" : "MultimapBuilder.ArrayListSupplier", - "com.google.common.collect.MultimapBuilder$EnumSetSupplier" : "MultimapBuilder.EnumSetSupplier", - "com.google.common.collect.MultimapBuilder$HashSetSupplier" : "MultimapBuilder.HashSetSupplier", - "com.google.common.collect.MultimapBuilder$LinkedHashSetSupplier" : "MultimapBuilder.LinkedHashSetSupplier", - "com.google.common.collect.MultimapBuilder$LinkedListSupplier" : "MultimapBuilder.LinkedListSupplier", - "com.google.common.collect.MultimapBuilder$ListMultimapBuilder" : "MultimapBuilder.ListMultimapBuilder", - "com.google.common.collect.MultimapBuilder$MultimapBuilderWithKeys" : "MultimapBuilder.MultimapBuilderWithKeys", - "com.google.common.collect.MultimapBuilder$SetMultimapBuilder" : "MultimapBuilder.SetMultimapBuilder", - "com.google.common.collect.MultimapBuilder$SortedSetMultimapBuilder" : "MultimapBuilder.SortedSetMultimapBuilder", - "com.google.common.collect.MultimapBuilder$TreeSetSupplier" : "MultimapBuilder.TreeSetSupplier", - "com.google.common.collect.Multimaps" : "Multimaps", - "com.google.common.collect.Multimaps$AsMap" : "Multimaps.AsMap", - "com.google.common.collect.Multimaps$AsMap$EntrySet" : "Multimaps.AsMap.EntrySet", - "com.google.common.collect.Multimaps$CustomListMultimap" : "Multimaps.CustomListMultimap", - "com.google.common.collect.Multimaps$CustomMultimap" : "Multimaps.CustomMultimap", - "com.google.common.collect.Multimaps$CustomSetMultimap" : "Multimaps.CustomSetMultimap", - "com.google.common.collect.Multimaps$CustomSortedSetMultimap" : "Multimaps.CustomSortedSetMultimap", - "com.google.common.collect.Multimaps$Entries" : "Multimaps.Entries", - "com.google.common.collect.Multimaps$Keys" : "Multimaps.Keys", - "com.google.common.collect.Multimaps$MapMultimap" : "Multimaps.MapMultimap", - "com.google.common.collect.Multimaps$TransformedEntriesListMultimap" : "Multimaps.TransformedEntriesListMultimap", - "com.google.common.collect.Multimaps$TransformedEntriesMultimap" : "Multimaps.TransformedEntriesMultimap", - "com.google.common.collect.Multimaps$UnmodifiableListMultimap" : "Multimaps.UnmodifiableListMultimap", - "com.google.common.collect.Multimaps$UnmodifiableMultimap" : "Multimaps.UnmodifiableMultimap", - "com.google.common.collect.Multimaps$UnmodifiableSetMultimap" : "Multimaps.UnmodifiableSetMultimap", - "com.google.common.collect.Multimaps$UnmodifiableSortedSetMultimap" : "Multimaps.UnmodifiableSortedSetMultimap", - "com.google.common.collect.Multiset" : "Multiset", - "com.google.common.collect.Multiset$Entry" : "Multiset.Entry", - "com.google.common.collect.Multisets" : "Multisets", - "com.google.common.collect.Multisets$AbstractEntry" : "Multisets.AbstractEntry", - "com.google.common.collect.Multisets$DecreasingCount" : "Multisets.DecreasingCount", - "com.google.common.collect.Multisets$ElementSet" : "Multisets.ElementSet", - "com.google.common.collect.Multisets$EntrySet" : "Multisets.EntrySet", - "com.google.common.collect.Multisets$FilteredMultiset" : "Multisets.FilteredMultiset", - "com.google.common.collect.Multisets$ImmutableEntry" : "Multisets.ImmutableEntry", - "com.google.common.collect.Multisets$MultisetIteratorImpl" : "Multisets.MultisetIteratorImpl", - "com.google.common.collect.Multisets$UnmodifiableMultiset" : "Multisets.UnmodifiableMultiset", - "com.google.common.collect.Multisets$ViewMultiset" : "Multisets.ViewMultiset", - "com.google.common.collect.MutableClassToInstanceMap" : "MutableClassToInstanceMap", - "com.google.common.collect.MutableClassToInstanceMap$SerializedForm" : "MutableClassToInstanceMap.SerializedForm", - "com.google.common.collect.NaturalOrdering" : "NaturalOrdering", - "com.google.common.collect.NullnessCasts" : "NullnessCasts", - "com.google.common.collect.NullsFirstOrdering" : "NullsFirstOrdering", - "com.google.common.collect.NullsLastOrdering" : "NullsLastOrdering", - "com.google.common.collect.ObjectArrays" : "ObjectArrays", - "com.google.common.collect.Ordering" : "Ordering", - "com.google.common.collect.Ordering$ArbitraryOrdering" : "Ordering.ArbitraryOrdering", - "com.google.common.collect.Ordering$ArbitraryOrderingHolder" : "Ordering.ArbitraryOrderingHolder", - "com.google.common.collect.Ordering$IncomparableValueException" : "Ordering.IncomparableValueException", - "com.google.common.collect.ParametricNullness" : "ParametricNullness", - "com.google.common.collect.PeekingIterator" : "PeekingIterator", - "com.google.common.collect.Platform" : "Platform", - "com.google.common.collect.Queues" : "Queues", - "com.google.common.collect.Range" : "Range", - "com.google.common.collect.Range$RangeLexOrdering" : "Range.RangeLexOrdering", - "com.google.common.collect.RangeGwtSerializationDependencies" : "RangeGwtSerializationDependencies", - "com.google.common.collect.RangeMap" : "RangeMap", - "com.google.common.collect.RangeSet" : "RangeSet", - "com.google.common.collect.RegularContiguousSet" : "RegularContiguousSet", - "com.google.common.collect.RegularContiguousSet$SerializedForm" : "RegularContiguousSet.SerializedForm", - "com.google.common.collect.RegularImmutableAsList" : "RegularImmutableAsList", - "com.google.common.collect.RegularImmutableBiMap" : "RegularImmutableBiMap", - "com.google.common.collect.RegularImmutableBiMap$Inverse" : "RegularImmutableBiMap.Inverse", - "com.google.common.collect.RegularImmutableBiMap$Inverse$InverseEntrySet" : "RegularImmutableBiMap.Inverse.InverseEntrySet", - "com.google.common.collect.RegularImmutableBiMap$InverseSerializedForm" : "RegularImmutableBiMap.InverseSerializedForm", - "com.google.common.collect.RegularImmutableList" : "RegularImmutableList", - "com.google.common.collect.RegularImmutableMap" : "RegularImmutableMap", - "com.google.common.collect.RegularImmutableMap$BucketOverflowException" : "RegularImmutableMap.BucketOverflowException", - "com.google.common.collect.RegularImmutableMap$KeySet" : "RegularImmutableMap.KeySet", - "com.google.common.collect.RegularImmutableMap$KeySet$SerializedForm" : "RegularImmutableMap.KeySet.SerializedForm", - "com.google.common.collect.RegularImmutableMap$Values" : "RegularImmutableMap.Values", - "com.google.common.collect.RegularImmutableMap$Values$SerializedForm" : "RegularImmutableMap.Values.SerializedForm", - "com.google.common.collect.RegularImmutableMultiset" : "RegularImmutableMultiset", - "com.google.common.collect.RegularImmutableMultiset$NonTerminalEntry" : "RegularImmutableMultiset.NonTerminalEntry", - "com.google.common.collect.RegularImmutableSet" : "RegularImmutableSet", - "com.google.common.collect.RegularImmutableSortedMultiset" : "RegularImmutableSortedMultiset", - "com.google.common.collect.RegularImmutableSortedSet" : "RegularImmutableSortedSet", - "com.google.common.collect.RegularImmutableTable" : "RegularImmutableTable", - "com.google.common.collect.RegularImmutableTable$CellSet" : "RegularImmutableTable.CellSet", - "com.google.common.collect.RegularImmutableTable$Values" : "RegularImmutableTable.Values", - "com.google.common.collect.ReverseNaturalOrdering" : "ReverseNaturalOrdering", - "com.google.common.collect.ReverseOrdering" : "ReverseOrdering", - "com.google.common.collect.RowSortedTable" : "RowSortedTable", - "com.google.common.collect.Serialization" : "Serialization", - "com.google.common.collect.Serialization$FieldSetter" : "Serialization.FieldSetter", - "com.google.common.collect.SetMultimap" : "SetMultimap", - "com.google.common.collect.Sets" : "Sets", - "com.google.common.collect.Sets$CartesianSet" : "Sets.CartesianSet", - "com.google.common.collect.Sets$DescendingSet" : "Sets.DescendingSet", - "com.google.common.collect.Sets$FilteredNavigableSet" : "Sets.FilteredNavigableSet", - "com.google.common.collect.Sets$FilteredSet" : "Sets.FilteredSet", - "com.google.common.collect.Sets$FilteredSortedSet" : "Sets.FilteredSortedSet", - "com.google.common.collect.Sets$ImprovedAbstractSet" : "Sets.ImprovedAbstractSet", - "com.google.common.collect.Sets$PowerSet" : "Sets.PowerSet", - "com.google.common.collect.Sets$SetView" : "Sets.SetView", - "com.google.common.collect.Sets$SubSet" : "Sets.SubSet", - "com.google.common.collect.Sets$UnmodifiableNavigableSet" : "Sets.UnmodifiableNavigableSet", - "com.google.common.collect.SingletonImmutableBiMap" : "SingletonImmutableBiMap", - "com.google.common.collect.SingletonImmutableList" : "SingletonImmutableList", - "com.google.common.collect.SingletonImmutableSet" : "SingletonImmutableSet", - "com.google.common.collect.SingletonImmutableTable" : "SingletonImmutableTable", - "com.google.common.collect.SortedIterable" : "SortedIterable", - "com.google.common.collect.SortedIterables" : "SortedIterables", - "com.google.common.collect.SortedLists" : "SortedLists", - "com.google.common.collect.SortedLists$KeyAbsentBehavior" : "SortedLists.KeyAbsentBehavior", - "com.google.common.collect.SortedLists$KeyPresentBehavior" : "SortedLists.KeyPresentBehavior", - "com.google.common.collect.SortedMapDifference" : "SortedMapDifference", - "com.google.common.collect.SortedMultiset" : "SortedMultiset", - "com.google.common.collect.SortedMultisetBridge" : "SortedMultisetBridge", - "com.google.common.collect.SortedMultisets" : "SortedMultisets", - "com.google.common.collect.SortedMultisets$ElementSet" : "SortedMultisets.ElementSet", - "com.google.common.collect.SortedMultisets$NavigableElementSet" : "SortedMultisets.NavigableElementSet", - "com.google.common.collect.SortedSetMultimap" : "SortedSetMultimap", - "com.google.common.collect.SparseImmutableTable" : "SparseImmutableTable", - "com.google.common.collect.StandardRowSortedTable" : "StandardRowSortedTable", - "com.google.common.collect.StandardRowSortedTable$RowSortedMap" : "StandardRowSortedTable.RowSortedMap", - "com.google.common.collect.StandardTable" : "StandardTable", - "com.google.common.collect.StandardTable$CellIterator" : "StandardTable.CellIterator", - "com.google.common.collect.StandardTable$Column" : "StandardTable.Column", - "com.google.common.collect.StandardTable$Column$EntrySet" : "StandardTable.Column.EntrySet", - "com.google.common.collect.StandardTable$Column$EntrySetIterator" : "StandardTable.Column.EntrySetIterator", - "com.google.common.collect.StandardTable$Column$KeySet" : "StandardTable.Column.KeySet", - "com.google.common.collect.StandardTable$Column$Values" : "StandardTable.Column.Values", - "com.google.common.collect.StandardTable$ColumnKeyIterator" : "StandardTable.ColumnKeyIterator", - "com.google.common.collect.StandardTable$ColumnKeySet" : "StandardTable.ColumnKeySet", - "com.google.common.collect.StandardTable$ColumnMap" : "StandardTable.ColumnMap", - "com.google.common.collect.StandardTable$ColumnMap$ColumnMapEntrySet" : "StandardTable.ColumnMap.ColumnMapEntrySet", - "com.google.common.collect.StandardTable$ColumnMap$ColumnMapValues" : "StandardTable.ColumnMap.ColumnMapValues", - "com.google.common.collect.StandardTable$Row" : "StandardTable.Row", - "com.google.common.collect.StandardTable$RowMap" : "StandardTable.RowMap", - "com.google.common.collect.StandardTable$RowMap$EntrySet" : "StandardTable.RowMap.EntrySet", - "com.google.common.collect.StandardTable$TableSet" : "StandardTable.TableSet", - "com.google.common.collect.Streams" : "Streams", - "com.google.common.collect.Streams$DoubleFunctionWithIndex" : "Streams.DoubleFunctionWithIndex", - "com.google.common.collect.Streams$FunctionWithIndex" : "Streams.FunctionWithIndex", - "com.google.common.collect.Streams$IntFunctionWithIndex" : "Streams.IntFunctionWithIndex", - "com.google.common.collect.Streams$LongFunctionWithIndex" : "Streams.LongFunctionWithIndex", - "com.google.common.collect.Streams$MapWithIndexSpliterator" : "Streams.MapWithIndexSpliterator", - "com.google.common.collect.Streams$TemporaryPair" : "Streams.TemporaryPair", - "com.google.common.collect.Synchronized" : "Synchronized", - "com.google.common.collect.Synchronized$SynchronizedAsMap" : "Synchronized.SynchronizedAsMap", - "com.google.common.collect.Synchronized$SynchronizedAsMapEntries" : "Synchronized.SynchronizedAsMapEntries", - "com.google.common.collect.Synchronized$SynchronizedAsMapValues" : "Synchronized.SynchronizedAsMapValues", - "com.google.common.collect.Synchronized$SynchronizedBiMap" : "Synchronized.SynchronizedBiMap", - "com.google.common.collect.Synchronized$SynchronizedCollection" : "Synchronized.SynchronizedCollection", - "com.google.common.collect.Synchronized$SynchronizedDeque" : "Synchronized.SynchronizedDeque", - "com.google.common.collect.Synchronized$SynchronizedEntry" : "Synchronized.SynchronizedEntry", - "com.google.common.collect.Synchronized$SynchronizedList" : "Synchronized.SynchronizedList", - "com.google.common.collect.Synchronized$SynchronizedListMultimap" : "Synchronized.SynchronizedListMultimap", - "com.google.common.collect.Synchronized$SynchronizedMap" : "Synchronized.SynchronizedMap", - "com.google.common.collect.Synchronized$SynchronizedMultimap" : "Synchronized.SynchronizedMultimap", - "com.google.common.collect.Synchronized$SynchronizedMultiset" : "Synchronized.SynchronizedMultiset", - "com.google.common.collect.Synchronized$SynchronizedNavigableMap" : "Synchronized.SynchronizedNavigableMap", - "com.google.common.collect.Synchronized$SynchronizedNavigableSet" : "Synchronized.SynchronizedNavigableSet", - "com.google.common.collect.Synchronized$SynchronizedObject" : "Synchronized.SynchronizedObject", - "com.google.common.collect.Synchronized$SynchronizedQueue" : "Synchronized.SynchronizedQueue", - "com.google.common.collect.Synchronized$SynchronizedRandomAccessList" : "Synchronized.SynchronizedRandomAccessList", - "com.google.common.collect.Synchronized$SynchronizedSet" : "Synchronized.SynchronizedSet", - "com.google.common.collect.Synchronized$SynchronizedSetMultimap" : "Synchronized.SynchronizedSetMultimap", - "com.google.common.collect.Synchronized$SynchronizedSortedMap" : "Synchronized.SynchronizedSortedMap", - "com.google.common.collect.Synchronized$SynchronizedSortedSet" : "Synchronized.SynchronizedSortedSet", - "com.google.common.collect.Synchronized$SynchronizedSortedSetMultimap" : "Synchronized.SynchronizedSortedSetMultimap", - "com.google.common.collect.Synchronized$SynchronizedTable" : "Synchronized.SynchronizedTable", - "com.google.common.collect.Table" : "Table", - "com.google.common.collect.Table$Cell" : "Table.Cell", - "com.google.common.collect.TableCollectors" : "TableCollectors", - "com.google.common.collect.TableCollectors$ImmutableTableCollectorState" : "TableCollectors.ImmutableTableCollectorState", - "com.google.common.collect.TableCollectors$MutableCell" : "TableCollectors.MutableCell", - "com.google.common.collect.Tables" : "Tables", - "com.google.common.collect.Tables$AbstractCell" : "Tables.AbstractCell", - "com.google.common.collect.Tables$ImmutableCell" : "Tables.ImmutableCell", - "com.google.common.collect.Tables$TransformedTable" : "Tables.TransformedTable", - "com.google.common.collect.Tables$TransposeTable" : "Tables.TransposeTable", - "com.google.common.collect.Tables$UnmodifiableRowSortedMap" : "Tables.UnmodifiableRowSortedMap", - "com.google.common.collect.Tables$UnmodifiableTable" : "Tables.UnmodifiableTable", - "com.google.common.collect.TopKSelector" : "TopKSelector", - "com.google.common.collect.TransformedIterator" : "TransformedIterator", - "com.google.common.collect.TransformedListIterator" : "TransformedListIterator", - "com.google.common.collect.TreeBasedTable" : "TreeBasedTable", - "com.google.common.collect.TreeBasedTable$Factory" : "TreeBasedTable.Factory", - "com.google.common.collect.TreeBasedTable$TreeRow" : "TreeBasedTable.TreeRow", - "com.google.common.collect.TreeMultimap" : "TreeMultimap", - "com.google.common.collect.TreeMultiset" : "TreeMultiset", - "com.google.common.collect.TreeMultiset$Aggregate" : "TreeMultiset.Aggregate", - "com.google.common.collect.TreeMultiset$AvlNode" : "TreeMultiset.AvlNode", - "com.google.common.collect.TreeMultiset$Reference" : "TreeMultiset.Reference", - "com.google.common.collect.TreeRangeMap" : "TreeRangeMap", - "com.google.common.collect.TreeRangeMap$AsMapOfRanges" : "TreeRangeMap.AsMapOfRanges", - "com.google.common.collect.TreeRangeMap$RangeMapEntry" : "TreeRangeMap.RangeMapEntry", - "com.google.common.collect.TreeRangeMap$SubRangeMap" : "TreeRangeMap.SubRangeMap", - "com.google.common.collect.TreeRangeMap$SubRangeMap$SubRangeMapAsMap" : "TreeRangeMap.SubRangeMap.SubRangeMapAsMap", - "com.google.common.collect.TreeRangeSet" : "TreeRangeSet", - "com.google.common.collect.TreeRangeSet$AsRanges" : "TreeRangeSet.AsRanges", - "com.google.common.collect.TreeRangeSet$Complement" : "TreeRangeSet.Complement", - "com.google.common.collect.TreeRangeSet$ComplementRangesByLowerBound" : "TreeRangeSet.ComplementRangesByLowerBound", - "com.google.common.collect.TreeRangeSet$RangesByUpperBound" : "TreeRangeSet.RangesByUpperBound", - "com.google.common.collect.TreeRangeSet$SubRangeSet" : "TreeRangeSet.SubRangeSet", - "com.google.common.collect.TreeRangeSet$SubRangeSetRangesByLowerBound" : "TreeRangeSet.SubRangeSetRangesByLowerBound", - "com.google.common.collect.TreeTraverser" : "TreeTraverser", - "com.google.common.collect.TreeTraverser$BreadthFirstIterator" : "TreeTraverser.BreadthFirstIterator", - "com.google.common.collect.TreeTraverser$PostOrderIterator" : "TreeTraverser.PostOrderIterator", - "com.google.common.collect.TreeTraverser$PostOrderNode" : "TreeTraverser.PostOrderNode", - "com.google.common.collect.TreeTraverser$PreOrderIterator" : "TreeTraverser.PreOrderIterator", - "com.google.common.collect.UnmodifiableIterator" : "UnmodifiableIterator", - "com.google.common.collect.UnmodifiableListIterator" : "UnmodifiableListIterator", - "com.google.common.collect.UnmodifiableSortedMultiset" : "UnmodifiableSortedMultiset", - "com.google.common.collect.UsingToStringOrdering" : "UsingToStringOrdering", - "com.google.common.collect.package-info" : "package-info", - "com.google.common.escape.ArrayBasedCharEscaper" : "ArrayBasedCharEscaper", - "com.google.common.escape.ArrayBasedEscaperMap" : "ArrayBasedEscaperMap", - "com.google.common.escape.ArrayBasedUnicodeEscaper" : "ArrayBasedUnicodeEscaper", - "com.google.common.escape.CharEscaper" : "CharEscaper", - "com.google.common.escape.CharEscaperBuilder" : "CharEscaperBuilder", - "com.google.common.escape.CharEscaperBuilder$CharArrayDecorator" : "CharEscaperBuilder.CharArrayDecorator", - "com.google.common.escape.ElementTypesAreNonnullByDefault" : "ElementTypesAreNonnullByDefault", - "com.google.common.escape.Escaper" : "Escaper", - "com.google.common.escape.Escapers" : "Escapers", - "com.google.common.escape.Escapers$Builder" : "Escapers.Builder", - "com.google.common.escape.ParametricNullness" : "ParametricNullness", - "com.google.common.escape.Platform" : "Platform", - "com.google.common.escape.UnicodeEscaper" : "UnicodeEscaper", - "com.google.common.escape.package-info" : "package-info", - "com.google.common.eventbus.AllowConcurrentEvents" : "AllowConcurrentEvents", - "com.google.common.eventbus.AsyncEventBus" : "AsyncEventBus", - "com.google.common.eventbus.DeadEvent" : "DeadEvent", - "com.google.common.eventbus.Dispatcher" : "Dispatcher", - "com.google.common.eventbus.Dispatcher$ImmediateDispatcher" : "Dispatcher.ImmediateDispatcher", - "com.google.common.eventbus.Dispatcher$LegacyAsyncDispatcher" : "Dispatcher.LegacyAsyncDispatcher", - "com.google.common.eventbus.Dispatcher$LegacyAsyncDispatcher$EventWithSubscriber" : "Dispatcher.LegacyAsyncDispatcher.EventWithSubscriber", - "com.google.common.eventbus.Dispatcher$PerThreadQueuedDispatcher" : "Dispatcher.PerThreadQueuedDispatcher", - "com.google.common.eventbus.Dispatcher$PerThreadQueuedDispatcher$Event" : "Dispatcher.PerThreadQueuedDispatcher.Event", - "com.google.common.eventbus.ElementTypesAreNonnullByDefault" : "ElementTypesAreNonnullByDefault", - "com.google.common.eventbus.EventBus" : "EventBus", - "com.google.common.eventbus.EventBus$LoggingHandler" : "EventBus.LoggingHandler", - "com.google.common.eventbus.ParametricNullness" : "ParametricNullness", - "com.google.common.eventbus.Subscribe" : "Subscribe", - "com.google.common.eventbus.Subscriber" : "Subscriber", - "com.google.common.eventbus.Subscriber$SynchronizedSubscriber" : "Subscriber.SynchronizedSubscriber", - "com.google.common.eventbus.SubscriberExceptionContext" : "SubscriberExceptionContext", - "com.google.common.eventbus.SubscriberExceptionHandler" : "SubscriberExceptionHandler", - "com.google.common.eventbus.SubscriberRegistry" : "SubscriberRegistry", - "com.google.common.eventbus.SubscriberRegistry$MethodIdentifier" : "SubscriberRegistry.MethodIdentifier", - "com.google.common.eventbus.package-info" : "package-info", - "com.google.common.graph.AbstractBaseGraph" : "AbstractBaseGraph", - "com.google.common.graph.AbstractDirectedNetworkConnections" : "AbstractDirectedNetworkConnections", - "com.google.common.graph.AbstractGraph" : "AbstractGraph", - "com.google.common.graph.AbstractGraphBuilder" : "AbstractGraphBuilder", - "com.google.common.graph.AbstractNetwork" : "AbstractNetwork", - "com.google.common.graph.AbstractUndirectedNetworkConnections" : "AbstractUndirectedNetworkConnections", - "com.google.common.graph.AbstractValueGraph" : "AbstractValueGraph", - "com.google.common.graph.BaseGraph" : "BaseGraph", - "com.google.common.graph.DirectedGraphConnections" : "DirectedGraphConnections", - "com.google.common.graph.DirectedGraphConnections$NodeConnection" : "DirectedGraphConnections.NodeConnection", - "com.google.common.graph.DirectedGraphConnections$NodeConnection$Pred" : "DirectedGraphConnections.NodeConnection.Pred", - "com.google.common.graph.DirectedGraphConnections$NodeConnection$Succ" : "DirectedGraphConnections.NodeConnection.Succ", - "com.google.common.graph.DirectedGraphConnections$PredAndSucc" : "DirectedGraphConnections.PredAndSucc", - "com.google.common.graph.DirectedMultiNetworkConnections" : "DirectedMultiNetworkConnections", - "com.google.common.graph.DirectedNetworkConnections" : "DirectedNetworkConnections", - "com.google.common.graph.EdgesConnecting" : "EdgesConnecting", - "com.google.common.graph.ElementOrder" : "ElementOrder", - "com.google.common.graph.ElementOrder$Type" : "ElementOrder.Type", - "com.google.common.graph.ElementTypesAreNonnullByDefault" : "ElementTypesAreNonnullByDefault", - "com.google.common.graph.EndpointPair" : "EndpointPair", - "com.google.common.graph.EndpointPair$Ordered" : "EndpointPair.Ordered", - "com.google.common.graph.EndpointPair$Unordered" : "EndpointPair.Unordered", - "com.google.common.graph.EndpointPairIterator" : "EndpointPairIterator", - "com.google.common.graph.EndpointPairIterator$Directed" : "EndpointPairIterator.Directed", - "com.google.common.graph.EndpointPairIterator$Undirected" : "EndpointPairIterator.Undirected", - "com.google.common.graph.ForwardingGraph" : "ForwardingGraph", - "com.google.common.graph.ForwardingNetwork" : "ForwardingNetwork", - "com.google.common.graph.ForwardingValueGraph" : "ForwardingValueGraph", - "com.google.common.graph.Graph" : "Graph", - "com.google.common.graph.GraphBuilder" : "GraphBuilder", - "com.google.common.graph.GraphConnections" : "GraphConnections", - "com.google.common.graph.GraphConstants" : "GraphConstants", - "com.google.common.graph.GraphConstants$Presence" : "GraphConstants.Presence", - "com.google.common.graph.Graphs" : "Graphs", - "com.google.common.graph.Graphs$NodeAndRemainingSuccessors" : "Graphs.NodeAndRemainingSuccessors", - "com.google.common.graph.Graphs$NodeVisitState" : "Graphs.NodeVisitState", - "com.google.common.graph.Graphs$TransposedGraph" : "Graphs.TransposedGraph", - "com.google.common.graph.Graphs$TransposedNetwork" : "Graphs.TransposedNetwork", - "com.google.common.graph.Graphs$TransposedValueGraph" : "Graphs.TransposedValueGraph", - "com.google.common.graph.GraphsBridgeMethods" : "GraphsBridgeMethods", - "com.google.common.graph.ImmutableGraph" : "ImmutableGraph", - "com.google.common.graph.ImmutableGraph$Builder" : "ImmutableGraph.Builder", - "com.google.common.graph.ImmutableNetwork" : "ImmutableNetwork", - "com.google.common.graph.ImmutableNetwork$Builder" : "ImmutableNetwork.Builder", - "com.google.common.graph.ImmutableValueGraph" : "ImmutableValueGraph", - "com.google.common.graph.ImmutableValueGraph$Builder" : "ImmutableValueGraph.Builder", - "com.google.common.graph.IncidentEdgeSet" : "IncidentEdgeSet", - "com.google.common.graph.InvalidatableSet" : "InvalidatableSet", - "com.google.common.graph.MapIteratorCache" : "MapIteratorCache", - "com.google.common.graph.MapRetrievalCache" : "MapRetrievalCache", - "com.google.common.graph.MapRetrievalCache$CacheEntry" : "MapRetrievalCache.CacheEntry", - "com.google.common.graph.MultiEdgesConnecting" : "MultiEdgesConnecting", - "com.google.common.graph.MutableGraph" : "MutableGraph", - "com.google.common.graph.MutableNetwork" : "MutableNetwork", - "com.google.common.graph.MutableValueGraph" : "MutableValueGraph", - "com.google.common.graph.Network" : "Network", - "com.google.common.graph.NetworkBuilder" : "NetworkBuilder", - "com.google.common.graph.NetworkConnections" : "NetworkConnections", - "com.google.common.graph.ParametricNullness" : "ParametricNullness", - "com.google.common.graph.PredecessorsFunction" : "PredecessorsFunction", - "com.google.common.graph.StandardMutableGraph" : "StandardMutableGraph", - "com.google.common.graph.StandardMutableNetwork" : "StandardMutableNetwork", - "com.google.common.graph.StandardMutableValueGraph" : "StandardMutableValueGraph", - "com.google.common.graph.StandardNetwork" : "StandardNetwork", - "com.google.common.graph.StandardValueGraph" : "StandardValueGraph", - "com.google.common.graph.SuccessorsFunction" : "SuccessorsFunction", - "com.google.common.graph.Traverser" : "Traverser", - "com.google.common.graph.Traverser$InsertionOrder" : "Traverser.InsertionOrder", - "com.google.common.graph.Traverser$Traversal" : "Traverser.Traversal", - "com.google.common.graph.UndirectedGraphConnections" : "UndirectedGraphConnections", - "com.google.common.graph.UndirectedMultiNetworkConnections" : "UndirectedMultiNetworkConnections", - "com.google.common.graph.UndirectedNetworkConnections" : "UndirectedNetworkConnections", - "com.google.common.graph.ValueGraph" : "ValueGraph", - "com.google.common.graph.ValueGraphBuilder" : "ValueGraphBuilder", - "com.google.common.graph.package-info" : "package-info", - "com.google.common.hash.AbstractByteHasher" : "AbstractByteHasher", - "com.google.common.hash.AbstractCompositeHashFunction" : "AbstractCompositeHashFunction", - "com.google.common.hash.AbstractHashFunction" : "AbstractHashFunction", - "com.google.common.hash.AbstractHasher" : "AbstractHasher", - "com.google.common.hash.AbstractNonStreamingHashFunction" : "AbstractNonStreamingHashFunction", - "com.google.common.hash.AbstractNonStreamingHashFunction$BufferingHasher" : "AbstractNonStreamingHashFunction.BufferingHasher", - "com.google.common.hash.AbstractNonStreamingHashFunction$ExposedByteArrayOutputStream" : "AbstractNonStreamingHashFunction.ExposedByteArrayOutputStream", - "com.google.common.hash.AbstractStreamingHasher" : "AbstractStreamingHasher", - "com.google.common.hash.BloomFilter" : "BloomFilter", - "com.google.common.hash.BloomFilter$SerialForm" : "BloomFilter.SerialForm", - "com.google.common.hash.BloomFilter$Strategy" : "BloomFilter.Strategy", - "com.google.common.hash.BloomFilterStrategies" : "BloomFilterStrategies", - "com.google.common.hash.BloomFilterStrategies$LockFreeBitArray" : "BloomFilterStrategies.LockFreeBitArray", - "com.google.common.hash.ChecksumHashFunction" : "ChecksumHashFunction", - "com.google.common.hash.ChecksumHashFunction$ChecksumHasher" : "ChecksumHashFunction.ChecksumHasher", - "com.google.common.hash.ChecksumHashFunction$ChecksumMethodHandles" : "ChecksumHashFunction.ChecksumMethodHandles", - "com.google.common.hash.Crc32cHashFunction" : "Crc32cHashFunction", - "com.google.common.hash.Crc32cHashFunction$Crc32cHasher" : "Crc32cHashFunction.Crc32cHasher", - "com.google.common.hash.ElementTypesAreNonnullByDefault" : "ElementTypesAreNonnullByDefault", - "com.google.common.hash.FarmHashFingerprint64" : "FarmHashFingerprint64", - "com.google.common.hash.Fingerprint2011" : "Fingerprint2011", - "com.google.common.hash.Funnel" : "Funnel", - "com.google.common.hash.Funnels" : "Funnels", - "com.google.common.hash.Funnels$ByteArrayFunnel" : "Funnels.ByteArrayFunnel", - "com.google.common.hash.Funnels$IntegerFunnel" : "Funnels.IntegerFunnel", - "com.google.common.hash.Funnels$LongFunnel" : "Funnels.LongFunnel", - "com.google.common.hash.Funnels$SequentialFunnel" : "Funnels.SequentialFunnel", - "com.google.common.hash.Funnels$SinkAsStream" : "Funnels.SinkAsStream", - "com.google.common.hash.Funnels$StringCharsetFunnel" : "Funnels.StringCharsetFunnel", - "com.google.common.hash.Funnels$StringCharsetFunnel$SerializedForm" : "Funnels.StringCharsetFunnel.SerializedForm", - "com.google.common.hash.Funnels$UnencodedCharsFunnel" : "Funnels.UnencodedCharsFunnel", - "com.google.common.hash.HashCode" : "HashCode", - "com.google.common.hash.HashCode$BytesHashCode" : "HashCode.BytesHashCode", - "com.google.common.hash.HashCode$IntHashCode" : "HashCode.IntHashCode", - "com.google.common.hash.HashCode$LongHashCode" : "HashCode.LongHashCode", - "com.google.common.hash.HashFunction" : "HashFunction", - "com.google.common.hash.Hasher" : "Hasher", - "com.google.common.hash.Hashing" : "Hashing", - "com.google.common.hash.Hashing$ChecksumType" : "Hashing.ChecksumType", - "com.google.common.hash.Hashing$ConcatenatedHashFunction" : "Hashing.ConcatenatedHashFunction", - "com.google.common.hash.Hashing$Crc32CSupplier" : "Hashing.Crc32CSupplier", - "com.google.common.hash.Hashing$Crc32cMethodHandles" : "Hashing.Crc32cMethodHandles", - "com.google.common.hash.Hashing$LinearCongruentialGenerator" : "Hashing.LinearCongruentialGenerator", - "com.google.common.hash.Hashing$Md5Holder" : "Hashing.Md5Holder", - "com.google.common.hash.Hashing$Sha1Holder" : "Hashing.Sha1Holder", - "com.google.common.hash.Hashing$Sha256Holder" : "Hashing.Sha256Holder", - "com.google.common.hash.Hashing$Sha384Holder" : "Hashing.Sha384Holder", - "com.google.common.hash.Hashing$Sha512Holder" : "Hashing.Sha512Holder", - "com.google.common.hash.HashingInputStream" : "HashingInputStream", - "com.google.common.hash.HashingOutputStream" : "HashingOutputStream", - "com.google.common.hash.IgnoreJRERequirement" : "IgnoreJRERequirement", - "com.google.common.hash.ImmutableSupplier" : "ImmutableSupplier", - "com.google.common.hash.Java8Compatibility" : "Java8Compatibility", - "com.google.common.hash.LittleEndianByteArray" : "LittleEndianByteArray", - "com.google.common.hash.LittleEndianByteArray$JavaLittleEndianBytes" : "LittleEndianByteArray.JavaLittleEndianBytes", - "com.google.common.hash.LittleEndianByteArray$LittleEndianBytes" : "LittleEndianByteArray.LittleEndianBytes", - "com.google.common.hash.LittleEndianByteArray$UnsafeByteArray" : "LittleEndianByteArray.UnsafeByteArray", - "com.google.common.hash.LongAddable" : "LongAddable", - "com.google.common.hash.LongAddables" : "LongAddables", - "com.google.common.hash.LongAddables$PureJavaLongAddable" : "LongAddables.PureJavaLongAddable", - "com.google.common.hash.LongAdder" : "LongAdder", - "com.google.common.hash.MacHashFunction" : "MacHashFunction", - "com.google.common.hash.MacHashFunction$MacHasher" : "MacHashFunction.MacHasher", - "com.google.common.hash.MessageDigestHashFunction" : "MessageDigestHashFunction", - "com.google.common.hash.MessageDigestHashFunction$MessageDigestHasher" : "MessageDigestHashFunction.MessageDigestHasher", - "com.google.common.hash.MessageDigestHashFunction$SerializedForm" : "MessageDigestHashFunction.SerializedForm", - "com.google.common.hash.Murmur3_128HashFunction" : "Murmur3_128HashFunction", - "com.google.common.hash.Murmur3_128HashFunction$Murmur3_128Hasher" : "Murmur3_128HashFunction.Murmur3_128Hasher", - "com.google.common.hash.Murmur3_32HashFunction" : "Murmur3_32HashFunction", - "com.google.common.hash.Murmur3_32HashFunction$Murmur3_32Hasher" : "Murmur3_32HashFunction.Murmur3_32Hasher", - "com.google.common.hash.ParametricNullness" : "ParametricNullness", - "com.google.common.hash.PrimitiveSink" : "PrimitiveSink", - "com.google.common.hash.SipHashFunction" : "SipHashFunction", - "com.google.common.hash.SipHashFunction$SipHasher" : "SipHashFunction.SipHasher", - "com.google.common.hash.Striped64" : "Striped64", - "com.google.common.hash.Striped64$Cell" : "Striped64.Cell", - "com.google.common.hash.package-info" : "package-info", - "com.google.common.html.ElementTypesAreNonnullByDefault" : "ElementTypesAreNonnullByDefault", - "com.google.common.html.HtmlEscapers" : "HtmlEscapers", - "com.google.common.html.ParametricNullness" : "ParametricNullness", - "com.google.common.html.package-info" : "package-info", - "com.google.common.io.AppendableWriter" : "AppendableWriter", - "com.google.common.io.BaseEncoding" : "BaseEncoding", - "com.google.common.io.BaseEncoding$Alphabet" : "BaseEncoding.Alphabet", - "com.google.common.io.BaseEncoding$Base16Encoding" : "BaseEncoding.Base16Encoding", - "com.google.common.io.BaseEncoding$Base64Encoding" : "BaseEncoding.Base64Encoding", - "com.google.common.io.BaseEncoding$DecodingException" : "BaseEncoding.DecodingException", - "com.google.common.io.BaseEncoding$SeparatedBaseEncoding" : "BaseEncoding.SeparatedBaseEncoding", - "com.google.common.io.BaseEncoding$StandardBaseEncoding" : "BaseEncoding.StandardBaseEncoding", - "com.google.common.io.ByteArrayDataInput" : "ByteArrayDataInput", - "com.google.common.io.ByteArrayDataOutput" : "ByteArrayDataOutput", - "com.google.common.io.ByteProcessor" : "ByteProcessor", - "com.google.common.io.ByteSink" : "ByteSink", - "com.google.common.io.ByteSink$AsCharSink" : "ByteSink.AsCharSink", - "com.google.common.io.ByteSource" : "ByteSource", - "com.google.common.io.ByteSource$AsCharSource" : "ByteSource.AsCharSource", - "com.google.common.io.ByteSource$ByteArrayByteSource" : "ByteSource.ByteArrayByteSource", - "com.google.common.io.ByteSource$ConcatenatedByteSource" : "ByteSource.ConcatenatedByteSource", - "com.google.common.io.ByteSource$EmptyByteSource" : "ByteSource.EmptyByteSource", - "com.google.common.io.ByteSource$SlicedByteSource" : "ByteSource.SlicedByteSource", - "com.google.common.io.ByteStreams" : "ByteStreams", - "com.google.common.io.ByteStreams$ByteArrayDataInputStream" : "ByteStreams.ByteArrayDataInputStream", - "com.google.common.io.ByteStreams$ByteArrayDataOutputStream" : "ByteStreams.ByteArrayDataOutputStream", - "com.google.common.io.ByteStreams$LimitedInputStream" : "ByteStreams.LimitedInputStream", - "com.google.common.io.CharSequenceReader" : "CharSequenceReader", - "com.google.common.io.CharSink" : "CharSink", - "com.google.common.io.CharSource" : "CharSource", - "com.google.common.io.CharSource$AsByteSource" : "CharSource.AsByteSource", - "com.google.common.io.CharSource$CharSequenceCharSource" : "CharSource.CharSequenceCharSource", - "com.google.common.io.CharSource$ConcatenatedCharSource" : "CharSource.ConcatenatedCharSource", - "com.google.common.io.CharSource$EmptyCharSource" : "CharSource.EmptyCharSource", - "com.google.common.io.CharSource$StringCharSource" : "CharSource.StringCharSource", - "com.google.common.io.CharStreams" : "CharStreams", - "com.google.common.io.CharStreams$NullWriter" : "CharStreams.NullWriter", - "com.google.common.io.Closeables" : "Closeables", - "com.google.common.io.Closer" : "Closer", - "com.google.common.io.Closer$Suppressor" : "Closer.Suppressor", - "com.google.common.io.CountingInputStream" : "CountingInputStream", - "com.google.common.io.CountingOutputStream" : "CountingOutputStream", - "com.google.common.io.ElementTypesAreNonnullByDefault" : "ElementTypesAreNonnullByDefault", - "com.google.common.io.FileBackedOutputStream" : "FileBackedOutputStream", - "com.google.common.io.FileBackedOutputStream$MemoryOutput" : "FileBackedOutputStream.MemoryOutput", - "com.google.common.io.FileWriteMode" : "FileWriteMode", - "com.google.common.io.Files" : "Files", - "com.google.common.io.Files$FileByteSink" : "Files.FileByteSink", - "com.google.common.io.Files$FileByteSource" : "Files.FileByteSource", - "com.google.common.io.Files$FilePredicate" : "Files.FilePredicate", - "com.google.common.io.Flushables" : "Flushables", - "com.google.common.io.IgnoreJRERequirement" : "IgnoreJRERequirement", - "com.google.common.io.InsecureRecursiveDeleteException" : "InsecureRecursiveDeleteException", - "com.google.common.io.Java8Compatibility" : "Java8Compatibility", - "com.google.common.io.LineBuffer" : "LineBuffer", - "com.google.common.io.LineProcessor" : "LineProcessor", - "com.google.common.io.LineReader" : "LineReader", - "com.google.common.io.LittleEndianDataInputStream" : "LittleEndianDataInputStream", - "com.google.common.io.LittleEndianDataOutputStream" : "LittleEndianDataOutputStream", - "com.google.common.io.MoreFiles" : "MoreFiles", - "com.google.common.io.MoreFiles$PathByteSink" : "MoreFiles.PathByteSink", - "com.google.common.io.MoreFiles$PathByteSource" : "MoreFiles.PathByteSource", - "com.google.common.io.MultiInputStream" : "MultiInputStream", - "com.google.common.io.MultiReader" : "MultiReader", - "com.google.common.io.ParametricNullness" : "ParametricNullness", - "com.google.common.io.PatternFilenameFilter" : "PatternFilenameFilter", - "com.google.common.io.ReaderInputStream" : "ReaderInputStream", - "com.google.common.io.RecursiveDeleteOption" : "RecursiveDeleteOption", - "com.google.common.io.Resources" : "Resources", - "com.google.common.io.Resources$UrlByteSource" : "Resources.UrlByteSource", - "com.google.common.io.TempFileCreator" : "TempFileCreator", - "com.google.common.io.TempFileCreator$JavaIoCreator" : "TempFileCreator.JavaIoCreator", - "com.google.common.io.TempFileCreator$JavaNioCreator" : "TempFileCreator.JavaNioCreator", - "com.google.common.io.TempFileCreator$JavaNioCreator$PermissionSupplier" : "TempFileCreator.JavaNioCreator.PermissionSupplier", - "com.google.common.io.TempFileCreator$ThrowingCreator" : "TempFileCreator.ThrowingCreator", - "com.google.common.io.package-info" : "package-info", - "com.google.common.math.BigDecimalMath" : "BigDecimalMath", - "com.google.common.math.BigDecimalMath$BigDecimalToDoubleRounder" : "BigDecimalMath.BigDecimalToDoubleRounder", - "com.google.common.math.BigIntegerMath" : "BigIntegerMath", - "com.google.common.math.BigIntegerMath$BigIntegerToDoubleRounder" : "BigIntegerMath.BigIntegerToDoubleRounder", - "com.google.common.math.DoubleMath" : "DoubleMath", - "com.google.common.math.DoubleUtils" : "DoubleUtils", - "com.google.common.math.ElementTypesAreNonnullByDefault" : "ElementTypesAreNonnullByDefault", - "com.google.common.math.IntMath" : "IntMath", - "com.google.common.math.LinearTransformation" : "LinearTransformation", - "com.google.common.math.LinearTransformation$LinearTransformationBuilder" : "LinearTransformation.LinearTransformationBuilder", - "com.google.common.math.LinearTransformation$NaNLinearTransformation" : "LinearTransformation.NaNLinearTransformation", - "com.google.common.math.LinearTransformation$RegularLinearTransformation" : "LinearTransformation.RegularLinearTransformation", - "com.google.common.math.LinearTransformation$VerticalLinearTransformation" : "LinearTransformation.VerticalLinearTransformation", - "com.google.common.math.LongMath" : "LongMath", - "com.google.common.math.LongMath$MillerRabinTester" : "LongMath.MillerRabinTester", - "com.google.common.math.MathPreconditions" : "MathPreconditions", - "com.google.common.math.PairedStats" : "PairedStats", - "com.google.common.math.PairedStatsAccumulator" : "PairedStatsAccumulator", - "com.google.common.math.ParametricNullness" : "ParametricNullness", - "com.google.common.math.Quantiles" : "Quantiles", - "com.google.common.math.Quantiles$Scale" : "Quantiles.Scale", - "com.google.common.math.Quantiles$ScaleAndIndex" : "Quantiles.ScaleAndIndex", - "com.google.common.math.Quantiles$ScaleAndIndexes" : "Quantiles.ScaleAndIndexes", - "com.google.common.math.Stats" : "Stats", - "com.google.common.math.StatsAccumulator" : "StatsAccumulator", - "com.google.common.math.ToDoubleRounder" : "ToDoubleRounder", - "com.google.common.math.package-info" : "package-info", - "com.google.common.net.ElementTypesAreNonnullByDefault" : "ElementTypesAreNonnullByDefault", - "com.google.common.net.HostAndPort" : "HostAndPort", - "com.google.common.net.HostSpecifier" : "HostSpecifier", - "com.google.common.net.HttpHeaders" : "HttpHeaders", - "com.google.common.net.HttpHeaders$ReferrerPolicyValues" : "HttpHeaders.ReferrerPolicyValues", - "com.google.common.net.InetAddresses" : "InetAddresses", - "com.google.common.net.InetAddresses$Scope" : "InetAddresses.Scope", - "com.google.common.net.InetAddresses$TeredoInfo" : "InetAddresses.TeredoInfo", - "com.google.common.net.InternetDomainName" : "InternetDomainName", - "com.google.common.net.MediaType" : "MediaType", - "com.google.common.net.MediaType$Tokenizer" : "MediaType.Tokenizer", - "com.google.common.net.ParametricNullness" : "ParametricNullness", - "com.google.common.net.PercentEscaper" : "PercentEscaper", - "com.google.common.net.UrlEscapers" : "UrlEscapers", - "com.google.common.net.package-info" : "package-info", - "com.google.common.primitives.Booleans" : "Booleans", - "com.google.common.primitives.Booleans$BooleanArrayAsList" : "Booleans.BooleanArrayAsList", - "com.google.common.primitives.Booleans$BooleanComparator" : "Booleans.BooleanComparator", - "com.google.common.primitives.Booleans$LexicographicalComparator" : "Booleans.LexicographicalComparator", - "com.google.common.primitives.Bytes" : "Bytes", - "com.google.common.primitives.Bytes$ByteArrayAsList" : "Bytes.ByteArrayAsList", - "com.google.common.primitives.Chars" : "Chars", - "com.google.common.primitives.Chars$CharArrayAsList" : "Chars.CharArrayAsList", - "com.google.common.primitives.Chars$LexicographicalComparator" : "Chars.LexicographicalComparator", - "com.google.common.primitives.Doubles" : "Doubles", - "com.google.common.primitives.Doubles$DoubleArrayAsList" : "Doubles.DoubleArrayAsList", - "com.google.common.primitives.Doubles$DoubleConverter" : "Doubles.DoubleConverter", - "com.google.common.primitives.Doubles$LexicographicalComparator" : "Doubles.LexicographicalComparator", - "com.google.common.primitives.DoublesMethodsForWeb" : "DoublesMethodsForWeb", - "com.google.common.primitives.ElementTypesAreNonnullByDefault" : "ElementTypesAreNonnullByDefault", - "com.google.common.primitives.Floats" : "Floats", - "com.google.common.primitives.Floats$FloatArrayAsList" : "Floats.FloatArrayAsList", - "com.google.common.primitives.Floats$FloatConverter" : "Floats.FloatConverter", - "com.google.common.primitives.Floats$LexicographicalComparator" : "Floats.LexicographicalComparator", - "com.google.common.primitives.FloatsMethodsForWeb" : "FloatsMethodsForWeb", - "com.google.common.primitives.ImmutableDoubleArray" : "ImmutableDoubleArray", - "com.google.common.primitives.ImmutableDoubleArray$AsList" : "ImmutableDoubleArray.AsList", - "com.google.common.primitives.ImmutableDoubleArray$Builder" : "ImmutableDoubleArray.Builder", - "com.google.common.primitives.ImmutableIntArray" : "ImmutableIntArray", - "com.google.common.primitives.ImmutableIntArray$AsList" : "ImmutableIntArray.AsList", - "com.google.common.primitives.ImmutableIntArray$Builder" : "ImmutableIntArray.Builder", - "com.google.common.primitives.ImmutableLongArray" : "ImmutableLongArray", - "com.google.common.primitives.ImmutableLongArray$AsList" : "ImmutableLongArray.AsList", - "com.google.common.primitives.ImmutableLongArray$Builder" : "ImmutableLongArray.Builder", - "com.google.common.primitives.Ints" : "Ints", - "com.google.common.primitives.Ints$IntArrayAsList" : "Ints.IntArrayAsList", - "com.google.common.primitives.Ints$IntConverter" : "Ints.IntConverter", - "com.google.common.primitives.Ints$LexicographicalComparator" : "Ints.LexicographicalComparator", - "com.google.common.primitives.IntsMethodsForWeb" : "IntsMethodsForWeb", - "com.google.common.primitives.Longs" : "Longs", - "com.google.common.primitives.Longs$AsciiDigits" : "Longs.AsciiDigits", - "com.google.common.primitives.Longs$LexicographicalComparator" : "Longs.LexicographicalComparator", - "com.google.common.primitives.Longs$LongArrayAsList" : "Longs.LongArrayAsList", - "com.google.common.primitives.Longs$LongConverter" : "Longs.LongConverter", - "com.google.common.primitives.ParametricNullness" : "ParametricNullness", - "com.google.common.primitives.ParseRequest" : "ParseRequest", - "com.google.common.primitives.Primitives" : "Primitives", - "com.google.common.primitives.Shorts" : "Shorts", - "com.google.common.primitives.Shorts$LexicographicalComparator" : "Shorts.LexicographicalComparator", - "com.google.common.primitives.Shorts$ShortArrayAsList" : "Shorts.ShortArrayAsList", - "com.google.common.primitives.Shorts$ShortConverter" : "Shorts.ShortConverter", - "com.google.common.primitives.ShortsMethodsForWeb" : "ShortsMethodsForWeb", - "com.google.common.primitives.SignedBytes" : "SignedBytes", - "com.google.common.primitives.SignedBytes$LexicographicalComparator" : "SignedBytes.LexicographicalComparator", - "com.google.common.primitives.UnsignedBytes" : "UnsignedBytes", - "com.google.common.primitives.UnsignedBytes$LexicographicalComparatorHolder" : "UnsignedBytes.LexicographicalComparatorHolder", - "com.google.common.primitives.UnsignedBytes$LexicographicalComparatorHolder$PureJavaComparator" : "UnsignedBytes.LexicographicalComparatorHolder.PureJavaComparator", - "com.google.common.primitives.UnsignedBytes$LexicographicalComparatorHolder$UnsafeComparator" : "UnsignedBytes.LexicographicalComparatorHolder.UnsafeComparator", - "com.google.common.primitives.UnsignedInteger" : "UnsignedInteger", - "com.google.common.primitives.UnsignedInts" : "UnsignedInts", - "com.google.common.primitives.UnsignedInts$LexicographicalComparator" : "UnsignedInts.LexicographicalComparator", - "com.google.common.primitives.UnsignedLong" : "UnsignedLong", - "com.google.common.primitives.UnsignedLongs" : "UnsignedLongs", - "com.google.common.primitives.UnsignedLongs$LexicographicalComparator" : "UnsignedLongs.LexicographicalComparator", - "com.google.common.primitives.UnsignedLongs$ParseOverflowDetection" : "UnsignedLongs.ParseOverflowDetection", - "com.google.common.primitives.package-info" : "package-info", - "com.google.common.reflect.AbstractInvocationHandler" : "AbstractInvocationHandler", - "com.google.common.reflect.ClassPath" : "ClassPath", - "com.google.common.reflect.ClassPath$ClassInfo" : "ClassPath.ClassInfo", - "com.google.common.reflect.ClassPath$LocationInfo" : "ClassPath.LocationInfo", - "com.google.common.reflect.ClassPath$ResourceInfo" : "ClassPath.ResourceInfo", - "com.google.common.reflect.ElementTypesAreNonnullByDefault" : "ElementTypesAreNonnullByDefault", - "com.google.common.reflect.IgnoreJRERequirement" : "IgnoreJRERequirement", - "com.google.common.reflect.ImmutableTypeToInstanceMap" : "ImmutableTypeToInstanceMap", - "com.google.common.reflect.ImmutableTypeToInstanceMap$Builder" : "ImmutableTypeToInstanceMap.Builder", - "com.google.common.reflect.Invokable" : "Invokable", - "com.google.common.reflect.Invokable$ConstructorInvokable" : "Invokable.ConstructorInvokable", - "com.google.common.reflect.Invokable$MethodInvokable" : "Invokable.MethodInvokable", - "com.google.common.reflect.MutableTypeToInstanceMap" : "MutableTypeToInstanceMap", - "com.google.common.reflect.MutableTypeToInstanceMap$UnmodifiableEntry" : "MutableTypeToInstanceMap.UnmodifiableEntry", - "com.google.common.reflect.Parameter" : "Parameter", - "com.google.common.reflect.ParametricNullness" : "ParametricNullness", - "com.google.common.reflect.Reflection" : "Reflection", - "com.google.common.reflect.TypeCapture" : "TypeCapture", - "com.google.common.reflect.TypeParameter" : "TypeParameter", - "com.google.common.reflect.TypeResolver" : "TypeResolver", - "com.google.common.reflect.TypeResolver$TypeMappingIntrospector" : "TypeResolver.TypeMappingIntrospector", - "com.google.common.reflect.TypeResolver$TypeTable" : "TypeResolver.TypeTable", - "com.google.common.reflect.TypeResolver$TypeVariableKey" : "TypeResolver.TypeVariableKey", - "com.google.common.reflect.TypeResolver$WildcardCapturer" : "TypeResolver.WildcardCapturer", - "com.google.common.reflect.TypeToInstanceMap" : "TypeToInstanceMap", - "com.google.common.reflect.TypeToken" : "TypeToken", - "com.google.common.reflect.TypeToken$Bounds" : "TypeToken.Bounds", - "com.google.common.reflect.TypeToken$ClassSet" : "TypeToken.ClassSet", - "com.google.common.reflect.TypeToken$InterfaceSet" : "TypeToken.InterfaceSet", - "com.google.common.reflect.TypeToken$SimpleTypeToken" : "TypeToken.SimpleTypeToken", - "com.google.common.reflect.TypeToken$TypeCollector" : "TypeToken.TypeCollector", - "com.google.common.reflect.TypeToken$TypeCollector$ForwardingTypeCollector" : "TypeToken.TypeCollector.ForwardingTypeCollector", - "com.google.common.reflect.TypeToken$TypeFilter" : "TypeToken.TypeFilter", - "com.google.common.reflect.TypeToken$TypeSet" : "TypeToken.TypeSet", - "com.google.common.reflect.TypeVisitor" : "TypeVisitor", - "com.google.common.reflect.Types" : "Types", - "com.google.common.reflect.Types$ClassOwnership" : "Types.ClassOwnership", - "com.google.common.reflect.Types$GenericArrayTypeImpl" : "Types.GenericArrayTypeImpl", - "com.google.common.reflect.Types$JavaVersion" : "Types.JavaVersion", - "com.google.common.reflect.Types$NativeTypeVariableEquals" : "Types.NativeTypeVariableEquals", - "com.google.common.reflect.Types$ParameterizedTypeImpl" : "Types.ParameterizedTypeImpl", - "com.google.common.reflect.Types$TypeVariableImpl" : "Types.TypeVariableImpl", - "com.google.common.reflect.Types$TypeVariableInvocationHandler" : "Types.TypeVariableInvocationHandler", - "com.google.common.reflect.Types$WildcardTypeImpl" : "Types.WildcardTypeImpl", - "com.google.common.reflect.package-info" : "package-info", - "com.google.common.util.concurrent.AbstractCatchingFuture" : "AbstractCatchingFuture", - "com.google.common.util.concurrent.AbstractCatchingFuture$AsyncCatchingFuture" : "AbstractCatchingFuture.AsyncCatchingFuture", - "com.google.common.util.concurrent.AbstractCatchingFuture$CatchingFuture" : "AbstractCatchingFuture.CatchingFuture", - "com.google.common.util.concurrent.AbstractExecutionThreadService" : "AbstractExecutionThreadService", - "com.google.common.util.concurrent.AbstractFuture" : "AbstractFuture", - "com.google.common.util.concurrent.AbstractFuture$AtomicHelper" : "AbstractFuture.AtomicHelper", - "com.google.common.util.concurrent.AbstractFuture$Cancellation" : "AbstractFuture.Cancellation", - "com.google.common.util.concurrent.AbstractFuture$Failure" : "AbstractFuture.Failure", - "com.google.common.util.concurrent.AbstractFuture$Listener" : "AbstractFuture.Listener", - "com.google.common.util.concurrent.AbstractFuture$SafeAtomicHelper" : "AbstractFuture.SafeAtomicHelper", - "com.google.common.util.concurrent.AbstractFuture$SetFuture" : "AbstractFuture.SetFuture", - "com.google.common.util.concurrent.AbstractFuture$SynchronizedHelper" : "AbstractFuture.SynchronizedHelper", - "com.google.common.util.concurrent.AbstractFuture$Trusted" : "AbstractFuture.Trusted", - "com.google.common.util.concurrent.AbstractFuture$TrustedFuture" : "AbstractFuture.TrustedFuture", - "com.google.common.util.concurrent.AbstractFuture$UnsafeAtomicHelper" : "AbstractFuture.UnsafeAtomicHelper", - "com.google.common.util.concurrent.AbstractFuture$Waiter" : "AbstractFuture.Waiter", - "com.google.common.util.concurrent.AbstractIdleService" : "AbstractIdleService", - "com.google.common.util.concurrent.AbstractIdleService$DelegateService" : "AbstractIdleService.DelegateService", - "com.google.common.util.concurrent.AbstractIdleService$ThreadNameSupplier" : "AbstractIdleService.ThreadNameSupplier", - "com.google.common.util.concurrent.AbstractListeningExecutorService" : "AbstractListeningExecutorService", - "com.google.common.util.concurrent.AbstractScheduledService" : "AbstractScheduledService", - "com.google.common.util.concurrent.AbstractScheduledService$Cancellable" : "AbstractScheduledService.Cancellable", - "com.google.common.util.concurrent.AbstractScheduledService$CustomScheduler" : "AbstractScheduledService.CustomScheduler", - "com.google.common.util.concurrent.AbstractScheduledService$CustomScheduler$ReschedulableCallable" : "AbstractScheduledService.CustomScheduler.ReschedulableCallable", - "com.google.common.util.concurrent.AbstractScheduledService$CustomScheduler$Schedule" : "AbstractScheduledService.CustomScheduler.Schedule", - "com.google.common.util.concurrent.AbstractScheduledService$CustomScheduler$SupplantableFuture" : "AbstractScheduledService.CustomScheduler.SupplantableFuture", - "com.google.common.util.concurrent.AbstractScheduledService$FutureAsCancellable" : "AbstractScheduledService.FutureAsCancellable", - "com.google.common.util.concurrent.AbstractScheduledService$Scheduler" : "AbstractScheduledService.Scheduler", - "com.google.common.util.concurrent.AbstractScheduledService$ServiceDelegate" : "AbstractScheduledService.ServiceDelegate", - "com.google.common.util.concurrent.AbstractScheduledService$ServiceDelegate$Task" : "AbstractScheduledService.ServiceDelegate.Task", - "com.google.common.util.concurrent.AbstractService" : "AbstractService", - "com.google.common.util.concurrent.AbstractService$HasReachedRunningGuard" : "AbstractService.HasReachedRunningGuard", - "com.google.common.util.concurrent.AbstractService$IsStartableGuard" : "AbstractService.IsStartableGuard", - "com.google.common.util.concurrent.AbstractService$IsStoppableGuard" : "AbstractService.IsStoppableGuard", - "com.google.common.util.concurrent.AbstractService$IsStoppedGuard" : "AbstractService.IsStoppedGuard", - "com.google.common.util.concurrent.AbstractService$StateSnapshot" : "AbstractService.StateSnapshot", - "com.google.common.util.concurrent.AbstractTransformFuture" : "AbstractTransformFuture", - "com.google.common.util.concurrent.AbstractTransformFuture$AsyncTransformFuture" : "AbstractTransformFuture.AsyncTransformFuture", - "com.google.common.util.concurrent.AbstractTransformFuture$TransformFuture" : "AbstractTransformFuture.TransformFuture", - "com.google.common.util.concurrent.AggregateFuture" : "AggregateFuture", - "com.google.common.util.concurrent.AggregateFuture$ReleaseResourcesReason" : "AggregateFuture.ReleaseResourcesReason", - "com.google.common.util.concurrent.AggregateFutureState" : "AggregateFutureState", - "com.google.common.util.concurrent.AggregateFutureState$AtomicHelper" : "AggregateFutureState.AtomicHelper", - "com.google.common.util.concurrent.AggregateFutureState$SafeAtomicHelper" : "AggregateFutureState.SafeAtomicHelper", - "com.google.common.util.concurrent.AggregateFutureState$SynchronizedAtomicHelper" : "AggregateFutureState.SynchronizedAtomicHelper", - "com.google.common.util.concurrent.AsyncCallable" : "AsyncCallable", - "com.google.common.util.concurrent.AsyncFunction" : "AsyncFunction", - "com.google.common.util.concurrent.AtomicDouble" : "AtomicDouble", - "com.google.common.util.concurrent.AtomicDoubleArray" : "AtomicDoubleArray", - "com.google.common.util.concurrent.AtomicLongMap" : "AtomicLongMap", - "com.google.common.util.concurrent.Atomics" : "Atomics", - "com.google.common.util.concurrent.Callables" : "Callables", - "com.google.common.util.concurrent.ClosingFuture" : "ClosingFuture", - "com.google.common.util.concurrent.ClosingFuture$AsyncClosingCallable" : "ClosingFuture.AsyncClosingCallable", - "com.google.common.util.concurrent.ClosingFuture$AsyncClosingFunction" : "ClosingFuture.AsyncClosingFunction", - "com.google.common.util.concurrent.ClosingFuture$CloseableList" : "ClosingFuture.CloseableList", - "com.google.common.util.concurrent.ClosingFuture$ClosingCallable" : "ClosingFuture.ClosingCallable", - "com.google.common.util.concurrent.ClosingFuture$ClosingFunction" : "ClosingFuture.ClosingFunction", - "com.google.common.util.concurrent.ClosingFuture$Combiner" : "ClosingFuture.Combiner", - "com.google.common.util.concurrent.ClosingFuture$Combiner$AsyncCombiningCallable" : "ClosingFuture.Combiner.AsyncCombiningCallable", - "com.google.common.util.concurrent.ClosingFuture$Combiner$CombiningCallable" : "ClosingFuture.Combiner.CombiningCallable", - "com.google.common.util.concurrent.ClosingFuture$Combiner2" : "ClosingFuture.Combiner2", - "com.google.common.util.concurrent.ClosingFuture$Combiner2$AsyncClosingFunction2" : "ClosingFuture.Combiner2.AsyncClosingFunction2", - "com.google.common.util.concurrent.ClosingFuture$Combiner2$ClosingFunction2" : "ClosingFuture.Combiner2.ClosingFunction2", - "com.google.common.util.concurrent.ClosingFuture$Combiner3" : "ClosingFuture.Combiner3", - "com.google.common.util.concurrent.ClosingFuture$Combiner3$AsyncClosingFunction3" : "ClosingFuture.Combiner3.AsyncClosingFunction3", - "com.google.common.util.concurrent.ClosingFuture$Combiner3$ClosingFunction3" : "ClosingFuture.Combiner3.ClosingFunction3", - "com.google.common.util.concurrent.ClosingFuture$Combiner4" : "ClosingFuture.Combiner4", - "com.google.common.util.concurrent.ClosingFuture$Combiner4$AsyncClosingFunction4" : "ClosingFuture.Combiner4.AsyncClosingFunction4", - "com.google.common.util.concurrent.ClosingFuture$Combiner4$ClosingFunction4" : "ClosingFuture.Combiner4.ClosingFunction4", - "com.google.common.util.concurrent.ClosingFuture$Combiner5" : "ClosingFuture.Combiner5", - "com.google.common.util.concurrent.ClosingFuture$Combiner5$AsyncClosingFunction5" : "ClosingFuture.Combiner5.AsyncClosingFunction5", - "com.google.common.util.concurrent.ClosingFuture$Combiner5$ClosingFunction5" : "ClosingFuture.Combiner5.ClosingFunction5", - "com.google.common.util.concurrent.ClosingFuture$DeferredCloser" : "ClosingFuture.DeferredCloser", - "com.google.common.util.concurrent.ClosingFuture$Peeker" : "ClosingFuture.Peeker", - "com.google.common.util.concurrent.ClosingFuture$State" : "ClosingFuture.State", - "com.google.common.util.concurrent.ClosingFuture$ValueAndCloser" : "ClosingFuture.ValueAndCloser", - "com.google.common.util.concurrent.ClosingFuture$ValueAndCloserConsumer" : "ClosingFuture.ValueAndCloserConsumer", - "com.google.common.util.concurrent.CollectionFuture" : "CollectionFuture", - "com.google.common.util.concurrent.CollectionFuture$ListFuture" : "CollectionFuture.ListFuture", - "com.google.common.util.concurrent.CollectionFuture$Present" : "CollectionFuture.Present", - "com.google.common.util.concurrent.CombinedFuture" : "CombinedFuture", - "com.google.common.util.concurrent.CombinedFuture$AsyncCallableInterruptibleTask" : "CombinedFuture.AsyncCallableInterruptibleTask", - "com.google.common.util.concurrent.CombinedFuture$CallableInterruptibleTask" : "CombinedFuture.CallableInterruptibleTask", - "com.google.common.util.concurrent.CombinedFuture$CombinedFutureInterruptibleTask" : "CombinedFuture.CombinedFutureInterruptibleTask", - "com.google.common.util.concurrent.CycleDetectingLockFactory" : "CycleDetectingLockFactory", - "com.google.common.util.concurrent.CycleDetectingLockFactory$CycleDetectingLock" : "CycleDetectingLockFactory.CycleDetectingLock", - "com.google.common.util.concurrent.CycleDetectingLockFactory$CycleDetectingReentrantLock" : "CycleDetectingLockFactory.CycleDetectingReentrantLock", - "com.google.common.util.concurrent.CycleDetectingLockFactory$CycleDetectingReentrantReadLock" : "CycleDetectingLockFactory.CycleDetectingReentrantReadLock", - "com.google.common.util.concurrent.CycleDetectingLockFactory$CycleDetectingReentrantReadWriteLock" : "CycleDetectingLockFactory.CycleDetectingReentrantReadWriteLock", - "com.google.common.util.concurrent.CycleDetectingLockFactory$CycleDetectingReentrantWriteLock" : "CycleDetectingLockFactory.CycleDetectingReentrantWriteLock", - "com.google.common.util.concurrent.CycleDetectingLockFactory$ExampleStackTrace" : "CycleDetectingLockFactory.ExampleStackTrace", - "com.google.common.util.concurrent.CycleDetectingLockFactory$LockGraphNode" : "CycleDetectingLockFactory.LockGraphNode", - "com.google.common.util.concurrent.CycleDetectingLockFactory$Policies" : "CycleDetectingLockFactory.Policies", - "com.google.common.util.concurrent.CycleDetectingLockFactory$Policy" : "CycleDetectingLockFactory.Policy", - "com.google.common.util.concurrent.CycleDetectingLockFactory$PotentialDeadlockException" : "CycleDetectingLockFactory.PotentialDeadlockException", - "com.google.common.util.concurrent.CycleDetectingLockFactory$WithExplicitOrdering" : "CycleDetectingLockFactory.WithExplicitOrdering", - "com.google.common.util.concurrent.DirectExecutor" : "DirectExecutor", - "com.google.common.util.concurrent.DirectExecutorService" : "DirectExecutorService", - "com.google.common.util.concurrent.ElementTypesAreNonnullByDefault" : "ElementTypesAreNonnullByDefault", - "com.google.common.util.concurrent.ExecutionError" : "ExecutionError", - "com.google.common.util.concurrent.ExecutionList" : "ExecutionList", - "com.google.common.util.concurrent.ExecutionList$RunnableExecutorPair" : "ExecutionList.RunnableExecutorPair", - "com.google.common.util.concurrent.ExecutionSequencer" : "ExecutionSequencer", - "com.google.common.util.concurrent.ExecutionSequencer$RunningState" : "ExecutionSequencer.RunningState", - "com.google.common.util.concurrent.ExecutionSequencer$TaskNonReentrantExecutor" : "ExecutionSequencer.TaskNonReentrantExecutor", - "com.google.common.util.concurrent.ExecutionSequencer$ThreadConfinedTaskQueue" : "ExecutionSequencer.ThreadConfinedTaskQueue", - "com.google.common.util.concurrent.FakeTimeLimiter" : "FakeTimeLimiter", - "com.google.common.util.concurrent.FluentFuture" : "FluentFuture", - "com.google.common.util.concurrent.FluentFuture$TrustedFuture" : "FluentFuture.TrustedFuture", - "com.google.common.util.concurrent.ForwardingBlockingDeque" : "ForwardingBlockingDeque", - "com.google.common.util.concurrent.ForwardingBlockingQueue" : "ForwardingBlockingQueue", - "com.google.common.util.concurrent.ForwardingCondition" : "ForwardingCondition", - "com.google.common.util.concurrent.ForwardingExecutorService" : "ForwardingExecutorService", - "com.google.common.util.concurrent.ForwardingFluentFuture" : "ForwardingFluentFuture", - "com.google.common.util.concurrent.ForwardingFuture" : "ForwardingFuture", - "com.google.common.util.concurrent.ForwardingFuture$SimpleForwardingFuture" : "ForwardingFuture.SimpleForwardingFuture", - "com.google.common.util.concurrent.ForwardingListenableFuture" : "ForwardingListenableFuture", - "com.google.common.util.concurrent.ForwardingListenableFuture$SimpleForwardingListenableFuture" : "ForwardingListenableFuture.SimpleForwardingListenableFuture", - "com.google.common.util.concurrent.ForwardingListeningExecutorService" : "ForwardingListeningExecutorService", - "com.google.common.util.concurrent.ForwardingLock" : "ForwardingLock", - "com.google.common.util.concurrent.FutureCallback" : "FutureCallback", - "com.google.common.util.concurrent.Futures" : "Futures", - "com.google.common.util.concurrent.Futures$CallbackListener" : "Futures.CallbackListener", - "com.google.common.util.concurrent.Futures$FutureCombiner" : "Futures.FutureCombiner", - "com.google.common.util.concurrent.Futures$InCompletionOrderFuture" : "Futures.InCompletionOrderFuture", - "com.google.common.util.concurrent.Futures$InCompletionOrderState" : "Futures.InCompletionOrderState", - "com.google.common.util.concurrent.Futures$NonCancellationPropagatingFuture" : "Futures.NonCancellationPropagatingFuture", - "com.google.common.util.concurrent.FuturesGetChecked" : "FuturesGetChecked", - "com.google.common.util.concurrent.FuturesGetChecked$GetCheckedTypeValidator" : "FuturesGetChecked.GetCheckedTypeValidator", - "com.google.common.util.concurrent.FuturesGetChecked$GetCheckedTypeValidatorHolder" : "FuturesGetChecked.GetCheckedTypeValidatorHolder", - "com.google.common.util.concurrent.FuturesGetChecked$GetCheckedTypeValidatorHolder$ClassValueValidator" : "FuturesGetChecked.GetCheckedTypeValidatorHolder.ClassValueValidator", - "com.google.common.util.concurrent.FuturesGetChecked$GetCheckedTypeValidatorHolder$WeakSetValidator" : "FuturesGetChecked.GetCheckedTypeValidatorHolder.WeakSetValidator", - "com.google.common.util.concurrent.GwtFluentFutureCatchingSpecialization" : "GwtFluentFutureCatchingSpecialization", - "com.google.common.util.concurrent.GwtFuturesCatchingSpecialization" : "GwtFuturesCatchingSpecialization", - "com.google.common.util.concurrent.ImmediateFuture" : "ImmediateFuture", - "com.google.common.util.concurrent.ImmediateFuture$ImmediateCancelledFuture" : "ImmediateFuture.ImmediateCancelledFuture", - "com.google.common.util.concurrent.ImmediateFuture$ImmediateFailedFuture" : "ImmediateFuture.ImmediateFailedFuture", - "com.google.common.util.concurrent.Internal" : "Internal", - "com.google.common.util.concurrent.InterruptibleTask" : "InterruptibleTask", - "com.google.common.util.concurrent.InterruptibleTask$Blocker" : "InterruptibleTask.Blocker", - "com.google.common.util.concurrent.InterruptibleTask$DoNothingRunnable" : "InterruptibleTask.DoNothingRunnable", - "com.google.common.util.concurrent.JdkFutureAdapters" : "JdkFutureAdapters", - "com.google.common.util.concurrent.JdkFutureAdapters$ListenableFutureAdapter" : "JdkFutureAdapters.ListenableFutureAdapter", - "com.google.common.util.concurrent.LazyLogger" : "LazyLogger", - "com.google.common.util.concurrent.ListenableFuture" : "ListenableFuture", - "com.google.common.util.concurrent.ListenableFutureTask" : "ListenableFutureTask", - "com.google.common.util.concurrent.ListenableScheduledFuture" : "ListenableScheduledFuture", - "com.google.common.util.concurrent.ListenerCallQueue" : "ListenerCallQueue", - "com.google.common.util.concurrent.ListenerCallQueue$Event" : "ListenerCallQueue.Event", - "com.google.common.util.concurrent.ListenerCallQueue$PerListenerQueue" : "ListenerCallQueue.PerListenerQueue", - "com.google.common.util.concurrent.ListeningExecutorService" : "ListeningExecutorService", - "com.google.common.util.concurrent.ListeningScheduledExecutorService" : "ListeningScheduledExecutorService", - "com.google.common.util.concurrent.Monitor" : "Monitor", - "com.google.common.util.concurrent.Monitor$Guard" : "Monitor.Guard", - "com.google.common.util.concurrent.MoreExecutors" : "MoreExecutors", - "com.google.common.util.concurrent.MoreExecutors$Application" : "MoreExecutors.Application", - "com.google.common.util.concurrent.MoreExecutors$ListeningDecorator" : "MoreExecutors.ListeningDecorator", - "com.google.common.util.concurrent.MoreExecutors$ScheduledListeningDecorator" : "MoreExecutors.ScheduledListeningDecorator", - "com.google.common.util.concurrent.MoreExecutors$ScheduledListeningDecorator$ListenableScheduledTask" : "MoreExecutors.ScheduledListeningDecorator.ListenableScheduledTask", - "com.google.common.util.concurrent.MoreExecutors$ScheduledListeningDecorator$NeverSuccessfulListenableFutureTask" : "MoreExecutors.ScheduledListeningDecorator.NeverSuccessfulListenableFutureTask", - "com.google.common.util.concurrent.NullnessCasts" : "NullnessCasts", - "com.google.common.util.concurrent.OverflowAvoidingLockSupport" : "OverflowAvoidingLockSupport", - "com.google.common.util.concurrent.ParametricNullness" : "ParametricNullness", - "com.google.common.util.concurrent.Partially" : "Partially", - "com.google.common.util.concurrent.Partially$GwtIncompatible" : "Partially.GwtIncompatible", - "com.google.common.util.concurrent.Platform" : "Platform", - "com.google.common.util.concurrent.RateLimiter" : "RateLimiter", - "com.google.common.util.concurrent.RateLimiter$SleepingStopwatch" : "RateLimiter.SleepingStopwatch", - "com.google.common.util.concurrent.Runnables" : "Runnables", - "com.google.common.util.concurrent.SequentialExecutor" : "SequentialExecutor", - "com.google.common.util.concurrent.SequentialExecutor$QueueWorker" : "SequentialExecutor.QueueWorker", - "com.google.common.util.concurrent.SequentialExecutor$WorkerRunningState" : "SequentialExecutor.WorkerRunningState", - "com.google.common.util.concurrent.Service" : "Service", - "com.google.common.util.concurrent.Service$Listener" : "Service.Listener", - "com.google.common.util.concurrent.Service$State" : "Service.State", - "com.google.common.util.concurrent.ServiceManager" : "ServiceManager", - "com.google.common.util.concurrent.ServiceManager$EmptyServiceManagerWarning" : "ServiceManager.EmptyServiceManagerWarning", - "com.google.common.util.concurrent.ServiceManager$FailedService" : "ServiceManager.FailedService", - "com.google.common.util.concurrent.ServiceManager$Listener" : "ServiceManager.Listener", - "com.google.common.util.concurrent.ServiceManager$NoOpService" : "ServiceManager.NoOpService", - "com.google.common.util.concurrent.ServiceManager$ServiceListener" : "ServiceManager.ServiceListener", - "com.google.common.util.concurrent.ServiceManager$ServiceManagerState" : "ServiceManager.ServiceManagerState", - "com.google.common.util.concurrent.ServiceManager$ServiceManagerState$AwaitHealthGuard" : "ServiceManager.ServiceManagerState.AwaitHealthGuard", - "com.google.common.util.concurrent.ServiceManager$ServiceManagerState$StoppedGuard" : "ServiceManager.ServiceManagerState.StoppedGuard", - "com.google.common.util.concurrent.ServiceManagerBridge" : "ServiceManagerBridge", - "com.google.common.util.concurrent.SettableFuture" : "SettableFuture", - "com.google.common.util.concurrent.SimpleTimeLimiter" : "SimpleTimeLimiter", - "com.google.common.util.concurrent.SmoothRateLimiter" : "SmoothRateLimiter", - "com.google.common.util.concurrent.SmoothRateLimiter$SmoothBursty" : "SmoothRateLimiter.SmoothBursty", - "com.google.common.util.concurrent.SmoothRateLimiter$SmoothWarmingUp" : "SmoothRateLimiter.SmoothWarmingUp", - "com.google.common.util.concurrent.Striped" : "Striped", - "com.google.common.util.concurrent.Striped$CompactStriped" : "Striped.CompactStriped", - "com.google.common.util.concurrent.Striped$LargeLazyStriped" : "Striped.LargeLazyStriped", - "com.google.common.util.concurrent.Striped$PaddedLock" : "Striped.PaddedLock", - "com.google.common.util.concurrent.Striped$PaddedSemaphore" : "Striped.PaddedSemaphore", - "com.google.common.util.concurrent.Striped$PowerOfTwoStriped" : "Striped.PowerOfTwoStriped", - "com.google.common.util.concurrent.Striped$SmallLazyStriped" : "Striped.SmallLazyStriped", - "com.google.common.util.concurrent.Striped$SmallLazyStriped$ArrayReference" : "Striped.SmallLazyStriped.ArrayReference", - "com.google.common.util.concurrent.Striped$WeakSafeCondition" : "Striped.WeakSafeCondition", - "com.google.common.util.concurrent.Striped$WeakSafeLock" : "Striped.WeakSafeLock", - "com.google.common.util.concurrent.Striped$WeakSafeReadWriteLock" : "Striped.WeakSafeReadWriteLock", - "com.google.common.util.concurrent.ThreadFactoryBuilder" : "ThreadFactoryBuilder", - "com.google.common.util.concurrent.TimeLimiter" : "TimeLimiter", - "com.google.common.util.concurrent.TimeoutFuture" : "TimeoutFuture", - "com.google.common.util.concurrent.TimeoutFuture$Fire" : "TimeoutFuture.Fire", - "com.google.common.util.concurrent.TimeoutFuture$TimeoutFutureException" : "TimeoutFuture.TimeoutFutureException", - "com.google.common.util.concurrent.TrustedListenableFutureTask" : "TrustedListenableFutureTask", - "com.google.common.util.concurrent.TrustedListenableFutureTask$TrustedFutureInterruptibleAsyncTask" : "TrustedListenableFutureTask.TrustedFutureInterruptibleAsyncTask", - "com.google.common.util.concurrent.TrustedListenableFutureTask$TrustedFutureInterruptibleTask" : "TrustedListenableFutureTask.TrustedFutureInterruptibleTask", - "com.google.common.util.concurrent.UncaughtExceptionHandlers" : "UncaughtExceptionHandlers", - "com.google.common.util.concurrent.UncaughtExceptionHandlers$Exiter" : "UncaughtExceptionHandlers.Exiter", - "com.google.common.util.concurrent.UncheckedExecutionException" : "UncheckedExecutionException", - "com.google.common.util.concurrent.UncheckedTimeoutException" : "UncheckedTimeoutException", - "com.google.common.util.concurrent.Uninterruptibles" : "Uninterruptibles", - "com.google.common.util.concurrent.WrappingExecutorService" : "WrappingExecutorService", - "com.google.common.util.concurrent.WrappingScheduledExecutorService" : "WrappingScheduledExecutorService", - "com.google.common.util.concurrent.internal.InternalFutureFailureAccess" : "InternalFutureFailureAccess", - "com.google.common.util.concurrent.internal.InternalFutures" : "InternalFutures", - "com.google.common.util.concurrent.package-info" : "package-info", - "com.google.common.xml.ElementTypesAreNonnullByDefault" : "ElementTypesAreNonnullByDefault", - "com.google.common.xml.ParametricNullness" : "ParametricNullness", - "com.google.common.xml.XmlEscapers" : "XmlEscapers", - "com.google.common.xml.package-info" : "package-info" - }, - "classpath" : "\/Users\/ktoso\/.gradle\/caches\/modules-2\/files-2.1\/com.google.guava\/guava\/33.3.1-jre\/852f8b363da0111e819460021ca693cacca3e8db\/guava-33.3.1-jre.jar:\/Users\/ktoso\/.gradle\/caches\/modules-2\/files-2.1\/com.google.guava\/failureaccess\/1.0.2\/c4a06a64e650562f30b7bf9aaec1bfed43aca12b\/failureaccess-1.0.2.jar:\/Users\/ktoso\/.gradle\/caches\/modules-2\/files-2.1\/com.google.guava\/listenablefuture\/9999.0-empty-to-avoid-conflict-with-guava\/b421526c5f297295adef1c886e5246c39d4ac629\/listenablefuture-9999.0-empty-to-avoid-conflict-with-guava.jar:\/Users\/ktoso\/.gradle\/caches\/modules-2\/files-2.1\/com.google.code.findbugs\/jsr305\/3.0.2\/25ea2e8b0c338a877313bd4672d3fe056ea78f0d\/jsr305-3.0.2.jar:\/Users\/ktoso\/.gradle\/caches\/modules-2\/files-2.1\/org.checkerframework\/checker-qual\/3.43.0\/9425eee39e56b116d2b998b7c2cebcbd11a3c98b\/checker-qual-3.43.0.jar:\/Users\/ktoso\/.gradle\/caches\/modules-2\/files-2.1\/com.google.errorprone\/error_prone_annotations\/2.28.0\/59fc00087ce372de42e394d2c789295dff2d19f0\/error_prone_annotations-2.28.0.jar:\/Users\/ktoso\/.gradle\/caches\/modules-2\/files-2.1\/com.google.j2objc\/j2objc-annotations\/3.0.0\/7399e65dd7e9ff3404f4535b2f017093bdb134c7\/j2objc-annotations-3.0.0.jar:\/Users\/ktoso\/.gradle\/caches\/modules-2\/files-2.1\/com.google.guava\/guava\/33.3.1-jre\/852f8b363da0111e819460021ca693cacca3e8db\/guava-33.3.1-jre.jar:\/Users\/ktoso\/.gradle\/caches\/modules-2\/files-2.1\/com.google.guava\/failureaccess\/1.0.2\/c4a06a64e650562f30b7bf9aaec1bfed43aca12b\/failureaccess-1.0.2.jar:\/Users\/ktoso\/.gradle\/caches\/modules-2\/files-2.1\/com.google.guava\/listenablefuture\/9999.0-empty-to-avoid-conflict-with-guava\/b421526c5f297295adef1c886e5246c39d4ac629\/listenablefuture-9999.0-empty-to-avoid-conflict-with-guava.jar:\/Users\/ktoso\/.gradle\/caches\/modules-2\/files-2.1\/com.google.code.findbugs\/jsr305\/3.0.2\/25ea2e8b0c338a877313bd4672d3fe056ea78f0d\/jsr305-3.0.2.jar:\/Users\/ktoso\/.gradle\/caches\/modules-2\/files-2.1\/org.checkerframework\/checker-qual\/3.43.0\/9425eee39e56b116d2b998b7c2cebcbd11a3c98b\/checker-qual-3.43.0.jar:\/Users\/ktoso\/.gradle\/caches\/modules-2\/files-2.1\/com.google.errorprone\/error_prone_annotations\/2.28.0\/59fc00087ce372de42e394d2c789295dff2d19f0\/error_prone_annotations-2.28.0.jar:\/Users\/ktoso\/.gradle\/caches\/modules-2\/files-2.1\/com.google.j2objc\/j2objc-annotations\/3.0.0\/7399e65dd7e9ff3404f4535b2f017093bdb134c7\/j2objc-annotations-3.0.0.jar:\/Users\/ktoso\/.gradle\/caches\/modules-2\/files-2.1\/com.google.guava\/guava\/33.3.1-jre\/852f8b363da0111e819460021ca693cacca3e8db\/guava-33.3.1-jre.jar:\/Users\/ktoso\/.gradle\/caches\/modules-2\/files-2.1\/com.google.guava\/failureaccess\/1.0.2\/c4a06a64e650562f30b7bf9aaec1bfed43aca12b\/failureaccess-1.0.2.jar:\/Users\/ktoso\/.gradle\/caches\/modules-2\/files-2.1\/com.google.guava\/listenablefuture\/9999.0-empty-to-avoid-conflict-with-guava\/b421526c5f297295adef1c886e5246c39d4ac629\/listenablefuture-9999.0-empty-to-avoid-conflict-with-guava.jar:\/Users\/ktoso\/.gradle\/caches\/modules-2\/files-2.1\/com.google.code.findbugs\/jsr305\/3.0.2\/25ea2e8b0c338a877313bd4672d3fe056ea78f0d\/jsr305-3.0.2.jar:\/Users\/ktoso\/.gradle\/caches\/modules-2\/files-2.1\/org.checkerframework\/checker-qual\/3.43.0\/9425eee39e56b116d2b998b7c2cebcbd11a3c98b\/checker-qual-3.43.0.jar:\/Users\/ktoso\/.gradle\/caches\/modules-2\/files-2.1\/com.google.errorprone\/error_prone_annotations\/2.28.0\/59fc00087ce372de42e394d2c789295dff2d19f0\/error_prone_annotations-2.28.0.jar:\/Users\/ktoso\/.gradle\/caches\/modules-2\/files-2.1\/com.google.j2objc\/j2objc-annotations\/3.0.0\/7399e65dd7e9ff3404f4535b2f017093bdb134c7\/j2objc-annotations-3.0.0.jar", - "dependencies" : [ - "com.google.guava:guava:33.3.1-jre" - ] -} diff --git a/Samples/JavaDependencySampleApp/Sources/JavaCommonsCSV/dummy.swift b/Samples/JavaDependencySampleApp/Sources/JavaCommonsCSV/dummy.swift new file mode 100644 index 00000000..59b16b3a --- /dev/null +++ b/Samples/JavaDependencySampleApp/Sources/JavaCommonsCSV/dummy.swift @@ -0,0 +1,14 @@ +//===----------------------------------------------------------------------===// +// +// This source file is part of the Swift.org open source project +// +// Copyright (c) 2024 Apple Inc. and the Swift.org project authors +// Licensed under Apache License v2.0 +// +// See LICENSE.txt for license information +// See CONTRIBUTORS.txt for the list of Swift.org project authors +// +// SPDX-License-Identifier: Apache-2.0 +// +//===----------------------------------------------------------------------===// + diff --git a/Samples/JavaDependencySampleApp/Sources/JavaCommonsCSV/swift-java.config b/Samples/JavaDependencySampleApp/Sources/JavaCommonsCSV/swift-java.config new file mode 100644 index 00000000..b6b92d88 --- /dev/null +++ b/Samples/JavaDependencySampleApp/Sources/JavaCommonsCSV/swift-java.config @@ -0,0 +1,9 @@ +{ + "classes" : { + "org.apache.commons.io.FilenameUtils" : "FilenameUtils" + }, + "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:\/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:JavaKit\/build\/classes\/java\/main:..\/..\/JavaKit\/build\/classes\/java\/main:\/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:JavaKit\/build\/classes\/java\/main:..\/..\/JavaKit\/build\/classes\/java\/main:\/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:JavaKit\/build\/classes\/java\/main:..\/..\/JavaKit\/build\/classes\/java\/main:\/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:JavaKit\/build\/classes\/java\/main:..\/..\/JavaKit\/build\/classes\/java\/main:\/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:JavaKit\/build\/classes\/java\/main:..\/..\/JavaKit\/build\/classes\/java\/main", + "dependencies" : [ + "org.apache.commons:commons-csv:1.12.0" + ] +} diff --git a/Samples/JavaDependencySampleApp/Sources/JavaDependencySample/main.swift b/Samples/JavaDependencySampleApp/Sources/JavaDependencySample/main.swift index 84bc07b0..92c580e7 100644 --- a/Samples/JavaDependencySampleApp/Sources/JavaDependencySample/main.swift +++ b/Samples/JavaDependencySampleApp/Sources/JavaDependencySample/main.swift @@ -14,7 +14,7 @@ import JavaKit import JavaKitFunction -import ReactiveStreams +import JavaCommonsCSV // Just showcasing that we imported the module let s: Subscriber? = nil diff --git a/Samples/JavaDependencySampleApp/Sources/JavaDependencySample/swift-java.config b/Samples/JavaDependencySampleApp/Sources/JavaDependencySample/swift-java.config index b7f52945..7a73a41b 100644 --- a/Samples/JavaDependencySampleApp/Sources/JavaDependencySample/swift-java.config +++ b/Samples/JavaDependencySampleApp/Sources/JavaDependencySample/swift-java.config @@ -1,7 +1,2 @@ { - "dependencies": [ - "com.google.guava:guava:33.3.1-jre" - ], - "__FIXME": "we should not need to express this classpath!", - "classpath": "JavaKit/build/classes/java/main:../../JavaKit/build/classes/java/main", -} +} \ No newline at end of file diff --git a/Samples/JavaDependencySampleApp/ci-validate.sh b/Samples/JavaDependencySampleApp/ci-validate.sh index 62e68b0b..e8a354ae 100755 --- a/Samples/JavaDependencySampleApp/ci-validate.sh +++ b/Samples/JavaDependencySampleApp/ci-validate.sh @@ -2,12 +2,12 @@ JAVASWIFT="../../.build/debug/Java2Swift" -MODULE_NAME=Guava +MODULE_NAME="JavaCommonsCSV" MODULE_CONFIG_DIR=$(pwd)/Sources/$MODULE_NAME/ MODULE_CONFIG_PATH="$MODULE_CONFIG_DIR/swift-java.config" ### 1) downloads all the dependencies -"$JAVASWIFT" --fetch Sources/JavaDependencySample/swift-java.config \ +"$JAVASWIFT" --fetch "$MODULE_CONFIG_DIR/swift-java.config" \ --module-name "$MODULE_NAME" \ --output-directory "$MODULE_CONFIG_DIR" @@ -17,8 +17,8 @@ DEP_JAR_CP=$(echo "$DEP_JAR_CP" | tr -d '"') # trim the "..." # shellcheck disable=SC2086 "$JAVASWIFT" --jar $DEP_JAR_CP \ --module-name "$MODULE_NAME" \ - --java-package-filter com.google.common \ --existing-config amend +# --java-package-filter com.google.common \ ### 3) make wrappers for the module "$JAVASWIFT" "$MODULE_CONFIG_PATH" --module-name "$MODULE_NAME" diff --git a/Sources/Java2Swift/JavaToSwift+EmitConfiguration.swift b/Sources/Java2Swift/JavaToSwift+EmitConfiguration.swift index 7863fae8..fd567234 100644 --- a/Sources/Java2Swift/JavaToSwift+EmitConfiguration.swift +++ b/Sources/Java2Swift/JavaToSwift+EmitConfiguration.swift @@ -54,7 +54,7 @@ extension JavaToSwift { environment: environment ) } else if FileManager.default.fileExists(atPath: entry) { - fatalError("[warning][swift-java] Currently unable handle directory classpath entries for config generation! Skipping: \(entry)") + print("[warning][swift-java] Currently unable handle directory classpath entries for config generation! Skipping: \(entry)") } else { print("[warning][swift-java] Classpath entry does not exist, skipping: \(entry)") } @@ -89,6 +89,9 @@ extension JavaToSwift { guard !entry.getName().hasSuffix("package-info") else { continue } + guard !entry.getName().hasSuffix("package-info.class") else { + continue + } // If this is a local class, it cannot be mapped into Swift. if entry.getName().isLocalJavaClass { diff --git a/Sources/Java2Swift/JavaToSwift.swift b/Sources/Java2Swift/JavaToSwift.swift index cc8f51b4..1e85de10 100644 --- a/Sources/Java2Swift/JavaToSwift.swift +++ b/Sources/Java2Swift/JavaToSwift.swift @@ -152,141 +152,159 @@ struct JavaToSwift: ParsableCommand { // FIXME each mode should have its own config? } - mutating func run() throws { - let config: Configuration - - // Determine the mode in which we'll execute. - let toolMode: ToolMode - if jar { - if let moduleBaseDir { - config = try readConfiguration(sourceDir: "file://" + moduleBaseDir.path) + mutating func run() { + print("[info][swift-java] Run: \(CommandLine.arguments.joined(separator: " "))") + do { + let config: Configuration + + // Determine the mode in which we'll execute. + let toolMode: ToolMode + if jar { + if let moduleBaseDir { + config = try readConfiguration(sourceDir: "file://" + moduleBaseDir.path) + } else { + config = Configuration() + } + toolMode = .configuration(extraClasspath: input) + } else if fetch { + config = try JavaTranslator.readConfiguration(from: URL(fileURLWithPath: input)) + guard let dependencies = config.dependencies else { + print("[swift-java] Running in 'fetch dependencies' mode but dependencies list was empty!") + print("[swift-java] Nothing to do: done.") + return + } + toolMode = .fetchDependencies } else { - config = Configuration() + config = try JavaTranslator.readConfiguration(from: URL(fileURLWithPath: input)) + toolMode = .classWrappers } - toolMode = .configuration(extraClasspath: input) - } else if fetch { - config = try JavaTranslator.readConfiguration(from: URL(fileURLWithPath: input)) - guard let dependencies = config.dependencies else { - print("[swift-java] Running in 'fetch dependencies' mode but dependencies list was empty!") - print("[swift-java] Nothing to do: done.") - return - } - toolMode = .fetchDependencies - } else { - config = try JavaTranslator.readConfiguration(from: URL(fileURLWithPath: input)) - toolMode = .classWrappers - } - let moduleName = self.moduleName ?? - input.split(separator: "/").dropLast().last.map(String.init) ?? - "__UnknownModule" + let moduleName = self.moduleName ?? + input.split(separator: "/").dropLast().last.map(String.init) ?? + "__UnknownModule" - // Load all of the dependent configurations and associate them with Swift - // modules. - let dependentConfigs = try dependsOn.map { dependentConfig in - guard let equalLoc = dependentConfig.firstIndex(of: "=") else { - throw JavaToSwiftError.badConfigOption(dependentConfig) - } + // Load all of the dependent configurations and associate them with Swift + // modules. + let dependentConfigs = try dependsOn.map { dependentConfig in + guard let equalLoc = dependentConfig.firstIndex(of: "=") else { + throw JavaToSwiftError.badConfigOption(dependentConfig) + } - let afterEqual = dependentConfig.index(after: equalLoc) - let swiftModuleName = String(dependentConfig[.. (javaClassName: String, swiftName: String) { diff --git a/Sources/Java2SwiftLib/JavaTranslator+Validation.swift b/Sources/Java2SwiftLib/JavaTranslator+Validation.swift index c85cedb0..9d4d00ca 100644 --- a/Sources/Java2SwiftLib/JavaTranslator+Validation.swift +++ b/Sources/Java2SwiftLib/JavaTranslator+Validation.swift @@ -52,7 +52,7 @@ package extension JavaTranslator { } } - func validateClassConfiguration() throws { + func validateClassConfiguration() throws(ValidationError) { // Group all classes by swift name let groupedDictionary: [SwiftTypeName: [(String, (String, String?))]] = Dictionary(grouping: translatedClasses, by: { SwiftTypeName(swiftType: $0.value.swiftType, swiftModule: $0.value.swiftModule) }) // Find all that are mapped to multiple names diff --git a/Sources/JavaKitConfigurationShared/Configuration.swift b/Sources/JavaKitConfigurationShared/Configuration.swift index ddb75a50..3bb34d97 100644 --- a/Sources/JavaKitConfigurationShared/Configuration.swift +++ b/Sources/JavaKitConfigurationShared/Configuration.swift @@ -86,7 +86,10 @@ public struct JavaDependencyDescriptor: Hashable, Codable { } public func readConfiguration(sourceDir: String, file: String = #fileID, line: UInt = #line) throws -> Configuration { - let configFile = URL(string: sourceDir)!.appendingPathComponent("swift-java.config", isDirectory: false) + let sourcePath = + if sourceDir.hasPrefix("file://") { sourceDir } else { "file://" + sourceDir } + let configFile = URL(string: sourcePath)!.appendingPathComponent("swift-java.config", isDirectory: false) + do { let configData = try Data(contentsOf: configFile) return try JSONDecoder().decode(Configuration.self, from: configData) From 4d0b38fa3af9b40f6ed864bf7f1abd5e30badd0f Mon Sep 17 00:00:00 2001 From: Konrad `ktoso` Malawski Date: Thu, 5 Dec 2024 22:34:17 +0900 Subject: [PATCH 11/25] first time JavaDependencySample showing a fetched dependency working! --- Package.swift | 13 ++++++---- .../Java2SwiftPlugin/Java2SwiftPlugin.swift | 11 +++++--- Samples/JavaDependencySampleApp/Package.swift | 1 + .../Sources/JavaCommonsCSV/dummy.swift | 1 - .../Sources/JavaCommonsCSV/swift-java.config | 2 +- .../Sources/JavaDependencySample/main.swift | 26 ++++++++++++++++--- .../JavaDependencySampleApp/ci-validate.sh | 20 +++++++------- Sources/Java2Swift/JavaToSwift.swift | 6 ++--- .../Configuration.swift | 9 +++++++ 9 files changed, 64 insertions(+), 25 deletions(-) diff --git a/Package.swift b/Package.swift index 706da53f..f6645115 100644 --- a/Package.swift +++ b/Package.swift @@ -188,7 +188,12 @@ let package = Package( .target( name: "JavaKit", - dependencies: ["JavaRuntime", "JavaKitMacros", "JavaTypes"], + dependencies: [ + "JavaRuntime", + "JavaKitMacros", + "JavaTypes", + "JavaKitConfigurationShared", // for Configuration reading at runtime + ], exclude: ["swift-java.config"], swiftSettings: [ .swiftLanguageMode(.v5), @@ -198,10 +203,8 @@ let package = Package( .unsafeFlags( [ "-L\(javaHome)/lib/server", - "-Xlinker", - "-rpath", - "-Xlinker", - "\(javaHome)/lib/server", + "-Xlinker", "-rpath", + "-Xlinker", "\(javaHome)/lib/server", ], .when(platforms: [.linux, .macOS]) ), diff --git a/Plugins/Java2SwiftPlugin/Java2SwiftPlugin.swift b/Plugins/Java2SwiftPlugin/Java2SwiftPlugin.swift index 16e5f442..51b41264 100644 --- a/Plugins/Java2SwiftPlugin/Java2SwiftPlugin.swift +++ b/Plugins/Java2SwiftPlugin/Java2SwiftPlugin.swift @@ -24,6 +24,7 @@ struct Java2SwiftBuildToolPlugin: SwiftJavaPluginProtocol, BuildToolPlugin { var verbose: Bool = getEnvironmentBool("SWIFT_JAVA_VERBOSE") func createBuildCommands(context: PluginContext, target: Target) throws -> [Command] { + log("Create build commands for: \(target.name)") guard let sourceModule = target.sourceModule else { return [] } // Note: Target doesn't have a directoryURL counterpart to directory, @@ -41,6 +42,7 @@ struct Java2SwiftBuildToolPlugin: SwiftJavaPluginProtocol, BuildToolPlugin { /// this target depends on. var dependentConfigFiles: [(String, URL)] = [] func searchForConfigFiles(in target: any Target) { + log("Search for config files in target: \(target.name)") let dependencyURL = URL(filePath: target.directory.string) // Look for a config file within this target. @@ -58,10 +60,13 @@ struct Java2SwiftBuildToolPlugin: SwiftJavaPluginProtocol, BuildToolPlugin { for dependency in target.dependencies { switch dependency { case .target(let target): + log("Dependency target: \(target.name)") searchForConfigFiles(in: target) case .product(let product): + log("Dependency product: \(product.name)") for target in product.targets { + log("Dependency product: \(product.name), target: \(target.name)") searchForConfigFiles(in: target) } @@ -72,6 +77,7 @@ struct Java2SwiftBuildToolPlugin: SwiftJavaPluginProtocol, BuildToolPlugin { // Process indirect target dependencies. for dependency in target.recursiveTargetDependencies { + log("Recursive dependency target: \(dependency.name)") searchForConfigFiles(in: dependency) } @@ -115,7 +121,7 @@ struct Java2SwiftBuildToolPlugin: SwiftJavaPluginProtocol, BuildToolPlugin { while classpath.lastPathComponent != "Java" { classpath.deleteLastPathComponent() } - arguments += [ "--classpath", classpath.path() ] + arguments += ["--classpath", classpath.path()] // For each of the class files, note that it can have Swift-native // implementations. We figure this out based on the path. @@ -131,7 +137,7 @@ struct Java2SwiftBuildToolPlugin: SwiftJavaPluginProtocol, BuildToolPlugin { let className = classNameComponents .reversed() .joined(separator: ".") - arguments += [ "--swift-native-implementation", className] + arguments += ["--swift-native-implementation", className] } } @@ -141,7 +147,6 @@ struct Java2SwiftBuildToolPlugin: SwiftJavaPluginProtocol, BuildToolPlugin { } let executable = try context.tool(named: "Java2Swift").url - log("Prepared build command: \(executable) \(arguments)") return [ .buildCommand( diff --git a/Samples/JavaDependencySampleApp/Package.swift b/Samples/JavaDependencySampleApp/Package.swift index 125aea0a..d8ced924 100644 --- a/Samples/JavaDependencySampleApp/Package.swift +++ b/Samples/JavaDependencySampleApp/Package.swift @@ -84,6 +84,7 @@ let package = Package( name: "JavaCommonsCSV", dependencies: [ .product(name: "JavaKit", package: "swift-java"), + .product(name: "JavaKitFunction", package: "swift-java"), .product(name: "JavaRuntime", package: "swift-java"), ], swiftSettings: [ diff --git a/Samples/JavaDependencySampleApp/Sources/JavaCommonsCSV/dummy.swift b/Samples/JavaDependencySampleApp/Sources/JavaCommonsCSV/dummy.swift index 59b16b3a..76f848f9 100644 --- a/Samples/JavaDependencySampleApp/Sources/JavaCommonsCSV/dummy.swift +++ b/Samples/JavaDependencySampleApp/Sources/JavaCommonsCSV/dummy.swift @@ -11,4 +11,3 @@ // SPDX-License-Identifier: Apache-2.0 // //===----------------------------------------------------------------------===// - diff --git a/Samples/JavaDependencySampleApp/Sources/JavaCommonsCSV/swift-java.config b/Samples/JavaDependencySampleApp/Sources/JavaCommonsCSV/swift-java.config index b6b92d88..7e1f4aeb 100644 --- a/Samples/JavaDependencySampleApp/Sources/JavaCommonsCSV/swift-java.config +++ b/Samples/JavaDependencySampleApp/Sources/JavaCommonsCSV/swift-java.config @@ -2,7 +2,7 @@ "classes" : { "org.apache.commons.io.FilenameUtils" : "FilenameUtils" }, - "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:\/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:JavaKit\/build\/classes\/java\/main:..\/..\/JavaKit\/build\/classes\/java\/main:\/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:JavaKit\/build\/classes\/java\/main:..\/..\/JavaKit\/build\/classes\/java\/main:\/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:JavaKit\/build\/classes\/java\/main:..\/..\/JavaKit\/build\/classes\/java\/main:\/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:JavaKit\/build\/classes\/java\/main:..\/..\/JavaKit\/build\/classes\/java\/main:\/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:JavaKit\/build\/classes\/java\/main:..\/..\/JavaKit\/build\/classes\/java\/main", + "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:\/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:JavaKit\/build\/classes\/java\/main:..\/..\/JavaKit\/build\/classes\/java\/main", "dependencies" : [ "org.apache.commons:commons-csv:1.12.0" ] diff --git a/Samples/JavaDependencySampleApp/Sources/JavaDependencySample/main.swift b/Samples/JavaDependencySampleApp/Sources/JavaDependencySample/main.swift index 92c580e7..53aef9dc 100644 --- a/Samples/JavaDependencySampleApp/Sources/JavaDependencySample/main.swift +++ b/Samples/JavaDependencySampleApp/Sources/JavaDependencySample/main.swift @@ -14,9 +14,29 @@ import JavaKit import JavaKitFunction +import JavaKitConfigurationShared +import Foundation + +// Import the commons-csv library wrapper: import JavaCommonsCSV -// Just showcasing that we imported the module -let s: Subscriber? = nil +// Make sure we have the classpath loaded +// TODO: this is more complex than that, need to account for dependencies of our module +let currentDir = FileManager.default.currentDirectoryPath +let configuration = try readConfiguration(sourceDir: "\(currentDir)/Sources/JavaCommonsCSV/") + +// 1) Start a JVM with apropriate classpath +let jvm = try JavaVirtualMachine.shared(classpath: configuration.classpathEntries) + +// 2) Get the FilenameUtils Java class so we can call the static methods on it +let FilenameUtilsClass = try JavaClass() + +// Some silly sample path we want to work with: +let path = "/example/path/executable.exe" +print("Path = \(path)") + +let ext = try! FilenameUtilsClass.getExtension(path) +print("Java FilenameUtils found extension = \(ext)") +precondition(ext == "exe") -print("Done.") \ No newline at end of file +print("Done.") diff --git a/Samples/JavaDependencySampleApp/ci-validate.sh b/Samples/JavaDependencySampleApp/ci-validate.sh index e8a354ae..658960c6 100755 --- a/Samples/JavaDependencySampleApp/ci-validate.sh +++ b/Samples/JavaDependencySampleApp/ci-validate.sh @@ -11,14 +11,16 @@ MODULE_CONFIG_PATH="$MODULE_CONFIG_DIR/swift-java.config" --module-name "$MODULE_NAME" \ --output-directory "$MODULE_CONFIG_DIR" -### 2) extract the config for the fetched dependency -DEP_JAR_CP=$(jq .classpath "$MODULE_CONFIG_PATH") -DEP_JAR_CP=$(echo "$DEP_JAR_CP" | tr -d '"') # trim the "..." -# shellcheck disable=SC2086 -"$JAVASWIFT" --jar $DEP_JAR_CP \ - --module-name "$MODULE_NAME" \ - --existing-config amend -# --java-package-filter com.google.common \ +#### 2) extract the config for the fetched dependency +#DEP_JAR_CP=$(jq .classpath "$MODULE_CONFIG_PATH") +#DEP_JAR_CP=$(echo "$DEP_JAR_CP" | tr -d '"') # trim the "..." +## shellcheck disable=SC2086 +#"$JAVASWIFT" --jar $DEP_JAR_CP \ +# --module-name "$MODULE_NAME" \ +# --java-package-filter org.apache.commons \ +# --existing-config amend + +# for now in CI we just use what we have already generated and comitted in the config ### 3) make wrappers for the module -"$JAVASWIFT" "$MODULE_CONFIG_PATH" --module-name "$MODULE_NAME" +swift run diff --git a/Sources/Java2Swift/JavaToSwift.swift b/Sources/Java2Swift/JavaToSwift.swift index 1e85de10..2f9347e6 100644 --- a/Sources/Java2Swift/JavaToSwift.swift +++ b/Sources/Java2Swift/JavaToSwift.swift @@ -161,7 +161,7 @@ struct JavaToSwift: ParsableCommand { let toolMode: ToolMode if jar { if let moduleBaseDir { - config = try readConfiguration(sourceDir: "file://" + moduleBaseDir.path) + config = try readConfiguration(sourceDir: moduleBaseDir.path) } else { config = Configuration() } @@ -304,7 +304,7 @@ struct JavaToSwift: ParsableCommand { fatalError(message) } - print("[info][swift-java] " + "Done.".green) + print("[info][swift-java] " + "Done: ".green + CommandLine.arguments.joined(separator: " ")) } private func names(from javaClassNameOpt: String) -> (javaClassName: String, swiftName: String) { @@ -380,7 +380,7 @@ extension JavaToSwift { return (false, .init()) case .amend: let configPath = actualOutputDirectory - return (true, try readConfiguration(sourceDir: "file://" + configPath.path)) + return (true, try readConfiguration(sourceDir: configPath.path)) } } } diff --git a/Sources/JavaKitConfigurationShared/Configuration.swift b/Sources/JavaKitConfigurationShared/Configuration.swift index 3bb34d97..6169c261 100644 --- a/Sources/JavaKitConfigurationShared/Configuration.swift +++ b/Sources/JavaKitConfigurationShared/Configuration.swift @@ -32,6 +32,14 @@ public struct Configuration: Codable { /// The Java class path that should be passed along to the Java2Swift tool. public var classpath: String? = nil + public var classpathEntries: [String] { + guard let classpath else { + return [] + } + + return classpath.split(separator: ":").map(String.init) + } + /// The Java classes that should be translated to Swift. The keys are /// canonical Java class names (e.g., java.util.Vector) and the values are /// the corresponding Swift names (e.g., JavaVector). @@ -86,6 +94,7 @@ public struct JavaDependencyDescriptor: Hashable, Codable { } public func readConfiguration(sourceDir: String, file: String = #fileID, line: UInt = #line) throws -> Configuration { + // Workaround since filePath is macOS 13 let sourcePath = if sourceDir.hasPrefix("file://") { sourceDir } else { "file://" + sourceDir } let configFile = URL(string: sourcePath)!.appendingPathComponent("swift-java.config", isDirectory: false) From e2391edda7610dc7b204b644f4150a7b677ff38a Mon Sep 17 00:00:00 2001 From: Konrad `ktoso` Malawski Date: Fri, 6 Dec 2024 11:30:21 +0900 Subject: [PATCH 12/25] fix shellcheck --- Samples/JavaDependencySampleApp/ci-validate.sh | 2 +- Samples/JavaSieve/ci-validate.sh | 4 ++-- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/Samples/JavaDependencySampleApp/ci-validate.sh b/Samples/JavaDependencySampleApp/ci-validate.sh index 658960c6..88f0013b 100755 --- a/Samples/JavaDependencySampleApp/ci-validate.sh +++ b/Samples/JavaDependencySampleApp/ci-validate.sh @@ -4,7 +4,6 @@ JAVASWIFT="../../.build/debug/Java2Swift" MODULE_NAME="JavaCommonsCSV" MODULE_CONFIG_DIR=$(pwd)/Sources/$MODULE_NAME/ -MODULE_CONFIG_PATH="$MODULE_CONFIG_DIR/swift-java.config" ### 1) downloads all the dependencies "$JAVASWIFT" --fetch "$MODULE_CONFIG_DIR/swift-java.config" \ @@ -12,6 +11,7 @@ MODULE_CONFIG_PATH="$MODULE_CONFIG_DIR/swift-java.config" --output-directory "$MODULE_CONFIG_DIR" #### 2) extract the config for the fetched dependency +#MODULE_CONFIG_PATH="$MODULE_CONFIG_DIR/swift-java.config" #DEP_JAR_CP=$(jq .classpath "$MODULE_CONFIG_PATH") #DEP_JAR_CP=$(echo "$DEP_JAR_CP" | tr -d '"') # trim the "..." ## shellcheck disable=SC2086 diff --git a/Samples/JavaSieve/ci-validate.sh b/Samples/JavaSieve/ci-validate.sh index 2a1fab17..a4b0c14d 100755 --- a/Samples/JavaSieve/ci-validate.sh +++ b/Samples/JavaSieve/ci-validate.sh @@ -2,9 +2,9 @@ echo "Prepare the dependency..." git clone https://github.com/gazman-sdk/quadratic-sieve-Java -cd quadratic-sieve-Java +cd quadratic-sieve-Java || exit sh ./gradlew jar -cd .. +cd .. || exit echo "Run the sample..." swift run JavaSieve From 0502ac1cb4106683c275d1c58ab888dd564be165 Mon Sep 17 00:00:00 2001 From: Konrad `ktoso` Malawski Date: Fri, 6 Dec 2024 11:35:26 +0900 Subject: [PATCH 13/25] fix JavaSieve ci-validate because it uses too old gradle --- Samples/JavaSieve/ci-validate.sh | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/Samples/JavaSieve/ci-validate.sh b/Samples/JavaSieve/ci-validate.sh index a4b0c14d..60115fb2 100755 --- a/Samples/JavaSieve/ci-validate.sh +++ b/Samples/JavaSieve/ci-validate.sh @@ -3,7 +3,8 @@ echo "Prepare the dependency..." git clone https://github.com/gazman-sdk/quadratic-sieve-Java cd quadratic-sieve-Java || exit -sh ./gradlew jar +# we use the root gradlew since this project uses ancient gradle that won't support our recent JDK in CI +sh ../../gradlew jar cd .. || exit echo "Run the sample..." From b3cfc743fa64174dcbdafc4b9159fc1a967a598d Mon Sep 17 00:00:00 2001 From: Konrad `ktoso` Malawski Date: Fri, 6 Dec 2024 11:38:03 +0900 Subject: [PATCH 14/25] fix license ignore with the symlink --- .licenseignore | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/.licenseignore b/.licenseignore index ce382547..5f93c9a6 100644 --- a/.licenseignore +++ b/.licenseignore @@ -42,4 +42,5 @@ gradlew.bat **/ci-validate.sh **/DO_NOT_EDIT.txt Plugins/**/_PluginsShared -Plugins/**/0_PLEASE_SYMLINK* \ No newline at end of file +Plugins/**/0_PLEASE_SYMLINK* +Plugins/PluginsShared/JavaKitConfigurationShared \ No newline at end of file From 7f47bcd5629139ad44dc6b2fa9e6cda5a6ae0f2a Mon Sep 17 00:00:00 2001 From: Konrad `ktoso` Malawski Date: Fri, 6 Dec 2024 11:52:18 +0900 Subject: [PATCH 15/25] give up on JavaSieve checking in CI --- Samples/JavaDependencySampleApp/ci-validate.sh | 3 +++ Samples/JavaKitSampleApp/ci-validate.sh | 3 +++ Samples/JavaProbablyPrime/ci-validate.sh | 3 +++ Samples/JavaSieve/ci-validate.sh | 10 +--------- 4 files changed, 10 insertions(+), 9 deletions(-) diff --git a/Samples/JavaDependencySampleApp/ci-validate.sh b/Samples/JavaDependencySampleApp/ci-validate.sh index 88f0013b..87313914 100755 --- a/Samples/JavaDependencySampleApp/ci-validate.sh +++ b/Samples/JavaDependencySampleApp/ci-validate.sh @@ -1,5 +1,8 @@ #!/bin/sh +set -e +set -x + JAVASWIFT="../../.build/debug/Java2Swift" MODULE_NAME="JavaCommonsCSV" diff --git a/Samples/JavaKitSampleApp/ci-validate.sh b/Samples/JavaKitSampleApp/ci-validate.sh index eff61551..f453a00b 100755 --- a/Samples/JavaKitSampleApp/ci-validate.sh +++ b/Samples/JavaKitSampleApp/ci-validate.sh @@ -1,5 +1,8 @@ #!/bin/sh +set -e +set -x + swift build "$JAVA_HOME/bin/java" \ -cp .build/plugins/outputs/javakitsampleapp/JavaKitExample/destination/JavaCompilerPlugin/Java \ diff --git a/Samples/JavaProbablyPrime/ci-validate.sh b/Samples/JavaProbablyPrime/ci-validate.sh index 948a390c..0bdd86d1 100755 --- a/Samples/JavaProbablyPrime/ci-validate.sh +++ b/Samples/JavaProbablyPrime/ci-validate.sh @@ -1,3 +1,6 @@ #!/bin/sh +set -e +set -x + swift run JavaProbablyPrime 1337 \ No newline at end of file diff --git a/Samples/JavaSieve/ci-validate.sh b/Samples/JavaSieve/ci-validate.sh index 60115fb2..730a8ba8 100755 --- a/Samples/JavaSieve/ci-validate.sh +++ b/Samples/JavaSieve/ci-validate.sh @@ -1,11 +1,3 @@ #!/bin/bash -echo "Prepare the dependency..." -git clone https://github.com/gazman-sdk/quadratic-sieve-Java -cd quadratic-sieve-Java || exit -# we use the root gradlew since this project uses ancient gradle that won't support our recent JDK in CI -sh ../../gradlew jar -cd .. || exit - -echo "Run the sample..." -swift run JavaSieve +echo "This sample is not verified in CI because old Gradle in the project making it hard to use its ./gradlew" \ No newline at end of file From 9992890202e49a6097d564242b92aceb5d45eef4 Mon Sep 17 00:00:00 2001 From: Konrad `ktoso` Malawski Date: Fri, 6 Dec 2024 12:20:34 +0900 Subject: [PATCH 16/25] avoid warnings adding not existing hardcoded paths to classpath --- .../Sources/JavaCommonsCSV/swift-java.config | 4 ++-- Samples/JavaDependencySampleApp/ci-validate.sh | 1 + Sources/Java2Swift/JavaToSwift.swift | 4 +++- 3 files changed, 6 insertions(+), 3 deletions(-) diff --git a/Samples/JavaDependencySampleApp/Sources/JavaCommonsCSV/swift-java.config b/Samples/JavaDependencySampleApp/Sources/JavaCommonsCSV/swift-java.config index 7e1f4aeb..a9f8b45a 100644 --- a/Samples/JavaDependencySampleApp/Sources/JavaCommonsCSV/swift-java.config +++ b/Samples/JavaDependencySampleApp/Sources/JavaCommonsCSV/swift-java.config @@ -1,8 +1,8 @@ { "classes" : { - "org.apache.commons.io.FilenameUtils" : "FilenameUtils" + }, - "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:\/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:JavaKit\/build\/classes\/java\/main:..\/..\/JavaKit\/build\/classes\/java\/main", + "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", "dependencies" : [ "org.apache.commons:commons-csv:1.12.0" ] diff --git a/Samples/JavaDependencySampleApp/ci-validate.sh b/Samples/JavaDependencySampleApp/ci-validate.sh index 87313914..9b19a79c 100755 --- a/Samples/JavaDependencySampleApp/ci-validate.sh +++ b/Samples/JavaDependencySampleApp/ci-validate.sh @@ -9,6 +9,7 @@ MODULE_NAME="JavaCommonsCSV" MODULE_CONFIG_DIR=$(pwd)/Sources/$MODULE_NAME/ ### 1) downloads all the dependencies +echo "Resolve dependencies..." "$JAVASWIFT" --fetch "$MODULE_CONFIG_DIR/swift-java.config" \ --module-name "$MODULE_NAME" \ --output-directory "$MODULE_CONFIG_DIR" diff --git a/Sources/Java2Swift/JavaToSwift.swift b/Sources/Java2Swift/JavaToSwift.swift index 2f9347e6..022b9f68 100644 --- a/Sources/Java2Swift/JavaToSwift.swift +++ b/Sources/Java2Swift/JavaToSwift.swift @@ -235,7 +235,9 @@ struct JavaToSwift: ParsableCommand { let classpathBuildJavaKitEntries = [ "JavaKit/build/classes/java/main", "../../JavaKit/build/classes/java/main", - ] + ].filter { + FileManager.default.fileExists(atPath: $0) + } classpathEntries += classpathBuildJavaKitEntries // Bring up the Java VM. From 47915d26a39ff9fa20f4b20b81b7c9da046bbe53 Mon Sep 17 00:00:00 2001 From: Konrad `ktoso` Malawski Date: Fri, 6 Dec 2024 13:09:53 +0900 Subject: [PATCH 17/25] use cached DependencyResolver classpath from file --- .../dependencies/DependencyResolver.java | 65 ++++++++++--------- .../Sources/JavaCommonsCSV/swift-java.config | 1 - .../JavaToSwift+FetchDependencies.swift | 26 ++++++++ Sources/Java2Swift/JavaToSwift.swift | 15 +++-- .../DependencyResolver.swift | 3 + 5 files changed, 71 insertions(+), 39 deletions(-) diff --git a/JavaKit/src/main/java/org/swift/javakit/dependencies/DependencyResolver.java b/JavaKit/src/main/java/org/swift/javakit/dependencies/DependencyResolver.java index 14c2a519..13bacc2d 100644 --- a/JavaKit/src/main/java/org/swift/javakit/dependencies/DependencyResolver.java +++ b/JavaKit/src/main/java/org/swift/javakit/dependencies/DependencyResolver.java @@ -32,7 +32,7 @@ public class DependencyResolver { private static final String COMMAND_OUTPUT_LINE_PREFIX_CLASSPATH = "CLASSPATH:"; - private static final String CLASSPATH_CACHE_FILENAME = "JavaKitDependencyResolver.classpath.swift-java"; + private static final String CLASSPATH_CACHE_FILENAME = "JavaKitDependencyResolver.swift-java.classpath"; public static String GRADLE_API_DEPENDENCY = "dev.gradleplugins:gradle-api:8.10.1"; public static String[] BASE_DEPENDENCIES = { @@ -46,42 +46,42 @@ public class DependencyResolver { @UsedFromSwift @SuppressWarnings("unused") public static String resolveDependenciesToClasspath(String projectBaseDirectoryString, String[] dependencies) throws IOException { -try { - simpleLog("Fetch dependencies: " + Arrays.toString(dependencies)); - simpleLog("projectBaseDirectoryString = " + projectBaseDirectoryString); - var projectBasePath = new File(projectBaseDirectoryString).toPath(); - - File projectDir = Files.createTempDirectory("java-swift-dependencies").toFile(); - projectDir.mkdirs(); - - if (hasDependencyResolverDependenciesLoaded()) { - // === Resolve dependencies using Gradle API in-process - simpleLog("Gradle API runtime dependency is available, resolve dependencies..."); - return resolveDependenciesUsingAPI(projectDir, dependencies); - } + try { + simpleLog("Fetch dependencies: " + Arrays.toString(dependencies)); + simpleLog("Classpath: " + System.getProperty("java.class.path")); + var projectBasePath = new File(projectBaseDirectoryString).toPath(); - // === Bootstrap the resolver dependencies and cache them - simpleLog("Gradle API not available on classpath, bootstrap %s dependencies: %s" - .formatted(DependencyResolver.class.getSimpleName(), Arrays.toString(BASE_DEPENDENCIES))); - String dependencyResolverDependenciesClasspath = bootstrapDependencyResolverClasspath(); - writeDependencyResolverClasspath(projectBasePath, dependencyResolverDependenciesClasspath); - - // --- Resolve dependencies using sub-process process - // TODO: it would be nice to just add the above classpath to the system classloader and here call the API - // immediately, but that's challenging and not a stable API we can rely on (hacks exist to add paths - // to system classloader but are not reliable). - printBuildFiles(projectDir, dependencies); - return resolveDependenciesWithSubprocess(projectDir); -} catch (Exception e) { - e.printStackTrace(); - throw e; -} + File projectDir = Files.createTempDirectory("java-swift-dependencies").toFile(); + projectDir.mkdirs(); + + if (hasDependencyResolverDependenciesLoaded()) { + // === Resolve dependencies using Gradle API in-process + simpleLog("Gradle API runtime dependency is available, resolve dependencies..."); + return resolveDependenciesUsingAPI(projectDir, dependencies); + } + + // === Bootstrap the resolver dependencies and cache them + simpleLog("Gradle API not available on classpath, bootstrap %s dependencies: %s" + .formatted(DependencyResolver.class.getSimpleName(), Arrays.toString(BASE_DEPENDENCIES))); + String dependencyResolverDependenciesClasspath = bootstrapDependencyResolverClasspath(); + writeDependencyResolverClasspath(projectBasePath, dependencyResolverDependenciesClasspath); + + // --- Resolve dependencies using sub-process process + // TODO: it would be nice to just add the above classpath to the system classloader and here call the API + // immediately, but that's challenging and not a stable API we can rely on (hacks exist to add paths + // to system classloader but are not reliable). + printBuildFiles(projectDir, dependencies); + return resolveDependenciesWithSubprocess(projectDir); + } catch (Exception e) { + e.printStackTrace(); + throw e; + } } /** * Use an external {@code gradle} invocation in order to download dependencies such that we can use `gradle-api` - * next time we want to resolve dependencies. This uses an external process and is sligtly worse than using the API + * next time we want to resolve dependencies. This uses an external process and is slightly worse than using the API * directly. * * @return classpath obtained for the dependencies @@ -158,7 +158,8 @@ private static void writeDependencyResolverClasspath(Path projectBasePath, Strin /** * Detect if we have the necessary dependencies loaded. */ - private static boolean hasDependencyResolverDependenciesLoaded() { + @UsedFromSwift + public static boolean hasDependencyResolverDependenciesLoaded() { return hasDependencyResolverDependenciesLoaded(DependencyResolver.class.getClassLoader()); } diff --git a/Samples/JavaDependencySampleApp/Sources/JavaCommonsCSV/swift-java.config b/Samples/JavaDependencySampleApp/Sources/JavaCommonsCSV/swift-java.config index a9f8b45a..09943bb9 100644 --- a/Samples/JavaDependencySampleApp/Sources/JavaCommonsCSV/swift-java.config +++ b/Samples/JavaDependencySampleApp/Sources/JavaCommonsCSV/swift-java.config @@ -2,7 +2,6 @@ "classes" : { }, - "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", "dependencies" : [ "org.apache.commons:commons-csv:1.12.0" ] diff --git a/Sources/Java2Swift/JavaToSwift+FetchDependencies.swift b/Sources/Java2Swift/JavaToSwift+FetchDependencies.swift index 779c3a46..5fd85db0 100644 --- a/Sources/Java2Swift/JavaToSwift+FetchDependencies.swift +++ b/Sources/Java2Swift/JavaToSwift+FetchDependencies.swift @@ -23,6 +23,32 @@ import JavaKitConfigurationShared import JavaKitShared extension JavaToSwift { + + /// Must be the same as `DependencyResolver#CLASSPATH_CACHE_FILENAME` on the java side. + var JavaKitDependencyResolverClasspathCacheFilename: String { + "JavaKitDependencyResolver.swift-java.classpath" + } + var JavaKitDependencyResolverClasspathCacheFilePath: String { + ".build/\(JavaKitDependencyResolverClasspathCacheFilename)" + } + + func fetchDependenciesCachedClasspath() -> [String]? { + guard let cachedClasspathURL = URL(string: "file://" + FileManager.default.currentDirectoryPath + "/" + JavaKitDependencyResolverClasspathCacheFilePath) else { + return [] + } + + guard FileManager.default.fileExists(atPath: cachedClasspathURL.path) else { + return [] + } + + guard let javaKitDependencyResolverCachedClasspath = try? String(contentsOf: cachedClasspathURL) else { + return [] + } + + print("[debug][swift-java] Cached dependency resolver classpath: \(javaKitDependencyResolverCachedClasspath)") + return javaKitDependencyResolverCachedClasspath.split(separator: ":").map(String.init) + } + func fetchDependencies(moduleName: String, dependencies: [JavaDependencyDescriptor], baseClasspath: [String], diff --git a/Sources/Java2Swift/JavaToSwift.swift b/Sources/Java2Swift/JavaToSwift.swift index 022b9f68..fa3094a1 100644 --- a/Sources/Java2Swift/JavaToSwift.swift +++ b/Sources/Java2Swift/JavaToSwift.swift @@ -222,13 +222,16 @@ struct JavaToSwift: ParsableCommand { let extraClasspathEntries = extraClasspath.split(separator: ":").map(String.init) print("[debug][swift-java] Extra classpath: \(extraClasspathEntries)") classpathEntries += extraClasspathEntries - case .classWrappers/*(let config)*/, - .fetchDependencies/*(let config)*/: + case .fetchDependencies: + // if we have already fetched dependencies for the dependency loader, + // let's use them so we can in-process resolve rather than forking a new + // gradle process. + if let dependencyResolverClasspath = fetchDependenciesCachedClasspath() { + print("[debug][swift-java] Found cached dependency resolver classpath: \(dependencyResolverClasspath)") + classpathEntries += dependencyResolverClasspath + } + case .classWrappers: break; - // * Classpath specified in the configuration file (if any) - // let extraClasspathEntries = config.classpath?.split(separator: ":").map(String.init) ?? [] - // print("[debug][swift-java] Config classpath: \(extraClasspathEntries)") - // classpathEntries += extraClasspathEntries } // Add extra classpath entries which are specific to building the JavaKit project and samples diff --git a/Sources/JavaKitDependencyResolver/DependencyResolver.swift b/Sources/JavaKitDependencyResolver/DependencyResolver.swift index 4b7d9edd..697e3d2a 100644 --- a/Sources/JavaKitDependencyResolver/DependencyResolver.swift +++ b/Sources/JavaKitDependencyResolver/DependencyResolver.swift @@ -26,4 +26,7 @@ extension JavaClass { projectBaseDirectory: String, dependencies: [String]) throws -> String + @JavaStaticMethod + public func hasDependencyResolverDependenciesLoaded() -> Bool + } \ No newline at end of file From 8c23a233a1c905bde30f5a2c7ee511f280f13b56 Mon Sep 17 00:00:00 2001 From: Konrad `ktoso` Malawski Date: Fri, 6 Dec 2024 15:01:03 +0900 Subject: [PATCH 18/25] writing swift-java.classpath per module now --- .../dependencies/DependencyResolver.java | 3 +- .../Java2SwiftPlugin/Java2SwiftPlugin.swift | 28 +++++++------ Plugins/PluginsShared/PluginUtils.swift | 5 +++ .../Sources/JavaCommonsCSV/swift-java.config | 3 +- .../JavaDependencySampleApp/ci-validate.sh | 19 +++++---- .../JavaToSwift+FetchDependencies.swift | 20 +++++----- Sources/Java2Swift/JavaToSwift.swift | 39 +++++++++++++++---- 7 files changed, 77 insertions(+), 40 deletions(-) diff --git a/JavaKit/src/main/java/org/swift/javakit/dependencies/DependencyResolver.java b/JavaKit/src/main/java/org/swift/javakit/dependencies/DependencyResolver.java index 13bacc2d..78ef72bb 100644 --- a/JavaKit/src/main/java/org/swift/javakit/dependencies/DependencyResolver.java +++ b/JavaKit/src/main/java/org/swift/javakit/dependencies/DependencyResolver.java @@ -29,6 +29,8 @@ * Fetches dependencies using the Gradle resolver and returns the resulting classpath which includes * the fetched dependency and all of its dependencies. */ +@UsedFromSwift +@SuppressWarnings("unused") public class DependencyResolver { private static final String COMMAND_OUTPUT_LINE_PREFIX_CLASSPATH = "CLASSPATH:"; @@ -48,7 +50,6 @@ public class DependencyResolver { public static String resolveDependenciesToClasspath(String projectBaseDirectoryString, String[] dependencies) throws IOException { try { simpleLog("Fetch dependencies: " + Arrays.toString(dependencies)); - simpleLog("Classpath: " + System.getProperty("java.class.path")); var projectBasePath = new File(projectBaseDirectoryString).toPath(); File projectDir = Files.createTempDirectory("java-swift-dependencies").toFile(); diff --git a/Plugins/Java2SwiftPlugin/Java2SwiftPlugin.swift b/Plugins/Java2SwiftPlugin/Java2SwiftPlugin.swift index 51b41264..44be53ab 100644 --- a/Plugins/Java2SwiftPlugin/Java2SwiftPlugin.swift +++ b/Plugins/Java2SwiftPlugin/Java2SwiftPlugin.swift @@ -97,17 +97,23 @@ struct Java2SwiftBuildToolPlugin: SwiftJavaPluginProtocol, BuildToolPlugin { } arguments.append(configFile.path(percentEncoded: false)) - guard let classes = config.classes else { - log("Config at \(configFile) did not have 'classes' configured, skipping java2swift step.") - return [] - } - +// guard let classes = config.classes else { +// log("Config at \(configFile) did not have 'classes' configured, skipping java2swift step.") +// return [] +// } + let classes = config.classes ?? [:] + /// Determine the set of Swift files that will be emitted by the Java2Swift /// tool. let outputSwiftFiles = classes.map { (javaClassName, swiftName) in let swiftNestedName = swiftName.replacingOccurrences(of: ".", with: "+") return outputDirectory.appending(path: "\(swiftNestedName).swift") } + + arguments += [ + "--cache-directory", + context.pluginWorkDirectoryURL.path(percentEncoded: false) + ] // Find the Java .class files generated from prior plugins. let compiledClassFiles = sourceModule.pluginGeneratedResources.filter { url in @@ -141,19 +147,17 @@ struct Java2SwiftBuildToolPlugin: SwiftJavaPluginProtocol, BuildToolPlugin { } } - guard let classes = config.classes else { - log("Skipping java2swift step: Missing 'classes' key in swift-java.config at '\(configFile.path)'") - return [] - } - let executable = try context.tool(named: "Java2Swift").url return [ .buildCommand( - displayName: "Wrapping \(classes.count) Java classes target \(sourceModule.name) in Swift", + displayName: "Wrapping \(classes.count) Java classes target in Swift target '\(sourceModule.name)'", executable: executable, arguments: arguments, - inputFiles: [ configFile ] + compiledClassFiles, + inputFiles: compiledClassFiles + [ + configFile, + context.cachedClasspathFile(moduleName: sourceModule.name) + ], outputFiles: outputSwiftFiles ) ] diff --git a/Plugins/PluginsShared/PluginUtils.swift b/Plugins/PluginsShared/PluginUtils.swift index bf4d0f0a..6932253a 100644 --- a/Plugins/PluginsShared/PluginUtils.swift +++ b/Plugins/PluginsShared/PluginUtils.swift @@ -71,4 +71,9 @@ extension PluginContext { self.pluginWorkDirectoryURL .appending(path: "Sources") } + + func cachedClasspathFile(moduleName: String) -> URL { + self.pluginWorkDirectoryURL + .appending(path: "\(moduleName)", directoryHint: .notDirectory) + } } diff --git a/Samples/JavaDependencySampleApp/Sources/JavaCommonsCSV/swift-java.config b/Samples/JavaDependencySampleApp/Sources/JavaCommonsCSV/swift-java.config index 09943bb9..ed6b0b35 100644 --- a/Samples/JavaDependencySampleApp/Sources/JavaCommonsCSV/swift-java.config +++ b/Samples/JavaDependencySampleApp/Sources/JavaCommonsCSV/swift-java.config @@ -1,7 +1,8 @@ { "classes" : { - + "org.apache.commons.io.FilenameUtils" : "FilenameUtils" }, + "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:\/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:..\/..\/JavaKit\/build\/classes\/java\/main:\/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:..\/..\/JavaKit\/build\/classes\/java\/main:\/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:..\/..\/JavaKit\/build\/classes\/java\/main", "dependencies" : [ "org.apache.commons:commons-csv:1.12.0" ] diff --git a/Samples/JavaDependencySampleApp/ci-validate.sh b/Samples/JavaDependencySampleApp/ci-validate.sh index 9b19a79c..b9976eb6 100755 --- a/Samples/JavaDependencySampleApp/ci-validate.sh +++ b/Samples/JavaDependencySampleApp/ci-validate.sh @@ -12,17 +12,20 @@ MODULE_CONFIG_DIR=$(pwd)/Sources/$MODULE_NAME/ echo "Resolve dependencies..." "$JAVASWIFT" --fetch "$MODULE_CONFIG_DIR/swift-java.config" \ --module-name "$MODULE_NAME" \ + --cache-dir "Plugins/outputs/javadependencysampleapp/${MODULE_NAME}/destination" --output-directory "$MODULE_CONFIG_DIR" #### 2) extract the config for the fetched dependency -#MODULE_CONFIG_PATH="$MODULE_CONFIG_DIR/swift-java.config" -#DEP_JAR_CP=$(jq .classpath "$MODULE_CONFIG_PATH") -#DEP_JAR_CP=$(echo "$DEP_JAR_CP" | tr -d '"') # trim the "..." -## shellcheck disable=SC2086 -#"$JAVASWIFT" --jar $DEP_JAR_CP \ -# --module-name "$MODULE_NAME" \ -# --java-package-filter org.apache.commons \ -# --existing-config amend +MODULE_CONFIG_PATH="$MODULE_CONFIG_DIR/swift-java.config" +DEP_JAR_CP=$(jq .classpath "$MODULE_CONFIG_PATH") +DEP_JAR_CP=$(echo "$DEP_JAR_CP" | tr -d '"') # trim the "..." + +# Import just a single class for our test purposes +# shellcheck disable=SC2086 +"$JAVASWIFT" --jar $DEP_JAR_CP \ + --module-name "$MODULE_NAME" \ + --java-package-filter org.apache.commons.io.FilenameUtils \ + --existing-config amend # for now in CI we just use what we have already generated and comitted in the config diff --git a/Sources/Java2Swift/JavaToSwift+FetchDependencies.swift b/Sources/Java2Swift/JavaToSwift+FetchDependencies.swift index 5fd85db0..a134572f 100644 --- a/Sources/Java2Swift/JavaToSwift+FetchDependencies.swift +++ b/Sources/Java2Swift/JavaToSwift+FetchDependencies.swift @@ -75,24 +75,22 @@ extension JavaToSwift { } extension JavaToSwift { - mutating func writeFetchDependencies(resolvedClasspath: ResolvedDependencyClasspath) throws { - var configuration = Configuration() - configuration.dependencies = resolvedClasspath.rootDependencies - configuration.classpath = resolvedClasspath.classpath - + mutating func writeFetchedDependenciesClasspath( + moduleName: String, + cacheDir: String, + resolvedClasspath: ResolvedDependencyClasspath) throws { // Convert the artifact name to a module name // e.g. reactive-streams -> ReactiveStreams - // TODO: Should we prefix them with `Java...`? - let targetModule = artifactIDAsModuleID(resolvedClasspath.rootDependencies.first!.artifactID) - // Encode the configuration. - let contents = try configuration.renderJSON() + // The file contents are just plain + let contents = resolvedClasspath.classpath // Write the file try writeContents( contents, - to: "swift-java.config", - description: "swift-java configuration file" + outputDirectoryOverride: URL(fileURLWithPath: cacheDir), + to: "\(moduleName).swift-java.classpath", + description: "swift-java.classpath file for module \(moduleName)" ) } diff --git a/Sources/Java2Swift/JavaToSwift.swift b/Sources/Java2Swift/JavaToSwift.swift index fa3094a1..e3b0dd79 100644 --- a/Sources/Java2Swift/JavaToSwift.swift +++ b/Sources/Java2Swift/JavaToSwift.swift @@ -62,6 +62,20 @@ struct JavaToSwift: ParsableCommand { @Option(name: .shortAndLong, help: "The directory in which to output the generated Swift files or the Java2Swift configuration file.") var outputDirectory: String? = nil + + @Option(name: .shortAndLong, help: "Directory where to write cached values (e.g. swift-java.classpath files)") + var cacheDirectory: String? = nil + + var effectiveCacheDirectory: String? { + if let cacheDirectory { + return cacheDirectory + } else if let outputDirectory { + return outputDirectory + } else { + return nil + } + } + @Option(name: .shortAndLong, help: "How to handle an existing swift-java.config; by default 'overwrite' by can be changed to amending a configuration") var existingConfig: ExistingConfigFileMode = .overwrite public enum ExistingConfigFileMode: String, ExpressibleByArgument, Codable { @@ -288,10 +302,16 @@ struct JavaToSwift: ParsableCommand { environment: jvm.environment() ) - case .fetchDependencies/*(let config)*/: + case .fetchDependencies: guard let dependencies = config.dependencies else { fatalError("Configuration for fetching dependencies must have 'dependencies' defined!") } + guard let moduleName = self.moduleName else { + fatalError("Fetching dependencies must specify module name (--module-name)!") + } + guard let effectiveCacheDirectory else { + fatalError("Fetching dependencies must effective cache directory! Specify --output-directory or --cache-directory") + } let dependencyClasspath = try fetchDependencies( moduleName: moduleName, @@ -300,7 +320,10 @@ struct JavaToSwift: ParsableCommand { environment: jvm.environment() ) - try writeFetchDependencies(resolvedClasspath: dependencyClasspath) + try writeFetchedDependenciesClasspath( + moduleName: moduleName, + cacheDir: effectiveCacheDirectory, + resolvedClasspath: dependencyClasspath) } } catch { // We fail like this since throwing out of the run often ends up hiding the failure reason when it is executed as SwiftPM plugin (!) @@ -309,7 +332,8 @@ struct JavaToSwift: ParsableCommand { fatalError(message) } - print("[info][swift-java] " + "Done: ".green + CommandLine.arguments.joined(separator: " ")) + // Just for debugging so it is clear which command has finished + print("[debug][swift-java] " + "Done: ".green + CommandLine.arguments.joined(separator: " ").green) } private func names(from javaClassNameOpt: String) -> (javaClassName: String, swiftName: String) { @@ -346,8 +370,9 @@ struct JavaToSwift: ParsableCommand { mutating func writeContents( _ contents: String, outputDirectoryOverride: Foundation.URL?, - to filename: String, description: String) throws { - guard let outputDir = actualOutputDirectory else { + to filename: String, + description: String) throws { + guard let outputDir = (outputDirectoryOverride ?? actualOutputDirectory) else { print("// \(filename) - \(description)") print(contents) return @@ -365,9 +390,9 @@ struct JavaToSwift: ParsableCommand { // Write the file: let file = outputDir.appendingPathComponent(filename) - print("[swift-java] Writing \(description) to '\(file.path)'...", terminator: "") + print("[debug][swift-java] Writing \(description) to '\(file.path)'... ", terminator: "") try contents.write(to: file, atomically: true, encoding: .utf8) - print(" done.".green) + print("done.".green) } } From 561efe2fb04bebd99208b66f5100daed221d7cd8 Mon Sep 17 00:00:00 2001 From: Konrad `ktoso` Malawski Date: Mon, 9 Dec 2024 12:39:39 +0900 Subject: [PATCH 19/25] Fetch and wrap dependencies as build plugin now works! --- JavaKit/build.gradle | 75 ++++++----- .../dependencies/DependencyResolver.java | 16 ++- .../Java2SwiftPlugin/Java2SwiftPlugin.swift | 123 +++++++++++++----- Samples/JavaDependencySampleApp/Package.swift | 6 +- .../Sources/JavaCommonsCSV/swift-java.config | 4 +- .../Sources/JavaDependencySample/main.swift | 6 +- .../JavaDependencySampleApp/ci-validate.sh | 4 + Sources/Java2Swift/JavaToSwift.swift | 13 +- .../Configuration.swift | 25 ++++ 9 files changed, 198 insertions(+), 74 deletions(-) diff --git a/JavaKit/build.gradle b/JavaKit/build.gradle index 80050c7a..6258e9d7 100644 --- a/JavaKit/build.gradle +++ b/JavaKit/build.gradle @@ -12,33 +12,48 @@ // //===----------------------------------------------------------------------===// - plugins { - id("build-logic.java-application-conventions") - } - - group = "org.swift.javakit" - version = "1.0-SNAPSHOT" - - repositories { - mavenCentral() - } - - java { - toolchain { - languageVersion.set(JavaLanguageVersion.of(22)) - } - } - - dependencies { - implementation("dev.gradleplugins:gradle-api:8.10.1") - - testImplementation(platform("org.junit:junit-bom:5.10.0")) - testImplementation("org.junit.jupiter:junit-jupiter") - } - - tasks.test { - useJUnitPlatform() - testLogging { - events("passed", "skipped", "failed") - } - } \ No newline at end of file +import groovy.json.JsonSlurper + +plugins { + id("build-logic.java-library-conventions") +} + +group = "org.swift.javakit" +version = "1.0-SNAPSHOT" + +repositories { + mavenCentral() +} + +java { + toolchain { + languageVersion.set(JavaLanguageVersion.of(22)) + } +} + +List loadDependenciesFromSwiftJavaJSON() { + def jsonFile = file("../Sources/JavaKitDependencyResolver/swift-java.config") + if (!jsonFile.exists()) { + throw new FileNotFoundException("Dependencies must be declared in Swift config file! Not found: ${jsonFile.absolutePath}") + } + def jsonContent = new JsonSlurper().parseText(jsonFile.text) + return jsonContent.dependencies +} + +dependencies { + // We load dependencies from one source of truth: the swift-java.config of module + // that is used to access this Java code. + loadDependenciesFromSwiftJavaJSON().each { + implementation(it) + } + + testImplementation(platform("org.junit:junit-bom:5.10.0")) + testImplementation("org.junit.jupiter:junit-jupiter") +} + +tasks.test { + useJUnitPlatform() + testLogging { + events("passed", "skipped", "failed") + } +} diff --git a/JavaKit/src/main/java/org/swift/javakit/dependencies/DependencyResolver.java b/JavaKit/src/main/java/org/swift/javakit/dependencies/DependencyResolver.java index 78ef72bb..cc553e97 100644 --- a/JavaKit/src/main/java/org/swift/javakit/dependencies/DependencyResolver.java +++ b/JavaKit/src/main/java/org/swift/javakit/dependencies/DependencyResolver.java @@ -23,6 +23,7 @@ import java.nio.file.StandardOpenOption; import java.util.Arrays; import java.util.concurrent.TimeUnit; +import java.util.stream.Collectors; import java.util.stream.Stream; /** @@ -137,7 +138,9 @@ private static String resolveDependenciesWithSubprocess(File gradleProjectDir) t ex.printStackTrace(); throw new SwiftJavaBootstrapException("Failed to bootstrap dependencies necessary for " + - DependencyResolver.class.getCanonicalName() + "!", ex); + DependencyResolver.class.getCanonicalName() + "! " + + "Make sure to invoke SwiftPM with --disable-sandbox because " + + "swift-java needs network access to fetch java dependencies.", ex); } } @@ -186,10 +189,19 @@ private static String resolveDependenciesUsingAPI(File projectDir, String[] depe .run(); var all = outputStream.toString(); - var classpath = Arrays.stream(all.split("\n")) + var classpathString = Arrays.stream(all.split("\n")) .filter(s -> s.startsWith(COMMAND_OUTPUT_LINE_PREFIX_CLASSPATH)) .map(s -> s.substring(COMMAND_OUTPUT_LINE_PREFIX_CLASSPATH.length())) .findFirst().orElseThrow(() -> new RuntimeException("Could not find classpath output from ':printRuntimeClasspath' task.")); + simpleLog("DEPENDENCY BUILD PATH = " + projectDir.getAbsolutePath()); + + // remove output directories of the project we used for the dependency resolution + var classpath = Arrays.stream(classpathString + .split(":")) + .filter(s -> !s.startsWith(projectDir.getAbsolutePath())) + .collect(Collectors.joining(":")); + + return classpath; } } diff --git a/Plugins/Java2SwiftPlugin/Java2SwiftPlugin.swift b/Plugins/Java2SwiftPlugin/Java2SwiftPlugin.swift index 44be53ab..d932ee97 100644 --- a/Plugins/Java2SwiftPlugin/Java2SwiftPlugin.swift +++ b/Plugins/Java2SwiftPlugin/Java2SwiftPlugin.swift @@ -20,13 +20,16 @@ fileprivate let SwiftJavaConfigFileName = "swift-java.config" @main struct Java2SwiftBuildToolPlugin: SwiftJavaPluginProtocol, BuildToolPlugin { - var pluginName: String = "swift-java-javac" + var pluginName: String = "swift-java" var verbose: Bool = getEnvironmentBool("SWIFT_JAVA_VERBOSE") func createBuildCommands(context: PluginContext, target: Target) throws -> [Command] { - log("Create build commands for: \(target.name)") + log("Create build commands for target '\(target.name)'") guard let sourceModule = target.sourceModule else { return [] } + let executable = try context.tool(named: "Java2Swift").url + var commands: [Command] = [] + // Note: Target doesn't have a directoryURL counterpart to directory, // so we cannot eliminate this deprecation warning. let sourceDir = target.directory.string @@ -35,14 +38,17 @@ struct Java2SwiftBuildToolPlugin: SwiftJavaPluginProtocol, BuildToolPlugin { // which we are generating Swift wrappers for Java classes. let configFile = URL(filePath: sourceDir) .appending(path: SwiftJavaConfigFileName) - let configData = try Data(contentsOf: configFile) - let config = try JSONDecoder().decode(Configuration.self, from: configData) + let config = try readConfiguration(sourceDir: sourceDir) + + log("Config on path: \(configFile.path(percentEncoded: false))") + log("Config was: \(config)") + var javaDependencies = config.dependencies ?? [] /// Find the manifest files from other Java2Swift executions in any targets /// this target depends on. var dependentConfigFiles: [(String, URL)] = [] func searchForConfigFiles(in target: any Target) { - log("Search for config files in target: \(target.name)") + // log("Search for config files in target: \(target.name)") let dependencyURL = URL(filePath: target.directory.string) // Look for a config file within this target. @@ -60,13 +66,13 @@ struct Java2SwiftBuildToolPlugin: SwiftJavaPluginProtocol, BuildToolPlugin { for dependency in target.dependencies { switch dependency { case .target(let target): - log("Dependency target: \(target.name)") + // log("Dependency target: \(target.name)") searchForConfigFiles(in: target) case .product(let product): - log("Dependency product: \(product.name)") + // log("Dependency product: \(product.name)") for target in product.targets { - log("Dependency product: \(product.name), target: \(target.name)") + // log("Dependency product: \(product.name), target: \(target.name)") searchForConfigFiles(in: target) } @@ -77,17 +83,14 @@ struct Java2SwiftBuildToolPlugin: SwiftJavaPluginProtocol, BuildToolPlugin { // Process indirect target dependencies. for dependency in target.recursiveTargetDependencies { - log("Recursive dependency target: \(dependency.name)") + // log("Recursive dependency target: \(dependency.name)") searchForConfigFiles(in: dependency) } - let outputDirectory = context.pluginWorkDirectoryURL - .appending(path: "generated") - - var arguments: [String] = [ - "--module-name", sourceModule.name, - "--output-directory", outputDirectory.path(percentEncoded: false), - ] + var arguments: [String] = [] + arguments += argumentsModuleName(sourceModule: sourceModule) + arguments += argumentsOutputDirectory(context: context) + arguments += dependentConfigFiles.flatMap { moduleAndConfigFile in let (moduleName, configFile) = moduleAndConfigFile return [ @@ -102,12 +105,14 @@ struct Java2SwiftBuildToolPlugin: SwiftJavaPluginProtocol, BuildToolPlugin { // return [] // } let classes = config.classes ?? [:] + print("Classes to wrap: \(classes.map(\.key))") - /// Determine the set of Swift files that will be emitted by the Java2Swift - /// tool. + /// Determine the set of Swift files that will be emitted by the Java2Swift tool. + // TODO: this is not precise and won't work with more advanced Java files, e.g. lambdas etc. + let outputDirectoryGenerated = self.outputDirectory(context: context, generated: true) let outputSwiftFiles = classes.map { (javaClassName, swiftName) in let swiftNestedName = swiftName.replacingOccurrences(of: ".", with: "+") - return outputDirectory.appending(path: "\(swiftNestedName).swift") + return outputDirectoryGenerated.appending(path: "\(swiftNestedName).swift") } arguments += [ @@ -147,19 +152,77 @@ struct Java2SwiftBuildToolPlugin: SwiftJavaPluginProtocol, BuildToolPlugin { } } - let executable = try context.tool(named: "Java2Swift").url + var fetchDependenciesOutputFiles: [URL] = [] + if let dependencies = config.dependencies, !dependencies.isEmpty { + let displayName = "Fetch (Java) dependencies for Swift target \(sourceModule.name)" + log("Prepared: \(displayName)") + + fetchDependenciesOutputFiles += [ + outputFilePath(context: context, generated: false, filename: "\(sourceModule.name).swift-java.classpath") + ] + + commands += [ + .buildCommand( + displayName: displayName, + executable: executable, + arguments: [ + "--fetch", configFile.path(percentEncoded: false), + "--module-name", sourceModule.name, + "--output-directory", outputDirectory(context: context, generated: false).path(percentEncoded: false) + ], + environment: [:], + inputFiles: [configFile], + outputFiles: fetchDependenciesOutputFiles + ) + ] + } else { + log("No dependencies to fetch for target \(sourceModule.name)") + } + + if !outputSwiftFiles.isEmpty { + commands += [ + .buildCommand( + displayName: "Wrapping \(classes.count) Java classes in Swift target '\(sourceModule.name)'", + executable: executable, + arguments: arguments, + inputFiles: compiledClassFiles + fetchDependenciesOutputFiles + [ + configFile + ], + outputFiles: outputSwiftFiles + ) + ] + } else { + log("No Swift output files, skip wrapping") + } + + return commands + } +} +extension Java2SwiftBuildToolPlugin { + func argumentsModuleName(sourceModule: Target) -> [String] { + return [ + "--module-name", sourceModule.name + ] + } + + func argumentsOutputDirectory(context: PluginContext, generated: Bool = true) -> [String] { return [ - .buildCommand( - displayName: "Wrapping \(classes.count) Java classes target in Swift target '\(sourceModule.name)'", - executable: executable, - arguments: arguments, - inputFiles: compiledClassFiles + [ - configFile, - context.cachedClasspathFile(moduleName: sourceModule.name) - ], - outputFiles: outputSwiftFiles - ) + "--output-directory", + outputDirectory(context: context, generated: generated).path(percentEncoded: false) ] } + + func outputDirectory(context: PluginContext, generated: Bool = true) -> URL { + let dir = context.pluginWorkDirectoryURL + if generated { + return dir.appending(path: "generated") + } else { + return dir + } + } + + func outputFilePath(context: PluginContext, generated: Bool, filename: String) -> URL { + outputDirectory(context: context, generated: generated).appending(path: filename) + } } diff --git a/Samples/JavaDependencySampleApp/Package.swift b/Samples/JavaDependencySampleApp/Package.swift index d8ced924..3d210e36 100644 --- a/Samples/JavaDependencySampleApp/Package.swift +++ b/Samples/JavaDependencySampleApp/Package.swift @@ -70,13 +70,13 @@ let package = Package( .product(name: "JavaKitFunction", package: "swift-java"), "JavaCommonsCSV" ], + exclude: ["swift-java.config"], swiftSettings: [ .unsafeFlags(["-I\(javaIncludePath)", "-I\(javaPlatformIncludePath)"]), .swiftLanguageMode(.v5), ], plugins: [ .plugin(name: "Java2SwiftPlugin", package: "swift-java"), -// .plugin(name: "SwiftJavaPlugin", package: "swift-java"), ] ), @@ -85,14 +85,14 @@ let package = Package( dependencies: [ .product(name: "JavaKit", package: "swift-java"), .product(name: "JavaKitFunction", package: "swift-java"), - .product(name: "JavaRuntime", package: "swift-java"), + .product(name: "JavaKitCollection", package: "swift-java"), ], + exclude: ["swift-java.config"], swiftSettings: [ .unsafeFlags(["-I\(javaIncludePath)", "-I\(javaPlatformIncludePath)"]), .swiftLanguageMode(.v5), ], plugins: [ -// .plugin(name: "SwiftJavaPlugin", package: "swift-java"), .plugin(name: "Java2SwiftPlugin", package: "swift-java"), ] ), diff --git a/Samples/JavaDependencySampleApp/Sources/JavaCommonsCSV/swift-java.config b/Samples/JavaDependencySampleApp/Sources/JavaCommonsCSV/swift-java.config index ed6b0b35..3ab83f79 100644 --- a/Samples/JavaDependencySampleApp/Sources/JavaCommonsCSV/swift-java.config +++ b/Samples/JavaDependencySampleApp/Sources/JavaCommonsCSV/swift-java.config @@ -1,8 +1,8 @@ { "classes" : { - "org.apache.commons.io.FilenameUtils" : "FilenameUtils" + "org.apache.commons.io.FilenameUtils" : "FilenameUtils", + "org.apache.commons.io.IOCase" : "IOCase" }, - "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:\/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:..\/..\/JavaKit\/build\/classes\/java\/main:\/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:..\/..\/JavaKit\/build\/classes\/java\/main:\/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:..\/..\/JavaKit\/build\/classes\/java\/main", "dependencies" : [ "org.apache.commons:commons-csv:1.12.0" ] diff --git a/Samples/JavaDependencySampleApp/Sources/JavaDependencySample/main.swift b/Samples/JavaDependencySampleApp/Sources/JavaDependencySample/main.swift index 53aef9dc..dbd36b8c 100644 --- a/Samples/JavaDependencySampleApp/Sources/JavaDependencySample/main.swift +++ b/Samples/JavaDependencySampleApp/Sources/JavaDependencySample/main.swift @@ -23,10 +23,10 @@ import JavaCommonsCSV // Make sure we have the classpath loaded // TODO: this is more complex than that, need to account for dependencies of our module let currentDir = FileManager.default.currentDirectoryPath -let configuration = try readConfiguration(sourceDir: "\(currentDir)/Sources/JavaCommonsCSV/") +let swiftJavaClasspath = findSwiftJavaClasspaths() -// 1) Start a JVM with apropriate classpath -let jvm = try JavaVirtualMachine.shared(classpath: configuration.classpathEntries) +// 1) Start a JVM with appropriate classpath +let jvm = try JavaVirtualMachine.shared(classpath: swiftJavaClasspath) // 2) Get the FilenameUtils Java class so we can call the static methods on it let FilenameUtilsClass = try JavaClass() diff --git a/Samples/JavaDependencySampleApp/ci-validate.sh b/Samples/JavaDependencySampleApp/ci-validate.sh index b9976eb6..38eebd8c 100755 --- a/Samples/JavaDependencySampleApp/ci-validate.sh +++ b/Samples/JavaDependencySampleApp/ci-validate.sh @@ -4,7 +4,11 @@ set -e set -x JAVASWIFT="../../.build/debug/Java2Swift" +cd ../../ +echo "Build Java2Swift binary..." +swift build +cd - MODULE_NAME="JavaCommonsCSV" MODULE_CONFIG_DIR=$(pwd)/Sources/$MODULE_NAME/ diff --git a/Sources/Java2Swift/JavaToSwift.swift b/Sources/Java2Swift/JavaToSwift.swift index e3b0dd79..0100b438 100644 --- a/Sources/Java2Swift/JavaToSwift.swift +++ b/Sources/Java2Swift/JavaToSwift.swift @@ -170,7 +170,7 @@ struct JavaToSwift: ParsableCommand { print("[info][swift-java] Run: \(CommandLine.arguments.joined(separator: " "))") do { let config: Configuration - + // Determine the mode in which we'll execute. let toolMode: ToolMode if jar { @@ -217,10 +217,16 @@ struct JavaToSwift: ParsableCommand { // * Command-line option --classpath let classpathOptionEntries: [String] = classpath.flatMap { $0.split(separator: ":").map(String.init) } let classpathFromEnv = ProcessInfo.processInfo.environment["CLASSPATH"]?.split(separator: ":").map(String.init) ?? [] - var classpathFromConfig: [String] = config.classpath?.split(separator: ":").map(String.init) ?? [] + let classpathFromConfig: [String] = config.classpath?.split(separator: ":").map(String.init) ?? [] print("[debug][swift-java] Base classpath from config: \(classpathFromConfig)") - + var classpathEntries: [String] = classpathFromConfig + + let swiftJavaCachedModuleClasspath = findSwiftJavaClasspaths( + in: self.effectiveCacheDirectory ?? FileManager.default.currentDirectoryPath) + print("[debug][swift-java] Classpath from *.swift-java.classpath files: \(swiftJavaCachedModuleClasspath)") + classpathEntries += swiftJavaCachedModuleClasspath + if !classpathOptionEntries.isEmpty { print("[debug][swift-java] Classpath from options: \(classpathOptionEntries)") classpathEntries += classpathOptionEntries @@ -276,7 +282,6 @@ struct JavaToSwift: ParsableCommand { // } // * Classespaths from all dependent configuration files - print("[debug][swift-java] Dependent configs: \(dependentConfigs.map { $0.1 })") for (_, config) in dependentConfigs { // TODO: may need to resolve the dependent configs rather than just get their configs // TODO: We should cache the resolved classpaths as well so we don't do it many times diff --git a/Sources/JavaKitConfigurationShared/Configuration.swift b/Sources/JavaKitConfigurationShared/Configuration.swift index 6169c261..22dd9f3b 100644 --- a/Sources/JavaKitConfigurationShared/Configuration.swift +++ b/Sources/JavaKitConfigurationShared/Configuration.swift @@ -108,6 +108,31 @@ public func readConfiguration(sourceDir: String, file: String = #fileID, line: U } } +public func findSwiftJavaClasspaths(in basePath: String = FileManager.default.currentDirectoryPath) -> [String] { + let fileManager = FileManager.default + + let baseURL = URL(fileURLWithPath: basePath) + var classpathEntries: [String] = [] + + print("[debug][swift-java] Searching for *.swift-java.classpath files in: \(baseURL)") + guard let enumerator = fileManager.enumerator(at: baseURL, includingPropertiesForKeys: []) else { + print("[warning][swift-java] Failed to get enumerator for \(baseURL)") + return [] + } + + for case let fileURL as URL in enumerator { + if fileURL.lastPathComponent.hasSuffix(".swift-java.classpath") { + print("[debug][swift-java] Constructing classpath with entries from: \(fileURL.relativePath)") + if let contents = try? String(contentsOf: fileURL) { + let entries = contents.split(separator: ":").map(String.init) + classpathEntries += entries + } + } + } + + return classpathEntries +} + extension Configuration { public var compilerVersionArgs: [String] { var compilerVersionArgs = [String]() From 69212ceadbb36400b7fa9dbb874c95131e80fba3 Mon Sep 17 00:00:00 2001 From: Konrad `ktoso` Malawski Date: Mon, 9 Dec 2024 12:48:43 +0900 Subject: [PATCH 20/25] validate samples with independent runs --- .github/scripts/validate_sample.sh | 32 ++++++++++++++++ .github/scripts/validate_samples.sh | 37 ------------------- .github/workflows/pull_request.yml | 14 ++++++- .../Sources/JavaDependencySample/main.swift | 2 +- .../JavaDependencySampleApp/ci-validate.sh | 33 +---------------- .../swift-java.config | 1 - 6 files changed, 46 insertions(+), 73 deletions(-) create mode 100755 .github/scripts/validate_sample.sh delete mode 100755 .github/scripts/validate_samples.sh diff --git a/.github/scripts/validate_sample.sh b/.github/scripts/validate_sample.sh new file mode 100755 index 00000000..64be8a40 --- /dev/null +++ b/.github/scripts/validate_sample.sh @@ -0,0 +1,32 @@ +#!/bin/bash + +# shellcheck disable=SC2034 +declare -r GREEN='\033[0;32m' +declare -r BOLD='\033[1m' +declare -r RESET='\033[0m' + +declare -r sampleDir="$1" +declare -r CI_VALIDATE_SCRIPT='ci-validate.sh' + +echo "" +echo "" +echo "========================================================================" +printf "Validate sample '${BOLD}%s${RESET}' using: " "$sampleDir" +cd "$sampleDir" || exit +if [[ $(find . -name ${CI_VALIDATE_SCRIPT} -maxdepth 1) ]]; then + echo -e "Custom ${BOLD}${CI_VALIDATE_SCRIPT}${RESET} script..." + ./${CI_VALIDATE_SCRIPT} || exit +elif [[ $(find . -name 'build.gradle*' -maxdepth 1) ]]; then + echo -e "${BOLD}Gradle${RESET} build..." + ./gradlew build || ./gradlew build --info # re-run to get better failure output +else + echo -e "${BOLD}SwiftPM${RESET} build..." + swift build || exit +fi + +echo -e "Validated sample '${BOLD}${sampleDir}${RESET}': ${BOLD}passed${RESET}." +cd - || exit + +echo +printf "Done validating sample: ${sampleDir}" +echo -e "${GREEN}done${RESET}." diff --git a/.github/scripts/validate_samples.sh b/.github/scripts/validate_samples.sh deleted file mode 100755 index 26273575..00000000 --- a/.github/scripts/validate_samples.sh +++ /dev/null @@ -1,37 +0,0 @@ -#!/bin/bash - -# shellcheck disable=SC2034 -declare -r GREEN='\033[0;32m' -declare -r BOLD='\033[1m' -declare -r RESET='\033[0m' - -# shellcheck disable=SC2155 -declare -r SAMPLE_PACKAGES=$(find Samples -name Package.swift -maxdepth 2) -declare -r CI_VALIDATE_SCRIPT='ci-validate.sh' - -for samplePackage in ${SAMPLE_PACKAGES} ; do - sampleDir=$(dirname "$samplePackage") - - echo "" - echo "" - echo "========================================================================" - printf "Validate sample '${BOLD}%s${RESET}' using: " "$sampleDir" - cd "$sampleDir" || exit - if [[ $(find . -name ${CI_VALIDATE_SCRIPT} -maxdepth 1) ]]; then - echo -e "Custom ${BOLD}${CI_VALIDATE_SCRIPT}${RESET} script..." - ./${CI_VALIDATE_SCRIPT} || exit - elif [[ $(find . -name 'build.gradle*' -maxdepth 1) ]]; then - echo -e "${BOLD}Gradle${RESET} build..." - ./gradlew build || ./gradlew build --info # re-run to get better failure output - else - echo -e "${BOLD}SwiftPM${RESET} build..." - swift build || exit - fi - - echo -e "Validated sample '${BOLD}${sampleDir}${RESET}': ${BOLD}passed${RESET}." - cd - || exit -done - -echo -printf "Done validating samples: " -echo -e "${GREEN}done${RESET}." diff --git a/.github/workflows/pull_request.yml b/.github/workflows/pull_request.yml index 06db1ff2..d289296d 100644 --- a/.github/workflows/pull_request.yml +++ b/.github/workflows/pull_request.yml @@ -82,8 +82,18 @@ jobs: - uses: actions/checkout@v4 - name: Prepare CI Environment uses: ./.github/actions/prepare_env - - name: Verify Samples (All) - run: .github/scripts/validate_samples.sh + - name: "Verify Sample: JavaDependencySampleApp" + run: .github/scripts/validate_sample.sh Samples/JavaDependencySampleApp + - name: "Verify Sample: JavaKitSampleApp" + run: .github/scripts/validate_sample.sh Samples/JavaKitSampleApp + - name: "Verify Sample: JavaProbablyPrime" + run: .github/scripts/validate_sample.sh Samples/JavaProbablyPrime + - name: "Verify Sample: JavaSieve" + run: .github/scripts/validate_sample.sh Samples/JavaSieve + - name: "Verify Sample: SwiftAndJavaJarSampleLib" + run: .github/scripts/validate_sample.sh Samples/SwiftAndJavaJarSampleLib + - name: "Verify Sample: SwiftKitSampleApp" + run: .github/scripts/validate_sample.sh Samples/SwiftKitSampleApp # TODO: Benchmark compile crashes in CI, enable when nightly toolchains in better shape. # - name: Build (Swift) Benchmarks # run: "swift package --package-path Benchmarks/ benchmark list" diff --git a/Samples/JavaDependencySampleApp/Sources/JavaDependencySample/main.swift b/Samples/JavaDependencySampleApp/Sources/JavaDependencySample/main.swift index dbd36b8c..3d7492cb 100644 --- a/Samples/JavaDependencySampleApp/Sources/JavaDependencySample/main.swift +++ b/Samples/JavaDependencySampleApp/Sources/JavaDependencySample/main.swift @@ -36,7 +36,7 @@ let path = "/example/path/executable.exe" print("Path = \(path)") let ext = try! FilenameUtilsClass.getExtension(path) -print("Java FilenameUtils found extension = \(ext)") +print("org.apache.commons.io.FilenameUtils.getExtension = \(ext)") precondition(ext == "exe") print("Done.") diff --git a/Samples/JavaDependencySampleApp/ci-validate.sh b/Samples/JavaDependencySampleApp/ci-validate.sh index 38eebd8c..7012b841 100755 --- a/Samples/JavaDependencySampleApp/ci-validate.sh +++ b/Samples/JavaDependencySampleApp/ci-validate.sh @@ -3,35 +3,4 @@ set -e set -x -JAVASWIFT="../../.build/debug/Java2Swift" -cd ../../ -echo "Build Java2Swift binary..." -swift build - -cd - -MODULE_NAME="JavaCommonsCSV" -MODULE_CONFIG_DIR=$(pwd)/Sources/$MODULE_NAME/ - -### 1) downloads all the dependencies -echo "Resolve dependencies..." -"$JAVASWIFT" --fetch "$MODULE_CONFIG_DIR/swift-java.config" \ - --module-name "$MODULE_NAME" \ - --cache-dir "Plugins/outputs/javadependencysampleapp/${MODULE_NAME}/destination" - --output-directory "$MODULE_CONFIG_DIR" - -#### 2) extract the config for the fetched dependency -MODULE_CONFIG_PATH="$MODULE_CONFIG_DIR/swift-java.config" -DEP_JAR_CP=$(jq .classpath "$MODULE_CONFIG_PATH") -DEP_JAR_CP=$(echo "$DEP_JAR_CP" | tr -d '"') # trim the "..." - -# Import just a single class for our test purposes -# shellcheck disable=SC2086 -"$JAVASWIFT" --jar $DEP_JAR_CP \ - --module-name "$MODULE_NAME" \ - --java-package-filter org.apache.commons.io.FilenameUtils \ - --existing-config amend - -# for now in CI we just use what we have already generated and comitted in the config - -### 3) make wrappers for the module -swift run +swift run --disable-sandbox diff --git a/Sources/JavaKitDependencyResolver/swift-java.config b/Sources/JavaKitDependencyResolver/swift-java.config index 0f44aecb..04220970 100644 --- a/Sources/JavaKitDependencyResolver/swift-java.config +++ b/Sources/JavaKitDependencyResolver/swift-java.config @@ -2,7 +2,6 @@ "dependencies": [ "dev.gradleplugins:gradle-api:8.10.1" ], - "classpath": "JavaKit/build/classes/java/main", "classes": { "org.swift.javakit.dependencies.DependencyResolver": "DependencyResolver" } From aa4e11fe21a8a466fb69461b3292ebd34cf27916 Mon Sep 17 00:00:00 2001 From: Konrad `ktoso` Malawski Date: Mon, 9 Dec 2024 20:43:08 +0900 Subject: [PATCH 21/25] cleanup JavaKit's DependencyResolver --- JavaKit/build.gradle | 26 +++++++------------ JavaKit/gradlew | 1 + JavaKit/gradlew.bat | 1 + .../dependencies/DependencyResolver.java | 1 - 4 files changed, 12 insertions(+), 17 deletions(-) create mode 120000 JavaKit/gradlew create mode 120000 JavaKit/gradlew.bat diff --git a/JavaKit/build.gradle b/JavaKit/build.gradle index 6258e9d7..f0fc8618 100644 --- a/JavaKit/build.gradle +++ b/JavaKit/build.gradle @@ -12,8 +12,6 @@ // //===----------------------------------------------------------------------===// -import groovy.json.JsonSlurper - plugins { id("build-logic.java-library-conventions") } @@ -31,21 +29,8 @@ java { } } -List loadDependenciesFromSwiftJavaJSON() { - def jsonFile = file("../Sources/JavaKitDependencyResolver/swift-java.config") - if (!jsonFile.exists()) { - throw new FileNotFoundException("Dependencies must be declared in Swift config file! Not found: ${jsonFile.absolutePath}") - } - def jsonContent = new JsonSlurper().parseText(jsonFile.text) - return jsonContent.dependencies -} - dependencies { - // We load dependencies from one source of truth: the swift-java.config of module - // that is used to access this Java code. - loadDependenciesFromSwiftJavaJSON().each { - implementation(it) - } + implementation("dev.gradleplugins:gradle-api:8.10.1") testImplementation(platform("org.junit:junit-bom:5.10.0")) testImplementation("org.junit.jupiter:junit-jupiter") @@ -57,3 +42,12 @@ tasks.test { events("passed", "skipped", "failed") } } + +// Task necessary to bootstrap +task printRuntimeClasspath { + def runtimeClasspath = sourceSets.main.runtimeClasspath + inputs.files(runtimeClasspath) + doLast { + println("CLASSPATH:${runtimeClasspath.asPath}") + } +} \ No newline at end of file diff --git a/JavaKit/gradlew b/JavaKit/gradlew new file mode 120000 index 00000000..502f5a2d --- /dev/null +++ b/JavaKit/gradlew @@ -0,0 +1 @@ +../gradlew \ No newline at end of file diff --git a/JavaKit/gradlew.bat b/JavaKit/gradlew.bat new file mode 120000 index 00000000..28401328 --- /dev/null +++ b/JavaKit/gradlew.bat @@ -0,0 +1 @@ +../gradlew.bat \ No newline at end of file diff --git a/JavaKit/src/main/java/org/swift/javakit/dependencies/DependencyResolver.java b/JavaKit/src/main/java/org/swift/javakit/dependencies/DependencyResolver.java index cc553e97..02bb6f39 100644 --- a/JavaKit/src/main/java/org/swift/javakit/dependencies/DependencyResolver.java +++ b/JavaKit/src/main/java/org/swift/javakit/dependencies/DependencyResolver.java @@ -193,7 +193,6 @@ private static String resolveDependenciesUsingAPI(File projectDir, String[] depe .filter(s -> s.startsWith(COMMAND_OUTPUT_LINE_PREFIX_CLASSPATH)) .map(s -> s.substring(COMMAND_OUTPUT_LINE_PREFIX_CLASSPATH.length())) .findFirst().orElseThrow(() -> new RuntimeException("Could not find classpath output from ':printRuntimeClasspath' task.")); - simpleLog("DEPENDENCY BUILD PATH = " + projectDir.getAbsolutePath()); // remove output directories of the project we used for the dependency resolution var classpath = Arrays.stream(classpathString From c54fef98bac59ef8d9a532a1ed968aab3067ac26 Mon Sep 17 00:00:00 2001 From: Konrad `ktoso` Malawski Date: Mon, 9 Dec 2024 20:43:25 +0900 Subject: [PATCH 22/25] validate in CI with before building JavaKit's dependency resovler --- Samples/JavaDependencySampleApp/ci-validate.sh | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/Samples/JavaDependencySampleApp/ci-validate.sh b/Samples/JavaDependencySampleApp/ci-validate.sh index 7012b841..86f83978 100755 --- a/Samples/JavaDependencySampleApp/ci-validate.sh +++ b/Samples/JavaDependencySampleApp/ci-validate.sh @@ -3,4 +3,8 @@ set -e set -x +cd ../../JavaKit +./gradlew build + +cd - swift run --disable-sandbox From 0e8e5a66c2edf5f7b6d4bbc263be37c2c32d2792 Mon Sep 17 00:00:00 2001 From: Konrad `ktoso` Malawski Date: Mon, 9 Dec 2024 22:22:27 +0900 Subject: [PATCH 23/25] Make bootstrapping from NOTHING possible by having JavaKit include gradle wrapper --- JavaKit/build.gradle | 26 ++++++++++- .../dependencies/DependencyResolver.java | 46 +++++++++++++++++-- .../Sources/JavaDependencySample/main.swift | 5 ++ .../JavaToSwift+FetchDependencies.swift | 5 +- Sources/Java2Swift/JavaToSwift.swift | 21 +++++---- .../JavaKitVM/JavaVirtualMachine.swift | 5 +- .../Configuration.swift | 26 +++++++++-- .../swift-java.config | 15 +++--- 8 files changed, 119 insertions(+), 30 deletions(-) diff --git a/JavaKit/build.gradle b/JavaKit/build.gradle index f0fc8618..8b243145 100644 --- a/JavaKit/build.gradle +++ b/JavaKit/build.gradle @@ -43,6 +43,30 @@ tasks.test { } } +// Copy the gradle wrapper we're using into the resulting jar's resources. +// We'll use it to bootstrap dependencies (and gradle!) if there is none yet. +tasks.processResources { + from('gradlew') { + into 'gradle/' + } + from('gradlew.bat') { + into 'gradle/' + } + from('../gradle/wrapper/gradle-wrapper.jar') { + into 'gradle/wrapper/' + } + from('../gradle/wrapper/gradle-wrapper.properties') { + into 'gradle/wrapper/' + } +} + +//task fatJar(type: Jar) { +// archiveBaseName = 'java-kit-fat-jar' +// duplicatesStrategy = DuplicatesStrategy.EXCLUDE +// from { configurations.runtimeClasspath.collect { it.isDirectory() ? it : zipTree(it) } } +// with jar +//} + // Task necessary to bootstrap task printRuntimeClasspath { def runtimeClasspath = sourceSets.main.runtimeClasspath @@ -50,4 +74,4 @@ task printRuntimeClasspath { doLast { println("CLASSPATH:${runtimeClasspath.asPath}") } -} \ No newline at end of file +} diff --git a/JavaKit/src/main/java/org/swift/javakit/dependencies/DependencyResolver.java b/JavaKit/src/main/java/org/swift/javakit/dependencies/DependencyResolver.java index 02bb6f39..ff4085c9 100644 --- a/JavaKit/src/main/java/org/swift/javakit/dependencies/DependencyResolver.java +++ b/JavaKit/src/main/java/org/swift/javakit/dependencies/DependencyResolver.java @@ -51,6 +51,7 @@ public class DependencyResolver { public static String resolveDependenciesToClasspath(String projectBaseDirectoryString, String[] dependencies) throws IOException { try { simpleLog("Fetch dependencies: " + Arrays.toString(dependencies)); + simpleLog("Classpath: " + System.getProperty("java.class.path")); var projectBasePath = new File(projectBaseDirectoryString).toPath(); File projectDir = Files.createTempDirectory("java-swift-dependencies").toFile(); @@ -118,7 +119,7 @@ private static String resolveDependenciesWithSubprocess(File gradleProjectDir) t stderrFile.deleteOnExit(); try { - ProcessBuilder gradleBuilder = new ProcessBuilder("gradle", ":printRuntimeClasspath"); + ProcessBuilder gradleBuilder = new ProcessBuilder("./gradlew", ":printRuntimeClasspath"); gradleBuilder.directory(gradleProjectDir); gradleBuilder.redirectOutput(stdoutFile); gradleBuilder.redirectError(stderrFile); @@ -172,7 +173,7 @@ public static boolean hasDependencyResolverDependenciesLoaded() { * * @return classpath which was resolved for the dependencies */ - private static String resolveDependenciesUsingAPI(File projectDir, String[] dependencies) throws FileNotFoundException { + private static String resolveDependenciesUsingAPI(File projectDir, String[] dependencies) throws IOException { printBuildFiles(projectDir, dependencies); var connection = GradleConnector.newConnector() @@ -196,7 +197,7 @@ private static String resolveDependenciesUsingAPI(File projectDir, String[] depe // remove output directories of the project we used for the dependency resolution var classpath = Arrays.stream(classpathString - .split(":")) + .split(":")) .filter(s -> !s.startsWith(projectDir.getAbsolutePath())) .collect(Collectors.joining(":")); @@ -221,7 +222,8 @@ private static boolean hasDependencyResolverDependenciesLoaded(ClassLoader class } } - private static void printBuildFiles(File projectDir, String[] dependencies) throws FileNotFoundException { + private static void printBuildFiles(File projectDir, String[] dependencies) throws IOException { + // === build.gradle File buildFile = new File(projectDir, "build.gradle"); try (PrintWriter writer = new PrintWriter(buildFile)) { writer.println("plugins { id 'java-library' }"); @@ -244,12 +246,48 @@ private static void printBuildFiles(File projectDir, String[] dependencies) thro """); } + // === settings.gradle File settingsFile = new File(projectDir, "settings.gradle.kts"); try (PrintWriter writer = new PrintWriter(settingsFile)) { writer.println(""" rootProject.name = "swift-java-resolve-temp-project" """); } + + // === gradle wrapper files, so we can even download gradle when necessary to bootstrap + File gradlew = new File(projectDir, "gradlew"); + writeResourceToFile("/gradle/gradlew", gradlew); + gradlew.setExecutable(true); + + File gradlewBat = new File(projectDir, "gradlew.bat"); + writeResourceToFile("/gradle/gradlew.bat", gradlewBat); + gradlew.setExecutable(true); + + File gradleDir = new File(projectDir, "gradle"); + File gradleWrapperDir = new File(gradleDir, "wrapper"); + gradleWrapperDir.mkdirs(); + + File gradleWrapperJar = new File(gradleWrapperDir, "gradle-wrapper.jar"); + writeResourceToFile("/gradle/wrapper/gradle-wrapper.jar", gradleWrapperJar); + File gradleWrapperProps = new File(gradleWrapperDir, "gradle-wrapper.properties"); + writeResourceToFile("/gradle/wrapper/gradle-wrapper.properties", gradleWrapperProps); + } + + private static void writeResourceToFile(String resource, File target) throws IOException { + try (PrintWriter writer = new PrintWriter(target)) { + try (InputStream inputStream = DependencyResolver.class.getResourceAsStream(resource)) { + if (inputStream == null) { + throw new FileNotFoundException("Not found: gradlew wrapper in resources!"); + } + try (var os = new BufferedOutputStream(new FileOutputStream(target))) { + byte[] buffer = new byte[8192]; // Buffer size of 8 KB + int bytesRead; + while ((bytesRead = inputStream.read(buffer)) != -1) { + os.write(buffer, 0, bytesRead); + } + } + } + } } private static void simpleLog(String message) { diff --git a/Samples/JavaDependencySampleApp/Sources/JavaDependencySample/main.swift b/Samples/JavaDependencySampleApp/Sources/JavaDependencySample/main.swift index 3d7492cb..86770ee8 100644 --- a/Samples/JavaDependencySampleApp/Sources/JavaDependencySample/main.swift +++ b/Samples/JavaDependencySampleApp/Sources/JavaDependencySample/main.swift @@ -20,6 +20,11 @@ import Foundation // Import the commons-csv library wrapper: import JavaCommonsCSV +print("") +print("") +print("-----------------------------------------------------------------------") +print("Start Sample app...") + // Make sure we have the classpath loaded // TODO: this is more complex than that, need to account for dependencies of our module let currentDir = FileManager.default.currentDirectoryPath diff --git a/Sources/Java2Swift/JavaToSwift+FetchDependencies.swift b/Sources/Java2Swift/JavaToSwift+FetchDependencies.swift index a134572f..391abb27 100644 --- a/Sources/Java2Swift/JavaToSwift+FetchDependencies.swift +++ b/Sources/Java2Swift/JavaToSwift+FetchDependencies.swift @@ -33,9 +33,8 @@ extension JavaToSwift { } func fetchDependenciesCachedClasspath() -> [String]? { - guard let cachedClasspathURL = URL(string: "file://" + FileManager.default.currentDirectoryPath + "/" + JavaKitDependencyResolverClasspathCacheFilePath) else { - return [] - } + let cachedClasspathURL = URL( + fileURLWithPath: FileManager.default.currentDirectoryPath + "/" + JavaKitDependencyResolverClasspathCacheFilePath) guard FileManager.default.fileExists(atPath: cachedClasspathURL.path) else { return [] diff --git a/Sources/Java2Swift/JavaToSwift.swift b/Sources/Java2Swift/JavaToSwift.swift index 0100b438..0d196933 100644 --- a/Sources/Java2Swift/JavaToSwift.swift +++ b/Sources/Java2Swift/JavaToSwift.swift @@ -255,20 +255,23 @@ struct JavaToSwift: ParsableCommand { } // Add extra classpath entries which are specific to building the JavaKit project and samples - let classpathBuildJavaKitEntries = [ - "JavaKit/build/classes/java/main", - "../../JavaKit/build/classes/java/main", - ].filter { - FileManager.default.fileExists(atPath: $0) - } + let classpathBuildJavaKitEntries = [ // FIXME: THIS IS A TRICK UNTIL WE FIGURE OUT HOW TO BOOTSTRAP THIS PART + FileManager.default.currentDirectoryPath, + FileManager.default.currentDirectoryPath + "/.build", + FileManager.default.currentDirectoryPath + "/JavaKit/build/libs", + URL(fileURLWithPath: FileManager.default.currentDirectoryPath) + .deletingLastPathComponent() + .deletingLastPathComponent().absoluteURL.path + "/JavaKit/build/libs/JavaKit-1.0-SNAPSHOT.jar" + ] classpathEntries += classpathBuildJavaKitEntries - + // Bring up the Java VM. // TODO: print only in verbose mode - let jvm = try JavaVirtualMachine.shared(classpath: classpathEntries) let classpath = classpathEntries.joined(separator: ":") print("[debug][swift-java] Initialize JVM with classpath: \(classpath)") + let jvm = try JavaVirtualMachine.shared(classpath: classpathEntries) + // FIXME: we should resolve dependencies here perhaps // if let dependencies = config.dependencies { // print("[info][swift-java] Resolve dependencies...") @@ -318,6 +321,8 @@ struct JavaToSwift: ParsableCommand { fatalError("Fetching dependencies must effective cache directory! Specify --output-directory or --cache-directory") } + print("[debug][swift-java] Base classpath to fetch dependencies: \(classpathOptionEntries)") + let dependencyClasspath = try fetchDependencies( moduleName: moduleName, dependencies: dependencies, diff --git a/Sources/JavaKit/JavaKitVM/JavaVirtualMachine.swift b/Sources/JavaKit/JavaKitVM/JavaVirtualMachine.swift index 279eb05c..55b01e43 100644 --- a/Sources/JavaKit/JavaKitVM/JavaVirtualMachine.swift +++ b/Sources/JavaKit/JavaKitVM/JavaVirtualMachine.swift @@ -73,8 +73,7 @@ public final class JavaVirtualMachine: @unchecked Sendable { for path in classpath { if !fileManager.fileExists(atPath: path) { // FIXME: this should be configurable, a classpath missing a directory isn't reason to blow up - print("[warning][swift-java][JavaVirtualMachine] Missing classpath element: \(path)") // TODO: stderr - // throw JavaKitError.classpathEntryNotFound(entry: path, classpath: classpath) + print("[warning][swift-java][JavaVirtualMachine] Missing classpath element: \(URL(fileURLWithPath: path).absoluteString)") // TODO: stderr } } let colonSeparatedClassPath = classpath.joined(separator: ":") @@ -250,6 +249,7 @@ extension JavaVirtualMachine { // wrapper. let javaVirtualMachine = JavaVirtualMachine(adoptingJVM: jvm!) sharedJVMPointer = javaVirtualMachine + print("WAS EXISTING") return javaVirtualMachine } @@ -261,6 +261,7 @@ extension JavaVirtualMachine { // Create a new instance of the JVM. let javaVirtualMachine: JavaVirtualMachine do { + print("CREATE") javaVirtualMachine = try JavaVirtualMachine( classpath: classpath, vmOptions: vmOptions, diff --git a/Sources/JavaKitConfigurationShared/Configuration.swift b/Sources/JavaKitConfigurationShared/Configuration.swift index 22dd9f3b..2078c544 100644 --- a/Sources/JavaKitConfigurationShared/Configuration.swift +++ b/Sources/JavaKitConfigurationShared/Configuration.swift @@ -71,9 +71,18 @@ public struct JavaDependencyDescriptor: Hashable, Codable { let container = try decoder.singleValueContainer() let string = try container.decode(String.self) let parts = string.split(separator: ":") + + if parts.count == 1 && string.hasPrefix(":") { + self.groupID = "" + self.artifactID = ":" + String(parts.first!) + self.version = "" + return + } + guard parts.count == 3 else { - throw JavaDependencyDescriptorError(message: "Illegal dependency, did not match: `groupID:artifactID:version`") + throw JavaDependencyDescriptorError(message: "Illegal dependency, did not match: `groupID:artifactID:version`, parts: '\(parts)'") } + self.groupID = String(parts[0]) self.artifactID = String(parts[1]) self.version = String(parts[2]) @@ -96,14 +105,18 @@ public struct JavaDependencyDescriptor: Hashable, Codable { public func readConfiguration(sourceDir: String, file: String = #fileID, line: UInt = #line) throws -> Configuration { // Workaround since filePath is macOS 13 let sourcePath = - if sourceDir.hasPrefix("file://") { sourceDir } else { "file://" + sourceDir } - let configFile = URL(string: sourcePath)!.appendingPathComponent("swift-java.config", isDirectory: false) + if sourceDir.hasPrefix("file://") { sourceDir } else { "file://" + sourceDir } + let configPath = URL(string: sourcePath)!.appendingPathComponent("swift-java.config", isDirectory: false) + + return try readConfiguration(configPath: configPath, file: file, line: line) +} +public func readConfiguration(configPath: URL, file: String = #fileID, line: UInt = #line) throws -> Configuration { do { - let configData = try Data(contentsOf: configFile) + let configData = try Data(contentsOf: configPath) return try JSONDecoder().decode(Configuration.self, from: configData) } catch { - throw ConfigurationError(message: "Failed to parse SwiftJava configuration at '\(configFile)'!", error: error, + throw ConfigurationError(message: "Failed to parse SwiftJava configuration at '\(configPath)'!", error: error, file: file, line: line) } } @@ -125,6 +138,9 @@ public func findSwiftJavaClasspaths(in basePath: String = FileManager.default.cu print("[debug][swift-java] Constructing classpath with entries from: \(fileURL.relativePath)") if let contents = try? String(contentsOf: fileURL) { let entries = contents.split(separator: ":").map(String.init) + for entry in entries { + print("[debug][swift-java] Classpath += \(entry)") + } classpathEntries += entries } } diff --git a/Sources/JavaKitDependencyResolver/swift-java.config b/Sources/JavaKitDependencyResolver/swift-java.config index 04220970..d2d9f448 100644 --- a/Sources/JavaKitDependencyResolver/swift-java.config +++ b/Sources/JavaKitDependencyResolver/swift-java.config @@ -1,8 +1,9 @@ { - "dependencies": [ - "dev.gradleplugins:gradle-api:8.10.1" - ], - "classes": { - "org.swift.javakit.dependencies.DependencyResolver": "DependencyResolver" - } - } \ No newline at end of file + "dependencies": [ + ":JavaKit", + ] + , + "__classes": { + "org.swift.javakit.dependencies.DependencyResolver": "DependencyResolver" + } + } From 08fc7747b3d6b84ace9c8a2fc73dd9be4ef442ba Mon Sep 17 00:00:00 2001 From: Konrad `ktoso` Malawski Date: Mon, 9 Dec 2024 22:28:55 +0900 Subject: [PATCH 24/25] fix CI warnings on license and shellcheck --- .github/scripts/validate_sample.sh | 2 +- .../JavaKitVM/JavaVirtualMachine.swift | 2 -- .../contents.xcworkspacedata | 23 ------------------- .../xcshareddata/WorkspaceSettings.xcsettings | 5 ---- 4 files changed, 1 insertion(+), 31 deletions(-) delete mode 100644 SwiftJava.xcworkspace/contents.xcworkspacedata delete mode 100644 SwiftJava.xcworkspace/xcshareddata/WorkspaceSettings.xcsettings diff --git a/.github/scripts/validate_sample.sh b/.github/scripts/validate_sample.sh index 64be8a40..7e0ab3d2 100755 --- a/.github/scripts/validate_sample.sh +++ b/.github/scripts/validate_sample.sh @@ -28,5 +28,5 @@ echo -e "Validated sample '${BOLD}${sampleDir}${RESET}': ${BOLD}passed${RESET}." cd - || exit echo -printf "Done validating sample: ${sampleDir}" +printf "Done validating sample: %s" "${sampleDir}" echo -e "${GREEN}done${RESET}." diff --git a/Sources/JavaKit/JavaKitVM/JavaVirtualMachine.swift b/Sources/JavaKit/JavaKitVM/JavaVirtualMachine.swift index 55b01e43..0800a89e 100644 --- a/Sources/JavaKit/JavaKitVM/JavaVirtualMachine.swift +++ b/Sources/JavaKit/JavaKitVM/JavaVirtualMachine.swift @@ -249,7 +249,6 @@ extension JavaVirtualMachine { // wrapper. let javaVirtualMachine = JavaVirtualMachine(adoptingJVM: jvm!) sharedJVMPointer = javaVirtualMachine - print("WAS EXISTING") return javaVirtualMachine } @@ -261,7 +260,6 @@ extension JavaVirtualMachine { // Create a new instance of the JVM. let javaVirtualMachine: JavaVirtualMachine do { - print("CREATE") javaVirtualMachine = try JavaVirtualMachine( classpath: classpath, vmOptions: vmOptions, diff --git a/SwiftJava.xcworkspace/contents.xcworkspacedata b/SwiftJava.xcworkspace/contents.xcworkspacedata deleted file mode 100644 index 6e4db1f6..00000000 --- a/SwiftJava.xcworkspace/contents.xcworkspacedata +++ /dev/null @@ -1,23 +0,0 @@ - - - - - - - - - - - - - - - diff --git a/SwiftJava.xcworkspace/xcshareddata/WorkspaceSettings.xcsettings b/SwiftJava.xcworkspace/xcshareddata/WorkspaceSettings.xcsettings deleted file mode 100644 index 0c67376e..00000000 --- a/SwiftJava.xcworkspace/xcshareddata/WorkspaceSettings.xcsettings +++ /dev/null @@ -1,5 +0,0 @@ - - - - - From 4aae98811aa81f31d7324d5789bc1ea0328278a6 Mon Sep 17 00:00:00 2001 From: Konrad `ktoso` Malawski Date: Mon, 9 Dec 2024 22:36:38 +0900 Subject: [PATCH 25/25] fix license formatting --- JavaKit/build.gradle | 24 ++++++++++++------------ 1 file changed, 12 insertions(+), 12 deletions(-) diff --git a/JavaKit/build.gradle b/JavaKit/build.gradle index 8b243145..8eed1c6e 100644 --- a/JavaKit/build.gradle +++ b/JavaKit/build.gradle @@ -1,16 +1,16 @@ //===----------------------------------------------------------------------===// - // - // This source file is part of the Swift.org open source project - // - // Copyright (c) 2024 Apple Inc. and the Swift.org project authors - // Licensed under Apache License v2.0 - // - // See LICENSE.txt for license information - // See CONTRIBUTORS.txt for the list of Swift.org project authors - // - // SPDX-License-Identifier: Apache-2.0 - // - //===----------------------------------------------------------------------===// +// +// This source file is part of the Swift.org open source project +// +// Copyright (c) 2024 Apple Inc. and the Swift.org project authors +// Licensed under Apache License v2.0 +// +// See LICENSE.txt for license information +// See CONTRIBUTORS.txt for the list of Swift.org project authors +// +// SPDX-License-Identifier: Apache-2.0 +// +//===----------------------------------------------------------------------===// plugins { id("build-logic.java-library-conventions")