Annotation processor is not being invoked by the maven compiler plugin - maven

I have written my annotation processor as a separate maven project, it contains my custom annotation and its processor. I have added this project as a dependency to a project where the classes have been annotated with the custom annotation. I want this processor to be invoked as part of the maven build.
Following is the pom snippet -
<!-- Compiler configuration -->
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-compiler-plugin</artifactId>
<version>3.1</version>
<configuration>
<source>1.8</source>
<target>1.8</target>
<annotationProcessorPaths>
<path>
<groupId>com.test.processor</groupId>
<artifactId>processor</artifactId>
<version>1.0.0</version>
</path>
</annotationProcessorPaths>
</configuration>
</plugin>
<!-- dependency for processor project -->
<dependencies>
<dependency>
<groupId>com.test.processor</groupId>
<artifactId>processor</artifactId>
<version>1.0.0</version>
</dependency>
</dependencies>
But the problem is that, the annotation processor is not getting triggered. Am I missing something or doing anything wrong.
Kindly guide me on this.

Try switching to a newer version of the maven-compiler-plugin.
I'm using 3.6.1 with the same configuration as you and it works.

Related

Spring boot application issues with using springdoc-openapi-javadoc

I am using springdoc-openapi-ui (Version 1.6.12) in my spring boot application (Spring boot version 2.7.2) for API documentation. It works fine and I had no issue with it. However I wanted to add the feature to push javadoc comments to swagger-ui as well.
For that I did add the dependency springdoc-openapi-javadoc (Version 1.6.12) to my POM file. To support the dependency to push the javadoc comments, I did add the following maven plugin as well which is required by the documentations.
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-compiler-plugin</artifactId>
<configuration>
<annotationProcessorPaths>
<path>
<groupId>com.github.therapi</groupId>
<artifactId>therapi-runtime-javadoc-scribe</artifactId>
<version>0.15.0</version>
</path>
</annotationProcessorPaths>
</configuration>
</plugin>
After adding the plugin and the dependency, I had so many issues within the application. As an example, I could not add new logs and build the application. I am adding logs using lombok and its annotation #Slf4j. The moment I add a new log, I get the following error.
java: cannot find symbol
symbol: variable log
location: class com.example.swaggerDemo.controllers.BookController
The root cause for this issue is not very clear for me. Did anyone faced the same issue? Is there a solution available or is there something wrong in my implementation which is leading to this error?
Your advices are kindly appreciated and thanks!
You need to add lombok and therapi-runtime-javadoc-scribe to the maven-compiler-plugin configuration
ie.
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-compiler-plugin</artifactId>
<configuration>
<annotationProcessorPaths>
<path>
<groupId>com.github.therapi</groupId>
<artifactId>therapi-runtime-javadoc-scribe</artifactId>
<version>0.15.0</version>
</path>
<path>
<groupId>org.projectlombok</groupId>
<artifactId>lombok</artifactId>
<version>${lombok.version}</version>
</path>
</annotationProcessorPaths>
</configuration>
</plugin>

Lombok with Netbeans/Maven Annotations are not Recognized/Working

I tried to update my existing Lombok version 1.16.16 to 1.18.2 in Netbeans 8.2 (maven multi-module project).
Unfortunately, all versions higher than 1.16.18 are not working. No annotation is recognized and I get compile errors in the IDE. The pure maven build is working.
You have to configure the maven compiler plugin. Add the following snippet to the build section of your pom (at best to your parent pom or to each project which is using Lombok).
If you already have a configuration of the build plugin in your pom make sure to add the <annotationProcessorPaths> section.
This will ensure that Lombok is available during the compiling process to manipulate the AST.
pom.xml - snippet
...
<build>
<plugins>
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-compiler-plugin</artifactId>
<version>3.8.0</version>
<configuration>
<source>1.8</source>
<target>1.8</target>
<encoding>UTF-8</encoding>
<annotationProcessorPaths>
<path>
<groupId>org.projectlombok</groupId>
<artifactId>lombok</artifactId>
<version>1.18.2</version>
</path>
</annotationProcessorPaths>
</configuration>
</plugin>
</plugins>
</build>
...

Using Spring Boot without the parent POM [duplicate]

Is there a specific recommended approach to the inclusion of the spring-boot parent pom into projects that already have a required parent POM?
What do you recommend for projects that need to extend from an organizational parent (this is extremely common and even something many/most projects published to Maven central depending on the feeder repos they come from). Most of the build stuff is related to creating executable JARs (e.g. running embedded Tomcat/Jetty). There are ways to structure things so that you can get all the dependencies without extending from a parent (similar to composition vs. inheritance). You can't get a build stuff that way though.
So is it preferable to include all of the spring-boot parent pom inside of the required parent POM or to simply have a POM dependency within the project POM file.
Other options?
TIA,
Scott
You can use the spring-boot-starter-parent like a "bom" (c.f. Spring and Jersey other projects that support this feature now), and include it only in the dependency management section with scope=import.That way you get a lot of the benefits of using it (i.e. dependency management) without replacing the settings in your actual parent.
The 2 main other things it does are
define a load of properties for quickly setting versions of dependencies that you want to override
configure some plugins with default configuration (principally the Spring Boot maven plugin). So those are the things you will have to do manually if you use your own parent.
Example provided in Spring Boot documentation:
<dependencyManagement>
<dependencies>
<dependency>
<!-- Import dependency management from Spring Boot -->
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-dependencies</artifactId>
<version>2.1.3.RELEASE</version>
<type>pom</type>
<scope>import</scope>
</dependency>
</dependencies>
</dependencyManagement>
Update 2022-05-29 with 1.5.9.RELEASE.
I have full code and runable example here https://github.com/surasint/surasint-examples/tree/master/spring-boot-jdbi/9_spring-boot-no-parent (see README.txt to see that you can try)
You need this as a basic
<dependencyManagement>
<dependencies>
<dependency>
<!-- Import dependency management from Spring Boot -->
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-dependencies</artifactId>
<version>${springframework.boot.version}</version>
<type>pom</type>
<scope>import</scope>
</dependency>
</dependencies>
</dependencyManagement>
But that is not enough, you also need explicitly define goal for spring-boot-maven-plugin (If you use Spring Boot as parent, you do not have to explicitly define this)
<plugins>
<plugin>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-maven-plugin</artifactId>
<version>${springframework.boot.version}</version>
<executions>
<execution>
<goals>
<goal>repackage</goal>
</goals>
</execution>
</executions>
</plugin>
</plugins>
Otherwise you cannot build as executable jar or war.
Not yet, if you are using JSP, you need to have this:
<properties>
<failOnMissingWebXml>false</failOnMissingWebXml>
</properties>
Otherwise, you will get this error message:
[ERROR] Failed to execute goal org.apache.maven.plugins:maven-war-plugin:2.2:war (default-war) on project spring-boot-09: Error assembling WAR: webxml attribute is required (or pre-existing WEB-INF/web.xml if executi
ng in update mode) -> [Help 1]
NO NO , this is still not enough if you are using Maven Profile and Resource Filter with Spring Boot with "#" instead of "${}" (like this example https://www.surasint.com/spring-boot-maven-resource-filter/). Then you need to explicitly add this in
<resources>
<resource>
<directory>src/main/resources</directory>
<filtering>true</filtering>
</resource>
</resources>
And this in
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-resources-plugin</artifactId>
<version>2.7</version>
<configuration>
<delimiters>
<delimiter>#</delimiter>
</delimiters>
<useDefaultDelimiters>false</useDefaultDelimiters>
</configuration>
</plugin>
See the example in the link https://www.surasint.com/spring-boot-with-no-parent-example/.
As per Surasin Tancharoen's answer, you may also want to define maven surefire plugin
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-surefire-plugin</artifactId>
<version>${maven-surefire-plugin.version}</version>
</plugin>
and possibly include fail-fast plugin
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-failsafe-plugin</artifactId>
<version>${maven-failsafe-plugin.version}</version>
<executions>
<execution>
<goals>
<goal>integration-test</goal>
<goal>verify</goal>
</goals>
</execution>
</executions>
</plugin>

How to build a project with AspectJ plugin which also has dependencies on querydsl plugin

I have Aspects defined in project A which can be referred from project B without any compilations issues because project A has project B as dependency. However project B needs AspectJ plugin so that aspects can be weaved via compilation/build.
Issue : My project B is using com.mysema.querydsl plugin to generate Q files for database entities. When I compile using AspectJ in eclipse (command clean aspectj:compile install) it does NOT auto generate these Q files and thus the compilation fails and weaving is not processed, overall build fails.
I have tried so many combinations of adding this dependency in AspectJ plugin but nothing works.
Please refer the pom part below:
<!-- AspectJ Maven Plugin -->
<plugin>
<groupId>org.codehaus.mojo</groupId>
<artifactId>aspectj-maven-plugin</artifactId>
<version>1.5</version>
<dependencies>
<dependency>
<groupId>com.mysema.querydsl</groupId>
<artifactId>querydsl-core</artifactId>
<version>3.6.0</version>
<scope>compile</scope>
</dependency>
</dependencies>
<configuration>
<source>${java.version}</source>
<target>${java.version}</target>
<complianceLevel>1.7</complianceLevel>
<!-- <aspectLibraries>
<aspectLibrary>
<groupId>projectA.groupId</groupId>
<artifactId>projectA.artifactId</artifactId>
</aspectLibrary>
</aspectLibraries> -->
</configuration>
<executions>
<execution>
<!-- <phase>generate-sources</phase> -->
<goals>
<goal>compile</goal>
</goals>
</execution>
</executions>
</plugin>
<!-- AspectJ Maven Plugin -->
What should be done here? I really dont want to create individual aspects in each project. All in all how to build projects with aspectj plugins which have querydsl plugin code references?

Entity mapping to DTO with DI with MapStruct

I am new in mapstruct and I am using spring as DI I follow up MapStruct documentation page regarding DI containers section 4.2 I tried to map my entity to dto as below :
#Mapper(componentModel = "spring")
public interface CustomerMapper {
#Mapping(source = "registered",target = "activeProfile")
CustomerDto customerToCustomerDto(Customer customer);
}
when i run mvn install i got this error :
java:27: error: No property named "registered" exists in source parameter(s).
#Mapping(source = "registered",target = "activeProfile")
my entity using lombok and I am sure there is registered field
please help
You don't have to to remove Lombok.
You can setup it to work before MapStruct as was described here by ahus1
https://github.com/mapstruct/mapstruct/issues/510
<!-- first de-lombok the sources to make getters/setters visible for mapstruct,
but *DON'T'* add the output directory to the sources, as we will only need it for mapstruct processing -->
<plugin>
<groupId>org.projectlombok</groupId>
<artifactId>lombok-maven-plugin</artifactId>
<version>${org.projectlombok.maven.version}</version>
<executions>
<execution>
<phase>generate-sources</phase>
<goals>
<goal>delombok</goal>
</goals>
<configuration>
<sourceDirectory>src/main/java</sourceDirectory>
<addOutputDirectory>false</addOutputDirectory>
<outputDirectory>${project.build.directory}/delombok</outputDirectory>
</configuration>
</execution>
</executions>
</plugin>
<!-- use the de-lomobok files to create the necessary mappers -->
<plugin>
<groupId>org.bsc.maven</groupId>
<artifactId>maven-processor-plugin</artifactId>
<version>2.2.4</version>
<configuration>
<defaultOutputDirectory>
${project.build.directory}/generated-sources/mapstruct
</defaultOutputDirectory>
<processors>
<processor>org.mapstruct.ap.MappingProcessor</processor>
</processors>
<sourceDirectory>
${project.build.directory}/delombok
</sourceDirectory>
</configuration>
<executions>
<execution>
<id>process</id>
<phase>generate-sources</phase>
<goals>
<goal>process</goal>
</goals>
</execution>
</executions>
</plugin>
<!-- now take the original sources together with the created mappers to the compiler -->
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-compiler-plugin</artifactId>
<version>3.0</version>
<configuration>
<annotationProcessors>
<annotationProcessor>lombok.launch.AnnotationProcessorHider$AnnotationProcessor</annotationProcessor>
</annotationProcessors>
</configuration>
</plugin>
I've solved the problem using annotationProcessors in pom.xml
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-compiler-plugin</artifactId>
<version>3.6.0</version>
<configuration>
<annotationProcessorPaths>
<path>
<groupId>org.projectlombok</groupId>
<artifactId>lombok</artifactId>
<version>${lombok.version}</version>
</path>
<path>
<groupId>org.mapstruct</groupId>
<artifactId>mapstruct-processor</artifactId>
<version>${mapstruct.version}</version>
</path>
</annotationProcessorPaths>
</configuration>
</plugin>
I removed lombok from Entity and created setters /getters manually and worked well
Neither you have to remove lombok from your project nor you have to mess up the maven compiler plugin. You just have to declare the lombok dependency before you declare the mapstruck dependency in your pom. With this order maven is able to de-lombok your classes, before mapstruct referes to the getters and setters. This is possibly a feature of maven's dependency mediation.
Dependency mediation - this determines what version of a dependency
will be used when multiple versions of an artifact are encountered.
Currently, Maven 2.0 only supports using the "nearest definition"
which means that it will use the version of the closest dependency to
your project in the tree of dependencies. You can always guarantee a
version by declaring it explicitly in your project's POM. Note that if
two dependency versions are at the same depth in the dependency tree,
until Maven 2.0.8 it was not defined which one would win, but since
Maven 2.0.9 it's the order in the declaration that counts: the first
declaration wins.
https://maven.apache.org/guides/introduction/introduction-to-dependency-mechanism.html#Transitive_Dependencies
The issue is, that Lombok generated properties are not visible to JSR-269 annotation processors. It uses internal api to modify the source elements directly instead of generating new artifacts from the annotated source files Therefore any annotation processor that relies on existence of getter/setter methods will not see them in the source code when it gets executed. Javac will pass the ,,original" source code to the annotation processor(in our case Mapstruct) without any modifications done by Lombok.
Right now the most clean solution how to get both of them working side-by-side is to move the Lombok annotated types and mappers into 2 separate projects. See an official example in Mapstruct repo.

Resources