将文件路径反映到源目录或jar时找不到Kotlin类

时间:2018-08-11 02:12:11

标签: reflection jar kotlin classloader

===更新:使用org.reflections:reflections:0.9.11

希望使用以下行从Kotlin源中提取类名称列表...

MATCH (c:Campaign{campaign_id:98}), (s:Sample{sample_id:2000005}), (a:DemographicAudience{audience_id:2}), (ng:NetworkGroup{network_group_id:2})
WITH c,s,a,ng 
LIMIT 1
MATCH (c)<-[:PART_OF]-(sa)
    , (sa)-[:AIRED_ON]->(n)
    , (n)-[:BELONGS_TO]->(ng)
    , (sa)<-[:EXPOSED_WITH]-(e)
    , (e)<-[se:CONTAINS_ENTITY]-(s)
    , (e)-[:MEMBER_OF]->(a)
WITH c, a, s, n, count(distinct sa) as `spot_airings`, sum(se.weight) as `spot_impressions`
RETURN c.campaign_id as `campaign_id`
    , a.audience_id as `audience_id`
    , a.audience_name as `audience_name`
    , s.sample_id as `sample_id`
    , n.network_id as `network_id`
    , n.network_name as `network_name`
    , n.network_call_sign as `network_call_sign`
    , `spot_airings`
    , `spot_impressions`

但是,当我运行以下脚本时,我收到一条消息,提示未显示Kotlin类文件...

Reflections.getSubTypesOf(Any::class.java)

===更新:“ getDirectoryUrls()”添加的3个url是包含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

1 个答案:

答案 0 :(得分:0)

似乎需要设置SubTypesScanner(false)才能使用getSubTypesOf(Any::class.java)获得任何类型(该参数本身代表excludeObjectClass)。查看立即看到的Kotlin类的字节码,它们实际上看起来与Java类相同。那里没有Any-超类。请注意,Kotlins Any实际上在其他方面也与Javas Object非常相似(但不相同,请同时检查以下answer to 'does Any == Object')。因此,在扫描Object的子类型(即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)

进一步分析:您提到“科特林类 文件” ...如果这意味着您指向的是包含.kt文件的目录,那可能是你的问题。尝试使用包含.class文件的目录。此外,确保类在类路径上。

也许您已经知道,也许还不知道?还要注意,如果您有一个{classes}目录,例如/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内)中的类,但这是相当不常见的设置。