Tech Stack being used :
Java 8
MapStruct : 1.2.0.Final
Lombok: 1.16.18
IDE: IntelliJ - Lombok Plugin already installed
Initially, I faced issues when I removed getters and setters and added #Getter and #Setter annotation, mapstruct is not able to find the property and says: Unknown property "id" in result type com.vg.once.dto.OneDto. Did you mean "null"?
I came to know that Lombok 1.16.14 or newer along with MapStruct 1.2.0.Beta1 or newer are compatible and can work together, but my versions are newer then the desired still the issue is arising.
One more solution that I have already tried is running Lombok's Delombok plugin, but still, the same issue is arising.
Below are the project files :
The Entity Object: One.java:
import lombok.Getter;
import lombok.Setter;
#Getter
#Setter
public class One {
private int id;
private Integer version;
private int projectId;
private String title;
private String code;
private int sortOrder;
}
The DTO Object: OneDTO.java :
import lombok.Getter;
import lombok.Setter;
#Getter
#Setter
public class OneDto {
private int id;
private Integer version;
private int projectId;
private String title;
private String code;
private int sortOrder;
}
Mapper Class : OneMapper.java
import org.mapstruct.Mapper;
import org.mapstruct.Mapping;
import com.vg.once.dto.OneDto;
import com.vg.once.entity.One;
#Mapper
public interface OneMapper {
#Mapping(target="id", source="one.id")
OneDto createOne (One one);
}
pom.xml
<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
<modelVersion>4.0.0</modelVersion>
<groupId>com.vg</groupId>
<artifactId>mapstruct</artifactId>
<version>0.0.1-SNAPSHOT</version>
<name>Mapstruct-test</name>
<properties>
<java.version>1.8</java.version>
<org.mapstruct.version>1.2.0.Final</org.mapstruct.version>
<org.projectlombok.version>1.16.18</org.projectlombok.version>
</properties>
<dependencies>
<dependency>
<groupId>org.projectlombok</groupId>
<artifactId>lombok</artifactId>
<version>${org.projectlombok.version}</version>
<scope>provided</scope>
</dependency>
<dependency>
<groupId>org.mapstruct</groupId>
<artifactId>mapstruct-jdk8</artifactId>
<version>${org.mapstruct.version}</version>
</dependency>
</dependencies>
<build>
<plugins>
<plugin>
<groupId>org.projectlombok</groupId>
<artifactId>lombok-maven-plugin</artifactId>
<version>1.16.18.1</version>
<executions>
<execution>
<phase>generate-sources</phase>
<goals>
<goal>delombok</goal>
</goals>
</execution>
</executions>
<configuration>
<sourceDirectory>src/main/java</sourceDirectory>
<addOutputDirectory>false</addOutputDirectory>
<outputDirectory>${project.build.directory}/delombok</outputDirectory>
<encoding>UTF-8</encoding>
<skip>false</skip>
<verbose>false</verbose>
</configuration>
</plugin>
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-compiler-plugin</artifactId>
<version>3.6.1</version>
<configuration>
<source>${java.version}</source>
<target>${java.version}</target>
<annotationProcessorPaths>
<path>
<groupId>org.mapstruct</groupId>
<artifactId>mapstruct-processor</artifactId>
<version>${org.mapstruct.version}</version>
</path>
</annotationProcessorPaths>
</configuration>
</plugin>
</plugins>
</build>
</project>
Build Trace:
[INFO] Scanning for projects...
[INFO]
[INFO] ------------------------------------------------------------------------
[INFO] Building Mapstruct-test 0.0.1-SNAPSHOT
[INFO] ------------------------------------------------------------------------
[INFO]
[INFO] --- lombok-maven-plugin:1.16.18.1:delombok (default) # mapstruct ---
[INFO] Delombok complete.
[INFO]
[INFO] --- maven-resources-plugin:2.6:resources (default-resources) # mapstruct ---
[WARNING] Using platform encoding (UTF-8 actually) to copy filtered resources, i.e. build is platform dependent!
[INFO] Copying 0 resource
[INFO]
[INFO] --- maven-compiler-plugin:3.6.1:compile (default-compile) # mapstruct ---
[INFO] Changes detected - recompiling the module!
[WARNING] File encoding has not been set, using platform encoding UTF-8, i.e. build is platform dependent!
[INFO] Compiling 5 source files to /home/vivekgupta/Documents/workspaces/mapstruct-test/mapstruct/target/classes
[INFO] -------------------------------------------------------------
[ERROR] COMPILATION ERROR :
[INFO] -------------------------------------------------------------
[ERROR] /home/vivekgupta/Documents/workspaces/mapstruct-test/mapstruct/src/main/java/com/vg/once/mapper/OneMapper.java:[12,9] Unknown property "id" in result type com.vg.once.dto.OneDto. Did you mean "null"?
[INFO] 1 error
[INFO] -------------------------------------------------------------
[INFO] ------------------------------------------------------------------------
[INFO] BUILD FAILURE
[INFO] ------------------------------------------------------------------------
[INFO] Total time: 1.637 s
[INFO] Finished at: 2017-12-06T19:23:53+05:30
[INFO] Final Memory: 19M/235M
[INFO] ------------------------------------------------------------------------
[ERROR] Failed to execute goal org.apache.maven.plugins:maven-compiler-plugin:3.6.1:compile (default-compile) on project mapstruct: Compilation failure
[ERROR] /home/vivekgupta/Documents/workspaces/mapstruct-test/mapstruct/src/main/java/com/vg/once/mapper/OneMapper.java:[12,9] Unknown property "id" in result type com.vg.once.dto.OneDto. Did you mean "null"?
[ERROR] -> [Help 1]
[ERROR]
[ERROR] To see the full stack trace of the errors, re-run Maven with the -e switch.
[ERROR] Re-run Maven using the -X switch to enable full debug logging.
[ERROR]
[ERROR] For more information about the errors and possible solutions, please read the following articles:
[ERROR] [Help 1] http://cwiki.apache.org/confluence/display/MAVEN/MojoFailureException
please share how can i get this working using both Lombok and MapStruct together?
The reason why it does not work is because Maven only uses the MapStruct processor and not the Lombok one. The annotationProcessorPaths tells maven which processors it should use.
The delombok does nothing as you are ending up with 2 files per class and I think that the maven compiler does not see them.
You have 2 options:
Option 1: Add the lombok dependency in the annotationProcessorPaths
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-compiler-plugin</artifactId>
<version>3.6.1</version>
<configuration>
<source>${java.version}</source>
<target>${java.version}</target>
<annotationProcessorPaths>
<path>
<groupId>org.projectlombok</groupId>
<artifactId>lombok</artifactId>
<version>${org.projectlombok.version}</version>
</path>
<!-- This is needed when using Lombok 1.18.16 and above -->
<path>
<groupId>org.projectlombok</groupId>
<artifactId>lombok-mapstruct-binding</artifactId>
<version>0.2.0</version>
</path>
<!-- Mapstruct should follow the lombok path(s) -->
<path>
<groupId>org.mapstruct</groupId>
<artifactId>mapstruct-processor</artifactId>
<version>${org.mapstruct.version}</version>
</path>
</annotationProcessorPaths>
</configuration>
</plugin>
Option 2:
Add the mapstruct-processor dependency to your dependencies and remove the annotationProcessorPaths. This way the maven compiler will pick up all the annotation processors that are in your dependencies.
I would advise in using Option 1, as with that you can be certain that you are not using some MapStruct transitive dependencies and internal classes in your code.
Edit:
To make sure that the IntelliJ annotation processing also works you will have to add the mapstruct-processor as a provided dependency due to IDEA-150621. IntelliJ in the moment does not use the annotationProcessorPaths from Maven to configure the project correctly.
Edit 2:
Add information and comment about lombok-mapstruct-binding needed from Lombok 1.18.16.
Just in case if somebody is looking for how to configure it using Gradle:
dependencies {
// Lombok
compileOnly 'org.projectlombok:lombok:1.18.2'
annotationProcessor 'org.projectlombok:lombok:1.18.2'
// MapStruct
compileOnly 'org.mapstruct:mapstruct-jdk8:1.2.0.Final'
annotationProcessor 'org.mapstruct:mapstruct-processor:1.2.0.Final'
}
After multiple attempts in my Spring Boot Maven project, the following finally worked:
Configuration of pom.xml:
The properties section:
<properties>
<project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
<maven.compiler.target>11</maven.compiler.target>
<maven.compiler.source>11</maven.compiler.source>
<version.lombok>1.18.18</version.lombok>
<version.mapstruct>1.4.2.Final</version.mapstruct>
<version.mapstruct-lombok>0.2.0</version.mapstruct-lombok>
</properties>
The dependencies section:
<dependency>
<groupId>org.projectlombok</groupId>
<artifactId>lombok</artifactId>
<version>${version.lombok}</version>
<optional>true</optional>
</dependency>
<dependency>
<groupId>org.mapstruct</groupId>
<artifactId>mapstruct</artifactId>
<version>${version.mapstruct}</version>
</dependency>
<dependency>
<groupId>org.projectlombok</groupId>
<artifactId>lombok-mapstruct-binding</artifactId>
<version>${version.mapstruct-lombok}</version>
</dependency>
The build plugins section:
<build>
<plugins>
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-compiler-plugin</artifactId>
<version>3.5.1</version>
<configuration>
<source>9</source>
<target>9</target>
<annotationProcessorPaths>
<path>
<groupId>org.mapstruct</groupId>
<artifactId>mapstruct-processor</artifactId>
<version>${version.mapstruct}</version>
</path>
<path>
<groupId>org.projectlombok</groupId>
<artifactId>lombok</artifactId>
<version>${version.lombok}</version>
</path>
<path>
<groupId>org.projectlombok</groupId>
<artifactId>lombok-mapstruct-binding</artifactId>
<version>${version.mapstruct-lombok}</version>
</path>
</annotationProcessorPaths>
</configuration>
</plugin>
</plugins>
</build>
Hope this helps, my mapper before did not map the field values, but now these are mapper between the source and the target + the nested list of elements in each is also being mapped along with field values.
For me solution was realy simple.
The order of the processors was important.
In my case mapstruct processor was defined before lombok processor. In case with bad order mapstruct does not generate mappings, just create instance of result class (i saw that in generated implementation).
My plugin configuration with right order:
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-compiler-plugin</artifactId>
<version>${maven.compiler.plugin.version}</version>
<configuration>
<source>15</source>
<target>15</target>
<compilerArgs>--enable-preview</compilerArgs>
<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>
And of course you need to add dependencies:
<dependencies>
<dependency>
<groupId>org.projectlombok</groupId>
<artifactId>lombok</artifactId>
<scope>provided</scope>
</dependency>
<dependency>
<groupId>org.mapstruct</groupId>
<artifactId>mapstruct</artifactId>
<version>${mapstruct.version}</version>
</dependency>
</dependencies>
I had similar issues. Turned out my MapStruct version was outdated!
I used MapStruct version 1.1.0.Final, but for Lombok support at least 1.2.0.Final is required.
If anyone is reading this when using the latest Lombok and Mapstruct library versions:-
If you are using Lombok 1.18.16 or newer then you also need to add lombok-mapstruct-binding in order to make Lombok and MapStruct work together.
https://mapstruct.org/faq/#Can-I-use-MapStruct-together-with-Project-Lombok
I feel a right way to declare versions in pom.xml is to refer to something like this for versions instead of manually specifying versions of everything. e.g. maven-compiler-plugin.version, lombok.version is already present there
properties block -
<properties>
<java.version>11</java.version>
<mapstruct.version>1.4.2.Final</mapstruct.version>
<lombok-mapstruct-binding.version>0.2.0</lombok-mapstruct-binding.version>
</properties>
dependencies block -
<dependencies>
<!-- ... -->
<dependency>
<groupId>org.projectlombok</groupId>
<artifactId>lombok</artifactId>
<optional>true</optional>
</dependency>
<dependency>
<groupId>org.mapstruct</groupId>
<artifactId>mapstruct</artifactId>
<version>${mapstruct.version}</version>
</dependency>
<dependency>
<groupId>org.mapstruct</groupId>
<artifactId>mapstruct-processor</artifactId>
<version>${mapstruct.version}</version>
</dependency>
<dependency>
<groupId>org.projectlombok</groupId>
<artifactId>lombok-mapstruct-binding</artifactId>
<version>${lombok-mapstruct-binding.version}</version>
</dependency>
<!-- ... -->
</dependencies>
build block -
<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.apache.maven.plugins</groupId>
<artifactId>maven-compiler-plugin</artifactId>
<version>${maven-compiler-plugin.version}</version>
<configuration>
<source>${java.version}</source>
<target>${java.version}</target>
<annotationProcessorPaths>
<path>
<groupId>org.projectlombok</groupId>
<artifactId>lombok</artifactId>
<version>${lombok.version}</version>
</path>
<path>
<groupId>org.projectlombok</groupId>
<artifactId>lombok-mapstruct-binding</artifactId>
<version>${lombok-mapstruct-binding.version}</version>
</path>
<path>
<groupId>org.mapstruct</groupId>
<artifactId>mapstruct-processor</artifactId>
<version>${mapstruct.version}</version>
</path>
</annotationProcessorPaths>
</configuration>
</plugin>
</plugins>
</build>
For issues after upgrading Intellij to 2020.3 version, following solution worked for me.
Use lombok version: 1.18.16, lombok-mapstruct-binding: 0.2.0
<dependency>
<groupId>org.projectlombok</groupId>
<artifactId>lombok</artifactId>
<version>1.18.16</version>
<scope>provided</scope>
</dependency>
<dependency>
<groupId>org.projectlombok</groupId>
<artifactId>lombok-mapstruct-binding</artifactId>
<version>0.2.0</version>
</dependency>
Change the order of the lombok and mapstruct plugin path in annotation processing section of plugins:
<plugins>
<plugin>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-maven-plugin</artifactId>
</plugin>
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-compiler-plugin</artifactId>
<version>3.5.1</version>
<configuration>
<source>11</source>
<target>11</target>
<annotationProcessorPaths>
<path>
<groupId>org.projectlombok</groupId>
<artifactId>lombok</artifactId>
<version>${org.projectlombok.version}</version>
</path>
<path>
<groupId>org.mapstruct</groupId>
<artifactId>mapstruct-processor</artifactId>
<version>${org.mapstruct.version}</version>
</path>
</annotationProcessorPaths>
</configuration>
</plugin>
</plugins>
Apparently this is how you are supposed to load multiple annotation processors in Gradle
dependencies {
implementation "org.mapstruct:mapstruct:1.4.2.Final", "org.projectlombok:lombok:1.18.20"
annotationProcessor "org.mapstruct:mapstruct-processor:1.4.2.Final", "org.projectlombok:lombok:1.18.20", "org.projectlombok:lombok-mapstruct-binding:0.2.0"
}
If someone is still looking for this answer, I faced a similar issue with JOOQ + MapStruct Integration. The answer is the order of paths matters
IntellijIdea 2020.2.3
Java 8
Spring Framework 2.4.0
My build snippet
<build>
<plugins>
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-compiler-plugin</artifactId>
<version>${maven.compiler.plugin.version}</version>
<configuration>
<source>${java.version}</source>
<target>${java.version}</target>
<annotationProcessorPaths>
<path>
<groupId>org.projectlombok</groupId>
<artifactId>lombok</artifactId>
<version>${org.lombok.version}</version>
</path>
<path>
<groupId>org.mapstruct</groupId>
<artifactId>mapstruct-processor</artifactId>
<version>${mapstruct.version}</version>
</path>
<!-- This is needed when using Lombok 1.8.16 and above -->
<path>
<groupId>org.projectlombok</groupId>
<artifactId>lombok-mapstruct-binding</artifactId>
<version>${org.lombok-mapstruct-binding.version}</version>
</path>
</annotationProcessorPaths>
</configuration>
</plugin>
<plugin>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-maven-plugin</artifactId>
<version>${spring.boot.version}</version>
</plugin>
</plugins>
</build>
The mapstruct was just returning a null instance. Recently I upgraded the Intellij version to 2020.3, and spring boot 2.4.0, and landed into this situation.
When I changed the spring version to 2.3.o.RELEASE, I could see after compilation is that mapstruct was building the mappings properly.
Going through the post that mapstruct has recently updated.. but it will take time.. :) so, for now, I moved from maven to Gradle project and all working absolutely fine.. sounds weird but true...
I would be thankful if anyone would post what exactly the right issue and what's the solution.
For people who uses build gradle, this is the .gradle file I successfully created
dependencies {
compileOnly 'org.projectlombok:lombok'
annotationProcessor 'org.projectlombok:lombok'
implementation "org.projectlombok:lombok-mapstruct-binding:${gradleMapstructVersion}"
implementation "org.mapstruct:mapstruct:${mapstructVersion}"
annotationProcessor "org.mapstruct:mapstruct-processor:${mapstructVersion}"
}
The things is that, as said above, we have to use the org.projectlombok:lombok-mapstruct-binding in order to use mapstruct with lombok
I agree that the order does play its role, also when using gradle. In my case it was failing as soon I was adding subprojects { ... dependencyManagement{}} to the parent build.gradle in a multimodule setup.
If you have reached till here, that means none of the above solutions worked for you. Finally what worked for me was:
The following order of annotation processor in pom.xml
<annotationProcessorPaths>
...
<path>
<groupId>org.projectlombok</groupId>
<artifactId>lombok</artifactId>
<version>1.18.20</version>
</path>
<path>
<groupId>org.mapstruct</groupId>
<artifactId>mapstruct-processor</artifactId>
<version>${mapstruct.version}</version>
</path>
<path>
<groupId>org.projectlombok</groupId>
<artifactId>lombok-mapstruct-binding</artifactId>
<version>0.2.0</version>
</path>
...
</annotationProcessorPaths>
The following setting of Annotation Processors in Intellij IDEA Preferences. Make sure your project is in the right profile. In my case the profile is Annotation Profile for Alippo and project is alippo. I really don't know how the configuration made the difference.
For Spring-Boot the simplest configuration with exclude processing code from result jar:
pom.xml
<dependencies>
<dependency>
<groupId>org.mapstruct</groupId>
<artifactId>mapstruct</artifactId>
<version>${mapstruct.version}</version>
</dependency>
<dependency>
<groupId>org.projectlombok</groupId>
<artifactId>lombok-mapstruct-binding</artifactId>
<version>0.2.0</version>
</dependency>
<dependency>
<groupId>org.mapstruct</groupId>
<artifactId>mapstruct-processor</artifactId>
<version>${mapstruct.version}</version>
</dependency>
....
</dependencies>
<build>
<plugins>
<!-- exclude from jar-->
<plugin>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-maven-plugin</artifactId>
<configuration>
<excludes>
<exclude>
<groupId>org.projectlombok</groupId>
<artifactId>lombok</artifactId>
</exclude>
<exclude>
<groupId>org.projectlombok</groupId>
<artifactId>lombok-mapstruct-binding</artifactId>
</exclude>
<exclude>
<groupId>org.mapstruct</groupId>
<artifactId>mapstruct</artifactId>
</exclude>
</excludes>
</configuration>
</plugin>
...
</plugins>
</build>
Without lombok-mapstruct-binding it also works fine.
Maybe somebody comments, what for does it needed?
It is enough to add the following dependencies:
implementation("org.mapstruct:mapstruct:1.4.2.Final")
annotationProcessor("org.mapstruct:mapstruct-processor:1.4.2.Final")
compileOnly("org.projectlombok:lombok")
annotationProcessor("org.projectlombok:lombok")
annotationProcessor("org.projectlombok:lombok-mapstruct-binding:0.2.0")
Format: Gradle(Kotlin)
I am creating a hook in liferay 7.2 but unfortunately when I deploy it.I come across this error. I had tried increasing version of "com.google.collections" dependency and also tried adding guauva
a dependency but nothing seems to resolve this error.
My dependencies in Pom.xml is as such:
<dependencies>
<dependency>
<groupId>com.liferay.portal</groupId>
<artifactId>com.liferay.portal.kernel</artifactId>
<scope>provided</scope>
</dependency>
<dependency>
<groupId>org.osgi</groupId>
<artifactId>org.osgi.service.component.annotations</artifactId>
<scope>provided</scope>
</dependency>
<dependency>
<groupId>com.google.collections</groupId>
<artifactId>google-collections</artifactId>
<version>1.0-rc2</version>
</dependency>
<dependency>
<groupId>org.osgi</groupId>
<artifactId>osgi.cmpn</artifactId>
<version>6.0.0</version>
<scope>provided</scope>
</dependency>
</dependencies>
<build>
<plugins>
<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>
</configuration>
</plugin>
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-jar-plugin</artifactId>
<version>3.1.2</version>
<configuration>
<archive>
<manifestFile>${project.build.outputDirectory}/META-INF/MANIFEST.MF</manifestFile>
</archive>
</configuration>
</plugin>
<plugin>
<groupId>biz.aQute.bnd</groupId>
<artifactId>bnd-maven-plugin</artifactId>
<version>4.3.0</version>
<executions>
<execution>
<goals>
<goal>bnd-process</goal>
</goals>
</execution>
</executions>
<dependencies>
<dependency>
<groupId>biz.aQute.bnd</groupId>
<artifactId>biz.aQute.bndlib</artifactId>
<version>4.3.0</version>
</dependency>
<dependency>
<groupId>com.liferay</groupId>
<artifactId>com.liferay.ant.bnd</artifactId>
<version>3.2.6</version>
</dependency>
</dependencies>
Error :
org.osgi.framework.BundleException: Could not resolve module: com.allen.portal.hook [1272]_ Unresolved requirement: Import-Package: com.google.common.collect_ [Sanitized]
at org.eclipse.osgi.container.Module.start(Module.java:444)
at org.eclipse.osgi.internal.framework.EquinoxBundle.start(EquinoxBundle.java:428)
at com.liferay.portal.file.install.internal.DirectoryWatcher._startBundle(DirectoryWatcher.java:1106)
at com.liferay.portal.file.install.internal.DirectoryWatcher._startBundles(DirectoryWatcher.java:1139)
at com.liferay.portal.file.install.internal.DirectoryWatcher._process(DirectoryWatcher.java:1001)
at com.liferay.portal.file.install.internal.DirectoryWatcher.run(DirectoryWatcher.java:313)
If you have any ways to resolve this error, please help me out
Unrelated: You're using an rc2 version released in October 2009, when a release was made in December 2009? Seriously?
It looks like you're building an OSGi module, which compiles fine (because you provide the dependency). However, that does not mean that the google collections code ends up in your jar as well. The runtime expects to find it though - and as Google collections is not an OSGi bundle itself, you'll have several choices:
repackage it as OSGi bundle (and deploy it to the runtime) (or find someone who did it already)
repackage it within your own bundle
use a different implementation. Chances are that collections utility code from 2009 has found its way into more current implementations and is no longer necessary.
In short: In one way or another, you'll need to make your dependencies available at runtime. Either by fattening your own bundle (but be careful: You can't pass those collections around to other bundles if they bring their own implementation) or by relying on the implementation being available to the runtime.
The third alternative is to switch to an implementation where it's easier to make it available at runtime, preferably as OSGi bundle.
I created a liferay workspace in gradle format and it basically only contains a theme and a TemplateContextContributor-module.
Now I want to build a maven "wrapper" around both artifacts to make them compatible with some other maven-processes/-plugins while keeping the original gradle structure. I dont want to use the liferay-maven-plugin or maven-tools to build those artifacts, because it seems to behave differently from the gradle/gulp toolset when it comes to compiling scss for example.
So I created some POMs from scratch for
Theme
TemplateContextContributor-Module
First off I will take about the mechanism for the theme, which is already working:
That wrapper uses the maven-war-plugin to bundle the contents of the build/-folder, where the previously built gradle artifact resides, into a WAR-file that can be deployed by Liferay without problems.
theme pom.xml:
<properties>
<src.dir>src</src.dir>
<com.liferay.portal.tools.theme.builder.outputDir>build</com.liferay.portal.tools.theme.builder.outputDir>
<project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
</properties>
[...]
<plugin>
<artifactId>maven-war-plugin</artifactId>
<version>3.0.0</version>
<configuration>
<webResources>
<resource>
<directory>${com.liferay.portal.tools.theme.builder.outputDir}</directory>
<excludes>
<exclude>**/*.sass-cache/</exclude>
</excludes>
</resource>
</webResources>
</configuration>
</plugin>
However, I am having difficulties creating a OSGI-Compatible JAR-File for the module contents. It seems that only the META-INF/MANIFEST.MF does not contain the right information and I seemingly cannot generate it in a way that Liferay (or OSGI) understands.
this is the module pom.xml dependencies and plugins that I tried:
<dependency>
<groupId>org.apache.felix</groupId>
<artifactId>org.apache.felix.scr.ds-annotations</artifactId>
<version>1.2.10</version>
<scope>provided</scope>
</dependency>
<dependency>
<groupId>com.liferay</groupId>
<artifactId>com.liferay.gradle.plugins</artifactId>
<version>3.9.9</version>
<scope>provided</scope>
</dependency>
<dependency>
<groupId>com.liferay.portal</groupId>
<artifactId>com.liferay.portal.kernel</artifactId>
<version>2.0.0</version>
<scope>provided</scope>
</dependency>
<dependency>
<groupId>org.osgi</groupId>
<artifactId>org.osgi.service.component.annotations</artifactId>
<version>1.3.0</version>
<scope>provided</scope>
</dependency>
[...]
<plugin>
<groupId>biz.aQute.bnd</groupId>
<artifactId>bnd-maven-plugin</artifactId>
<version>3.3.0</version>
<executions>
<execution>
<goals>
<goal>bnd-process</goal>
</goals>
</execution>
</executions>
<dependencies>
<dependency>
<groupId>biz.aQute.bnd</groupId>
<artifactId>biz.aQute.bndlib</artifactId>
<version>3.2.0</version>
</dependency>
<dependency>
<groupId>com.liferay</groupId>
<artifactId>com.liferay.ant.bnd</artifactId>
<version>2.0.48</version>
</dependency>
</dependencies>
</plugin>
<plugin>
<groupId>org.apache.felix</groupId>
<artifactId>maven-scr-plugin</artifactId>
<version>1.25.0</version>
<executions>
<execution>
<id>generate-scr-scrdescriptor</id>
<goals>
<goal>scr</goal>
</goals>
</execution>
</executions>
</plugin>
I was able to create a JAR using the above but its' META-INF/MANIFEST.MF is not identical to the one produced by the gradle build:
I guess that's why Liferay does not deploy it. The log says "processing module xxx ....", but that never ends and the module does not work in Liferay.
These are the plugins I have tried in different combinations so far:
maven-build-plugin
maven-scr-plugin
maven-jar-plugin
maven-war-plugin
maven-compiler-plugin
Any help in creating a liferay-deployable module JAR would be great.
I'm not sure why you're manually building a maven wrapper for the Template Context Contributor. The Liferay (blade) samples are available for Liferay-workspace, pure Gradle as well as for Maven. I'd just go with the standard and not worry about re-inventing the wheel.
To make this answer self-contained: The current pom.xml listed in the Template Context Contributor plugin is:
<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>
<artifactId>template-context-contributor</artifactId>
<version>1.0.0</version>
<packaging>jar</packaging>
<parent>
<groupId>blade</groupId>
<artifactId>parent.bnd.bundle.plugin</artifactId>
<version>1.0.0</version>
<relativePath>../../parent.bnd.bundle.plugin</relativePath>
</parent>
<dependencies>
<dependency>
<groupId>com.liferay.portal</groupId>
<artifactId>com.liferay.portal.kernel</artifactId>
<version>2.0.0</version>
<scope>provided</scope>
</dependency>
<dependency>
<groupId>javax.portlet</groupId>
<artifactId>portlet-api</artifactId>
<version>2.0</version>
<scope>provided</scope>
</dependency>
<dependency>
<groupId>javax.servlet</groupId>
<artifactId>javax.servlet-api</artifactId>
<version>3.0.1</version>
<scope>provided</scope>
</dependency>
<dependency>
<groupId>org.osgi</groupId>
<artifactId>org.osgi.service.component.annotations</artifactId>
<version>1.3.0</version>
<scope>provided</scope>
</dependency>
</dependencies>
<build>
<finalName>com.liferay.blade.template.context.contributor-${project.version}</finalName>
</build>
</project>
I am running SonarQuebe 6.2 on my local machine, I have Spring Boot Java 8 project with written unit tests that I want to upload to Sonar for static analysis all together with code coverage.
Code coverage is generated - I have my JaCoCo HTML report, JUnit XML test files are generated but my Sonar seems to miss Unit Tests result even thought that Code Coverage is diplayed:
pom.xml:
<parent>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-parent</artifactId>
<version>1.5.2.RELEASE</version>
</parent>
<dependencies>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-web</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-test</artifactId>
<scope>test</scope>
</dependency>
<dependency>
<groupId>org.springframework.security</groupId>
<artifactId>spring-security-test</artifactId>
<scope>test</scope>
</dependency>
<dependency>
<groupId>com.h2database</groupId>
<artifactId>h2</artifactId>
<scope>test</scope>
</dependency>
<dependency>
<groupId>org.powermock</groupId>
<artifactId>powermock-module-junit4</artifactId>
<version>1.6.6</version>
<scope>test</scope>
</dependency>
<dependency>
<groupId>org.powermock</groupId>
<artifactId>powermock-api-mockito</artifactId>
<version>1.6.6</version>
<scope>test</scope>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-data-jpa</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-security</artifactId>
</dependency>
<dependency>
<groupId>org.facebook4j</groupId>
<artifactId>facebook4j-core</artifactId>
<version>2.4.8</version>
</dependency>
<dependency>
<groupId>net.sf.dozer</groupId>
<artifactId>dozer</artifactId>
<version>5.5.1</version>
</dependency>
<dependency>
<groupId>org.hibernate</groupId>
<artifactId>hibernate-java8</artifactId>
</dependency>
<dependency>
<groupId>mysql</groupId>
<artifactId>mysql-connector-java</artifactId>
</dependency>
<dependency>
<groupId>org.apache.commons</groupId>
<artifactId>commons-csv</artifactId>
<version>1.4</version>
</dependency>
</dependencies>
<build>
<finalName>${project.artifactId}</finalName>
<plugins>
<plugin>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-maven-plugin</artifactId>
</plugin>
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-compiler-plugin</artifactId>
<version>3.6.1</version>
<configuration>
<source>1.8</source>
<target>1.8</target>
</configuration>
</plugin>
<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>
<execution>
<id>default-check</id>
<goals>
<goal>check</goal>
</goals>
</execution>
<execution>
<id>generate-code-coverage-report</id>
<phase>test</phase>
<goals>
<goal>report</goal>
</goals>
</execution>
</executions>
</plugin>
</plugins>
</build>
My sonar-project.properties:
sonar.projectKey=org.eventizer:EventizerServer
sonar.projectName=EventizerServer
sonar.projectVersion=1.0
sonar.log.level=DEBUG
sonar.sources=src/main/
sonar.language=java
sonar.java.source=1.8
sonar.sourceEncoding=UTF-8
sonar.java.binaries=target/classes/org/eventizer/eventizerserver/
sonar.java.test.binaries=target/test-classes/org/eventizer/eventizerserver/
sonar.tests=src/test/
sonar.java.coveragePlugin=jacoco
sonar.jacoco.reportPaths=target/jacoco.exec
sonar.junit.reportPaths=target/surefire-reports/
I am running this mvn command:
mvn clean org.jacoco:jacoco-maven-plugin:prepare-agent test -Dmaven.test.failure.ignore=true
As a result I am getting target directory with following output:
Classes directory that is set for sonar.java.binaries:
Test classes directory that is set for sonar.java.test.binaries:
Surefire JUnit test reports directory that is set for sonar.junit.reportPaths:
JaCoCo report output directory:
JaCoCo HTML report in browers:
After that I am running sonar-scanner.bat, below some important (I tihnk so) outputs:
My Sonar web instance project analysis:
And I really do not have idea why this is happening since it looks like everything got generated properly. Since yesterday I think I have tried everything on StackOverflow so please do not mark it as duplicate.
This is even weirder because when I access Coverage metrics for this project I can see that 100% Unit tests passed:
Well... I suppose, that could because of sonar.sources=src/main/... If you set it as sonar.sources=src, it will show again.
And, I just find there's a Sonar Parater:
sonar.tests=src/test will show the junit report in sonar.
here's my sonar-project.properties:
sonar.projectKey=com.test.marslo:marslo-test
sonar.projectName=marslo-test
sonar.projectVersion=1.1.0
sonar.projectBaseDir=.
sonar.sources=src/main
sonar.tests=src/test
sonar.java.binaries=build
sonar.sourceEncoding=UTF-8
sonar.java.source=1.8
sonar.jacoco.reportPaths=./build/jacoco/test.exec
sonar.junit.reportPaths=./build/test-results/test
And the build.gradle:
...
apply plugin: "jacoco"
...
...
jacoco {
toolVersion = "0.8.0"
}
jacocoTestReport {
reports {
xml.enabled true
csv.enabled true
html.enabled true
}
}
test {
jacoco {
append = false
destinationFile = file("$buildDir/jacoco/jacocoTest.exec")
classDumpDir = file("$buildDir/jacoco/classpathdumps")
}
}
Build with:
gradle clean build test jacocoTestReport
Okay, so I have discovered something that may be a Sonar bug.
Basically, this project has been pushed to Sonar for a long time with basic mvn sonar:sonar configuration. So, it was not even doing test results. Now I wanted to run that via Jenkins, so I filled all necessary fields in sonar-project.properties and pushed via Sonar-Runner not mvn sonar:sonar.
After doing so as you could see, Unit Tests Quality gate was failing with no good reason. Because in my latest screenshoot, you can see that in fact Unit Tests passed 100.0%.
I decide to push that analysis to a separate project by changing projectKey property to something else and all of the sudden everything went smoothly.
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.