Spring 4 Java Config Transactions Proxy and Aspecj - proxy

I am creating a new project that uses aspectj transactions. It also uses legacy jars that contain services that are using the proxy method where an interface is required.
I am using java config and when I set
#EnableTransactionManagement(mode=AdviceMode.ASPECTJ)
Then I get the following exception thrown with accessing the proxy style services from the legacy libs:
org.hibernate.LazyInitializationException: could not initialize proxy - no Session
If I change to:
#EnableTransactionManagement(mode=AdviceMode.PROXY)
Then I don't get the problem but I can't then use the aspectj style transactions in my new project.
I've tried adding two #EnableTransactionManagement annotations with each adviceMode, but that is not allowed.
Here is the annotated class
#EnableWebMvc
#Configuration
#ComponentScan("com.mydomain")
#EnableTransactionManagement(mode=AdviceMode.ASPECTJ)
public class ApplicationConfig extends WebMvcConfigurerAdapter {
...
I've also added the aspectj maven plugin to the legacy project in the hope that it would handle the weaving at compile time and thus aspectj transactions would work. But this has not solved the problem.
<plugin>
<groupId>org.codehaus.mojo</groupId>
<artifactId>aspectj-maven-plugin</artifactId>
<version>1.7</version>
<configuration>
<aspectLibraries>
<aspectLibrary>
<groupId>org.springframework</groupId>
<artifactId>spring-aspects</artifactId>
</aspectLibrary>
</aspectLibraries>
<complianceLevel>1.8</complianceLevel>
<source>1.8</source>
<target>1.8</target>
<showWeaveInfo>true</showWeaveInfo>
</configuration>
<executions>
<execution>
<goals>
<goal>compile</goal>
</goals>
</execution>
</executions>
</plugin>
Is it possible to have spring deal with both advice modes? How would I do this?
Or is there another way around this problem.

The problem was with the aspectj config on the legacy project.
When I ran mvn compile it became apparent. I had to add the dependency:
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-aspects</artifactId>
<version>${spring.version}</version>
</dependency>
That got it working when compiled using maven, but I it would still not work in eclipse. I had to right click on the legacy project in eclipse:
Configure>Convert to Aspectj Project
Then I could deploy from eclipse and I had aspectj transactional support in the legacy jars.

Related

Spring #Configurable annotation with AspectJ

Can't make my project compile with Aspectj. There's an issue with Apache CXF that ResourceContext.getResource(SomeClass.class) creates a simple object not a Spring-managed one. So I would like to use weaving and #Configurable to come over this hardship. I got it to work in my test Spring Boot application (I could provide a link on the Github if needed) with the following set up using #Configurable itself and #EnableSpringConfigured:
Here is a snapshot of my pom.xml (Spring version is 4.3.3.RELEASE):
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-aspects</artifactId>
<version>${spring.version}</version>
</dependency>
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-tx</artifactId>
<version>${spring.version}</version>
</dependency>
and the aspectj-maven-plugin plugin configuration:
<plugin>
<groupId>org.codehaus.mojo</groupId>
<artifactId>aspectj-maven-plugin</artifactId>
<version>1.8</version>
<configuration>
<source>1.8</source>
<target>1.8</target>
<complianceLevel>1.8</complianceLevel>
<showWeaveInfo>true</showWeaveInfo>
<aspectLibraries>
<aspectLibrary>
<groupId>org.springframework</groupId>
<artifactId>spring-aspects</artifactId>
</aspectLibrary>
</aspectLibraries>
</configuration>
<executions>
<execution>
<goals>
<goal>compile</goal>
</goals>
</execution>
</executions>
</plugin>
However, when I try to apply the configuration above in the real project in my company I get this weird error:
[ERROR] *path to the java file being weaving* can't determine annotations of missing type javax.transaction.Transactional
[ERROR] when weaving type *the full java class name*
[ERROR] when weaving classes
[ERROR] when weaving
[ERROR] when batch building BuildConfig[null] #Files=27 AopXmls=#0
[ERROR] [Xlint:cantFindType]
[ERROR] error at (no source information available)
My test project doesn't use #Transactional but the real one does. So I've tried to add spring-tx and persistence-api dependencies but nothing works. And the last note: the project is built successful the second time I run mvn install and unsuccessful every time I run mvn clean install.
Any help is much appreciated as I'm really stuck with this error.
Adding the following dependency to the classpath should solve the issue:
<dependency>
<groupId>javax.transaction</groupId>
<artifactId>javax.transaction-api</artifactId>
<version>1.2</version>
<scope>provided</scope>
</dependency>

AspectJ: Issue on Weblogic 12

I worked on a Java EE application with following configs:
JDK 1.7
AspectJ 1.7
Weblogic 12.1.3
However, after upgrading the configs to followings, all aspects with "call" wildcards have not worked properly and as a result, no joinpoints, which already hit, can be touched, now:
JDK Verion: 1.8.0_66
AspectJ Version: 1.8.7
Application Server: Weblogic 12.2.1
The aspect snippet is as follows:
#Before("call(public * com.gam.commons.core.api.services.Service+.(..)) && within(com.gam.calendar.biz.service.internal.impl.)")
public void handle(JoinPoint thisJoinPoint) {
Class declaringType = thisJoinPoint.getSignature().getDeclaringType();
if (declaringType.isInterface()) {
UserProfileTO userProfileTO = ((AbstractService) thisJoinPoint.getThis()).getUserProfileTO();/* Caller or this /
((Service) thisJoinPoint.getTarget()).setUserProfileTO(userProfileTO);/ Callee or target */
}
}
Now, I am delightfully looking forward in case of any meaningful points you would have for feeding me.
Attention: My problem was due to something else, please look at my answer to glean more information about the issue.
I made a mistake as my problem was completely due to something else. As I updated my project to be compiled by JDK 1.8.0_66, I should have re-configured aspect-maven-plugin to be compatible with this upgrade. Fortunately, my problem has been solved by re-configuring the appropriate plugin on the POM file, as follows:
<plugin>
<groupId>org.codehaus.mojo</groupId>
<artifactId>aspectj-maven-plugin</artifactId>
<version>1.8</version>
<dependencies>
<dependency>
<groupId>org.aspectj</groupId>
<artifactId>aspectjrt</artifactId>
<version>1.8.7</version>
</dependency>
<dependency>
<groupId>org.aspectj</groupId>
<artifactId>aspectjtools</artifactId>
<version>1.8.7</version>
</dependency>
</dependencies>
<configuration>
<complianceLevel>1.8</complianceLevel>
<source>1.8</source>
<target>1.8</target>
</configuration>
<executions>
<execution>
<goals>
<goal>compile</goal>
<goal>test-compile</goal>
</goals>
</execution>
</executions>
</plugin>
More info about "aspectj-maven-plugin" is available on aspectj-maven-plugin

Compile-time aspects throwing NoSuchMethodError in Spring Boot

I am getting an error when running my "compile-time-weaver" classes from Maven on a JAR file that is included in my Spring Boot 1.2.2 WAR.
So, I have a jar, ctms-components.jar, that I run my aspect (e.g., a method timing profiler) on using MAVEN. Then, Spring Boot puts it all in an embedded WAR (I'm using Tomcat). I see both the aspectj woven classes like AJC Closures(), etc. and I see the logs from Maven are weaving my classes as per my pointcuts.
<plugin>
<groupId>org.codehaus.mojo</groupId>
<artifactId>aspectj-maven-plugin</artifactId>
<version>1.7</version>
<configuration>
<showWeaveInfo>true</showWeaveInfo>
<source>${compiler.version}</source>
<target>${compiler.version}</target>
<Xlint>ignore</Xlint>
<complianceLevel>${compiler.version}</complianceLevel>
<encoding>UTF-8</encoding>
<verbose>false</verbose>
<aspectLibraries>
<aspectLibrary>
<groupId>cdot.ctms</groupId>
<artifactId>ctms-aspects</artifactId>
</aspectLibrary>
</aspectLibraries>
<weaveDependencies>
<weaveDependency>
<groupId>cdot.ctms</groupId>
<artifactId>ctms-components</artifactId>
</weaveDependency>
</weaveDependencies>
</configuration>
<executions>
<execution>
<goals>
<goal>compile</goal>
</goals>
</execution>
</executions>
<dependencies>
<dependency>
<groupId>org.aspectj</groupId>
<artifactId>aspectjrt</artifactId>
<version>${aspectj.version}</version>
</dependency>
<dependency>
<groupId>org.aspectj</groupId>
<artifactId>aspectjtools</artifactId>
<version>${aspectj.version}</version>
</dependency>
</dependencies>
</plugin>
Here is an excerpt from my maven log.
[INFO] Join point 'method-execution(cdot.base.DataAccessObject cdot.ctms.layer.services.comm.device.doppler.facade.DopplerFacade.getDopplerExchange())' in Type 'cdot.ctms.layer.services.comm.device.doppler.facade.DopplerFacade' (DopplerFacade.java:78) advised by around advice from 'cdot.aop.profiler.MethodTimerAspect' (ctms-aspects-2.0.0-SNAPSHOT.jar!MethodTimerAspect.class(from MethodTimerAspect.java))
[INFO] Join point 'method-execution(cdot.base.DataAccessObject cdot.ctms.layer.services.comm.device.doppler.facade.DopplerFacade.getDopplerRawDataExchange())' in Type 'cdot.ctms.layer.services.comm.device.doppler.facade.DopplerFacade' (DopplerFacade.java:84) advised by around advice from 'cdot.aop.profiler.MethodTimerAspect' (ctms-aspects-2.0.0-SNAPSHOT.jar!MethodTimerAspect.class(from MethodTimerAspect.java))
My Spring Boot WAR shows the AJC Closures are bundled in the WAR:
The ERROR I get when running the application is:
java.lang.NoSuchMethodError: cdot.aop.profiler.MethodTimerAspect.aspectOf()Lcdot/aop/profiler/MethodTimerAspect
nested exception is java.lang.NoSuchMethodError: cdot.aop.profiler.MethodTimerAspect.aspectOf()Lcdot/aop/profiler/MethodTimerAspect;
at org.springframework.beans.AbstractPropertyAccessor.setPropertyValues(AbstractPropertyAccessor.java:121)
at org.springframework.beans.AbstractPropertyAccessor.setPropertyValues(AbstractPropertyAccessor.java:75)
at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.applyPropertyValues(AbstractAutowireCapableBeanFactory.java:1502)
... 87 more
I don't understand why it does compile time weaving, adds it to my Spring Boot WAR just fine, and also includes the ctms-aspects.jar, but cannot find the method on my Aspect?
The AspectJ runtime library aspectjrt.jar must be on your classpath, so it should be a Maven <dependency> not just for the AspectJ Maven Plugin but also for the Maven module as such.

JUnit tests fail with Java error when using IntelliJ within maven module after adding Hibernate Metamodel classes

On my project we've used Hibernate's (JPA) Metamodel Generator to make our Criteria queries type safe. It all works great within our app, however, when we run the JUnit tests within that Maven module using our IDE they now fail with the following error:-
Error:java: Annotation processor 'org.hibernate.jpamodelgen.JPAMetaModelEntityProcessor' not found
Which I guess is due to the following in our generated classes:-
#Generated(value = "org.hibernate.jpamodelgen.JPAMetaModelEntityProcessor")
#StaticMetamodel(MyEntity.class)
When Maven runs the tests as part of our build process then they run with no problems at all.
I suspect I'm missing something within the set up of my IDE, which is IntelliJ IDEA 14. Any ideas what this might be? Or have I done something wrong within Maven? :-
<plugin>
<groupId>org.bsc.maven</groupId>
<artifactId>maven-processor-plugin</artifactId>
<version>2.1.0</version>
<executions>
<execution>
<id>process</id>
<goals>
<goal>process</goal>
</goals>
<phase>generate-sources</phase>
<configuration>
<processors>
<processor>org.hibernate.jpamodelgen.JPAMetaModelEntityProcessor</processor>
</processors>
</configuration>
</execution>
</executions>
<dependencies>
<dependency>
<groupId>org.hibernate</groupId>
<artifactId>hibernate-jpamodelgen</artifactId>
<version>4.3.4.Final</version>
<optional>true</optional>
</dependency>
</dependencies>
</plugin>
I had a similar problem after I upgraded to IntelliJ IDEA 14.1.2. For me the following action resolved the problem:
Go to Settings > Build, Execution, Deployment > Compiler > Annotation Processors.
On the left of this configuration panel I have an Annotation profile for every maven module in my project. I did not set up these profiles myself: maybe they where inferred by the IDE. I don't know, but in some of these annotation profiles, the enable annotation processing flag was enabled. Moreover, in some cases, the JPAMetaModelEntityProcessor was explicitly listed here as an annotation processor. After removing the annotation processor from the profile and disabling the checkbox, the error disappeared and my test ran successfully.
The answer by #Jeroen Noels disables annotation processing in IDEA.
To keep it enabled I've added
<dependency>
<groupId>org.hibernate</groupId>
<artifactId>hibernate-jpamodelgen</artifactId>
<version>4.3.4.Final</version>
<scope>provided</scope>
</dependency>
to the Maven dependencies, i.e. to the classpath. Note that the scope is provided!

How to disable Spring's JpaExceptionTranslatorAspect

I'm migrating from Spring 2.5.6 to 3.2.5. The jar spring-aspects-3.2.5 contains the new aspect JpaExceptionTranslatorAspect which translates standard JPA exceptions into Spring exceptions. It seems to be a Roo-specific aspect. This aspect gets automatically weaved into repositories (annotated with #Repository). Consequently, standard JPA exceptions are not caught anymore and the application is broken.
How can I exclude JpaExceptionTranslatorAspect from being weaved? If it can't be done, is there any other workaround? Or am I missing some piece of configuration?
I'm using AspectJ 1.7.4 and AspectJ Maven Plugin 1.4.
What I have already gathered:
Spring rejected the issue because it's a build issue
AspectJ Maven Plugin rejected the issue because the AspectJ compiler doesn't support excluding specific aspects from a library
However, I wonder if those pieces of information are up to date.
First, upgrade aspectj-maven-plugin to 1.5 and add the complianceLevel tag in the configuration of the plugin (otherwise it will try to compile with java 1.4 compliance by default).
Then you can specify the exclusion through the xmlConfigured property of the aspectj-maven-plugin. This property references a file from your local directory (i.e. where your pom.xml is)
pom.xml exemple :
<plugin>
<groupId>org.codehaus.mojo</groupId>
<artifactId>aspectj-maven-plugin</artifactId>
<version>1.5</version>
<configuration>
<source>${maven.compiler.source}</source>
<target>${maven.compiler.target}</target>
<complianceLevel>${maven.compiler.target}</complianceLevel>
<xmlConfigured>myCtAspects.xml</xmlConfigured>
<aspectLibraries>
<aspectLibrary>
<groupId>org.springframework</groupId>
<artifactId>spring-aspects</artifactId>
</aspectLibrary>
</aspectLibraries>
<showWeaveInfo>true</showWeaveInfo>
<weaveMainSourceFolder>true</weaveMainSourceFolder>
<proceedOnError>${maven.aspectj.failOnError}</proceedOnError>
</configuration>
<executions>
<execution>
<goals>
<goal>compile</goal>
</goals>
<phase>process-resources</phase>
</execution>
</executions>
<dependencies>
<dependency>
<groupId>org.aspectj</groupId>
<artifactId>aspectjrt</artifactId>
<version>${aspectj.version}</version>
</dependency>
<dependency>
<groupId>org.aspectj</groupId>
<artifactId>aspectjtools</artifactId>
<version>${aspectj.version}</version>
</dependency>
</dependencies>
</plugin>
Then in myCtAspects.xml file, you just have to specify all the wanted aspects explicitly, including Spring Aspects. In your case:
<?xml version="1.0"?>
<aspectj>
<aspects>
<!-- Spring Aspects -->
<aspect name="org.springframework.beans.factory.aspectj.AbstractInterfaceDrivenDependencyInjectionAspect"/>
<aspect name="org.springframework.beans.factory.aspectj.AnnotationBeanConfigurerAspect"/>
<aspect name="org.springframework.transaction.aspectj.AnnotationTransactionAspect"/>
<!-- Your Application Aspects -->
</aspects>
</aspectj>
Please try to use aop-autoproxy's include proprety with some invert regexp (something like ^((?! JpaExceptionTranslatorAspect).)*$).

Resources