2017-05-08 2 views
0

Ich versuche, zu Transaktion-API 1.2 statt JTA 1.1 zu migrieren.Mule/Spring ClassLoader Problem beim Migrieren zu transaction-api 1.2

Während ich weiß, kann ich mule bereitgestellten libs anpassen Ich kann nicht verstehen, warum die Anwendung nicht funktioniert, indem Sie nur Transaktion-API zum application/lib-Ordner hinzufügen. Ohne transaktions api alles funktioniert wie erwartet, aber damit ich:

Caused by: java.lang.ClassNotFoundException: javax.transaction.Transactional 
at java.net.URLClassLoader.findClass(URLClassLoader.java:381) ~[?:1.8.0_66] 
at java.lang.ClassLoader.loadClass(ClassLoader.java:424) ~[?:1.8.0_66] 
at java.lang.ClassLoader.loadClass(ClassLoader.java:357) ~[?:1.8.0_66] 
at org.springframework.transaction.annotation.JtaTransactionAnnotationParser.parseTransactionAnnotation(JtaTransactionAnnotationParser.java:42) ~[spring-tx-4.2.4.RELEASE.jar:4.2.4.RELEASE] 
at org.springframework.data.repository.core.support.TransactionalRepositoryProxyPostProcessor$CustomAnnotationTransactionAttributeSource.determineTransactionAttribute(TransactionalRepositoryProxyPostProcessor.java:229) ~[?:?] 
at org.springframework.data.repository.core.support.TransactionalRepositoryProxyPostProcessor$CustomAnnotationTransactionAttributeSource.findTransactionAttribute(TransactionalRepositoryProxyPostProcessor.java:208) ~[?:?] 
at org.springframework.data.repository.core.support.TransactionalRepositoryProxyPostProcessor$AbstractFallbackTransactionAttributeSource.computeTransactionAttribute(TransactionalRepositoryProxyPostProcessor.java:397) ~[?:?] 
at org.springframework.data.repository.core.support.TransactionalRepositoryProxyPostProcessor$AbstractFallbackTransactionAttributeSource.getTransactionAttribute(TransactionalRepositoryProxyPostProcessor.java:345) ~[?:?] 
at org.springframework.transaction.interceptor.TransactionAspectSupport.invokeWithinTransaction(TransactionAspectSupport.java:270) ~[spring-tx-4.2.4.RELEASE.jar:4.2.4.RELEASE] 

Hier sind einige relevante snippers von Spring-Code.

spring-data-commons (application/lib):

  if (jta12Present) { 
      this.annotationParsers.add(new JtaTransactionAnnotationParser()); 
     } 

wo:

 private static final boolean jta12Present = ClassUtils.isPresent("javax.transaction.Transactional", 
      CustomAnnotationTransactionAttributeSource.class.getClassLoader()); 

- scheint, wie diese Prüfung bestanden, wenn transaktions api zur Anwendung hinzugefügt wird.

JtaTransactionAnnotationParser kommt von mule-supplied spring-tx (MULE_HOME \ lib \ opt). Dies ist, wo es eine Ausnahme auslöst:

public class JtaTransactionAnnotationParser implements TransactionAnnotationParser, Serializable { 
    @Override 
    public TransactionAttribute parseTransactionAnnotation(AnnotatedElement ae) { 
     AnnotationAttributes attributes = AnnotatedElementUtils.getMergedAnnotationAttributes(ae, javax.transaction.Transactional.class); - ClassNotFoundException 

Warum kann Transactional an einem Ort Frühling identifiziert, kann aber nicht in einem anderen? Es scheint, dass Spring-Data-Commons und Spring-Tx in verschiedenen Bereichen den Grund dafür darstellen können, aber ich verstehe nicht warum, weil Mule eine komplexe hierarchische ClassLoader-Struktur bereitstellen und die gesamte Hierarchie durchsuchen soll.

Antwort

0

Ok, nachdem ich darüber nachgedacht habe, denke ich, dass ich es jetzt besser verstehe. Wie am Ende meiner Frage vorgeschlagen, handelt es sich um ein mit ClassLoader zusammenhängendes Problem. Es ist jedoch nicht Mule oder Spring spezifisch. Es ist klar, alt Classloader Sichtbarkeit Prinzip:

Sichtbarkeit Prinzip Kind Class Loader ermöglicht durch Eltern Classloader, aber Eltern Class Loader kann nicht sehen, von Kind geladen Klassen geladen alle Klassen zu sehen.

http://javarevisited.blogspot.com/2012/12/how-classloader-works-in-java.html

In meinem Fall endete 2-abhängige Feder Bibliotheken, indem getrennte Classloader geladen werden. Aus diesem Grund empfehle ich dringend, Ihre provided Abhängigkeiten zu überprüfen, bevor Sie der Anwendung Bibliotheken mit dem Bereich compile hinzufügen. Wenn Zweideutigkeiten nicht vermieden werden können, kann die Verwaltung der ClassLoader-Priorität eine Option sein (Parent-First vs Parent-Last)

Verwandte Themen