稍作扩展,列举classpath的主要原因是Java从未定义一种受支持的列举方式。
系统类加载器通常加载在系统属性java.class.path
上找到的依赖项,但有保证它的类型是ClassLoader
,而这不能被列举。
直到Java 9,可以通过依赖实现细节来列举系统类加载器:它会可靠地返回一个URLClassLoader
,它有一个getURLs
方法。然而,这是一种未记录的行为。
从Java 9开始,系统类加载器实现改为一个不可枚举的内部类。
直接使用系统属性java.class.path
隐含了某种运行时行为,而不是检查实际行为的结果。这个假设在许多情况下是成立的,但在其他情况下可能失败。
理想解决方案是一个能在Java 9+上工作,并且能列举系统类加载器和(可能)平台类加载器加载的资源的方式,以便整个classpath层次结构都可以被列举。
如果没有这个解决方案,对于Java 9+,可能需要依赖于java.class.path
属性。如果是这样的话,最佳替代方案应该至少能够解决以下两个特定情况
- 应用程序可能在一个容器中运行,
- 动态类加载器可能在运行时添加资源。