From 745af894066747f6bc4d9b2ea751e267832bc93b Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=E6=B2=88=E8=8B=B1=E5=8D=97?= <1799833473qq@gmail.com> Date: Fri, 31 Jul 2026 19:12:08 +0800 Subject: [PATCH 1/2] Add native library check and update bootclasspath Added a method to check for native library file names and updated bootclasspath handling to exclude native libraries. --- .../jdt/internal/compiler/util/Util.java | 74 ++++++++++++++++++- 1 file changed, 72 insertions(+), 2 deletions(-) diff --git a/org.eclipse.jdt.core.compiler.batch/src/org/eclipse/jdt/internal/compiler/util/Util.java b/org.eclipse.jdt.core.compiler.batch/src/org/eclipse/jdt/internal/compiler/util/Util.java index 2a4f458a68b..f4c5b07892e 100644 --- a/org.eclipse.jdt.core.compiler.batch/src/org/eclipse/jdt/internal/compiler/util/Util.java +++ b/org.eclipse.jdt.core.compiler.batch/src/org/eclipse/jdt/internal/compiler/util/Util.java @@ -668,6 +668,9 @@ public final static boolean isPotentialZipArchive(String name) { } return false; // it is a ".class" file, it cannot be a zip archive name } + if (isNativeLibrary(name)) { + return false; + } return true; // it is neither a ".java" file nor a ".class" file, so this is a potential archive name } @@ -705,6 +708,9 @@ public final static int archiveFormat(String name) { } return -1; // it is a ".class" file, it cannot be a zip archive name } + if (isNativeLibrary(name)) { + return -1; + } if (extensionLength == EXTENSION_jmod.length()) { for (int i = extensionLength-1; i >=0; i--) { if (Character.toLowerCase(name.charAt(length - extensionLength + i)) != EXTENSION_jmod.charAt(i)) { @@ -720,6 +726,61 @@ public final static int archiveFormat(String name) { * Returns true iff str.toLowerCase().endsWith(".class") * implementation is not creating extra strings. */ + /** + * Returns whether the given name is a native library file name + * (.so, .dll, .dylib). + *

+ * The name may be a simple file name, a file system path, or a jar entry + * path. Comparison is done character-by-character to avoid extra string + * allocations, consistent with {@link #isClassFileName}. + *

+ *

+ * This check prevents native libraries from being misclassified as ZIP/JMOD + * archives or from being added to the bootclasspath. + * See issue 5253. + *

+ * + * @param name the file name or path to check; must not be {@code null} + * @return {@code true} if the name ends with a native library extension + */ + private static boolean isNativeLibrary(String name) { + int lastDot = name.lastIndexOf('.'); + if (lastDot == -1) + return false; + // Reject if the last dot belongs to a directory segment rather than + // a file extension (e.g. "some.dir/file.so" is still valid because + // the separator is before the last dot, but "dir.so/file" is not). + // On Android/Linux File.separatorChar is '/', so jar-style paths are + // handled correctly for the primary target platform. + if (name.lastIndexOf(File.separatorChar) > lastDot) + return false; + int length = name.length(); + int extensionLength = length - lastDot - 1; + if (extensionLength == 2) { // .so + if ((name.charAt(length - 2) == 's' || name.charAt(length - 2) == 'S') + && (name.charAt(length - 1) == 'o' || name.charAt(length - 1) == 'O')) { + return true; + } + } + if (extensionLength == 3) { // .dll + if ((name.charAt(length - 3) == 'd' || name.charAt(length - 3) == 'D') + && (name.charAt(length - 2) == 'l' || name.charAt(length - 2) == 'L') + && (name.charAt(length - 1) == 'l' || name.charAt(length - 1) == 'L')) { + return true; + } + } + if (extensionLength == 5) { // .dylib + if ((name.charAt(length - 5) == 'd' || name.charAt(length - 5) == 'D') + && (name.charAt(length - 4) == 'y' || name.charAt(length - 4) == 'Y') + && (name.charAt(length - 3) == 'l' || name.charAt(length - 3) == 'L') + && (name.charAt(length - 2) == 'i' || name.charAt(length - 2) == 'I') + && (name.charAt(length - 1) == 'b' || name.charAt(length - 1) == 'B')) { + return true; + } + } + return false; + } + public final static boolean isClassFileName(char[] name) { int nameLength = name == null ? 0 : name.length; int suffixLength = SUFFIX_CLASS.length; @@ -1101,7 +1162,12 @@ public static List collectPlatformLibraries(File javaHome) if ((bootclasspathProperty != null) && (bootclasspathProperty.length() != 0)) { StringTokenizer tokenizer = new StringTokenizer(bootclasspathProperty, File.pathSeparator); while (tokenizer.hasMoreTokens()) { - filePaths.add(tokenizer.nextToken()); + String path = tokenizer.nextToken(); + // Exclude native libraries (.so, .dll, .dylib) from the bootclasspath. + // See https://github.com/eclipse-jdt/eclipse.jdt.core/issues/5253 + if (!isNativeLibrary(path)) { + filePaths.add(path); + } } } else { // try to get all jars inside the lib folder of the java home @@ -1125,7 +1191,11 @@ public static List collectPlatformLibraries(File javaHome) for (File[] current : systemLibrariesJars) { if (current != null) { for (File file : current) { - filePaths.add(file.getAbsolutePath()); + // Exclude native libraries (.so, .dll, .dylib) from the bootclasspath. + // See https://github.com/eclipse-jdt/eclipse.jdt.core/issues/5253 + if (!isNativeLibrary(file.getAbsolutePath())) { + filePaths.add(file.getAbsolutePath()); + } } } } From 9afe5834376a2f570945c9c3cfa60f2e3c9c1fb8 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=E6=B2=88=E8=8B=B1=E5=8D=97?= <1799833473qq@gmail.com> Date: Sat, 1 Aug 2026 17:51:36 +0800 Subject: [PATCH 2/2] Potential fix for pull request finding Store the result of file.getAbsolutePath() in a local variable to avoid redundant calls, as suggested by Copilot review. Co-authored-by: Copilot Autofix powered by AI <175728472+Copilot@users.noreply.github.com> --- .../org/eclipse/jdt/internal/compiler/util/Util.java | 11 ++++++----- 1 file changed, 6 insertions(+), 5 deletions(-) diff --git a/org.eclipse.jdt.core.compiler.batch/src/org/eclipse/jdt/internal/compiler/util/Util.java b/org.eclipse.jdt.core.compiler.batch/src/org/eclipse/jdt/internal/compiler/util/Util.java index f4c5b07892e..0cb25517429 100644 --- a/org.eclipse.jdt.core.compiler.batch/src/org/eclipse/jdt/internal/compiler/util/Util.java +++ b/org.eclipse.jdt.core.compiler.batch/src/org/eclipse/jdt/internal/compiler/util/Util.java @@ -1191,11 +1191,12 @@ public static List collectPlatformLibraries(File javaHome) for (File[] current : systemLibrariesJars) { if (current != null) { for (File file : current) { - // Exclude native libraries (.so, .dll, .dylib) from the bootclasspath. - // See https://github.com/eclipse-jdt/eclipse.jdt.core/issues/5253 - if (!isNativeLibrary(file.getAbsolutePath())) { - filePaths.add(file.getAbsolutePath()); - } + // Exclude native libraries (.so, .dll, .dylib) from the bootclasspath. + // See https://github.com/eclipse-jdt/eclipse.jdt.core/issues/5253 + String absolutePath = file.getAbsolutePath(); + if (!isNativeLibrary(absolutePath)) { + filePaths.add(absolutePath); + } } } }