I try to use Jacoco in my Eclipse IDE with the Eclemma plugin but it does not work. It worked when I was using JBoss 7 but not anymore with Wildfly 9. I can run my JUnit tests whithout error but the code coverage is always 0%. I'm using arquillian. This is what I have in my pom.xml :
...
<properties>
<version.jacoco>0.7.5.201505241946</version.jacoco>
</properties>
...
<dependencies>
...
<dependency>
<groupId>org.jboss.arquillian.junit</groupId>
<artifactId>arquillian-junit-container</artifactId>
<scope>test</scope>
</dependency>
<dependency>
<groupId>org.jboss.arquillian.protocol</groupId>
<artifactId>arquillian-protocol-servlet</artifactId>
<scope>test</scope>
</dependency>
<dependency>
<groupId>org.wildfly</groupId>
<artifactId>wildfly-jms-client-bom</artifactId>
<version>9.0.1.Final</version>
<type>pom</type>
<scope>provided</scope>
</dependency>
<dependency>
<groupId>org.jboss.arquillian.extension</groupId>
<artifactId>arquillian-jacoco</artifactId>
<version>1.0.0.Alpha8</version>
<scope>test</scope>
</dependency>
<dependency>
<groupId>org.jacoco</groupId>
<artifactId>org.jacoco.core</artifactId>
<version>${version.jacoco}</version>
<scope>test</scope>
</dependency>
...
</dependencies>
<build>
<plugins>
...
<plugin>
<groupId>org.jacoco</groupId>
<artifactId>jacoco-maven-plugin</artifactId>
<version>${version.jacoco}</version>
<executions>
<execution>
<id>default-prepare-agent</id>
<goals>
<goal>prepare-agent</goal>
</goals>
</execution>
<execution>
<id>default-report</id>
<phase>prepare-package</phase>
<goals>
<goal>report</goal>
</goals>
</execution>
<execution>
<id>default-check</id>
<goals>
<goal>check</goal>
</goals>
</execution>
</executions>
</plugin>
...
</plugins>
</build>
<profiles>
...
<profile>
<id>arq-wildfly-managed</id>
<dependencies>
<dependency>
<groupId>org.wildfly</groupId>
<artifactId>wildfly-arquillian-container-managed</artifactId>
<scope>test</scope>
</dependency>
</dependencies>
</profile>
<profile>
<id>arq-wildfly-remote</id>
<dependencies>
<dependency>
<groupId>org.wildfly</groupId>
<artifactId>wildfly-arquillian-container-remote</artifactId>
<scope>test</scope>
</dependency>
</dependencies>
</profile>
</profiles>
....
Any suggestion ?
This guide shows you step by step to setup Jacoco in your project: http://www.petrikainulainen.net/programming/maven/creating-code-coverage-reports-for-unit-and-integration-tests-with-the-jacoco-maven-plugin/
Step 1: with jacoco-maven-plugin:
<plugin>
<groupId>org.jacoco</groupId>
<artifactId>jacoco-maven-plugin</artifactId>
<version>0.7.5.201505241946</version>
<executions>
<!--
Prepares the property pointing to the JaCoCo runtime agent which
is passed as VM argument when Maven the Surefire plugin is executed.
-->
<execution>
<id>pre-unit-test</id>
<goals>
<goal>prepare-agent</goal>
</goals>
<configuration>
<!-- Sets the path to the file which contains the execution data. -->
<destFile>${project.build.directory}/coverage-reports/jacoco-ut.exec</destFile>
<!--
Sets the name of the property containing the settings
for JaCoCo runtime agent.
-->
<propertyName>surefireArgLine</propertyName>
</configuration>
</execution>
<!--
Ensures that the code coverage report for unit tests is created after
unit tests have been run.
-->
<execution>
<id>post-unit-test</id>
<phase>test</phase>
<goals>
<goal>report</goal>
</goals>
<configuration>
<!-- Sets the path to the file which contains the execution data. -->
<dataFile>${project.build.directory}/coverage-reports/jacoco-ut.exec</dataFile>
<!-- Sets the output directory for the code coverage report. -->
<outputDirectory>${project.reporting.outputDirectory}/jacoco-ut</outputDirectory>
</configuration>
</execution>
</executions>
</plugin>
Step 2: With maven-surefire-plugin
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-surefire-plugin</artifactId>
<version>2.15</version>
<configuration>
<!-- Sets the VM argument line used when unit tests are run. -->
<argLine>${surefireArgLine}</argLine>
<!-- Skips unit tests if the value of skip.unit.tests property is true -->
<skipTests>${skip.unit.tests}</skipTests>
<!-- Excludes integration tests when unit tests are run. -->
<excludes>
<exclude>**/IT*.java</exclude>
</excludes>
</configuration>
Be aware about surefireArgline property, which defined in jacoco-maven-plugin, and used in maven-surefire-plugin.
Try this configuration:
<plugin>
<groupId>org.jacoco</groupId>
<artifactId>jacoco-maven-plugin</artifactId>
<version>0.7.5.201505241946</version>
<executions>
<!--
Prepares the property pointing to the JaCoCo runtime agent which
is passed as VM argument when Maven the Surefire plugin is executed.
-->
<execution>
<id>pre-unit-test</id>
<goals>
<goal>prepare-agent</goal>
</goals>
<configuration>
<!-- Sets the path to the file which contains the execution data. -->
<destFile>${project.build.directory}/coverage-reports/jacoco-ut.exec</destFile>
<!--
Sets the name of the property containing the settings
for JaCoCo runtime agent.
-->
<propertyName>surefireArgLine</propertyName>
</configuration>
</execution>
<!--
Ensures that the code coverage report for unit tests is created after
unit tests have been run.
-->
<execution>
<id>post-unit-test</id>
<phase>test</phase>
<goals>
<goal>report</goal>
</goals>
<configuration>
<!-- Sets the path to the file which contains the execution data. -->
<dataFile>${project.build.directory}/coverage-reports/jacoco-ut.exec</dataFile>
<!-- Sets the output directory for the code coverage report. -->
<outputDirectory>${project.reporting.outputDirectory}/jacoco-ut</outputDirectory>
</configuration>
</execution>
</executions>
</plugin>
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-failsafe-plugin</artifactId>
<version>2.15</version>
<configuration>
<!-- Sets the VM argument line used when integration tests are run. -->
<argLine>${failsafeArgLine}</argLine>
</configuration>
</plugin>
Related
I'm currently working on a java project where I need to generate and compile JPA metamodel classes as part of the build. I did some research and found an answer here: Generate the JPA metamodel files using maven-processor-plugin - What is a convenient way for re-generation? that seems like a reasonable solution. The problem is, my project also contains some groovy classes that need to be compiled alongside the java. If I enable the maven-processor-plugin, the maven build will fail as soon as it encounters a java class that depends on a groovy class. Looking at the console output, I can see that maven-processor-plugin is running before the groovy compiler, so those groovy classes have not had a chance to be compiled.
Does anyone know if there is a good way to handle this? Is there some way to break the compilation process up into stages so that I can control what gets processed when?
Here is a snippet of my pom.xml:
<build>
<plugins>
<plugin>
<artifactId>maven-compiler-plugin</artifactId>
<configuration>
<showWarnings>false</showWarnings>
<compilerId>groovy-eclipse-compiler</compilerId>
<compilerArgument>-proc:none</compilerArgument>
</configuration>
<dependencies>
<dependency>
<groupId>org.codehaus.groovy</groupId>
<artifactId>groovy-eclipse-compiler</artifactId>
<version>3.6.0-03</version>
</dependency>
<dependency>
<groupId>org.codehaus.groovy</groupId>
<artifactId>groovy-eclipse-batch</artifactId>
<version>3.0.7-02</version>
</dependency>
</dependencies>
</plugin>
<plugin>
<groupId>org.bsc.maven</groupId>
<artifactId>maven-processor-plugin</artifactId>
<version>4.5-jdk8</version>
<executions>
<execution>
<id>process</id>
<goals>
<goal>process</goal>
</goals>
<phase>generate-sources</phase>
<configuration>
<outputDirectory>${project.build.directory}/../src/main/generated-sources/java/jpametamodel</outputDirectory>
<processors>
<processor>org.hibernate.jpamodelgen.JPAMetaModelEntityProcessor</processor>
</processors>
<overwrite>true</overwrite>
</configuration>
</execution>
</executions>
<dependencies>
<dependency>
<groupId>org.hibernate</groupId>
<artifactId>hibernate-jpamodelgen</artifactId>
<version>5.3.13.Final</version>
</dependency>
</dependencies>
</plugin>
<plugin>
<groupId>org.codehaus.mojo</groupId>
<artifactId>build-helper-maven-plugin</artifactId>
<executions>
<execution>
<id>add-source</id>
<phase>generate-sources</phase>
<goals>
<goal>add-source</goal>
</goals>
<configuration>
<sources>
<source>${project.build.directory}/../src/main/generated-sources/java/jpametamodel</source>
</sources>
</configuration>
</execution>
</executions>
</plugin>
</plugins>
</build>
After a good bit of trial and error I finally found a solution that seems to work. maven-processor-plugin can use include/exclude filters to limit the scope of the files it looks at. I added an includes filter that restricts the processing to my domain classes. Now when I build it can process my annotated classes without getting hung up on the groovy files.
My final result ended up looking like this:
<plugin>
<groupId>org.bsc.maven</groupId>
<artifactId>maven-processor-plugin</artifactId>
<version>4.5-jdk8</version>
<executions>
<execution>
<id>process</id>
<goals>
<goal>process</goal>
</goals>
<phase>generate-sources</phase>
<configuration>
<includes>
<include>com/tura/product/domain/*.java</include>
</includes>
<outputDirectory>${project.build.directory}/generated-sources/java</outputDirectory>
<processors>
<processor>org.hibernate.jpamodelgen.JPAMetaModelEntityProcessor</processor>
</processors>
<overwrite>true</overwrite>
</configuration>
</execution>
</executions>
<dependencies>
<dependency>
<groupId>org.hibernate</groupId>
<artifactId>hibernate-jpamodelgen</artifactId>
<version>5.3.13.Final</version>
</dependency>
</dependencies>
</plugin>
The Apache Tika Project has a root directory within which there is a pom.xml present. Inside the Root directory there are submodules and module named "Tika-Parent". Inside Parent module there is also a pom.xml file.
Now i am adding jacoco Maven Plugin to Tika to get Code Coverage but i am facing problems because when i add Jacoco Maven Plugin to the Pom.xml in Root Directory. It builds successfully but gives an error :"Skipping JaCoCo execution due to missing execution data file:C:\Users\adity\IdeaProjects\tika-1.20\target\jacoco.exec"
I tried adding JaCOCO Plugin to both the pom.xml files together as well as one by one each also but no result.
Also when I Perform Maven Test on the pom.xml in root directory it builds successfully running all tests.
BUT when I Perform Maven Test on the Tika-parent's pom.xml it doesnt run any tests but builds successfully.
I am attaching below the Pom.xml in root directory as well as pom.xml from Tika-parent module inside the root directory.
I am using IntelliJ Community edition ( latest version on website).
Java version - JDK 8 ,
Maven version 3.
THese details are from Root directory pom.xml
<modules>
<module>tika-parent</module>
<module>tika-core</module>
<module>tika-parsers</module>
<module>tika-bundle</module>
<module>tika-xmp</module>
<module>tika-serialization</module>
<module>tika-batch</module>
<module>tika-app</module>
<module>tika-server</module>
<module>tika-translate</module>
<module>tika-langdetect</module>
<module>tika-example</module>
<module>tika-java7</module>
<module>tika-eval</module>
<module>tika-dl</module>
<module>tika-nlp</module>
</modules>
These are the properties
<jacoco.version>0.7.5.201505241946</jacoco.version>
<junit.version>4.12</junit.version>
<junit.platform.version>1.3.1</junit.platform.version>
<maven.antrun.version>1.8</maven.antrun.version>
<maven.assembly.version>3.1.0</maven.assembly.version>
<maven.bundle.version>4.0.0</maven.bundle.version>
<maven.failsafe.version>2.22.1</maven.failsafe.version>
<maven.javadoc.version>3.0.1</maven.javadoc.version>
<maven.scr.version>1.7.4</maven.scr.version>
<maven.surefire.version>2.22.1</maven.surefire.version>
<maven.shade.version>3.2.0</maven.shade.version>
<rat.version>0.12</rat.version>
These are Dependencies
<dependencies>
<dependency>
<groupId>org.junit.platform</groupId>
<artifactId>junit-platform-launcher</artifactId>
<version>${junit.platform.version}</version>
</dependency>
<dependency>
<groupId>junit</groupId>
<artifactId>junit</artifactId>
<version>${junit.version}</version>
</dependency>
<dependency>
<groupId>org.junit.jupiter</groupId>
<artifactId>junit-jupiter-api</artifactId>
<version>5.3.1</version>
<scope>test</scope>
</dependency>
<dependency>
<groupId>org.junit.jupiter</groupId>
<artifactId>junit-jupiter-params</artifactId>
<version>5.3.1</version>
<scope>test</scope>
</dependency>
<dependency>
<groupId>org.junit.jupiter</groupId>
<artifactId>junit-jupiter</artifactId>
<version>5.4.0</version>
<scope>test</scope>
</dependency>
<dependency>
<groupId>org.junit.jupiter</groupId>
<artifactId>junit-jupiter-engine</artifactId>
<version>5.3.1</version>
<scope>test</scope>
</dependency>
<dependency>
<groupId>org.junit-pioneer</groupId>
<artifactId>junit-pioneer</artifactId>
<version>0.3.0</version>
<scope>test</scope>
</dependency>
</dependencies>
Below are all Plugins in Build.Plugins.
This is the JACOCO Plugin
<plugin>
<groupId>org.jacoco</groupId>
<artifactId>jacoco-maven-plugin</artifactId>
<version>${jacoco.version}</version>
<executions>
<execution>
<id>prepare-agent</id>
<goals>
<goal>prepare-agent</goal>
</goals>
</execution>
<execution>
<id>report</id>
<phase>prepare-package</phase>
<goals>
<goal>report</goal>
</goals>
</execution>
<execution>
<id>post-unit-test</id>
<phase>test</phase>
<goals>
<goal>report</goal>
</goals>
<configuration>
<dataFile>target/jacoco.exec</dataFile>
<outputDirectory>target/jacoco-ut</outputDirectory>
</configuration>
</execution>
</executions>
</plugin>
This is the Surefire plugin
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-surefire-plugin</artifactId>
<configuration>
<reuseForks>false</reuseForks>
<forkCount>1</forkCount>
</configuration>
</plugin>
THis is apache Rat Plugin
<plugin>
<groupId>org.apache.rat</groupId>
<artifactId>apache-rat-plugin</artifactId>
<version>${rat.version}</version>
<configuration>
<excludes>
<exclude>CHANGES.txt</exclude>
</excludes>
</configuration>
</plugin>
Rest there are no other plugins in this pom.xml
BELOW is pom.xml from Iika-Parent module in root directory.
These are the properties.
<maven.compiler.source>1.8</maven.compiler.source>
<maven.compiler.target>1.8</maven.compiler.target>
<project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
<project.reporting.outputEncoding>${project.build.sourceEncoding}
</project.reporting.outputEncoding>
<!-- plugin versions -->
<jacoco.version>0.7.5.201505241946</jacoco.version>
<junit.version>4.12</junit.version>
<junit.platform.version>1.3.1</junit.platform.version>
<forbiddenapis.version>2.6</forbiddenapis.version>
<groovy.maven.version>2.0</groovy.maven.version>
<maven.antrun.version>1.8</maven.antrun.version>
<maven.assembly.version>3.1.0</maven.assembly.version>
<maven.bundle.version>4.0.0</maven.bundle.version>
<maven.failsafe.version>2.22.1</maven.failsafe.version>
<maven.javadoc.version>3.0.1</maven.javadoc.version>
<maven.scr.version>1.7.4</maven.scr.version>
<maven.surefire.version>2.22.1</maven.surefire.version>
<maven.shade.version>3.2.0</maven.shade.version>
<rat.version>0.12</rat.version>
<!-- NOTE: sync tukaani version with commons-compress in tika-parsers -->
<poi.version>4.0.1</poi.version>
<commons.compress.version>1.18</commons.compress.version>
<commons.io.version>2.6</commons.io.version>
<commons.lang3.version>3.8.1</commons.lang3.version>
<gson.version>2.8.5</gson.version>
<osgi.core.version>6.0.0</osgi.core.version>
<cxf.version>3.2.7</cxf.version>
<slf4j.version>1.7.25</slf4j.version>
<jackson.version>2.9.7</jackson.version>
<!-- when this is next upgraded, see if we can get rid of
javax.activation dependency in tika-server -->
<jaxb.version>2.3.1</jaxb.version>
<cli.version>1.4</cli.version>
<lucene.version>7.5.0</lucene.version>
<mockito.version>2.23.4</mockito.version>
Additional Dependencies in this pom.xml ( rest all are same as earlier pom)
<dependency>
<groupId>biz.aQute</groupId>
<artifactId>bndlib</artifactId>
<version>1.50.0</version>
</dependency>
<dependency>
<groupId>org.apache.felix</groupId>
<artifactId>org.apache.felix.scr.annotations</artifactId>
<version>1.12.0</version>
</dependency>
<dependency>
<groupId>org.slf4j</groupId>
<artifactId>slf4j-api</artifactId>
<version>${slf4j.version}</version>
</dependency>
<dependency>
<groupId>org.slf4j</groupId>
<artifactId>slf4j-log4j12</artifactId>
<version>${slf4j.version}</version>
</dependency>
<dependency>
<groupId>org.slf4j</groupId>
<artifactId>slf4j-simple</artifactId>
<version>${slf4j.version}</version>
</dependency>
<dependency>
<groupId>org.slf4j</groupId>
<artifactId>jcl-over-slf4j</artifactId>
<version>${slf4j.version}</version>
</dependency>
<dependency>
<groupId>org.slf4j</groupId>
<artifactId>jul-to-slf4j</artifactId>
<version>${slf4j.version}</version>
</dependency>
Below are all extra plugins in Build.plugins( rest all are same as earlier pom.xml)
<plugin>
<artifactId>maven-compiler-plugin</artifactId>
<version>3.8.0</version>
<configuration>
<source>${maven.compiler.source}</source>
<target>${maven.compiler.target}</target>
</configuration>
</plugin>
<plugin>
<groupId>org.codehaus.mojo</groupId>
<artifactId>versions-maven-plugin</artifactId>
<version>2.7</version>
<configuration>
<generateBackupPoms>false</generateBackupPoms>
</configuration>
</plugin>
<plugin>
<groupId>de.thetaphi</groupId>
<artifactId>forbiddenapis</artifactId>
<!-- if this version contains commons-io 2.6, remove hard-coded commons-io version below -->
<version>${forbiddenapis.version}</version>
<configuration>
<targetVersion>${maven.compiler.target}</targetVersion>
<failOnUnresolvableSignatures>false</failOnUnresolvableSignatures>
<failOnUnsupportedJava>false</failOnUnsupportedJava>
<bundledSignatures>
<bundledSignature>jdk-unsafe</bundledSignature>
<bundledSignature>jdk-deprecated</bundledSignature>
<bundledSignature>jdk-non-portable</bundledSignature>
<bundledSignature>jdk-internal</bundledSignature>
<bundledSignature>commons-io-unsafe-${commons.io.version}</bundledSignature>
</bundledSignatures>
</configuration>
<executions>
<execution>
<goals>
<goal>check</goal>
<goal>testCheck</goal>
</goals>
</execution>
</executions>
</plugin>
<plugin>
<groupId>org.apache.felix</groupId>
<artifactId>maven-bundle-plugin</artifactId>
<version>${maven.bundle.version}</version>
</plugin>
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-surefire-plugin</artifactId>
<version>${maven.surefire.version}</version> <!-- versions greater than this don't like System.exit calls in tika-batch -->
<configuration>
<argLine>-Xmx3072m -Duser.timezone=UTC</argLine>
</configuration>
</plugin>
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-shade-plugin</artifactId>
<version>${maven.shade.version}</version>
</plugin>
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-release-plugin</artifactId>
<version>2.5.3</version>
<dependencies>
<dependency>
<groupId>org.apache.maven.scm</groupId>
<artifactId>maven-scm-provider-gitexe</artifactId>
<version>1.9.5</version>
</dependency>
</dependencies>
</plugin>
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-enforcer-plugin</artifactId>
<version>3.0.0-M2</version>
<executions>
<execution>
<id>enforce</id>
<configuration>
<rules>
<dependencyConvergence />
<requireMavenVersion>
<version>3.1</version>
</requireMavenVersion>
</rules>
</configuration>
<goals>
<goal>enforce</goal>
</goals>
</execution>
</executions>
</plugin>
The Jacoco Plugin is present in this pom file too which is same as earlier pom file.
I tried placing in this file and building it. Didnt work. THen tried placing jacoco plugin in Root pom file , didnt work. Gives the same above mentionde error.
Please HELP!!
in my code i insert jacoco plugin in root pom under pluginManagement tag:
<pluginManagement>
<plugins>
<plugin>
<groupId>org.jacoco</groupId>
<artifactId>jacoco-maven-plugin</artifactId>
<version>0.7.9</version>
<executions>
<execution>
<id>default-prepare-agent</id>
<goals>
<goal>prepare-agent</goal>
</goals>
</execution>
<execution>
<id>default-report</id>
<phase>prepare-package</phase>
<goals>
<goal>report</goal>
</goals>
</execution>
</executions>
</plugin>
</plugins>
</pluginManagement>
And in every sub-module where I do unit test I insert the following pom.xml configuration:
<build>
<plugins>
<plugin>
<groupId>org.jacoco</groupId>
<artifactId>jacoco-maven-plugin</artifactId>
</plugin>
</plugins>
</build>
You have to enable jacoco plugin only inside java module where there are unit test.
So I have an application that uses both, Java and Kotlin sourcefiles (all placed in the /src/main/kotlin directory because we eventually want to migrate to kotlin anyway) and that generates an hibernate metamodel.
So our maven compile plugins look like this:
<build>
<sourceDirectory>${project.basedir}/src/main/kotlin</sourceDirectory>
<testSourceDirectory>${project.basedir}/src/test/kotlin</testSourceDirectory>
<finalName>${project.artifactId}</finalName>
<plugins>
<plugin>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-maven-plugin</artifactId>
</plugin>
<!--COMPILATION-->
<plugin>
<groupId>org.jetbrains.kotlin</groupId>
<artifactId>kotlin-maven-plugin</artifactId>
<version>${kotlin.version}</version>
<executions>
<execution>
<id>kapt</id>
<goals>
<goal>kapt</goal>
</goals>
<configuration>
<sourceDirs>
<sourceDir>src/main/kotlin</sourceDir>
</sourceDirs>
<annotationProcessorPaths>
<annotationProcessorPath>
<groupId>org.hibernate</groupId>
<artifactId>hibernate-jpamodelgen</artifactId>
<version>${hibernate.version}</version>
</annotationProcessorPath>
</annotationProcessorPaths>
</configuration>
</execution>
<execution>
<id>compile</id>
<phase>compile</phase>
<goals>
<goal>compile</goal>
</goals>
</execution>
<execution>
<id>test-compile</id>
<phase>test-compile</phase>
<goals>
<goal>test-compile</goal>
</goals>
</execution>
</executions>
<configuration>
<jvmTarget>1.8</jvmTarget>
<compilerPlugins>
<plugin>all-open</plugin>
<plugin>jpa</plugin>
<plugin>spring</plugin>
<plugin>no-arg</plugin>
</compilerPlugins>
<args>
<arg>-Xjsr305=strict</arg>
</args>
<pluginOptions>
<!-- Each annotation is placed on its own line -->
<option>all-open:annotation=javax.ejb.Stateless</option>
<option>no-arg:annotation=javax.ejb.Stateless</option>
<option>all-open:annotation=javax.ws.rs.ext.Provider</option>
<option>no-arg:annotation=javax.ws.rs.ext.Provider</option>
</pluginOptions>
</configuration>
<dependencies>
<dependency>
<groupId>org.jetbrains.kotlin</groupId>
<artifactId>kotlin-maven-allopen</artifactId>
<version>${kotlin.version}</version>
</dependency>
<dependency>
<groupId>org.jetbrains.kotlin</groupId>
<artifactId>kotlin-maven-noarg</artifactId>
<version>${kotlin.version}</version>
</dependency>
</dependencies>
</plugin>
<plugin>
<!-- Check https://kotlinlang.org/docs/reference/using-maven.html#compiling-kotlin-and-java-sources -->
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-compiler-plugin</artifactId>
<version>3.5.1</version>
<executions>
<!-- Replacing default-compile as it is treated specially by maven -->
<execution>
<id>default-compile</id>
<phase>none</phase>
</execution>
<!-- Replacing default-testCompile as it is treated specially by maven -->
<execution>
<id>default-testCompile</id>
<phase>none</phase>
</execution>
<execution>
<id>java-compile</id>
<phase>compile</phase>
<goals> <goal>compile</goal> </goals>
</execution>
<execution>
<id>java-test-compile</id>
<phase>test-compile</phase>
<goals> <goal>testCompile</goal> </goals>
</execution>
</executions>
</plugin>
<!--END COMPILATION-->
<!-- ... -->
</plugins>
</build>
this results in
[WARNING] Duplicate source root: /home/cypherk/code/myapp/target/generated-sources/kapt/compile
[WARNING] Duplicate source root: /home/cypherk/code/myapp/target/generated-sources/kaptKotlin/compile
which I have no idea why but may be related.
If I do not declare a dependency to
<dependency>
<groupId>org.hibernate</groupId>
<artifactId>hibernate-jpamodelgen</artifactId>
<version>${hibernate.version}</version>
</dependency>
under <dependencies>, that's alright, everything gets generated the way it's supposed to get generated in /target/generated-sources/kapt/compile/. (/target/generated-sources-kaptKotlin/compile gets generated but remains empty).
However, if I do declare the dependency under <dependencies>, the java (but not kotlin) entities will get generated a second time in /target/generated-sources/annotations/, which will trigger a compilation error because all Java-based generated classes have a duplicate class in the kapt folder.
I'm no expert on Maven, I just use it because that's what we are supposed to use for the project. As such, I find simply declaring a dependency having such an effect exceedingly unintuitive.
Could anybody explain to me why this is happening?
I don't know why, but when you change the compile execution to:
<execution>
<id>compile</id>
<phase>compile</phase>
<goals>
<goal>compile</goal>
</goals>
<configuration>
<sourceDirs>
<sourceDir>src/main/kotlin</sourceDir>
</sourceDirs>
</configuration>
</execution>
It should work. Same with test-compile.
I'm trying to use Lombok in combination with AspectJ and Maven.
So, what's the problem?
When I use the AspectJ Maven Plugin (www.mojohaus.org/aspectj-maven-plugin/), it takes the sources and compiles them and ignores changes made by Lombok. I followed this tutorial and came up with this code and AspectJ works, but Lombok dies with this message:
[WARNING] You aren't using a compiler supported by lombok, so lombok will not work and has been disabled.
Your processor is: org.aspectj.org.eclipse.jdt.internal.compiler.apt.dispatch.BatchProcessingEnvImpl
Lombok supports: sun/apple javac 1.6, ECJ
So, does anyone know how to get Lombok in combination with AspectJ working?
Use ajc to process classes.
<plugin>
<groupId>org.codehaus.mojo</groupId>
<artifactId>aspectj-maven-plugin</artifactId>
<version>1.11</version>
<configuration>
<complianceLevel>8</complianceLevel>
<source>8</source>
<target>8</target>
<showWeaveInfo>true</showWeaveInfo>
<verbose>true</verbose>
<Xlint>ignore</Xlint>
<encoding>UTF-8</encoding>
<!-- IMPORTANT-->
<excludes>
<exclude>**/*.java</exclude>
</excludes>
<forceAjcCompile>true</forceAjcCompile>
<sources/>
<!-- IMPORTANT-->
<aspectLibraries>
<aspectLibrary>
<groupId>you.own.aspect.libary</groupId>
<artifactId>your-library</artifactId>
</aspectLibrary>
</aspectLibraries>
</configuration>
<executions>
<execution>
<id>default-compile</id>
<phase>process-classes</phase>
<goals>
<!-- use this goal to weave all your main classes -->
<goal>compile</goal>
</goals>
<configuration>
<weaveDirectories>
<weaveDirectory>${project.build.directory}/classes</weaveDirectory>
</weaveDirectories>
</configuration>
</execution>
<execution>
<id>default-testCompile</id>
<phase>process-test-classes</phase>
<goals>
<!-- use this goal to weave all your test classes -->
<goal>test-compile</goal>
</goals>
<configuration>
<weaveDirectories>
<weaveDirectory>${project.build.directory}/test-classes</weaveDirectory>
</weaveDirectories>
</configuration>
</execution>
</executions>
</plugin>
Use delombok to generate normal source code. And then proceed as you would if Lombok were not being used.
Store your Lombok-annotated code in main/src/lombok (for example) and then have the delombok plugin convert these annotations into normal code and into the directory /delomboked (for example).
I tried various solutions, finally specifying the javac compiler option like the below one worked
This works for me with command line mvn clean install, but in Eclipse IDE, the problem is not solved, eg. log is not correctly recognized for #Slf4j.
<plugin>
<groupId>org.codehaus.mojo</groupId>
<artifactId>aspectj-maven-plugin</artifactId>
<version>1.10</version>
<configuration>
<verbose>true</verbose>
<showWeaveInfo>true</showWeaveInfo>
<source>1.7</source>
<target>1.7</target>
<complianceLevel>1.7</complianceLevel>
<!-- <encoding>UTF-8</encoding> -->
<verbose>false</verbose>
<Xlint>ignore</Xlint>
<outxml>true</outxml>
<forceAjcCompile>true</forceAjcCompile>
<reweavable>false</reweavable>
<aspectLibraries>
<aspectLibrary>
<groupId>com.aspectj.library.yours</groupId>
<artifactId>your-library</artifactId>
</aspectLibrary>
</aspectLibraries>
<!-- this is important: start-->
<sources/>
<weaveDirectories>
<weaveDirectory>${project.build.directory}/classes</weaveDirectory>
</weaveDirectories>
<!-- this is important: end-->
</configuration>
<executions>
<execution>
<!-- The right phase is very important! Compile and weave aspects after all classes compiled by javac -->
<phase>process-classes</phase>
<goals>
<goal>compile</goal>
</goals>
</execution>
</executions>
<dependencies>
<dependency>
<groupId>org.aspectj</groupId>
<artifactId>aspectjweaver</artifactId>
<version>1.8.9</version>
</dependency>
<dependency>
<groupId>org.aspectj</groupId>
<artifactId>aspectjtools</artifactId>
<version>1.8.9</version>
</dependency>
</dependencies>
</plugin>
I had a configuration/excludes/exclude section with the spring-boot-maven-plugin where the "aspectjweaver" dependency had been declared. The exclude section had "org.projectlombok" in it, and looks like that's why none of my lombok annotations were being processed while building using "mvn clean install"
I initially had this:
<plugin>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-maven-plugin</artifactId>
<dependencies>
<dependency>
<groupId>org.aspectj</groupId>
<artifactId>aspectjweaver</artifactId>
<version>${aspectj.version}</version>
</dependency>
</dependencies>
<configuration>
<excludes> <!------- THIS IS WHERE my problem started by exluding lombok -->
<exclude>
<groupId>org.projectlombok</groupId>
<artifactId>lombok</artifactId>
</exclude>
</excludes>
</configuration>
</plugin>
When I removed the excludes part, then the build started taking the lombok annotations and worked. This is my section now:
<plugin>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-maven-plugin</artifactId>
<dependencies>
<dependency>
<groupId>org.aspectj</groupId>
<artifactId>aspectjweaver</artifactId>
<version>${aspectj.version}</version>
</dependency>
</dependencies>
</plugin>
SpringBoot AND Java: 16
At this moment (19-11-2022) aspectJ plugin not support 17
<parent>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-parent</artifactId>
<version>2.7.5</version>
<relativePath/>
</parent>
...
YOUR GROUP, ARTIFACT NAME, VERSION ETC HERE
...
<dependencies>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-web</artifactId>
</dependency>
<dependency>
<groupId>org.aspectj</groupId>
<artifactId>aspectjweaver</artifactId>
<scope>compile</scope>
</dependency>
<dependency>
<groupId>org.projectlombok</groupId>
<artifactId>lombok</artifactId>
<version>1.18.24</version>
</dependency>
<dependency>
<groupId>kkl.lib.dev.tools</groupId>
<artifactId>lib-dev-tools</artifactId>
<version>1.0-SNAPSHOT</version>
</dependency>
</dependencies>
<build>
<plugins>
<plugin>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-maven-plugin</artifactId>
<configuration>
<excludes>
<exclude>
<groupId>org.projectlombok</groupId>
<artifactId>lombok</artifactId>
</exclude>
</excludes>
</configuration>
</plugin>
<plugin>
<groupId>org.codehaus.mojo</groupId>
<artifactId>aspectj-maven-plugin</artifactId>
<version>1.14.0</version>
<configuration>
<showWeaveInfo/>
<sources/>
<weaveDirectories>
<weaveDirectory>${project.build.directory}/classes</weaveDirectory>
</weaveDirectories>
<forceAjcCompile>true</forceAjcCompile>
<source>16</source>
<target>16</target>
<proc>none</proc>
<complianceLevel>16</complianceLevel>
</configuration>
<executions>
<execution>
<phase>process-classes</phase>
<goals>
<goal>compile</goal>
</goals>
</execution>
</executions>
</plugin>
</plugins>
</build>
After reseach and testing all day, here is my success build.
Main idea is using javac to compile code first (compliance with lombok) and after that use aspectj only for weaving class.
<build>
<extensions>
<extension>
<groupId>kr.motd.maven</groupId>
<artifactId>os-maven-plugin</artifactId>
<version>1.6.1</version>
</extension>
</extensions>
<plugins>
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-antrun-plugin</artifactId>
<version>1.8</version>
<executions>
<execution>
<id>unwovenClassesFolder</id>
<phase>generate-resources</phase>
<configuration>
<tasks>
<delete dir="${project.build.directory}/unwoven-classes"/>
<mkdir dir="${project.build.directory}/unwoven-classes"/>
</tasks>
</configuration>
<goals>
<goal>run</goal>
</goals>
</execution>
</executions>
</plugin>
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-compiler-plugin</artifactId>
<version>3.1</version>
<executions>
<execution>
<!-- Modifying output directory of default compile because non-weaved classes must be stored
in separate folder to not confuse ajc by reweaving already woven classes (which leads to
to ajc error message like "bad weaverState.Kind: -115") -->
<id>default-compile</id>
<configuration>
<source>16</source>
<target>16</target>
<outputDirectory>${project.build.directory}/unwoven-classes</outputDirectory>
</configuration>
</execution>
</executions>
</plugin>
<plugin>
<groupId>org.codehaus.mojo</groupId>
<artifactId>aspectj-maven-plugin</artifactId>
<version>1.14.0</version>
<dependencies>
<dependency>
<groupId>org.aspectj</groupId>
<artifactId>aspectjtools</artifactId>
<version>${aspectj.version}</version>
</dependency>
</dependencies>
<configuration>
<showWeaveInfo>true</showWeaveInfo>
<verbose>true</verbose>
<Xlint>ignore</Xlint>
<encoding>UTF-8</encoding>
<weaveDirectories>
<weaveDirectory>${project.build.directory}/unwoven-classes</weaveDirectory>
</weaveDirectories>
<!-- IMPORTANT-->
<excludes>
<exclude>**/*.java</exclude>
</excludes>
<forceAjcCompile>true</forceAjcCompile>
<sources/>
<!-- IMPORTANT-->
<complianceLevel>16</complianceLevel>
<source>16</source>
<target>16</target>
</configuration>
<executions>
<execution>
<!-- Compile and weave aspects after all classes compiled by javac -->
<phase>process-classes</phase>
<goals>
<goal>compile</goal>
</goals>
<configuration>
<complianceLevel>16</complianceLevel>
</configuration>
</execution>
</executions>
</plugin>
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-surefire-plugin</artifactId>
<version>2.22.2</version>
</plugin>
</plugins>
</build>
What is the recommended Maven setup for using Dagger 2 in a mixed Java/Kotlin project?
I found a sample project which uses Gradle: https://github.com/damianpetla/kotlin-dagger-example
Something similar with Maven would be very helpful.
UPDATE: What have I tried?
I used the Kotlin configuration from kotlinlang.org/docs/reference/using-maven.html
and the Dagger configuration from google.github.io/dagger.
I also used the build-helper-maven-plugin plugin to integrate the annotation processing in IDEA.
My main problem was that I run into compilation cycles. My configuration mixed the compilation of Kotlin and calling the annotation processor, which generates Dagger2 classes. I unsystematically tried to separate both phases but lacked the deeper Maven understanding to get it working.
javac can scan both source files (java) and classes in search for annotations:
http://docs.oracle.com/javase/7/docs/technotes/tools/windows/javac.html#processing
This means that you can make this work if you don't have any Dagger-generated classes referenced in Kotlin code (which means Dagger module implementations)
invoke kotlin compiler (no Dagger generated types in Kotlin code)
invoke annotation processor (processes annotations in both java files and kotlin-compiled files)
invoke java compiler - has access to both Dagger generated types and Kotlin types
You can write your services in both java and kotlin, but the module must be created by a java class
Here is the corresponding pom.xml
<?xml version="1.0" encoding="UTF-8"?>
<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/xsd/maven-4.0.0.xsd">
<modelVersion>4.0.0</modelVersion>
<groupId>com.test</groupId>
<artifactId>testkotlindagger</artifactId>
<version>1.0-SNAPSHOT</version>
<properties>
<kotlin.version>1.0.6</kotlin.version>
<dagger2.version>2.7</dagger2.version>
</properties>
<dependencies>
<dependency>
<groupId>org.jetbrains.kotlin</groupId>
<artifactId>kotlin-stdlib</artifactId>
<version>${kotlin.version}</version>
</dependency>
<dependency>
<groupId>org.jetbrains.kotlin</groupId>
<artifactId>kotlin-test</artifactId>
<version>${kotlin.version}</version>
<scope>test</scope>
</dependency>
<!-- Dagger 2 -->
<dependency>
<groupId>com.google.dagger</groupId>
<artifactId>dagger</artifactId>
<version>${dagger2.version}</version>
</dependency>
<dependency>
<groupId>com.google.dagger</groupId>
<artifactId>dagger-compiler</artifactId>
<version>${dagger2.version}</version>
<optional>true</optional>
</dependency>
</dependencies>
<build>
<plugins>
<plugin>
<artifactId>kotlin-maven-plugin</artifactId>
<groupId>org.jetbrains.kotlin</groupId>
<version>${kotlin.version}</version>
<executions>
<execution>
<id>compile</id>
<phase>compile</phase>
<goals> <goal>compile</goal> </goals>
<configuration>
<sourceDirs>
<source>src/main/java</source>
<source>src/main/kotlin</source>
</sourceDirs>
</configuration>
</execution>
<execution>
<id>test-compile</id>
<phase>test-compile</phase>
<goals> <goal>test-compile</goal> </goals>
</execution>
</executions>
</plugin>
<plugin>
<groupId>org.bsc.maven</groupId>
<artifactId>maven-processor-plugin</artifactId>
<version>2.2.4</version>
<executions>
<execution>
<id>process</id>
<goals>
<goal>process</goal>
</goals>
<phase>compile</phase>
<configuration>
<outputDirectory>target/generated-sources/annotations</outputDirectory>
</configuration>
</execution>
</executions>
</plugin>
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-compiler-plugin</artifactId>
<version>3.5.1</version>
<executions>
<!-- Replacing default-compile as it is treated specially by maven -->
<execution>
<id>default-compile</id>
<phase>none</phase>
</execution>
<!-- Replacing default-testCompile as it is treated specially by maven -->
<execution>
<id>default-testCompile</id>
<phase>none</phase>
</execution>
<execution>
<id>java-compile</id>
<phase>compile</phase>
<goals> <goal>compile</goal> </goals>
</execution>
<execution>
<id>java-test-compile</id>
<phase>test-compile</phase>
<goals> <goal>testCompile</goal> </goals>
</execution>
</executions>
</plugin>
</plugins>
</build>
</project>
On the other hand, if you include Dagger-generated types in your kotlin code, you must have these available before kotlin code is compiled, which means you need Kotlin-aware annotation processor (KAPT)
In this scenario the problem boils down to the question:
Is kapt supported in maven?
Sadly, the answer is no, but there is a bug filed to support it:
https://youtrack.jetbrains.com/issue/KT-14478
Since kapt is now supported in maven, you can write your services in both Java and Kotlin, and the module can be created by either a Java class or a Kotlin class. You can configure pom.xml build file like this:
<dependencies>
<dependency>
<groupId>org.jetbrains.kotlin</groupId>
<artifactId>kotlin-stdlib</artifactId>
<version>1.7.20</version>
</dependency>
<dependency>
<groupId>com.google.dagger</groupId>
<artifactId>dagger</artifactId>
<version>2.22</version>
</dependency>
</dependencies>
<build>
<plugins>
<plugin>
<groupId>org.jetbrains.kotlin</groupId>
<artifactId>kotlin-maven-plugin</artifactId>
<version>${kotlin.version}</version>
<executions>
<execution>
<id>kapt</id>
<goals>
<goal>kapt</goal>
</goals>
<configuration>
<sourceDirs>
<sourceDir>src/main/kotlin</sourceDir>
<sourceDir>src/main/java</sourceDir>
</sourceDirs>
<annotationProcessorPaths>
<!-- Specify your annotation processors here. -->
<annotationProcessorPath>
<groupId>com.google.dagger</groupId>
<artifactId>dagger-compiler</artifactId>
<version>2.22</version>
</annotationProcessorPath>
</annotationProcessorPaths>
</configuration>
</execution>
<execution>
<id>compile</id>
<phase>compile</phase>
<goals>
<goal>compile</goal>
</goals>
<configuration>
<sourceDirs>
<sourceDir>src/main/kotlin</sourceDir>
<sourceDir>src/main/java</sourceDir>
</sourceDirs>
</configuration>
</execution>
<execution>
<id>test-compile</id>
<phase>test-compile</phase>
<goals>
<goal>test-compile</goal>
</goals>
<configuration>
<sourceDirs>
<sourceDir>src/test/kotlin</sourceDir>
<sourceDir>src/test/java</sourceDir>
</sourceDirs>
</configuration>
</execution>
</executions>
</plugin>
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-compiler-plugin</artifactId>
<version>3.8.1</version>
<configuration>
<source>11</source>
<target>11</target>
</configuration>
<executions>
<execution>
<id>default-compile</id>
<phase>none</phase>
</execution>
<execution>
<id>default-testCompile</id>
<phase>none</phase>
</execution>
<execution>
<id>java-compile</id>
<phase>compile</phase>
<goals>
<goal>compile</goal>
</goals>
</execution>
<execution>
<id>java-test-compile</id>
<phase>test-compile</phase>
<goals>
<goal>testCompile</goal>
</goals>
</execution>
</executions>
</plugin>
</plugins>
</build>
These are the links usefull to read when you want to create maven project with java, kotlin and dagger:
https://www.baeldung.com/kotlin/maven-java-project
https://kotlinlang.org/docs/kapt.html#using-in-maven
https://github.com/google/dagger#installation
Please note that kapt is still not supported for IntelliJ IDEA's own build system. Because of this, you will not be able to compile and run the application in the Intellij IDE by clicking on the Play button next to the Main method. To run the application, first build the project using the maven toolbox. After that, you can run the application in the Intellij IDE by clicking on the Play button next to the Main method. Alternatively you can create a run configuration to run the jar file. After that, you can run this configuration, or run it in debug mode by clicking on the run or debug button next to the run configuration combobox.