ClassPath.getTopLevelClasses()应该返回`java.*`包吗?

rai*_*lin 5 java guava java-9 java-10

我正在使用guava的ClassPath来检索可用的类.使用Java 8,这很好用,但我正在迁移到Java 10,现在它不起作用.我已经尝试了guava 24.1(Maven Central上可用的最新jar文件)和github上的最新资源(截至2018年4月27日) - 大概是或多或少的番石榴25.0,因为他们昨天发布了它.

我可以检索一些类,但任何java.*包中的任何内容都无法显示.这实际上是一个错误,还是我使用Java 10错误(即模块化意味着我需要做一些特别的事情)?我在Java 9中看到了相同的症状.我尝试使用Java 10(或9)构建和运行以及使用Java 8构建并使用Java 10(或9)运行,这两种行为都是相同的.

我已经建立了一个虚拟的例子,在封装两个类com.just.mecom.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;
        }
    }
}
Run Code Online (Sandbox Code Playgroud)

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;
    }
}
Run Code Online (Sandbox Code Playgroud)

输出(Java 8)

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
Run Code Online (Sandbox Code Playgroud)

输出(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
Run Code Online (Sandbox Code Playgroud)

Zhe*_*lov 1

我认为,没有任何错误ClassPath。它代表一个类路径,但系统类不在 Java 10 中的类路径上:

// doesn't print rt.jar because there is no rt.jar anymore
System.out.println(StandardSystemProperty.JAVA_CLASS_PATH.value());
Run Code Online (Sandbox Code Playgroud)

所以这是正确的行为,getTopLevelClasses不会返回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);
Run Code Online (Sandbox Code Playgroud)