CompilingClassLoader забавно, есть идеи, как в этом случае дочерний класс загружается из другого загрузчика классов?

createController в строке 29 в приведенной ниже трассировке стека имеет clazz.getClasslo

protected Object createController(Injector injector, String controllerClassFullName) {
    Class<?> clazz = classLoader.clazzForName(controllerClassFullName);
    return injector.getInstance(clazz); //line 29!!!!
}

loadClass online 521 загружает класс конструктора вышеуказанной переменной clazz, НО не загружает из CompilingClassLoader. Как-то пропускает. В конструкторе есть ТРИ параметра, все они загружаются из CompilingClassLoader, кроме последнего :(

Вот конструктор, о котором я говорю (вы можете видеть, как он вызывает getDeclaredConstructors в трассировке стека)

@Inject
public CustomerController(
        HashCreator hashCreator,
        TokenGenerator tokenGenerator,
        DataClientProxy clientProxy
) {
    this.hashCreator = hashCreator;
    this.tokenGenerator = tokenGenerator;
    this.clientProxy = clientProxy;
}

Наконец, вот трассировка стека

loadClass:521, ClassLoader (java.lang)
getDeclaredConstructors0:-1, Class (java.lang)
privateGetDeclaredConstructors:3137, Class (java.lang)
getDeclaredConstructors:2357, Class (java.lang)
forConstructorOf:245, InjectionPoint (com.google.inject.spi)
create:115, ConstructorBindingImpl (com.google.inject.internal)
createUninitializedBinding:706, InjectorImpl (com.google.inject.internal)
createJustInTimeBinding:930, InjectorImpl (com.google.inject.internal)
createJustInTimeBindingRecursive:852, InjectorImpl (com.google.inject.internal)
getJustInTimeBinding:291, InjectorImpl (com.google.inject.internal)
getBindingOrThrow:222, InjectorImpl (com.google.inject.internal)
getProviderOrThrow:1040, InjectorImpl (com.google.inject.internal)
getProvider:1071, InjectorImpl (com.google.inject.internal)
getProvider:1034, InjectorImpl (com.google.inject.internal)
getInstance:1086, InjectorImpl (com.google.inject.internal)
createController:29, DevLoader (org.webpieces.devrouter.impl)

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

(Я пытаюсь исправить это, так как по какой-то причине в CompilingClassLoader отсутствует загрузка этого класса, что вызывает очень забавную ситуацию, например существование ДВУХ объектов DataApi.class, загруженных разными загрузчиками классов).

Хммм, копаясь дальше, я обнаружил, что могу вызывать clazz.getMethods(), НО когда я вызываю clazz.getDeclaredConstructors(), я получаю ClassCircularityError. Самое смешное, что ни CustomerController, ни DataClientProxy никого не расширяют, так что это действительно странно.

Дин


person Dean Hiller    schedule 28.05.2020    source источник
comment
Контейнер, вероятно, имеет свой собственный загрузчик классов, и внедрение контейнера находится где-то в спектре магии, поэтому он может делать все, что хочет, однако… какое вам дело? Единственная разница, которая приходит на ум с 2 загрузчиками, это dataApiObj1.getClass().equals(dataApiObj2.getClass()), но dataApiObj1.getClass() != dataApiObj2.getClass()   -  person Bohemian♦    schedule 29.05.2020


Ответы (1)


Злоба. Итак, у файла было неправильное имя пакета. В то время как eclipse не позволяет этого, и intellij помечает его как красный, gradle и java позволяют ему компилироваться просто отлично, но когда мы ищем источник, мы не можем найти источник, поэтому в итоге мы не можем загрузить его через CompilingClassLoader, вызывая очень запутанный вопрос. Я даже не могу создать исключение по этому поводу, сообщая разработчику, что пакет неверен, потому что я получаю только имена классов и понятия не имею, неверно ли имя пакета или нет, поскольку все классы проходят через этот загрузчик классов. ик.

person Dean Hiller    schedule 28.05.2020