Welcome to OGeek Q&A Community for programmer and developer-Open, Learning and Share
Welcome To Ask or Share your Answers For Others

Categories

0 votes
90 views
in Technique[技术] by (71.8m points)

java - @Transactional in super classes not weaved when using load time weaving

The project I am working on has a similar structure for the DAOs to the one bellow:

/** 
* Base DAO class
*/
@Transactional    
public class JPABase {

  @PersistenceContext
  private EntityManager entityManager;

  public void persist(Object entity) {
    entityManager.persist(entity);
  }
 //some more methods in here
}

and

/** 
* Generic DAO class implementation
*/
@Transactional 
public abstract class GenericDao extends JpaBase {
   //some methods in here
}

and

/** 
* Specialized DAO class
*/
@Repository
@Transactional
public class PersonDao extends GenericDao {
  //some methods in here
}

Until now, the project used compile time weaving, but the configuration has changed to use <context:load-time-weaver/> with -javaagent:/opt/tomcat7-1/lib/spring-instrument.jar.

Since this change has been applied, the JpaBase's and GenericDao's @Transactional annotations are not weaved anymore. Each time a service class calls the persist method on a PersonDao object, no transaction is started.

Noteworthy:

  • this used to work in the past, when using compile time weaving.
  • all the methods that are defined in the PersonDao are weaved correctly, but the ones inherited (e.g. persist(Object entity)) are NOT weaved.

Compile time weaving and load time weaving are supposed to do the same thing, just at different moments in time. Why has the weaving behaviour changed?

question from:https://stackoverflow.com/questions/31164486/transactional-in-super-classes-not-weaved-when-using-load-time-weaving

与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…
Welcome To Ask or Share your Answers For Others

1 Reply

0 votes
by (71.8m points)

Tomcat default classlLoader is WebappClassLoader, but you need `TomcatInstrumentableClassLoader.

There are two solutions:

  1. Modify WebappLoader.class

Change WebappLoader.java

private String loaderClass =  "org.apache.catalina.loader.WebappClassLoader";

Replace:

private String loaderClass = "org.springframework.instrument.classloading.tomcat.TomcatInstrumentableClassLoader";  

Compile it and replaced the class file(catalina.jar), then it works.

Here is required dependency jars: catalina.jar,tomcat-coyote.jar,tomcat-util.jar(/bin),tomcat-juli.jar

  1. Modify context.xml:


<?xml version="1.0" encoding="UTF-8"?>  
<Context>  
    <Loader loaderClass="org.springframework.instrument.classloading.tomcat.TomcatInstrumentableClassLoader"/>  
</Context>


与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…
OGeek|极客中国-欢迎来到极客的世界,一个免费开放的程序员编程交流平台!开放,进步,分享!让技术改变生活,让极客改变未来! Welcome to OGeek Q&A Community for programmer and developer-Open, Learning and Share
Click Here to Ask a Question

...