Как мне подтвердить, что в моей структуре ClassLoader нет повторяющихся классов? - PullRequest
1 голос
/ 12 июня 2019

Я использую GroovyClassLoader для загрузки нескольких файлов groovy (не скриптов), которые имеют имена классов и структуры пакетов.Я полагаю, что сталкиваюсь с проблемой загрузки нескольких файлов Class для одного и того же Class, несмотря на то, что parseClass вызывается только один раз для каждого файла на основе этого типа сообщения об ошибке:

org.codehaus.groovy.runtime.typehandling.GroovyCastException: Невозможно привести объект 'TickIt.Pizza@3eea9be9' с классом 'TickIt.Pizza' к классу 'TickIt.Pizza'

Кроме того, у меня есть несколько случаев, когда я использую статический установщик для хранения переменной,и неявный вызов класса, кажется, указывает на наличие дополнительных копий класса, поскольку после установки переменной я могу ссылаться на нее, и она кажется пустой.

Я провел небольшой тест, чтобы попытаться доказать проблемуи, похоже, это указывает на то, что действительно загружено несколько классов.Найдя соответствующий класс в загруженных классах на моем GroovyClassLoader, я могу сравнить с неявным классом.Для моего класса DockingBay у меня есть статическая карта, называемая челноками.Загруженный класс 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.Кажется, нет.Я заметил, что сравнение classLoaders классов показывает, что они разные (но непротиворечивые) InnerLoaders.Почему?

...