Spring java.lang.LinkageError:加载器约束违规:加载器之前为名称为X的不同类型启动加载

声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow 原文地址: http://stackoverflow.com/questions/18127431/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me): StackOverFlow

提示:将鼠标放在中文语句上可以显示对应的英文。显示中英文
时间:2020-08-11 22:33:49  来源:igfitidea点击:

Spring java.lang.LinkageError: loader constraint violation: loader previously initiated loading for a different type with name X

javaspring

提问by 4thfloorstudios

I am new to Spring and use Spring 3.2.2. I have some beans which I injected via <constructor-arg>which works fine. Now I wanted to inject some bean via @Autowiredwhich totally went wrong. I have done this:

我是 Spring 的新手并使用 Spring 3.2.2。我有一些豆子,我通过<constructor-arg>它们注入了它们,效果很好。现在我想注入一些@Autowired完全出错的bean 。我已经这样做了:

beans.xml:

豆类.xml:

<context:annotation-config />
<bean id="formulaFactory" class="my.project.formula.impl.GenericFormulaFactory"
    factory-method="getInstance">
<qualifier value="formulaFactory"></qualifier>
</bean>

Java source:

Java源代码:

@Autowired
@Qualifier("formulaFactory")
private FormulaFactory formulaFactory;

(Changing the qualifier or leaving it out did not make any difference...)

(更改限定符或将其排除在外没有任何区别......)

And I get this error:

我得到这个错误:

java.lang.LinkageError: loader constraint violation: loader (instance of org/springframework/context/support/ContextTypeMatchClassLoader$ContextOverridingClassLoader) previously initiated loading for a different type with name "my/project/formula/FormulaKey"

java.lang.LinkageError: loader constraint violation: loader (instance of org/springframework/context/support/ContextTypeMatchClassLoader$ContextOverridingClassLoader) previously initiated loading for a different type with name "my/project/formula/FormulaKey"

I wonder why this error comes up. Especially the type FormulaKeyirritates me. When I use the @Autowiredannotation with some other bean, it works.

我想知道为什么会出现这个错误。尤其是那种类型FormulaKey让我很恼火。当我将@Autowired注释与其他 bean 一起使用时,它会起作用。

I have to mention that I implemented the GenericFormulaFactory as singleton via getInstancemethod. Maybe that causes some problems?

我不得不提一下,我通过getInstance方法将 GenericFormulaFactory 实现为单例。也许这会导致一些问题?

The application is a stand-alone app. I checked all the jars for duplicity too and I do not assume that this is the cause of the problem because the error relates to my own classes.

该应用程序是一个独立的应用程序。我也检查了所有罐子的重复性,我不认为这是问题的原因,因为错误与我自己的类有关。

Regards, Oliver

问候, 奥利弗

UPDATE:I removed the error without knowing what cause it.

更新:我在不知道是什么原因的情况下删除了错误。

What I did:

我做了什么:

  1. Remove the getInstance() method and singleton nature of the factory implementation
  2. Added the factory interface to a handler classes constructor (and constructor-argin xml)
  1. 移除工厂实现的 getInstance() 方法和单例特性
  2. 将工厂接口添加到处理程序类构造函数(并constructor-arg在 xml 中)

Now I can use the xml to configure the implementation and use it with @Autowiredannotations too.

现在我可以使用 xml 来配置实现并将它与@Autowired注释一起使用。

xml:

xml:

<bean id="formulaHandler" class="my.project.formula.impl.DefaultFormulaHandler">
    <constructor-arg ref="formulaFactory" />
</bean>
<bean id="formulaFactory" class="my.project.formula.impl.GenericFormulaFactory" />

Still wondering why the error came up in the first place. In the implementation of the factory, a HashMapwas created using FormulaKeyas key, so maybe this caused trouble. If someone knows the answer, I would really like to know it.

仍然想知道为什么首先出现错误。在工厂的实现中,aHashMap是用FormulaKey作为key创建的,所以可能会造成麻烦。如果有人知道答案,我真的很想知道。

采纳答案by Santosh

Here is what I could gather so far:

以下是我目前可以收集到的信息:

  1. The error java.lang.LinkageErrorcomes in a situation when there are two classloaders involved in loading a class.
  2. A classloader keeps track of the classes loaded by generating a unique identifier which contains the fully qualified class name itself and the classloader loaded it.
  3. When a classloader receives a reference of a class loaded by another class which is already loaded by itself, this results into erroneous situation as a class can be loaded only once in a classloading hierarchy.
  4. When custom classloaders are involved, for loading a particular class, the practice is that the parent classloaders are queried first if that class is already loaded.
  5. In the scenario, when a custom classloader does not query the parent hierarchy and decided to load the class itself, there might be case wherein the class being loaded is already loaded by some classloader in parent hierarchy.
  6. Read Kieviet, Frank's "The java.lang.LinkageError: loader constraint violation" demystified"to know more about it.
  7. For your case, I guess the XML configuration and Annotation processing is done by two different classloaders.
  8. In the error scenario, my.project.formula.FormulaKeyis loaded by one classloader and then the class loader involved in annotation processing loads it one more time.
  9. When you changed the code, the loading of my.project.formula.FormulaKeyis deferred as its no more referred while loading the context from XML .
  1. java.lang.LinkageError当加载一个类涉及两个类加载器时,就会出现错误。
  2. 类加载器通过生成唯一标识符来跟踪加载的类,该标识符包含完全限定的类名本身和类加载器加载它。
  3. 当类加载器接收到由另一个类加载的类的引用时,这会导致错误的情况,因为类在类加载层次结构中只能加载一次。
  4. 当涉及自定义类加载器时,为了加载特定类,实践是如果该类已经加载,则首先查询父类加载器。
  5. 在这种情况下,当自定义类加载器不查询父层次结构并决定加载类本身时,可能会出现正在加载的类已经由父层次结构中的某个类加载器加载的情况。
  6. 阅读 Kieviet, Frank 的The java.lang.LinkageError:加载器约束违规“揭秘以了解更多信息。
  7. 对于您的情况,我猜 XML 配置和注释处理是由两个不同的类加载器完成的。
  8. 在错误场景中,my.project.formula.FormulaKey由一个类加载器加载,然后参与注释处理的类加载器再加载一次。
  9. 当您更改代码时,加载my.project.formula.FormulaKey被推迟,因为在从 XML 加载上下文时不再引用它。