2017-05-08 6 views
0

jta 1.1 대신 transaction-api 1.2로 마이그레이션하려고합니다.transaction-api 1.2로 마이그레이션 할 때 Mule/Spring ClassLoader 문제가 발생했습니다.

내가 뮬 제공 libs 조정할 수있는 동안 응용 프로그램/lib 폴더에 트랜잭션 API를 추가하여 응용 프로그램이 작동하지 않는 이유를 이해할 수 없습니다. 예상대로 트랜잭션 API를하지 않고 모든 작동하지만, 그것으로 내가 얻을 :

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] 

여기 봄 코드의 일부 관련 스니퍼입니다.

spring-data-commons (응용 프로그램/lib에) :

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

:

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

이 - 트랜잭션 API는 응용 프로그램에 추가 할 때이 검사가 전달되는 것 같다.

JtaTransactionAnnotationParser은 mule-spring-tx (MULE_HOME \ lib \ opt)에서 제공됩니다. 여기에서 예외가 발생합니다.

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

Spring은 한 곳에서 트랜잭션을 식별 할 수 있지만 다른 곳에서는 확인할 수없는 이유는 무엇입니까? 스프링 데이터 커먼 (spring-data-commons)과 스프링 - 텍사스 (spring-data-commons)를 다른 범위에서 사용하는 것이 그 이유 일 수 있습니다. 그러나 Mule은 복잡한 계층 적 ClassLoader 구조를 제공하고 전체 계층 구조를 검색해야하기 때문에 이해가되지 않습니다.

답변

0

좋아, 조금 더 생각해 봤는데, 지금은 더 잘 이해하고 있다고 생각합니다. 내 질문의 끝에서 제안대로, 그것은 ClassLoader 관련 문제입니다. 그러나 Mule 또는 Spring과 관련이 없습니다.

가시성 원리는 자식 클래스 로더는 부모 클래스 로더에 의해로드 된 모든 클래스 를 볼 수 있지만, 부모 클래스 로더는 자식에 의해로드 클래스를 볼 수 없습니다 : 그것은 평범한 구식 클래스 로더 가시성의 원칙이다.

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

, 2 의존 스프링 라이브러리는 별도의 클래스 로더에 의해로드되는 끝났다. 따라서 compile 범위의 라이브러리를 응용 프로그램에 추가하기 전에 provided 종속성을 확인하는 것이 좋습니다. 모호성을 피할 수없는 경우 ClassLoader 우선 순위를 관리하는 옵션이 될 수 있습니다 (부모 - 첫 번째 대 부모 - 마지막)