2017-05-08 91 views
0

我想迁移到事务API 1.2,而不是1.1 JTA当骡子/春天的ClassLoader问题。迁移到事务API 1.2

虽然我知道我可以调整骡子提供林达我无法理解为什么应用程序不能仅仅通过增加交易-API应用程序/ lib文件夹中工作。没有交易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代码片断。

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从骡提供的弹簧-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 

为什么春天识别在一个地方事务,但不能在其他?似乎有不同的范围弹簧数据共用和弹簧TX可能是原因,但我不明白为什么,因为骡子是应该提供一个复杂的层次的ClassLoader结构和跨越整个层次的搜索。

回答

0

好了,说完想过多一点,我想我最好现在明白了。正如我的问题最后提出的,这是一个与ClassLoader相关的问题。但是,它不是Mule或Spring特定的。这是普通的旧的ClassLoader的可视性原则:

能见度原则让孩子的类加载器看到父ClassLoader加载的所有类 ,但父类加载器无法看到孩子加载 类。

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

在我的情况,2依赖的弹簧库结束了由单独的类加载器加载。这就是为什么我强烈建议在向应用程序添加任何具有compile范围的库之前检查provided依赖关系。如果无法避免歧义,管理ClassLoader的优先级可以是一种选择(母体第一VS家长最后)