如何确认我的ClassLoader结构中没有重复的类?

时间:2019-06-12 02:52:35

标签: java groovy groovyclassloader

我正在使用GroovyClassLoader加载具有类名和包结构的多个groovy文件(不是脚本)。我相信我遇到了一个问题,即为同一个类加载了多个类文件,尽管基于这种错误消息,每个文件只调用一次parseClass:

org.codehaus.groovy.runtime.type.handling.GroovyCastException:无法将类为“ TickIt.Pizza”的对象“ TickIt.Pizza@3eea9be9”转换为类“ TickIt.Pizza”

此外,在某些情况下,我使用静态设置器来存储变量,并且隐式调用Class似乎表明Class的其他副本,因为在设置变量后我可以引用该变量,并且它似乎为空

我已经做了一个小测试以尝试证明问题,并且似乎表明确实有多个类加载。通过在GroovyClassLoader的loadedClasses中找到匹配的Class,我可以将其与隐式Class进行比较。对于我的DockingBay类,我有一个称为Shuttles的静态地图。已加载的DockingBay类具有价值,但隐式调用Dockingbay.shuttles却为空。见下文:

DockingBay:   ${ DockingBay.classLoader } <br>
              ${ DockingBay.shuttles } <br>
Loaded:       ${ PartsStore.groovyClassLoader.loadedClasses[28].classLoader } <br>
              ${ PartsStore.groovyClassLoader.loadedClasses[28].shuttles }<br>

Are they the same?: ${ PartsStore.groovyClassLoader.loadedClasses.contains(DockingBay) }

输出:

DockingBay: groovy.lang.GroovyClassLoader$InnerLoader@6bc407fd 
[:] 
Loaded: groovy.lang.GroovyClassLoader$InnerLoader@4b79ac84 
[class hudelements.HudElements:hudelements.HudElements@4f936da8, class TickIt.PizzaShop:TickIt.PizzaShop@e041f0c, class calc.Calc:calc.Calc@6a175569, class monitor.Monitor:monitor.Monitor@69c79f09]

Are they the same?: false

这是将代码加载到GroovyClassLoader的代码,我将其称为PartsStore。

boolean hasLoaded = false
GroovyClassLoader groovyClassLoader
loadedClasses = []

public scan() {

    if (hasLoaded) { 
        println('Purging groovyClassLoader Meta.')
        for (def clazz in groovyClassLoader.loadedClasses)
            GroovySystem.getMetaClassRegistry().removeMetaClass(clazz)

        println('Clearing groovyClassLoader Cache.')
        groovyClassLoader.clearCache()

    } else {
        println('Creating new groovyClassLoader.')
        groovyClassLoader = new GroovyClassLoader(Spaceport.class)
    }

    hasLoaded = true

    for (String path in Spaceport.config.modules.'class paths') {
        File dir = new File(path)
        groovyClassLoader.addClasspath(dir.getAbsolutePath())
    }

    def errors = false

    for (String path in Spaceport.config.modules.'include paths') {
        // Get directory listing
        println('+ -> ' + path)
        File[] directoryListing = FileUtils.listFiles(new File(path), null, false)
        // Load all .groovy files
        if (directoryListing != null) {
            for (File child : directoryListing) {
                if (FilenameUtils.getExtension(child.getName()) == 'groovy') {
                    try {
                        println 'Loading include "' + child + '"'
                        groovyClassLoader.parseClass(child))
                    } catch (Exception e) {
                        errors = true
                        e.printStackTrace()
                    }
                }
            }
        }
    }
}

无论我从哪里调用我的类DockingBay(只要它被加载在同一GroovyClassLoader上),我都希望得到与在ClassLoader中加载的相同的类。看来我不是。我注意到比较这些类的classLoader显示它们是不同的(但一致的)InnerLoader。为什么?

0 个答案:

没有答案