reflection - 将文件路径反映到源目录或 jar 时找不到 Kotlin 类
问题描述
===更新:使用 org.reflections:reflections:0.9.11
希望使用以下行从 Kotlin 源中提取类名列表...
Reflections.getSubTypesOf(Any::class.java)
但是,当我运行以下脚本时,我收到一条消息说没有看到 Kotlin 类文件...
val classLoader = URLClassLoader(this.getDirectoryUrls(), null)
println("retrieved class loader")
val config = getConfig(classLoader)
println("retrieved source config")
val reflections = Reflections(config)
println("retrieved reflections")
// For 3 paths: Reflections took 3 ms to scan 3 urls, producing 0 keys and 0 values
=== 更新:“getDirectoryUrls()”添加的 3 个 url 是包含 kotlin 类源文件的目录。
以下是我的配置...想法?
private fun getConfig(classLoader: ClassLoader): ConfigurationBuilder {
val config = ConfigurationBuilder().setUrls(ClasspathHelper.forClassLoader(classLoader))
// .setScanners(SubTypesScanner(false), ResourcesScanner())
if (!packagePath.isNullOrBlank()){
System.out.println("looking in package [$packagePath]")
config.filterInputsBy(FilterBuilder().include(FilterBuilder.prefix(packagePath)))
}
config.addClassLoader(classLoader)
config.setScanners(SubTypesScanner(), TypeAnnotationsScanner())
return config
}
解决方案
SubTypesScanner(false)
似乎需要设置才能获得任何类型getSubTypesOf(Any::class.java)
(该参数本身代表excludeObjectClass
)。查看 Kotlin 类的字节码,您会立即看到,它们实际上看起来与 Java 类相同。那里没有Any
-superclass。请注意,KotlinsAny
实际上在其他方面也与 Java 非常相似Object
(但不一样,请检查以下对 'does Any == Object' 的答案)。因此,我们需要在扫描(ie )Object
的子类型时包含 -class 。Any
excludeObjectClass=false
另一个问题可能是您的URL
阵列的设置。我只是使用以下设置反射工具:
val reflections = Reflections(ConfigurationBuilder()
.addUrls(ClasspathHelper.forPackage("my.test.package"))
.setScanners(TypeAnnotationsScanner(), SubTypesScanner(false)))
这将解析所有匹配的子类型,并将返回子类型也为Any
.
reflections.getSubTypesOf(MyCustomSuperType::class.java).forEach(::println)
reflections.getSubTypesOf(Any::class.java).forEach(::println)
进一步分析:您提到“Kotlin 类源文件”......如果这意味着您指向包含.kt
-files 的目录,那么这可能是您的问题。尝试使用包含.class
-files 的目录。此外,确保类在类路径上。
也许你已经知道了,也许还没有?另请注意,如果您有一个(类)目录,比如说/sample/directory
,它在类路径上并且包含一个包,比如说org.example
(对应于文件夹结构org/example
或完整路径/sample/directory/org/example
),那么您必须确保添加URL
类似于以下内容:
YourClass::class.java.classLoader.getResource("")
并不是:
YourClass::class.java.classLoader.getResource("org.example")
// nor:
YourClass::class.java.classLoader.getResource("org/example")
您基本上需要“基本”目录(在示例中/sample/directory
或仅从类加载器的视图中""
))在其中查找包而不是包本身。如果您提供后者之一,则实际上只会找到URL
默认包(在 内/sample/directory/org/example
)中的类,但这是一种相当不常见的设置。
推荐阅读
- r - 从R中的列表列创建单列向量
- python-3.x - Python 子进程太多?
- python - 如何将这个“学生级”代码压缩成循环?
- c# - 将配置文件中的连接字符串注入 EF Core DbContext
- java - 在访问值之前调用“Optional#isPresent()
- python - secp256k1 及其依赖项作为一个包
- python - 在python中获取json/字典中的所有键路径组合
- r - 自定义数据集/列表中的帧
- angular - Angular 7 & Angular Material - 验证器未显示 MinLength 错误
- python - Pyftdi - ValueError:没有可用的后端。是否有任何解决此错误的故障排除有关 Windows 10 的问题?