CompilingClassLoader fun, any ideas how child class loads from different classloader in this case?

huangapple 未分类评论46阅读模式
英文:

CompilingClassLoader fun, any ideas how child class loads from different classloader in this case?

问题

在线 29 的堆栈跟踪下的 createController 方法中的代码如下clazz.getClasslo

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

在线 521 的 loadClass 正在加载上述 'clazz' 变量的构造函数所在的类但没有从 CompilingClassLoader 加载它以某种方式跳过了它构造函数有三个参数除了最后一个参数外其余参数都从 CompilingClassLoader 加载(

这是我所说的构造函数您可以在堆栈跟踪中看到它调用 getDeclaredConstructors

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

最后这是堆栈跟踪

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

为什么前两个参数是如何从 CompilingClassLoader 加载的而第三个构造函数是如何从普通的 ClassLoader 加载的我以为任何子类都应该通过与父类相同的类加载器加载

我正在试图修复这个问题因为由于某种原因CompilingClassLoader 没有加载该类导致存在两个由不同类加载器加载的 DataApi.class 对象这让我很困惑)。

当我更深入挖掘时我发现可以调用 clazz.getMethods()但是当我调用 clazz.getDeclaredConstructors()会出现 ClassCircularityError真正有趣的是CustomerController 和 DataClientProxy 都没有继承任何类所以这真的很奇怪

Dean
英文:

createController on line 29 in the below stack trace has clazz.getClasslo

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

loadClass online 521 is loading a class of the constructor of the above 'clazz' variable BUT is not loading from CompilingClassLoader. It somehow is skipping it. There are THREE parameters to the constructor all loading from CompilingClassLoader except the last one CompilingClassLoader fun, any ideas how child class loads from different classloader in this case?

Here is the constructor I am talking about(you can see it calling getDeclaredConstructors in the stack trace)

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

Finally here is the stack trace

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)

How in the world are the first two parameters loaded from CompilingClassLoader and the 3rd constructor is loaded from a normal ClassLoader. I thought any children classes should go through the same classloader as the parent to load?

(I am trying to fix this as for some reason, the CompilingClassLoader is missing loading that class causing a very fun like existence of TWO DataApi.class objects loaded by different classloaders).

Hmmm, As I dig more, I found out I can call clazz.getMethods() BUT when I call clazz.getDeclaredConstructors(), then I get a ClassCircularityError. The real funny thing is CustomerController nor DataClientProxy extend anyone so it's really weird.

Dean

答案1

得分: 0

Nastiness. 所以,这个文件有错误的包名。尽管 Eclipse 不允许这样做,而 Intellij 会将其标记为红色,但是 Gradle 和 Java 却可以正常编译,但是当我们寻找源代码时,我们找不到源代码,因此我们无法通过 CompilingClassLoader 加载它,从而导致了一个非常令人困惑的问题。我甚至无法抛出异常来告诉开发人员包名错误,因为我只接收类名,并且不知道包名是否错误,因为所有的类都会经过这个类加载器。糟糕。

英文:

Nastiness. So, the file had the wrong package name. While eclipse doesn't allow this and intellij flags it as red, gradle and java let it compile just fine but when we look for source, we can't find the source so it ends up we can't load it via the CompilingClassLoader causing a very confusing issue. I can't even throw an exception to this effect telling the developer the package is wrong because I only receve classnames and have no idea if the package name is wrong or not since all classes go through this classloader. ick.

huangapple
  • 本文由 发表于 2020年5月29日 05:50:33
  • 转载请务必保留本文链接:https://java.coder-hub.com/62075117.html
匿名

发表评论

匿名网友

:?: :razz: :sad: :evil: :!: :smile: :oops: :grin: :eek: :shock: :???: :cool: :lol: :mad: :twisted: :roll: :wink: :idea: :arrow: :neutral: :cry: :mrgreen:

确定