How to configure Spring to use aspectj for Transactional?

In accordance with this answer, https://stackoverflow.com/a/2126185/2126322 To use @Transactional when executing a local method, I followed these steps:

added to pom.xml:

  <dependency> <groupId>org.aspectj</groupId> <artifactId>aspectjrt</artifactId> <version>1.8.7</version> </dependency> <dependency> <groupId>org.aspectj</groupId> <artifactId>aspectjweaver</artifactId> <version>1.8.7</version> </dependency> <dependency> <groupId>org.springframework</groupId> <artifactId>spring-aspects</artifactId> </dependency> 

replace in context

 <tx:annotation-driven transaction-manager="transactionManager"/> 

with

 <tx:annotation-driven transaction-manager="transactionManager" mode="aspectj"/> 

after that I saw

Failed to get transaction sync session for current thread

additionally added:

 <context:load-time-weaver/> 

But when make mvn clean install I see (the problem occurs when tests try to run. In my test I use the application context):

  java.lang.IllegalStateException: Failed to load ApplicationContext at org.springframework.test.context.DefaultCacheAwareContextLoaderDelegate.loadContext(DefaultCacheAwareContextLoaderDelegate.java:94) at org.springframework.test.context.DefaultTestContext.getApplicationContext(DefaultTestContext.java:72) at org.springframework.test.context.support.DependencyInjectionTestExecutionListener.injectDependencies(DependencyInjectionTestExecutionListener.java:117) .... Caused by: org.springframework.beans.factory.BeanCreationException: Error creating bean with name 'org.springframework.context.weaving.AspectJWeavingEnabler#0': Initialization of bean failed; nested exception is org.springframework.beans.factory.BeanCreationException: Error creating bean with name 'loadTimeWeaver': Initialization of bean failed; nested exception is java.lang.IllegalStateException: ClassLoader [sun.misc.Launcher$AppClassLoader] does NOT provide an 'addTransformer(ClassFileTransformer)' method. Specify a custom LoadTimeWeaver or start your Java virtual machine with Spring agent: -javaagent:org.springframework.instrument.jar at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.doCreateBean(AbstractAutowireCapableBeanFactory.java:547) ... 31 more Caused by: org.springframework.beans.factory.BeanCreationException: Error creating bean with name 'loadTimeWeaver': Initialization of bean failed; nested exception is java.lang.IllegalStateException: ClassLoader [sun.misc.Launcher$AppClassLoader] does NOT provide an 'addTransformer(ClassFileTransformer)' method. Specify a custom LoadTimeWeaver or start your Java virtual machine with Spring agent: -javaagent:org.springframework.instrument.jar at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.doCreateBean(AbstractAutowireCapableBeanFactory.java:547) at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.createBean(AbstractAutowireCapableBeanFactory.java:476) ... 45 more Caused by: java.lang.IllegalStateException: ClassLoader [sun.misc.Launcher$AppClassLoader] does NOT provide an 'addTransformer(ClassFileTransformer)' method. Specify a custom LoadTimeWeaver or start your Java virtual machine with Spring agent: -javaagent:org.springframework.instrument.jar at org.springframework.context.weaving.DefaultContextLoadTimeWeaver.setBeanClassLoader(DefaultContextLoadTimeWeaver.java:91) at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.invokeAwareMethods(AbstractAutowireCapableBeanFactory.java:1590) at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.initializeBean(AbstractAutowireCapableBeanFactory.java:1561) at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.doCreateBean(AbstractAutowireCapableBeanFactory.java:539) ... 54 more 

Update

integer pom.xml :

 <project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/maven-v4_0_0.xsd"> <modelVersion>4.0.0</modelVersion> <groupId>com.terminal</groupId> <artifactId>terminal-company</artifactId> <packaging>war</packaging> <version>1.0-SNAPSHOT</version> <name>terminal-company</name> <properties> <spring.version>4.1.6.RELEASE</spring.version> <spring.security.version>3.2.4.RELEASE</spring.security.version> <org.slf4j-version>1.5.10</org.slf4j-version> <jetty.version>9.2.5.v20141112</jetty.version> </properties> <dependencyManagement> <dependencies> <dependency> <groupId>org.springframework</groupId> <artifactId>spring-framework-bom</artifactId> <version>${spring.version}</version> <type>pom</type> <scope>import</scope> </dependency> <dependency> <groupId>org.springframework.security</groupId> <artifactId>spring-security-bom</artifactId> <version>${spring.security.version}</version> <type>pom</type> <scope>import</scope> </dependency> </dependencies> </dependencyManagement> <dependencies> <!-- Web --> <dependency> <groupId>org.springframework</groupId> <artifactId>spring-webmvc</artifactId> </dependency> <dependency> <groupId>javax.servlet</groupId> <artifactId>jstl</artifactId> <version>1.2</version> <scope>runtime</scope> </dependency> <dependency> <groupId>javax.servlet</groupId> <artifactId>javax.servlet-api</artifactId> <version>3.1.0</version> <scope>provided</scope> </dependency> <dependency> <groupId>javax.el</groupId> <artifactId>el-api</artifactId> <version>2.2</version> </dependency> <!-- Data --> <dependency> <groupId>postgresql</groupId> <artifactId>postgresql</artifactId> <version>9.0-801.jdbc4</version> </dependency> <dependency> <groupId>com.h2database</groupId> <artifactId>h2</artifactId> <version>1.4.182</version> </dependency> <dependency> <groupId>org.springframework</groupId> <artifactId>spring-orm</artifactId> </dependency> <dependency> <groupId>org.springframework</groupId> <artifactId>spring-aop</artifactId> </dependency> <dependency> <groupId>org.aspectj</groupId> <artifactId>aspectjrt</artifactId> <version>1.8.0</version> </dependency> <dependency> <groupId>org.aspectj</groupId> <artifactId>aspectjweaver</artifactId> <version>1.8.0</version> </dependency> <dependency> <groupId>javassist</groupId> <artifactId>javassist</artifactId> <version>3.12.0.GA</version> </dependency> <!-- Spring Security --> <dependency> <groupId>org.springframework.security</groupId> <artifactId>spring-security-core</artifactId> </dependency> <dependency> <groupId>org.springframework.security</groupId> <artifactId>spring-security-web</artifactId> </dependency> <dependency> <groupId>org.springframework.security</groupId> <artifactId>spring-security-config</artifactId> </dependency> <dependency> <groupId>org.springframework.security</groupId> <artifactId>spring-security-taglibs</artifactId> </dependency> <!-- Integration--> <dependency> <groupId>org.springframework.integration</groupId> <artifactId>spring-integration-http</artifactId> <version>${spring.version}</version> </dependency> <!-- Hibernate --> <dependency> <groupId>org.hibernate</groupId> <artifactId>hibernate-core</artifactId> <version>4.3.10.Final</version> </dependency> <dependency> <groupId>org.hibernate</groupId> <artifactId>hibernate-validator</artifactId> <version>5.1.3.Final</version> </dependency> <!-- logging --> <dependency> <groupId>org.slf4j</groupId> <artifactId>slf4j-api</artifactId> <version>${org.slf4j-version}</version> </dependency> <dependency> <groupId>org.slf4j</groupId> <artifactId>jcl-over-slf4j</artifactId> <version>${org.slf4j-version}</version> </dependency> <dependency> <groupId>org.slf4j</groupId> <artifactId>slf4j-log4j12</artifactId> <version>${org.slf4j-version}</version> </dependency> <!-- JSON --> <dependency> <groupId>com.fasterxml.jackson.core</groupId> <artifactId>jackson-core</artifactId> <version>2.2.2</version> </dependency> <dependency> <groupId>com.fasterxml.jackson.core</groupId> <artifactId>jackson-databind</artifactId> <version>2.2.2</version> </dependency> <dependency> <groupId>com.fasterxml.jackson.core</groupId> <artifactId>jackson-annotations</artifactId> <version>2.2.2</version> </dependency> <dependency> <groupId>org.codehaus.jackson</groupId> <artifactId>jackson-mapper-asl</artifactId> <version>1.9.12</version> </dependency> <dependency> <groupId>org.json</groupId> <artifactId>json</artifactId> <version>20140107</version> </dependency> <dependency> <groupId>com.google.code.gson</groupId> <artifactId>gson</artifactId> <version>1.7.1</version> </dependency> <!-- Commons --> <dependency> <groupId>commons-beanutils</groupId> <artifactId>commons-beanutils</artifactId> <version>1.8.3</version> </dependency> <dependency> <groupId>org.apache.commons</groupId> <artifactId>commons-lang3</artifactId> <version>3.1</version> </dependency> <dependency> <groupId>commons-io</groupId> <artifactId>commons-io</artifactId> <version>2.4</version> </dependency> <dependency> <groupId>commons-fileupload</groupId> <artifactId>commons-fileupload</artifactId> <version>1.3</version> </dependency> <dependency> <groupId>org.apache.poi</groupId> <artifactId>poi</artifactId> <version>3.8</version> </dependency> <dependency> <groupId>commons-httpclient</groupId> <artifactId>commons-httpclient</artifactId> <version>3.1</version> </dependency> <dependency> <groupId>org.apache.httpcomponents</groupId> <artifactId>httpclient</artifactId> <version>4.0.2</version> </dependency> <dependency> <groupId>javax.mail</groupId> <artifactId>mail</artifactId> <version>1.4</version> </dependency> <!-- Test --> <dependency> <groupId>junit</groupId> <artifactId>junit</artifactId> <version>4.11</version> <scope>test</scope> </dependency> <dependency> <groupId>org.springframework</groupId> <artifactId>spring-test</artifactId> <scope>test</scope> </dependency> <dependency> <groupId>org.mockito</groupId> <artifactId>mockito-all</artifactId> <version>1.10.19</version> <scope>test</scope> </dependency> <!-- other --> <dependency> <groupId>org.imgscalr</groupId> <artifactId>imgscalr-lib</artifactId> <version>4.2</version> <type>jar</type> <scope>compile</scope> </dependency> <dependency> <groupId>net.sourceforge.pmd</groupId> <artifactId>pmd-jsp</artifactId> <version>5.2.1</version> </dependency> <dependency> <groupId>net.sourceforge.pmd</groupId> <artifactId>pmd-core</artifactId> <version>5.2.1</version> </dependency> <dependency> <groupId>net.sourceforge.pmd</groupId> <artifactId>pmd-java</artifactId> <version>5.2.1</version> </dependency> <dependency> <groupId>xml-apis</groupId> <artifactId>xml-apis</artifactId> <version>1.4.01</version> </dependency> <dependency> <groupId>commons-dbcp</groupId> <artifactId>commons-dbcp</artifactId> <version>1.4</version> </dependency> <dependency> <groupId>org.apache.httpcomponents</groupId> <artifactId>httpcore</artifactId> <version>4.4</version> <type>jar</type> </dependency> <dependency> <groupId>org.apache.velocity</groupId> <artifactId>velocity</artifactId> <version>1.7</version> </dependency> <dependency> <groupId>org.apache.velocity</groupId> <artifactId>velocity-tools</artifactId> <version>2.0</version> </dependency> <dependency> <groupId>org.apache.tika</groupId> <artifactId>tika-core</artifactId> <version>1.9</version> </dependency> <dependency> <groupId>net.bull.javamelody</groupId> <artifactId>javamelody-core</artifactId> <version>1.56.0</version> </dependency> <dependency> <groupId>org.aspectj</groupId> <artifactId>aspectjrt</artifactId> <version>1.8.7</version> </dependency> <dependency> <groupId>org.aspectj</groupId> <artifactId>aspectjweaver</artifactId> <version>1.8.7</version> </dependency> <dependency> <groupId>org.springframework</groupId> <artifactId>spring-aspects</artifactId> </dependency> </dependencies> <build> <finalName>terminal-company</finalName> <plugins> <plugin> <groupId>org.apache.maven.plugins</groupId> <artifactId>maven-pmd-plugin</artifactId> <version>3.3</version> <configuration> <includeTests>true</includeTests> <printFailingErrors>true</printFailingErrors> <verbose>true</verbose> <rulesets> <ruleset>rulesets/java/basic.xml</ruleset> <ruleset>rulesets/java/braces.xml</ruleset> <ruleset>rulesets/java/unusedcode.xml</ruleset> <!--<ruleset>rulesets/java/codesize.xml</ruleset>--> <ruleset>rulesets/java/imports.xml</ruleset> <ruleset>rulesets/java/empty.xml</ruleset> <ruleset>rulesets/jsp/basic.xml</ruleset> <ruleset>ruleset-naming.xml</ruleset> </rulesets> <includes> <include>**\/*.jsp</include> <include>**\/*.java</include> </includes> </configuration> <executions> <execution> <goals> <goal>check</goal> </goals> <configuration> <excludeFromFailureFile>${basedir}/src/main/resources/exclude-pmd.properties </excludeFromFailureFile> </configuration> </execution> </executions> </plugin> <plugin> <groupId>org.apache.maven.plugins</groupId> <artifactId>maven-compiler-plugin</artifactId> <version>3.2</version> <configuration> <source>1.8</source> <target>1.8</target> <encoding>UTF-8</encoding> </configuration> </plugin> <plugin> <groupId>org.apache.maven.plugins</groupId> <artifactId>maven-war-plugin</artifactId> <version>2.1.1</version> <configuration> <warName>terminal-company</warName> <webXml>src/main/webapp/WEB-INF/web.xml</webXml> <webResources> <resource> <directory>${basedir}/src/main/resources/</directory> <targetPath>/</targetPath> </resource> </webResources> </configuration> </plugin> <!-- IDE --> <plugin> <groupId>org.codehaus.mojo</groupId> <artifactId>tomcat-maven-plugin</artifactId> <version>1.1</version> </plugin> <plugin> <groupId>org.eclipse.jetty</groupId> <artifactId>jetty-maven-plugin</artifactId> <version>${jetty.version}</version> <configuration> <webAppConfig> <contextPath>/</contextPath> </webAppConfig> <httpConnector> <port>8081</port> </httpConnector> </configuration> </plugin> <plugin> <groupId>org.apache.maven.plugins</groupId> <artifactId>maven-dependency-plugin</artifactId> <version>2.3</version> <executions> <execution> <phase>package</phase> <goals> <goal>copy</goal> </goals> <configuration> <artifactItems> <artifactItem> <groupId>org.mortbay.jetty</groupId> <artifactId>jetty-runner</artifactId> <version>8.1.15.v20140411</version> <destFileName>jetty-runner.jar</destFileName> </artifactItem> </artifactItems> </configuration> </execution> </executions> </plugin> <plugin> <groupId>org.flywaydb</groupId> <artifactId>flyway-maven-plugin</artifactId> <version>3.1</version> <configuration> <url>jdbc:postgresql://127.0.0.1:5432/marc_db</url> <user>marc</user> <password>marc</password> </configuration> <dependencies> <dependency> <groupId>org.postgresql</groupId> <artifactId>postgresql</artifactId> <version>9.4-1200-jdbc4</version> </dependency> </dependencies> </plugin> </plugins> </build> <repositories> <repository> <id>central</id> <name>Maven Repository Switchboard</name> <layout>default</layout> <url>http://repo1.maven.org/maven2</url> <snapshots> <enabled>false</enabled> </snapshots> </repository> <repository> <id>spring-maven-release</id> <name>Spring Maven Release Repository</name> <url>http://maven.springframework.org/release</url> </repository> <repository> <id>spring-maven-milestone</id> <name>Spring Maven Milestone Repository</name> <url>http://maven.springframework.org/milestone</url> </repository> <repository> <id>JBoss Repo</id> <url>https://repository.jboss.org/nexus/content/repositories/releases</url> <name>JBoss Repo</name> </repository> <repository> <id>codelds</id> <url>https://code.lds.org/nexus/content/groups/main-repo</url> </repository> <repository> <id>glassfish-repository</id> <url>http://download.java.net/maven/glassfish</url> <snapshots> <updatePolicy>never</updatePolicy> </snapshots> </repository> </repositories> <pluginRepositories> <pluginRepository> <id>spring-maven-release</id> <name>Spring Maven Release Repository</name> <url>http://maven.springframework.org/release</url> </pluginRepository> <pluginRepository> <id>spring-maven-milestone</id> <name>Spring Maven Milestone Repository</name> <url>http://maven.springframework.org/milestone</url> </pluginRepository> <pluginRepository> <id>spring-roo-repository</id> <name>Spring Roo Repository</name> <url>http://spring-roo-repository.springsource.org/release</url> </pluginRepository> <pluginRepository> <id>central</id> <name>Maven Plugin Repository</name> <url>http://repo1.maven.org/maven2</url> <layout>default</layout> <snapshots> <enabled>false</enabled> </snapshots> <releases> <updatePolicy>never</updatePolicy> </releases> </pluginRepository> </pluginRepositories> </project> 

update 2:

If you skip the testing phase when creating the application, perform a successful operation , and then run mvn clean install jetty:run I see the following stack:

 org.springframework.beans.factory.BeanCreationException: Error creating bean with name 'org.springframework.transaction.config.internalTransactionAspect': Post-processing failed of bean type [class org.springframework.transaction.aspectj.AnnotationTransactionAspect] failed; nested exception is java.lang.IllegalStateException: Failed to introspect annotations: protected abstract void org.springframework.transaction.aspectj.AbstractTransactionAspect.ajc$pointcut$$transactionalMethodExecution$e12(java.lang.Object) at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.applyMergedBeanDefinitionPostProcessors(AbstractAutowireCapableBeanFactory.java:936) at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.doCreateBean(AbstractAutowireCapableBeanFactory.java:512) ... Caused by: java.lang.IllegalStateException: Failed to introspect annotations: protected abstract void org.springframework.transaction.aspectj.AbstractTransactionAspect.ajc$pointcut$$transactionalMethodExecution$e12(java.lang.Object) at org.springframework.core.annotation.AnnotatedElementUtils.process(AnnotatedElementUtils.java:166) ... 69 more Caused by: java.lang.IllegalAccessError: class sun.reflect.GeneratedConstructorAccessor14 cannot access its superclass sun.reflect.ConstructorAccessorImpl at sun.misc.Unsafe.defineClass(Native Method) at sun.reflect.ClassDefiner.defineClass(ClassDefiner.java:63) ... 76 more 13.11.2015 04:57:35 ERROR: org.springframework.web.context.ContextLoader - Context initialization failed org.springframework.beans.factory.BeanCreationException: Error creating bean with name 'org.springframework.transaction.config.internalTransactionAspect': Post-processing failed of bean type [class org.springframework.transaction.aspectj.AnnotationTransactionAspect] failed; nested exception is java.lang.IllegalStateException: Failed to introspect annotations: protected abstract void org.springframework.transaction.aspectj.AbstractTransactionAspect.ajc$pointcut$$transactionalMethodExecution$e12(java.lang.Object) at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.applyMergedBeanDefinitionPostProcessors(AbstractAutowireCapableBeanFactory.java:936) at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.doCreateBean(AbstractAutowireCapableBeanFactory.java:512) ... Caused by: java.lang.IllegalStateException: Failed to introspect annotations: protected abstract void org.springframework.transaction.aspectj.AbstractTransactionAspect.ajc$pointcut$$transactionalMethodExecution$e12(java.lang.Object) at org.springframework.core.annotation.AnnotatedElementUtils.process(AnnotatedElementUtils.java:166) at org.springframework.core.annotation.AnnotatedElementUtils.getAnnotationAttributes(AnnotatedElementUtils.java:91) ... 69 more Caused by: java.lang.IllegalAccessError: class sun.reflect.GeneratedConstructorAccessor14 cannot access its superclass sun.reflect.ConstructorAccessorImpl at sun.misc.Unsafe.defineClass(Native Method) ... 76 more 

update 3

I also tried to add

 @Configuration @EnableLoadTimeWeaving(aspectjWeaving= EnableLoadTimeWeaving.AspectJWeaving.ENABLED) public class Configiuration { 

I see the same result

update 4:

which uses the Transactional annotation:

 @Service @Transactional public class CompanyServiceImpl implements CompanyService { @PostConstruct public void init() { this.refreshStopJobs(); } ... } 

Decision

This post is actually useful to me.

+5
source share
3 answers

Basically, to get AspectJ Load Time Weaving to work, you first need to think about the environment in which your application will run. As the name says, β€œload time” means that your classes will be modified by the class loader. Therefore, from your question, I understand that you need your LTW in two environments. Firstly, this is a "test" environment, which is a command line, and the second is a servlet container (Jetty / Tomcat).

So, let's start with the test environment: your tests fail because the classloader does not have the ability to edit / write / drag classes, Spring cannot help you because it is not already running, and you chose Load Time over the weaving time. Therefore, we need to somehow inform the default class loader that we will crack classes. This is documented in Spring Documentation. For this, we need to add -javaagent , which in our case, instead of tools / profiling, the classes will simply change at boot time. To do this, just tell maven to add 2 javaaganets : aspectj-weaver-x.jar and special spring-instrument-x.jar , so just add plugins maven section.

 <plugin> <groupId>org.apache.maven.plugins</groupId> <artifactId>maven-surefire-plugin</artifactId> <version>2.19</version> <configuration> <forkMode>once</forkMode> <argLine> -javaagent:${settings.localRepository}/org/springframework/spring-instrument/4.2.2.RELEASE/spring-instrument-4.1.6.RELEASE.jar -javaagent:${settings.localRepository}/org/aspectj/aspectjweaver/1.8.7/aspectjweaver-1.8.7.jar </argLine> <useSystemClassloader>true</useSystemClassloader> </configuration> </plugin> 

Remember to add spring-instrument-4.1.6.RELEASE.jar as a dependency, at least in the provided , to make sure it is in the repo;) After adding these configuration parameters that you execute, execution will work fine . Just try:

mvn clean package

It starts from the second environment in the servlet container. If you use Tomcat, then you are happy, as you can override the default bootloader with the one that comes with Spring by adding the following META-INF/context.xml to the project.

 <Context path="/myWebApp" docBase="/my/webApp/location"> <Loader loaderClass="org.springframework.instrument.classloading.tomcat.TomcatInstrumentableClassLoader"/> </Context> 

More details here . For Jetty, you must manually edit the run script and add two -javaagent , as was done for the maven test environment.

+4
source

In the XML configuration that you used

 <context:load-time-weaver/> 

however, when using the default startup mode, the time loading mode will be executed only if you have the META-INF / aop.xml file. Since you do not have similar, you should change it to

 <context:load-time-weaver aspectj-weaving="on"/> 

or add META-INF / aop.xml. I see that you did this in the Java configuration, but it looks like you are the main part of your configuration file in XML.

0
source

You can refer to this useful link:

Spring 2.0 AOP - Spring 2.0 provides an easier and more efficient way to write custom aspects using either a schema-based approach or @AspectJ annotation style . Both of these styles offer fully typed tips and use the AspectJ pointcut language, but when using Spring AOP for weaving.

This chapter discusses support for AOP Spring 2.0 and AOP-based @ApectJ. Spring 2.0 AOP remains fully backward compatible with Spring 1.2 AOP, and the lower level AOP support offered by the Spring 1.2 API is discussed in the next chapter.

http://docs.spring.io/spring/docs/current/spring-framework-reference/html/aop.html

0
source

Source: https://habr.com/ru/post/1235544/


All Articles