Spring #Configurable annotation with AspectJ - spring

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>

Related

how to fix the maven surefire plugin error [there was error in the forked process]?

I am trying to run my sample project which uses Maven- testNG-cucumber and deploy it using docker . here is my Dockerfile
FROM maven:3.6.0-jdk-8
RUN mkdir /docker
WORKDIR /docker
COPY pom.xml .
COPY testng.xml .
COPY src .
RUN mvn clean verify
POM.XML
<dependencies>
<dependency>
<groupId>info.cukes</groupId>
<artifactId>cucumber-java</artifactId>
<version>1.2.5</version>
<scope>test</scope>
</dependency>
<dependency>
<groupId>info.cukes</groupId>
<artifactId>cucumber-jvm-deps</artifactId>
<version>1.0.5</version>
<scope>test</scope>
</dependency>
<dependency>
<groupId>info.cukes</groupId>
<artifactId>cucumber-testng</artifactId>
<version>1.2.5</version>
<scope>compile</scope>
<exclusions>
<exclusion>
<groupId>junit</groupId>
<artifactId>junit</artifactId>
</exclusion>
</exclusions>
</dependency>
<dependency>
<groupId>org.testng</groupId>
<artifactId>testng</artifactId>
<version>6.9.8</version>
<scope>test</scope>
</dependency>
<dependency>
<groupId>net.masterthought</groupId>
<artifactId>cucumber-reporting</artifactId>
<version>3.8.0</version>
</dependency>
<dependency>
<groupId>org.seleniumhq.selenium</groupId>
<artifactId>selenium-java</artifactId>
<version>2.44.0</version>
</dependency>
</dependencies>
<build>
<plugins>
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-resources-plugin</artifactId>
<version>2.4</version>
</plugin>
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-surefire-plugin</artifactId>
<version>2.20.1</version>
<configuration>
<suiteXmlFiles>
<suiteXmlFile>testng.xml</suiteXmlFile>
</suiteXmlFiles>
<useSystemClassLoader>false</useSystemClassLoader>
</configuration>
</plugin>
<plugin>
<groupId>net.masterthought</groupId>
<artifactId>maven-cucumber-reporting</artifactId>
<version>3.8.0</version>
<executions>
<execution>
<id>execution</id>
<phase>verify</phase>
<goals>
<goal>generate</goal>
</goals>
<configuration>
<projectName>Sample</projectName>
<outputDirectory>target/cucumber-reports/advanced-reports</outputDirectory>
<cucumberOutput>target/cucumber-reports/CucumberTestReport.json</cucumberOutput>
<buildNumber>1</buildNumber>
<parallelTesting>false</parallelTesting>
</configuration>
</execution>
</executions>
</plugin>
</plugins>
</build>
above scenario works completely fine when i run the project locally using mvn verify .Then i try to build the image using docker build -t sample . . this time i have got the following error .
[ERROR] Failed to execute goal org.apache.maven.plugins:maven-surefire-plugin:2.20.1:test (default-test) on project Sample: There are test failures.
[ERROR] Please refer to /docker/target/surefire-reports for the individual test results.
[ERROR] Please refer to dump files (if any exist) [date]-jvmRun[N].dump, [date].dumpstream and [date]-jvmRun[N].dumpstream.
[ERROR] There was an error in the forked process
[ERROR] Cannot find class in classpath: TestRunner
[ERROR] org.apache.maven.surefire.booter.SurefireBooterForkException: There was an error in the forked process
[ERROR] Cannot find class in classpath: TestRunner
[ERROR] at org.apache.maven.plugin.surefire.booterclient.ForkStarter.fork
(ForkStarter.java:673)
[ERROR] at org.apache.maven.plugin.surefire.booterclient.ForkStarter.fork
(ForkStarter.java:535)
[ERROR] at org.apache.maven.plugin.surefire.booterclient.ForkStarter.run
(ForkStarter.java:280)
[ERROR] at org.apache.maven.plugin.surefire.booterclient.ForkStarter.run
(ForkStarter.java:245)
[ERROR] at
org.apache.maven.plugin.surefire.AbstractSurefireMojo.executeProvider
(AbstractSurefireMojo.java:1124)
[ERROR] at
org.apache.maven.plugin.surefire.AbstractSurefireMojo.
executeAfterPreconditionsChecked(AbstractSurefireMojo.java:954)
Any help would be much appreciated
I had a similar issue and after using older version of maven-surefire-plugin solved my issue.
<plugin>
<artifactId>maven-surefire-plugin</artifactId>
<!-- latest version does not work well with JUnit5 -->
<version>2.19.1</version>
<dependencies>
<dependency>
<groupId>org.junit.platform</groupId>
<artifactId>junit-platform-surefire-provider</artifactId>
<version>1.0.3</version>
</dependency>
<dependency>
<groupId>org.junit.jupiter</groupId>
<artifactId>junit-jupiter-engine</artifactId>
<version>5.0.3</version>
</dependency>
</dependencies>
</plugin>
I had the same issue, I just used the clean command for maven.
clean -f pom.xml
If you are working in IntelliJ you can use maven plugin instead.
On the right side click maven Tab -> plugins -> clean -> clean:clean
I faced the same issue but it got resolved with different solution, you can check below problems as well.
Actually i have given the wrong testNG.xml path in POM.XML that's why it was throwing me that error. Please cross verify your testNG.xml path.
The above exception log clearly states that it is unable to find the TestRunner class. Make sure your TestRunner class is on the classpath.
I was getting a similar exception due to there were few extra characters added in the Classes section of the TestNG XML file. Its worth checking TestNG XML file is correct and doesn't contain any extra chars than needed structure.
I faced the same issue. It got resolved after the maven clean build and then ran the test.

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.

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).)*$).

All jUnit test cases are not running for Maven project using PowerMock with easymock, Surefire

In a Maven Project I am using PowerMock-easymock to run jUnit test cases. but while doing "mvn clean install" , I am getting below output..
T E S T S
Running TestSuite
Tests run: 2, Failures: 0, Errors: 0, Skipped: 0, Time elapsed: 0.621 sec
Results :
Tests run: 2, Failures: 0, Errors: 0, Skipped: 0
But I have many other test cases.
Here is a part of pom.xml
<dependency>
<groupId>junit</groupId>
<artifactId>junit</artifactId>
<version>4.8.2</version>
<scope>test</scope>
</dependency>
<dependency>
<groupId>org.easymock</groupId>
<artifactId>easymock</artifactId>
<version>3.1</version>
<scope>test</scope>
</dependency>
<dependency>
<groupId>org.powermock</groupId>
<artifactId>powermock-easymock-release-full</artifactId>
<version>1.4.12</version>
<type>pom</type>
</dependency>
If I remove, PowerMock dependency and do "mvn clean install" , all test cases are running fine. But I have to use PowerMock. How to solve this issue?
I guess that some of your test cases are not running, did you try this
Use mvn surefire plugin, and include test cases in that.
ensure dependancy of powermock-module-junit4.
check out these link: code.google.com/p/powermock/wiki/EasyMock_maven
http://code.google.com/p/powermock/wiki/GettingStarted
I had the same problem, and it took me a while to figure out. My setup was pulling in an older version of jboss.javassist, which oddly was preventing the PowerMockRunner from working at all.
It's worth noting that I also have a mixed JUnit / TestNG environment. I previously tried the solution of adding multiple surefire providers, and that didn't work either (using surefire 2.14.1). After upgrading to surefire 2.17, both my JUnit and TestNG tests started running without needing to declare any surefire providers. In fact, the JUnit provider threw an error for me, because I'm using groups. Apparently the TestNG provider allows free-form text (e.g. "integration") while the JUnit provider expects a classpath (e.g. "com.example.UnitTests").
Here's my plugin section...
<plugin>
<artifactId>maven-surefire-plugin</artifactId>
<version>2.17</version>
<configuration>
<groups>spring, unit, integration</groups>
<systemPropertyVariables>
<java.awt.headless>true</java.awt.headless>
<org.apache.activemq.default.directory.prefix>target/test/</org.apache.activemq.default.directory.prefix>
<log4j.configuration>file:${project.basedir}/src/test/resources/log4j.properties</log4j.configuration>
</systemPropertyVariables>
<argLine>${surefire.args}</argLine>
</configuration>
</plugin>
... and the relevant testing deps ...
<dependency>
<groupId>org.mockito</groupId>
<artifactId>mockito-all</artifactId>
<version>1.9.5</version>
<scope>test</scope>
</dependency>
<!--
PowerMock versions are compatible with specific Mockito versions.
https://code.google.com/p/powermock/wiki/MockitoUsage13
-->
<dependency>
<groupId>org.powermock</groupId>
<artifactId>powermock-module-junit4</artifactId>
<version>1.5.4</version>
<scope>test</scope>
</dependency>
<dependency>
<groupId>org.powermock</groupId>
<artifactId>powermock-api-mockito</artifactId>
<version>1.5.4</version>
<scope>test</scope>
</dependency>
<!-- without this PowerMock tests don't run in maven -->
<dependency>
<groupId>jboss</groupId>
<artifactId>javassist</artifactId>
<version>3.8.0.GA</version>
<scope>test</scope>
</dependency>
As per Dipak,
Solution 1:
Add below code in pom.xml
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-surefire-plugin</artifactId>
<version>2.13</version>
<dependencies>
<dependency>
<groupId>org.apache.maven.surefire</groupId>
<artifactId>surefire-junit47</artifactId>
<version>2.13</version>
</dependency>
</dependencies>
</plugin>
For Correct ArtifactId in dependency , you can see this link if you are using jUnit.
Then do "mvn clean install"
Solution 2:
Add below code in pom.xml
<properties>
<powermock.version>1.5</powermock.version>
</properties>
<dependency>
<groupId>org.powermock</groupId>
<artifactId>powermock-module-junit4</artifactId>
<version>${powermock.version}</version>
<scope>test</scope>
</dependency>
<dependency>
<groupId>org.powermock</groupId>
<artifactId>powermock-api-easymock</artifactId>
<version>${powermock.version}</version>
<scope>test</scope>
</dependency>
Refer this link for detail
All credits go to Dipak
I had a situation recently where PowerMock tests were run, but not included in the surefire coverage report. We found that the problem had to do with instrumentation.
I'll note that most of our tests run with TestNG. In general, we only use JUnit when we need to leverage PowerMock.
Here is the POM snippet:
<plugin>
<artifactId>maven-surefire-plugin</artifactId>
<version>2.18.1</version>
<configuration>
<systemPropertyVariables>
<org.apache.activemq.default.directory.prefix>target/test/</org.apache.activemq.default.directory.prefix>
<log4j.configuration>file:${project.basedir}/src/test/resources/log4j.properties</log4j.configuration>
<jacoco-agent.destfile>${project.basedir}/target/jacoco.exec</jacoco-agent.destfile>
</systemPropertyVariables>
<argLine>-Xmx512m -XX:MaxPermSize=256m -Djava.awt.headless=true</argLine>
</configuration>
</plugin>
<plugin>
<groupId>org.jacoco</groupId>
<artifactId>jacoco-maven-plugin</artifactId>
<version>0.7.5.201505241946</version>
<executions>
<execution>
<id>instrument</id>
<phase>process-classes</phase>
<goals>
<goal>instrument</goal>
</goals>
</execution>
<execution>
<id>restore</id>
<phase>test</phase>
<goals>
<goal>restore-instrumented-classes</goal>
<goal>report</goal>
</goals>
</execution>
</executions>
</plugin>
The <systemPropertyVariables> are probably not relevant to the fix.
Also, note that JaCoCo's documentation warns against using this type of configuration unless you find it necessary.
http://www.eclemma.org/jacoco/trunk/doc/instrument-mojo.html
Warning: The preferred way for code coverage analysis with JaCoCo is
on-the-fly instrumentation. Offline instrumentation has several
drawbacks and should only be used if a specific scenario explicitly
requires this mode. Please consult documentation about offline
instrumentation before using this mode.

How do you configure aspectj maven plugin to use Java 7?

What are the appropriate configuration/versions/plugin versions for the aspectj plugin to use Java 7?
I am trying to upgrade from Java 6 to Java 7, and the aspectj compiler seems to not be compiling Java 7. I'm specifying the java source and target version as 1.7 in the plugin configuration for aspectj plugin and for the maven compiler plugin. I introduced Java7-specific syntax to my code, adding several language features such as string in switch and the diamond operator. During the build, I get errors from aspectj about the Java7 syntax. The first sign that things are going wrong is:
[INFO] --- aspectj-maven-plugin:1.4:compile (default) # site ---
[ERROR] Cannot switch on a value of type String. Only int values or enum constants are permitted
[ERROR] Cannot instantiate the type HashSet<?>
[ERROR] Syntax error on token "<", ? expected after this token
If I remove the executions section from the aspectj maven plugin so it doesn't run, and use mvn clean install, the new code compiles fine. So I think it's something misconfigured with aspectj. Here is my plugin configuration:
<properties>
<project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
<java-version>1.7</java-version>
<org.aspectj-version>1.6.11</org.aspectj-version>
</properties>
<plugin>
<groupId>org.codehaus.mojo</groupId>
<artifactId>aspectj-maven-plugin</artifactId>
<version>1.4</version>
<dependencies>
<dependency>
<groupId>org.aspectj</groupId>
<artifactId>aspectjrt</artifactId>
<version>${org.aspectj-version}</version>
</dependency>
<dependency>
<groupId>org.aspectj</groupId>
<artifactId>aspectjtools</artifactId>
<version>${org.aspectj-version}</version>
</dependency>
</dependencies>
<executions>
<execution>
<goals>
<goal>compile</goal>
<goal>test-compile</goal>
</goals>
</execution>
</executions>
<configuration>
<complianceLevel>${java-version}</complianceLevel>
<encoding>${project.build.sourceEncoding}</encoding>
<outxml>true</outxml>
<source>${java-version}</source>
<target>${java-version}</target>
</configuration>
</plugin>
Also aspectjrt is defined as a dependency outside of the plugins section
<dependencies>
<dependency>
<groupId>org.aspectj</groupId>
<artifactId>aspectjrt</artifactId>
<version>${org.aspectj-version}</version>
</dependency>
<dependencies>
I updated from 1.6.11 to 1.7.0, which has been released since I asked this question. I no longer have any aspectj/Java1.7 issues, so that resolves this question.

Resources