diff --git a/commandsv2/src/dev/java/org/wpilib/commands2/DevMain.java b/commandsv2/src/dev/java/org/wpilib/commands2/DevMain.java
index b88b4e7916..ec909bb1ca 100644
--- a/commandsv2/src/dev/java/org/wpilib/commands2/DevMain.java
+++ b/commandsv2/src/dev/java/org/wpilib/commands2/DevMain.java
@@ -6,13 +6,13 @@ package org.wpilib.commands2;
import org.wpilib.hardware.hal.HALUtil;
import org.wpilib.networktables.NetworkTablesJNI;
-import org.wpilib.util.runtime.CombinedRuntimeLoader;
+import org.wpilib.util.runtime.RuntimeLoader;
public final class DevMain {
/** Main entry point. */
public static void main(String[] args) {
System.out.println("Hello World!");
- System.out.println(CombinedRuntimeLoader.getPlatformPath());
+ System.out.println(RuntimeLoader.getPlatformName());
System.out.println(NetworkTablesJNI.now());
System.out.println(HALUtil.getHALRuntimeType());
}
diff --git a/commandsv3/src/dev/java/org/wpilib/command3/DevMain.java b/commandsv3/src/dev/java/org/wpilib/command3/DevMain.java
index 8b73a7b586..1baa56e513 100644
--- a/commandsv3/src/dev/java/org/wpilib/command3/DevMain.java
+++ b/commandsv3/src/dev/java/org/wpilib/command3/DevMain.java
@@ -6,7 +6,7 @@ package org.wpilib.command3;
import org.wpilib.hardware.hal.HALUtil;
import org.wpilib.networktables.NetworkTablesJNI;
-import org.wpilib.util.runtime.CombinedRuntimeLoader;
+import org.wpilib.util.runtime.RuntimeLoader;
/** Dev main. */
public final class DevMain {
@@ -14,7 +14,7 @@ public final class DevMain {
public static void main(String[] args) {
System.out.println("Commands V3 DevMain");
- System.out.println(CombinedRuntimeLoader.getPlatformPath());
+ System.out.println(RuntimeLoader.getPlatformName());
System.out.println(NetworkTablesJNI.now());
System.out.println(HALUtil.getHALRuntimeType());
}
diff --git a/cscore/src/dev/java/org/wpilib/vision/camera/DevMain.java b/cscore/src/dev/java/org/wpilib/vision/camera/DevMain.java
index 74549fd7b3..18b056b123 100644
--- a/cscore/src/dev/java/org/wpilib/vision/camera/DevMain.java
+++ b/cscore/src/dev/java/org/wpilib/vision/camera/DevMain.java
@@ -4,13 +4,13 @@
package org.wpilib.vision.camera;
-import org.wpilib.util.runtime.CombinedRuntimeLoader;
+import org.wpilib.util.runtime.RuntimeLoader;
public final class DevMain {
/** Main method. */
public static void main(String[] args) {
System.out.println("Hello World!");
- System.out.println(CombinedRuntimeLoader.getPlatformPath());
+ System.out.println(RuntimeLoader.getPlatformName());
System.out.println(CameraServerJNI.getHostname());
}
diff --git a/ntcore/src/dev/java/org/wpilib/networktables/DevMain.java b/ntcore/src/dev/java/org/wpilib/networktables/DevMain.java
index c7b834c8ba..6413425e1a 100644
--- a/ntcore/src/dev/java/org/wpilib/networktables/DevMain.java
+++ b/ntcore/src/dev/java/org/wpilib/networktables/DevMain.java
@@ -4,13 +4,13 @@
package org.wpilib.networktables;
-import org.wpilib.util.runtime.CombinedRuntimeLoader;
+import org.wpilib.util.runtime.RuntimeLoader;
public final class DevMain {
/** Main method. */
public static void main(String[] args) {
System.out.println("Hello World!");
- System.out.println(CombinedRuntimeLoader.getPlatformPath());
+ System.out.println(RuntimeLoader.getPlatformName());
NetworkTablesJNI.flush(NetworkTablesJNI.getDefaultInstance());
}
diff --git a/romiVendordep/src/dev/java/org/wpilib/romi/DevMain.java b/romiVendordep/src/dev/java/org/wpilib/romi/DevMain.java
index 4412287991..bd0a93067d 100644
--- a/romiVendordep/src/dev/java/org/wpilib/romi/DevMain.java
+++ b/romiVendordep/src/dev/java/org/wpilib/romi/DevMain.java
@@ -6,13 +6,13 @@ package org.wpilib.romi;
import org.wpilib.hardware.hal.HALUtil;
import org.wpilib.networktables.NetworkTablesJNI;
-import org.wpilib.util.runtime.CombinedRuntimeLoader;
+import org.wpilib.util.runtime.RuntimeLoader;
public final class DevMain {
/** Main entry point. */
public static void main(String[] args) {
System.out.println("Hello World!");
- System.out.println(CombinedRuntimeLoader.getPlatformPath());
+ System.out.println(RuntimeLoader.getPlatformName());
System.out.println(NetworkTablesJNI.now());
System.out.println(HALUtil.getHALRuntimeType());
}
diff --git a/styleguide/spotbugs-exclude.xml b/styleguide/spotbugs-exclude.xml
index 3cad3f3d8a..7abc2792c9 100644
--- a/styleguide/spotbugs-exclude.xml
+++ b/styleguide/spotbugs-exclude.xml
@@ -36,8 +36,7 @@
-
-
+
@@ -106,10 +105,6 @@
-
-
-
-
diff --git a/wpilibj/src/dev/java/org/wpilib/DevMain.java b/wpilibj/src/dev/java/org/wpilib/DevMain.java
index 26e3ec4ef4..bb04e0e7da 100644
--- a/wpilibj/src/dev/java/org/wpilib/DevMain.java
+++ b/wpilibj/src/dev/java/org/wpilib/DevMain.java
@@ -6,13 +6,13 @@ package org.wpilib;
import org.wpilib.hardware.hal.HALUtil;
import org.wpilib.networktables.NetworkTablesJNI;
-import org.wpilib.util.runtime.CombinedRuntimeLoader;
+import org.wpilib.util.runtime.RuntimeLoader;
public final class DevMain {
/** Main entry point. */
public static void main(String[] args) {
System.out.println("Hello World!");
- System.out.println(CombinedRuntimeLoader.getPlatformPath());
+ System.out.println(RuntimeLoader.getPlatformName());
System.out.println(NetworkTablesJNI.now());
System.out.println(HALUtil.getHALRuntimeType());
}
diff --git a/wpinet/src/dev/java/org/wpilib/net/DevMain.java b/wpinet/src/dev/java/org/wpilib/net/DevMain.java
index 82617988b3..210e115ef0 100644
--- a/wpinet/src/dev/java/org/wpilib/net/DevMain.java
+++ b/wpinet/src/dev/java/org/wpilib/net/DevMain.java
@@ -4,13 +4,13 @@
package org.wpilib.net;
-import org.wpilib.util.runtime.CombinedRuntimeLoader;
+import org.wpilib.util.runtime.RuntimeLoader;
public final class DevMain {
/** Main entry point. */
public static void main(String[] args) {
System.out.println("Hello World!");
- System.out.println(CombinedRuntimeLoader.getPlatformPath());
+ System.out.println(RuntimeLoader.getPlatformName());
}
private DevMain() {}
diff --git a/wpiutil/build.gradle b/wpiutil/build.gradle
index c3f40f17c1..2f587a1148 100644
--- a/wpiutil/build.gradle
+++ b/wpiutil/build.gradle
@@ -3,9 +3,6 @@ apply from: "${rootDir}/shared/resources.gradle"
apply plugin: 'c'
ext {
noWpiutil = true
- skipJniSymbols = [
- 'Java_org_wpilib_util_CombinedRuntimeLoader_setDllDirectory'
- ]
baseId = 'wpiutil'
groupId = 'org.wpilib.wpiutil'
diff --git a/wpiutil/src/dev/java/org/wpilib/util/DevMain.java b/wpiutil/src/dev/java/org/wpilib/util/DevMain.java
index 58da26088b..dbf8c82daf 100644
--- a/wpiutil/src/dev/java/org/wpilib/util/DevMain.java
+++ b/wpiutil/src/dev/java/org/wpilib/util/DevMain.java
@@ -4,13 +4,13 @@
package org.wpilib.util;
-import org.wpilib.util.runtime.CombinedRuntimeLoader;
+import org.wpilib.util.runtime.RuntimeLoader;
public final class DevMain {
/** Main entry point. */
public static void main(String[] args) {
System.out.println("Hello World!");
- System.out.println(CombinedRuntimeLoader.getPlatformPath());
+ System.out.println(RuntimeLoader.getPlatformName());
WPIUtilJNI.checkMsvcRuntime();
}
diff --git a/wpiutil/src/main/java/org/wpilib/util/runtime/CombinedRuntimeLoader.java b/wpiutil/src/main/java/org/wpilib/util/runtime/CombinedRuntimeLoader.java
deleted file mode 100644
index e96391b5ad..0000000000
--- a/wpiutil/src/main/java/org/wpilib/util/runtime/CombinedRuntimeLoader.java
+++ /dev/null
@@ -1,226 +0,0 @@
-// Copyright (c) FIRST and other WPILib contributors.
-// Open Source Software; you can modify and/or share it under the terms of
-// the WPILib BSD license file in the root directory of this project.
-
-package org.wpilib.util.runtime;
-
-import com.fasterxml.jackson.core.type.TypeReference;
-import com.fasterxml.jackson.databind.ObjectMapper;
-import java.io.File;
-import java.io.IOException;
-import java.nio.file.Files;
-import java.nio.file.Paths;
-import java.util.ArrayList;
-import java.util.HashMap;
-import java.util.List;
-import java.util.Map;
-import java.util.Objects;
-
-/** Loads dynamic libraries for all platforms. */
-public final class CombinedRuntimeLoader {
- private CombinedRuntimeLoader() {}
-
- private static String extractionDirectory;
-
- /**
- * Returns library extraction directory.
- *
- * @return Library extraction directory.
- */
- public static synchronized String getExtractionDirectory() {
- return extractionDirectory;
- }
-
- private static synchronized void setExtractionDirectory(String directory) {
- extractionDirectory = directory;
- }
-
- private static String defaultExtractionRoot;
-
- /**
- * Gets the default extraction root location (~/.wpilib/nativecache) for use if
- * setExtractionDirectory is not set.
- *
- * @return The default extraction root location.
- */
- public static synchronized String getDefaultExtractionRoot() {
- if (defaultExtractionRoot != null) {
- return defaultExtractionRoot;
- }
- String home = System.getProperty("user.home");
- defaultExtractionRoot = Paths.get(home, ".wpilib", "nativecache").toString();
- return defaultExtractionRoot;
- }
-
- /**
- * Returns platform path.
- *
- * @return The current platform path.
- * @throws IllegalStateException Thrown if the operating system is unknown.
- */
- public static String getPlatformPath() {
- String filePath;
- String arch = System.getProperty("os.arch");
-
- boolean intel32 = "x86".equals(arch) || "i386".equals(arch);
- boolean intel64 = "amd64".equals(arch) || "x86_64".equals(arch);
-
- if (System.getProperty("os.name").startsWith("Windows")) {
- if (intel32) {
- filePath = "/windows/x86/";
- } else {
- filePath = "/windows/x86-64/";
- }
- } else if (System.getProperty("os.name").startsWith("Mac")) {
- filePath = "/osx/universal/";
- } else if (System.getProperty("os.name").startsWith("Linux")) {
- if (intel32) {
- filePath = "/linux/x86/";
- } else if (intel64) {
- filePath = "/linux/x86-64/";
- } else if (new File("/usr/local/frc/bin/frcRunRobot.sh").exists()) {
- filePath = "/linux/athena/";
- } else if ("arm".equals(arch) || "arm32".equals(arch)) {
- filePath = "/linux/arm32/";
- } else if ("aarch64".equals(arch) || "arm64".equals(arch)) {
- filePath = "/linux/arm64/";
- } else {
- filePath = "/linux/nativearm/";
- }
- } else {
- throw new IllegalStateException();
- }
-
- return filePath;
- }
-
- private static String getLoadErrorMessage(String libraryName, UnsatisfiedLinkError ule) {
- StringBuilder msg = new StringBuilder(512);
- msg.append(libraryName)
- .append(" could not be loaded from path\n" + "\tattempted to load for platform ")
- .append(getPlatformPath())
- .append("\nLast Load Error: \n")
- .append(ule.getMessage())
- .append('\n');
- if (System.getProperty("os.name").startsWith("Windows")) {
- msg.append(
- "A common cause of this error is missing the C++ runtime.\n"
- + "Download the latest at https://support.microsoft.com/en-us/help/2977003/the-latest-supported-visual-c-downloads\n");
- }
- return msg.toString();
- }
-
- /**
- * Extract a list of native libraries.
- *
- * @param The class where the resources would be located
- * @param clazz The actual class object
- * @param resourceName The resource name on the classpath to use for file lookup
- * @return List of all libraries that were extracted
- * @throws IOException Thrown if resource not found or file could not be extracted
- */
- @SuppressWarnings("unchecked")
- public static List extractLibraries(Class clazz, String resourceName)
- throws IOException {
- TypeReference> typeRef = new TypeReference<>() {};
- ObjectMapper mapper = new ObjectMapper();
- Map map;
- try (var stream = clazz.getResourceAsStream(resourceName)) {
- map = mapper.readValue(stream, typeRef);
- }
-
- var platformPath = Paths.get(getPlatformPath());
- var platform = platformPath.getName(0).toString();
- var arch = platformPath.getName(1).toString();
-
- var platformMap = (Map>) map.get(platform);
-
- var fileList = platformMap.get(arch);
-
- var extractionPathString = getExtractionDirectory();
-
- if (extractionPathString == null) {
- String hash = (String) map.get("hash");
-
- var defaultExtractionRoot = getDefaultExtractionRoot();
- var extractionPath = Paths.get(defaultExtractionRoot, platform, arch, hash);
- extractionPathString = extractionPath.toString();
-
- setExtractionDirectory(extractionPathString);
- }
-
- List extractedFiles = new ArrayList<>();
-
- byte[] buffer = new byte[0x10000]; // 64K copy buffer
-
- for (var file : fileList) {
- try (var stream = clazz.getResourceAsStream(file)) {
- Objects.requireNonNull(stream);
-
- var outputFile = Paths.get(extractionPathString, new File(file).getName());
- extractedFiles.add(outputFile.toString());
- if (outputFile.toFile().exists()) {
- continue;
- }
- var parent = outputFile.getParent();
- if (parent == null) {
- throw new IOException("Output file has no parent");
- }
- parent.toFile().mkdirs();
-
- try (var os = Files.newOutputStream(outputFile)) {
- int readBytes;
- while ((readBytes = stream.read(buffer)) != -1) { // NOPMD
- os.write(buffer, 0, readBytes);
- }
- }
- }
- }
-
- return extractedFiles;
- }
-
- /**
- * Load a single library from a list of extracted files.
- *
- * @param libraryName The library name to load
- * @param extractedFiles The extracted files to search
- * @throws IOException If library was not found
- */
- public static void loadLibrary(String libraryName, List extractedFiles)
- throws IOException {
- String currentPath = null;
- try {
- for (var extractedFile : extractedFiles) {
- if (extractedFile.contains(libraryName)) {
- // Load it
- currentPath = extractedFile;
- System.load(extractedFile);
- return;
- }
- }
- throw new IOException("Could not find library " + libraryName);
- } catch (UnsatisfiedLinkError ule) {
- throw new IOException(getLoadErrorMessage(currentPath, ule));
- }
- }
-
- /**
- * Load a list of native libraries out of a single directory.
- *
- * @param The class where the resources would be located
- * @param clazz The actual class object
- * @param librariesToLoad List of libraries to load
- * @throws IOException Throws an IOException if not found
- */
- public static void loadLibraries(Class clazz, String... librariesToLoad)
- throws IOException {
- // Extract everything
-
- var extractedFiles = extractLibraries(clazz, "/ResourceInformation.json");
-
- for (var library : librariesToLoad) {
- loadLibrary(library, extractedFiles);
- }
- }
-}
diff --git a/wpiutil/src/main/java/org/wpilib/util/runtime/RuntimeDetector.java b/wpiutil/src/main/java/org/wpilib/util/runtime/RuntimeDetector.java
deleted file mode 100644
index ec6023e1c8..0000000000
--- a/wpiutil/src/main/java/org/wpilib/util/runtime/RuntimeDetector.java
+++ /dev/null
@@ -1,197 +0,0 @@
-// Copyright (c) FIRST and other WPILib contributors.
-// Open Source Software; you can modify and/or share it under the terms of
-// the WPILib BSD license file in the root directory of this project.
-
-package org.wpilib.util.runtime;
-
-import java.io.File;
-
-/**
- * A utility class for detecting and providing platform-specific such as OS and CPU architecture.
- *
- * @deprecated platform detection is brittle and may be removed in the future.
- */
-@Deprecated(since = "2025", forRemoval = true)
-public final class RuntimeDetector {
- private static String filePrefix;
- private static String fileExtension;
- private static String filePath;
-
- private static synchronized void computePlatform() {
- if (fileExtension != null && filePath != null && filePrefix != null) {
- return;
- }
-
- boolean intel32 = is32BitIntel();
- boolean intel64 = is64BitIntel();
- boolean arm64 = isArm64();
-
- if (isWindows()) {
- filePrefix = "";
- fileExtension = ".dll";
- if (intel32) {
- filePath = "/windows/x86/";
- } else {
- filePath = "/windows/x86-64/";
- }
- } else if (isMac()) {
- filePrefix = "lib";
- fileExtension = ".dylib";
- filePath = "/osx/universal/";
- } else if (isLinux()) {
- filePrefix = "lib";
- fileExtension = ".so";
- if (intel32) {
- filePath = "/linux/x86/";
- } else if (intel64) {
- filePath = "/linux/x86-64/";
- } else if (isAthena()) {
- filePath = "/linux/athena/";
- } else if (isArm32()) {
- filePath = "/linux/arm32/";
- } else if (arm64) {
- filePath = "/linux/arm64/";
- } else {
- filePath = "/linux/nativearm/";
- }
- } else {
- throw new IllegalStateException("Failed to determine OS");
- }
- }
-
- /**
- * Get the file prefix for the current system.
- *
- * @return The file prefix.
- */
- public static synchronized String getFilePrefix() {
- computePlatform();
-
- return filePrefix;
- }
-
- /**
- * Get the file extension for the current system.
- *
- * @return The file extension.
- */
- public static synchronized String getFileExtension() {
- computePlatform();
-
- return fileExtension;
- }
-
- /**
- * Get the platform path for the current system.
- *
- * @return The platform path.
- */
- public static synchronized String getPlatformPath() {
- computePlatform();
-
- return filePath;
- }
-
- /**
- * Get the path to the requested resource.
- *
- * @param libName Library name.
- * @return The path to the requested resource.
- */
- public static synchronized String getLibraryResource(String libName) {
- computePlatform();
-
- return filePath + filePrefix + libName + fileExtension;
- }
-
- /**
- * Get the path to the hash to the requested resource.
- *
- * @param libName Library name.
- * @return The path to the hash to the requested resource.
- */
- public static synchronized String getHashLibraryResource(String libName) {
- computePlatform();
-
- return filePath + libName + ".hash";
- }
-
- /**
- * Check if hardware platform is Athena.
- *
- * @return True if hardware platform is Athena.
- */
- public static boolean isAthena() {
- File runRobotFile = new File("/usr/local/frc/bin/frcRunRobot.sh");
- return runRobotFile.exists();
- }
-
- /**
- * Check if OS is Arm32.
- *
- * @return True if OS is Arm32.
- */
- public static boolean isArm32() {
- String arch = System.getProperty("os.arch");
- return "arm".equals(arch) || "arm32".equals(arch);
- }
-
- /**
- * Check if architecture is Arm64.
- *
- * @return if architecture is Arm64.
- */
- public static boolean isArm64() {
- String arch = System.getProperty("os.arch");
- return "aarch64".equals(arch) || "arm64".equals(arch);
- }
-
- /**
- * Check if OS is Linux.
- *
- * @return if OS is Linux.
- */
- public static boolean isLinux() {
- return System.getProperty("os.name").startsWith("Linux");
- }
-
- /**
- * Check if OS is Windows.
- *
- * @return if OS is Windows.
- */
- public static boolean isWindows() {
- return System.getProperty("os.name").startsWith("Windows");
- }
-
- /**
- * Check if OS is Mac.
- *
- * @return if OS is Mac.
- */
- public static boolean isMac() {
- return System.getProperty("os.name").startsWith("Mac");
- }
-
- /**
- * Check if OS is 32bit Intel.
- *
- * @return if OS is 32bit Intel.
- */
- public static boolean is32BitIntel() {
- String arch = System.getProperty("os.arch");
- return "x86".equals(arch) || "i386".equals(arch);
- }
-
- /**
- * Check if OS is 64bit Intel.
- *
- * @return if OS is 64bit Intel.
- */
- public static boolean is64BitIntel() {
- String arch = System.getProperty("os.arch");
- return "amd64".equals(arch) || "x86_64".equals(arch);
- }
-
- private RuntimeDetector() {}
-}
diff --git a/wpiutil/src/main/java/org/wpilib/util/runtime/RuntimeLoader.java b/wpiutil/src/main/java/org/wpilib/util/runtime/RuntimeLoader.java
index 7b04fa81b7..1d21aacb5f 100644
--- a/wpiutil/src/main/java/org/wpilib/util/runtime/RuntimeLoader.java
+++ b/wpiutil/src/main/java/org/wpilib/util/runtime/RuntimeLoader.java
@@ -8,6 +8,42 @@ import java.io.IOException;
/** Loads a native library at runtime. */
public final class RuntimeLoader {
+ /**
+ * Returns platform name.
+ *
+ * @return The current platform name.
+ * @throws IllegalStateException Thrown if the operating system is unknown.
+ */
+ public static String getPlatformName() {
+ String arch = System.getProperty("os.arch");
+
+ boolean intel64 = "amd64".equals(arch) || "x86_64".equals(arch);
+ boolean arm64 = "aarch64".equals(arch) || "arm64".equals(arch);
+
+ if (intel64) {
+ arch = "x86_64";
+ } else if (arm64) {
+ arch = "arm64";
+ } else {
+ throw new IllegalStateException("Unsupported architecture: " + arch);
+ }
+
+ String osName = System.getProperty("os.name");
+
+ if (osName.startsWith("Windows")) {
+ osName = "windows";
+ } else if (osName.startsWith("Mac")) {
+ osName = "osx";
+ arch = "universal";
+ } else if (osName.startsWith("Linux")) {
+ osName = "linux";
+ } else {
+ throw new IllegalStateException("Unsupported operating system: " + osName);
+ }
+
+ return osName + "-" + arch;
+ }
+
/**
* Returns a load error message given the information in the provided UnsatisfiedLinkError.
*
@@ -20,7 +56,7 @@ public final class RuntimeLoader {
StringBuilder msg = new StringBuilder(512);
msg.append(libraryName)
.append(" could not be loaded from path.\n" + "\tattempted to load for platform ")
- .append(CombinedRuntimeLoader.getPlatformPath())
+ .append(getPlatformName())
.append("\nLast Load Error: \n")
.append(ule.getMessage())
.append('\n')
diff --git a/xrpVendordep/src/dev/java/org/wpilib/xrp/DevMain.java b/xrpVendordep/src/dev/java/org/wpilib/xrp/DevMain.java
index 4320336fb8..a4ae5164c0 100644
--- a/xrpVendordep/src/dev/java/org/wpilib/xrp/DevMain.java
+++ b/xrpVendordep/src/dev/java/org/wpilib/xrp/DevMain.java
@@ -6,13 +6,13 @@ package org.wpilib.xrp;
import org.wpilib.hardware.hal.HALUtil;
import org.wpilib.networktables.NetworkTablesJNI;
-import org.wpilib.util.runtime.CombinedRuntimeLoader;
+import org.wpilib.util.runtime.RuntimeLoader;
public final class DevMain {
/** Main entry point. */
public static void main(String[] args) {
System.out.println("Hello World!");
- System.out.println(CombinedRuntimeLoader.getPlatformPath());
+ System.out.println(RuntimeLoader.getPlatformName());
System.out.println(NetworkTablesJNI.now());
System.out.println(HALUtil.getHALRuntimeType());
}