我正在使用 GroovyClassLoader 加载多个具有类名和包结构的 groovy 文件(不是脚本)。我相信我遇到了为同一个类加载多个类文件的问题,尽管基于这种类型的错误消息,每个文件只调用一次 parseClass:
org.codehaus.groovy.runtime.typehandling.GroovyCastException:无法将具有类“TickIt.Pizza”的对象“TickIt.Pizza@3eea9be9”转换为类“TickIt.Pizza”
此外,我在某些情况下使用静态设置器来存储变量,并且隐式调用 Class 似乎表明存在 Class 的其他副本,因为在设置变量后我可以引用它并且它似乎是空的。
我做了一个小测试来试图证明这个问题,它似乎表明确实加载了多个类。通过在我的 GroovyClassLoader 上的加载类中找到匹配的类,我可以与隐式类进行比较。对于我的 DockingBay 类,我有一个名为班车的静态地图。已加载的 DockingBay 类具有值,但隐式调用 Dockingbay.shuttle 是空的。见下文:
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 中的同一个类。看来我不是。我注意到比较类的类加载器表明它们是不同的(但一致的)内部加载器。为什么?