应该 ClassPath.getTopLevelClasses() return `java.*` 包吗?
Should ClassPath.getTopLevelClasses() return `java.*` packages?
我正在使用 guava 的 ClassPath 来检索可用的 类。使用 Java 8 时,效果很好,但我正在迁移到 Java 10,现在它不起作用了。我已经尝试过 guava 24.1(Maven Central 上最新的 jarfile)和 github 上的最新资源(截至 2018 年 4 月 27 日)——大概或多或少是 guava 25.0,因为他们昨天发布了它。
我可以检索一些 类,但任何 java.*
包中的任何内容都无法显示。这实际上是一个错误,还是我使用 Java 10 错误(即,模块化是否意味着我需要做一些特别的事情)?我在 Java 9 中看到相同的症状。我已经尝试构建 运行 Java 10(或 9)以及构建 Java 8 和 运行 Java 10(或 9),两种方式的行为都相同。
我在包 com.just.me
和 com.just.another
:
中设置了一个包含两个 类 的虚拟示例
com.just.me.Main.java
package com.just.me;
import com.google.common.reflect.ClassPath;
import com.just.another.Dummy;
import java.lang.String;
import java.util.Collections;
import java.util.List;
import java.io.IOException;
public class Main {
public static void main(String[] args) {
List<String> dummyList = Collections.emptyList();
printClassCount("com.just.me", Main.class);
printClassCount("com.just.another", Main.class);
printClassCount("com.just", Main.class);
printClassCount("com.google", Main.class);
printClassCount("java.lang", Main.class);
printClassCount("java.util", Main.class);
printClassCount("java", Main.class);
}
private static void printClassCount(String packageName, Class classForClassLoader) {
System.out.println("Number of toplevel classes in " + packageName + ": " + countTopleveClassesInPackage(packageName, classForClassLoader));
}
private static int countTopleveClassesInPackage(String packageName, Class clazz) {
try {
ClassPath classPath = ClassPath.from(clazz.getClassLoader());
return classPath.getTopLevelClassesRecursive(packageName).size();
} catch (IOException e) {
return 0;
}
}
}
com.just.another.Dummy.java
package com.just.another;
public class Dummy {
private String s;
Dummy(String s) {
this.s = s;
}
@Override
public String toString() {
return s;
}
}
输出(Java8)
Number of toplevel classes in com.just.me: 1
Number of toplevel classes in com.just.another: 1
Number of toplevel classes in com.just: 2
Number of toplevel classes in com.google: 569
Number of toplevel classes in java.lang: 232
Number of toplevel classes in java.util: 367
Number of toplevel classes in java: 1878
输出 (Java 9/10)
Number of toplevel classes in com.just.me: 1
Number of toplevel classes in com.just.another: 1
Number of toplevel classes in com.just: 2
Number of toplevel classes in com.google: 569
Number of toplevel classes in java.lang: 0
Number of toplevel classes in java.util: 0
Number of toplevel classes in java: 0
我认为,ClassPath
中没有错误。它表示类路径,但系统 类 不在 Java 10:
中的类路径中
// doesn't print rt.jar because there is no rt.jar anymore
System.out.println(StandardSystemProperty.JAVA_CLASS_PATH.value());
所以这是正确的行为,getTopLevelClasses
不会 return java.*
包的任何 类。
如果您仍想列出顶级系统 类,您可以这样做(不是确切的代码,只是一个草图):
FileSystem fs = FileSystems.getFileSystem(URI.create("jrt:/"));
Files
.list(fs.getPath("modules", "java.base", "java/lang"))
.map(Path::getFileName)
.filter(p -> p.toString().endsWith(".class") && !p.toString().contains("$"))
.forEach(System.out::println);
我正在使用 guava 的 ClassPath 来检索可用的 类。使用 Java 8 时,效果很好,但我正在迁移到 Java 10,现在它不起作用了。我已经尝试过 guava 24.1(Maven Central 上最新的 jarfile)和 github 上的最新资源(截至 2018 年 4 月 27 日)——大概或多或少是 guava 25.0,因为他们昨天发布了它。
我可以检索一些 类,但任何 java.*
包中的任何内容都无法显示。这实际上是一个错误,还是我使用 Java 10 错误(即,模块化是否意味着我需要做一些特别的事情)?我在 Java 9 中看到相同的症状。我已经尝试构建 运行 Java 10(或 9)以及构建 Java 8 和 运行 Java 10(或 9),两种方式的行为都相同。
我在包 com.just.me
和 com.just.another
:
com.just.me.Main.java
package com.just.me;
import com.google.common.reflect.ClassPath;
import com.just.another.Dummy;
import java.lang.String;
import java.util.Collections;
import java.util.List;
import java.io.IOException;
public class Main {
public static void main(String[] args) {
List<String> dummyList = Collections.emptyList();
printClassCount("com.just.me", Main.class);
printClassCount("com.just.another", Main.class);
printClassCount("com.just", Main.class);
printClassCount("com.google", Main.class);
printClassCount("java.lang", Main.class);
printClassCount("java.util", Main.class);
printClassCount("java", Main.class);
}
private static void printClassCount(String packageName, Class classForClassLoader) {
System.out.println("Number of toplevel classes in " + packageName + ": " + countTopleveClassesInPackage(packageName, classForClassLoader));
}
private static int countTopleveClassesInPackage(String packageName, Class clazz) {
try {
ClassPath classPath = ClassPath.from(clazz.getClassLoader());
return classPath.getTopLevelClassesRecursive(packageName).size();
} catch (IOException e) {
return 0;
}
}
}
com.just.another.Dummy.java
package com.just.another;
public class Dummy {
private String s;
Dummy(String s) {
this.s = s;
}
@Override
public String toString() {
return s;
}
}
输出(Java8)
Number of toplevel classes in com.just.me: 1
Number of toplevel classes in com.just.another: 1
Number of toplevel classes in com.just: 2
Number of toplevel classes in com.google: 569
Number of toplevel classes in java.lang: 232
Number of toplevel classes in java.util: 367
Number of toplevel classes in java: 1878
输出 (Java 9/10)
Number of toplevel classes in com.just.me: 1
Number of toplevel classes in com.just.another: 1
Number of toplevel classes in com.just: 2
Number of toplevel classes in com.google: 569
Number of toplevel classes in java.lang: 0
Number of toplevel classes in java.util: 0
Number of toplevel classes in java: 0
我认为,ClassPath
中没有错误。它表示类路径,但系统 类 不在 Java 10:
// doesn't print rt.jar because there is no rt.jar anymore
System.out.println(StandardSystemProperty.JAVA_CLASS_PATH.value());
所以这是正确的行为,getTopLevelClasses
不会 return java.*
包的任何 类。
如果您仍想列出顶级系统 类,您可以这样做(不是确切的代码,只是一个草图):
FileSystem fs = FileSystems.getFileSystem(URI.create("jrt:/"));
Files
.list(fs.getPath("modules", "java.base", "java/lang"))
.map(Path::getFileName)
.filter(p -> p.toString().endsWith(".class") && !p.toString().contains("$"))
.forEach(System.out::println);