2013-08-08 8 views
5

Jestem nowy w Spring i używam wersji Spring 3.2.2. Mam trochę fasoli, którą wstrzyknięto przez <constructor-arg>, która działa dobrze. Teraz chciałem wstrzyknąć trochę fasoli przez @Autowired, co całkowicie poszło nie tak. Zrobiłem tak:Spring java.lang.LinkageError: naruszenie ograniczenia programu ładującego: program ładujący wcześniej zainicjował ładowanie dla innego typu o nazwie X

beans.xml:

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

Java źródło:

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

(Zmiana kwalifikator lub pozostawienie go na zewnątrz nie robi żadnej różnicy ...)

I pojawia się ten błąd:

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"

Zastanawiam się, dlaczego pojawia się ten błąd. Szczególnie irytuje mnie typ FormulaKey. Kiedy używam adnotacji @Autowired z innym komponentem bean, to działa.

Muszę wspomnieć, że zaimplementowałem GenericFormulaFactory jako singleton metodą getInstance. Może to powoduje pewne problemy?

Aplikacja jest samodzielną aplikacją. Sprawdziłem również wszystkie słoiki pod kątem obłudy i nie zakładam, że to jest przyczyna problemu, ponieważ błąd dotyczy moich własnych klas.

Pozdrawiam, Oliver

UPDATE: usunąłem błąd, nie wiedząc, czego przyczyną tego.

Co zrobiłem:

  1. Usuń metodę getInstance() i singleton charakter wykonania fabrycznego
  2. Dodano interfejs fabryki do konstruktora klasy Wózek (i constructor-arg w XML)

Teraz mogę użyć xml, aby skonfigurować implementację i używać jej również z adnotacjami @Autowired.

xml:

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

Wciąż zastanawiasz się, dlaczego błąd pojawił się w pierwszej kolejności. Podczas implementacji fabryki, HashMap został utworzony przy użyciu FormulaKey jako klucza, więc może to spowodowało problemy. Jeśli ktoś zna odpowiedź, naprawdę chciałbym to wiedzieć.

+0

Nadal wywołujesz 'GenericFormulaFactory.getInstance()' w konstruktorze 'DefaultFormulaHandler'? – Santosh

+0

@Santosh: Tak, tak było. Teraz jest wstrzykiwany. – 4thfloorstudios

+0

Oznacza to, że klasa 'my.project.formula.FormulaKey' nie jest już ładowana w czasie, gdy kontener sprężyny ładuje ziarna. – Santosh

Odpowiedz

16

Oto co mogę zebrać do tej pory:

  1. Błąd java.lang.LinkageError jest w sytuacji, gdy istnieją dwa classloaders zajmujących się ładuje klasę.
  2. Program ładujący klasy śledzi klasy ładowane przez wygenerowanie unikalnego identyfikatora, który zawiera w pełni kwalifikowaną nazwę klasy i załadowany przez moduł ładujący klasy.
  3. Gdy program ładujący klasy odbiera odwołanie do klasy ładowanej przez inną klasę, która jest już załadowana przez nią samą, wynikiem jest sytuacja błędna, ponieważ klasa może być ładowana tylko jeden raz w hierarchii ładowania klas.
  4. Jeśli używane są niestandardowe moduły ładujące klasy, w celu załadowania konkretnej klasy należy najpierw sprawdzić, czy nadrzędne klasy ładujące są kwerendowane, jeśli ta klasa jest już załadowana.
  5. W scenariuszu, gdy niestandardowy program ładujący klasy nie wysyła zapytania do hierarchii nadrzędnej i zdecydował się załadować samą klasę, może się zdarzyć, że ładowana klasa jest już załadowana przez pewien moduł ładujący klasy w hierarchii nadrzędnej.
  6. Śledź this link, aby dowiedzieć się więcej na ten temat.
  7. Dla twojej sprawy, domyślam się, że konfiguracja XML i przetwarzanie adnotacji jest wykonywane przez dwa różne programy ładujące klasy.
  8. W scenariuszu błędu my.project.formula.FormulaKey jest ładowany przez jeden program ładujący klasy, a następnie moduł ładujący klasy zaangażowany w przetwarzanie adnotacji ładuje go jeszcze raz.
  9. Po zmianie kodu ładowanie my.project.formula.FormulaKey zostaje odłożone jako niezwiązane z poleceniem podczas ładowania kontekstu z pliku XML.
+0

Dzięki za twoje badania! Mogę dodać, że ze względu na moją własną, singletonową implementację fabryki, klasa 'FormulaKey' wydawała się być załadowana podczas uruchamiania aplikacji, a następnie ponownie przez adnotację' @ Autowire'. Przenosząc inicjalizację singletona na Spring (i ładowanie klasowe), problem wydawał się być rozwiązany, ponieważ Spring mógł zająć się wszystkim ładowaniem klasowym. – 4thfloorstudios

+0

Tak. Tak się właśnie stało. – Santosh

Powiązane problemy