略微展开来说,枚举classpath的原因不直接,这是因为Java从来没有定义过一种受支持的枚举方式。
系统类加载器通常加载java.class.path
系统属性上找到的依赖项,但它只保证是ClassLoader
类型,这是不可枚举的。
在Java 9之前,可以通过依赖实现细节来枚举系统类加载器:它会可靠地返回一个URLClassLoader
,它有一个getURLs
方法。然而,这并不是官方文档化的行为。
从Java 9开始,系统类加载器的实现已被更改为一个不可枚举的内部类。
直接使用java.class.path
系统属性,是基于对运行时行为的特定假设,而不是检查实际行为的结果。在很多情况下,这个假设是成立的,但也会在其他情况下失败。
理想的解决方案是找到一个可以枚举Java 9+中系统(以及可能平台)类加载器加载的资源的方法,以便整个classpath层次结构可以枚举。
如果没有这个,依靠java.class.path
属性对Java 9+来说可能是必要的。如果是这样,次优解决方案应至少考虑到两种特定情况:
- 应用程序可能在一个容器中运行,
- 动态类加载器可能会在运行时添加资源。