I'm using xsdtojava with cxf maven` plugin:
<plugin>
<groupId>org.apache.cxf</groupId>
<artifactId>cxf-xjc-plugin</artifactId>
<executions>
<execution>
<id>generate-sources</id>
<phase>generate-sources</phase>
<configuration>
...
</configuration>
<goals>
<goal>xsdtojava</goal>
</goals>
</execution>
</executions>
</plugin>
Question: I want to prevent executing this plugin on every mvn package. Instead, I only want to trigger the source generation manually. But how? I tried setting a custom phase or goal like <phase>generate-sources-now</phase> or <goal>generate-sources-now</goal>, but did does not work.
Though I'd prefer a maven goal approach, the profile approach works as suggested:
<profiles>
<profile>
<id>xsdtojava</id>
<build>
<plugins>
<plugin>
<groupId>org.apache.cxf</groupId>
<artifactId>cxf-xjc-plugin</artifactId>
<executions>
<execution>
<phase>generate-sources</phase>
<goals>
<goal>xsdtojava</goal>
</goals>
</execution>
</executions>
<configuration>
.....
Run with: mvn package -P xsdtojava
Plugins don't need to have executions.
Just configure you plugin as
<plugin>
<groupId>org.apache.cxf</groupId>
<artifactId>cxf-xjc-plugin</artifactId>
<configuration>
...
</configuration>
</plugin>
and call the goal in the usual : notation (cxf-xjc-plugin:goal).
Related
With maven I set up a plugin that runs an external script.
<plugin>
<artifactId>exec-maven-plugin</artifactId>
<groupId>org.codehaus.mojo</groupId>
<version>3.0.0</version>
<executions>
<execution>
<id>Execute External Command</id>
<phase>generate-sources</phase>
<goals>
<goal>exec</goal>
</goals>
<configuration>
<executable>
${basedir}/external.sh
</executable>
</configuration>
</execution>
</executions>
</plugin>
The problem is that it also starts with the mvn clean command. Is it possible not to start the plugin in clean phase? or is it possible to parameterize my external script with a parameter that makes me understand that I am in the clean phase?
Something like:
<executable>
${basedir}/external.sh ${phase}
</executable>
Can you try to change the phase in your plugin, for exmple:
<phase>install</phase>
full plugin:
<plugin>
<artifactId>exec-maven-plugin</artifactId>
<groupId>org.codehaus.mojo</groupId>
<version>3.0.0</version>
<executions>
<execution>
<id>Execute External Command</id>
<phase>install</phase>
<goals>
<goal>exec</goal>
</goals>
<configuration>
<executable>
${basedir}/external.sh
</executable>
</configuration>
</execution>
</executions>
</plugin>
you can choose any of the other suitable phases.
When building my service project with jib command mvn clean compile jib:build it's give the following error:
Failed to execute goal
com.google.cloud.tools:jib-maven-plugin:1.0.2:build
(build-image-and-tag-image) on project my-service: Multiple valid
main classes were found: com.myservice.MyServiceApplication,
io.swagger.Swagger2SpringBoot, perhaps you should add a mainClass
configuration to jib-maven-plugin -> [Help 1]
However I have set the main classes for spring-boot
<plugin>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-maven-plugin</artifactId>
<configuration>
<mainClass>com.myservice.MyServiceApplication</mainClass>
</configuration>
<executions>
<execution>
<goals>
<goal>repackage</goal>
</goals>
</execution>
</executions>
</plugin>
It's still doesn't work.
I've tried to add it to the jib config to:
<plugins>
<plugin>
<groupId>com.google.cloud.tools</groupId>
<artifactId>jib-maven-plugin</artifactId>
<configuration>
<container>
<mainClass>com.myservice.MyServiceApplication</mainClass>
</container>
</configuration>
<executions>
<execution>
<id>build-image-and-tag-image</id>
<phase>package</phase>
<goals>
<goal>dockerBuild</goal>
</goals>
</execution>
</executions>
</plugin>
</plugins>
</build>
It's still doesn't work.
Any other way to force jib to ignore the other class and use com.myservice.MyServiceApplication instead.
Note: mvn clean install work fine and I have no problem using it has a stand alone spring boot app.
The main class need to be set in the < plugins > define in < build > of the pom.xml file.
It would look like this to fix the problem:
<build>
<plugins>
<plugin>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-maven-plugin</artifactId>
<configuration>
<mainClass>com.myservice.MyServiceApplication</mainClass>
</configuration>
<executions>
<execution>
<goals>
<goal>repackage</goal>
</goals>
</execution>
</executions>
</plugin>
<plugin>
<groupId>com.google.cloud.tools</groupId>
<artifactId>jib-maven-plugin</artifactId>
<configuration>
<container>
<mainClass>com.myservice.MyServiceApplication</mainClass>
<ports>
<port>8080</port>
</ports>
<environment>
<application.title>${project.name}</application.title>
<application.version>${project.version}</application.version>
</environment>
<jvmFlags>
<jvmFlag>-javaagent:/usr/local/newrelic/newrelic.jar</jvmFlag>
</jvmFlags>
</container>
</configuration>
</plugin>
.... (more plugin)
</plugins>
</build>
Disclaimer: I have solved this problem and am documenting the solution for the world to know.
How do I create and install a *-sources.jar containing "delomboked" source code in maven?
By default, The maven-source-plugin creates a sources jar without delomboking the source files, which causes projects that depend on the library binaries to complain about mismatching source files.
TL;DR (explained beneath)
Add the following plugins configuration to your plugins configuration in the project.build element of your pom.xml
<project>
...
<build>
<plugins>
...
<plugin>
<groupId>org.projectlombok</groupId>
<artifactId>lombok-maven-plugin</artifactId>
<version>1.18.0.0</version>
<executions>
<execution>
<phase>generate-sources</phase>
<goals>
<goal>delombok</goal>
</goals>
</execution>
</executions>
<configuration>
<sourceDirectory>src/main/java</sourceDirectory>
<outputDirectory>${project.build.directory}/delombok</outputDirectory>
<addOutputDirectory>false</addOutputDirectory>
<encoding>UTF-8</encoding>
</configuration>
</plugin>
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-resources-plugin</artifactId>
<version>3.1.0</version>
<executions>
<execution>
<id>copy-to-lombok-build</id>
<phase>process-resources</phase>
<goals>
<goal>copy-resources</goal>
</goals>
<configuration>
<resources>
<resource>
<directory>${project.basedir}/src/main/resources</directory>
</resource>
</resources>
<outputDirectory>${project.build.directory}/delombok</outputDirectory>
</configuration>
</execution>
</executions>
</plugin>
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-antrun-plugin</artifactId>
<version>1.8</version>
<executions>
<execution>
<id>generate-delomboked-sources-jar</id>
<phase>package</phase>
<goals>
<goal>run</goal>
</goals>
<configuration>
<target>
<jar destfile="${project.build.directory}/${project.build.finalName}-sources.jar"
basedir="${project.build.directory}/delombok"/>
</target>
</configuration>
</execution>
</executions>
</plugin>
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-install-plugin</artifactId>
<version>2.5.2</version>
<executions>
<execution>
<id>install-source-jar</id>
<goals>
<goal>install-file</goal>
</goals>
<phase>install</phase>
<configuration>
<file>${project.build.directory}/${project.build.finalName}-sources.jar</file>
<groupId>${project.groupId}</groupId>
<artifactId>${project.artifactId}</artifactId>
<version>${project.version}</version>
<classifier>sources</classifier>
<generatePom>true</generatePom>
<pomFile>${project.basedir}/pom.xml</pomFile>
</configuration>
</execution>
</executions>
</plugin>
</plugins>
</build>
</project>
Explanation
lombok-maven-plugin will enable you to delombok the source code (${project.basedir}/src/main/java) and place it in the target directory (${project.build.directory}/delombok). Usually this will place the code in the ${project.build.directory}/generated-sources/delombok folder, but because Intellij automatically considers this additional source-code, duplicate code errors will occur when developing your library, in order to stop this, just specify a non-default target directory (in this case just outside of the generated-sources dir).
maven-resources-plugin is necessary in order to also copy resources from the standard ${project.basedir}/src/main/resources directory. If there are any other non-standard resource directories in your project, you should configure them in the resources section for this plugin.
maven-antrun-plugin is used instead of the maven-source-plugin because you cannot specify a custom source directory in the latter. The jar task points to our custom "generated-sources" and produces the standard-named sources jar.
maven-install-plugin install-file goal is used because you cannot attach jars using the install goal. We can hack a solution by manually installing a file using the install-file goal with a classifier of sources.
I hope this helps others who are on struggle street like I was with this problem.
The following solution is based on the one offered above but improves it by using the build-helper plugin to attach the generated delomboked source jar instead of using install-file. This has the benefit that the normal maven install and deploy phases correctly handle the generated file just as they would if the sources plugin had been used.
<project>
...
<build>
<plugins>
...
<plugin>
<groupId>org.projectlombok</groupId>
<artifactId>lombok-maven-plugin</artifactId>
<version>1.18.12.0</version>
<executions>
<execution>
<id>delombok-sources</id>
<phase>generate-sources</phase>
<goals>
<goal>delombok</goal>
</goals>
<configuration>
<sourceDirectory>src/main/java</sourceDirectory>
<outputDirectory>${project.build.directory}/delombok</outputDirectory>
<addOutputDirectory>false</addOutputDirectory>
<encoding>UTF-8</encoding>
</configuration>
</execution>
</executions>
</plugin>
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-antrun-plugin</artifactId>
<version>1.8</version>
<executions>
<execution>
<id>generate-delomboked-sources-jar</id>
<phase>package</phase>
<goals>
<goal>run</goal>
</goals>
<configuration>
<target>
<jar destfile="${project.build.directory}/${project.build.finalName}-sources.jar"
basedir="${project.build.directory}/delombok"/>
</target>
</configuration>
</execution>
</executions>
</plugin>
<plugin>
<groupId>org.codehaus.mojo</groupId>
<artifactId>build-helper-maven-plugin</artifactId>
<version>3.1.0</version>
<executions>
<execution>
<id>attach-delomboked-sources-jar</id>
<phase>package</phase>
<goals>
<goal>attach-artifact</goal>
</goals>
<configuration>
<artifacts>
<artifact>
<file>${project.build.directory}/${project.build.finalName}-sources.jar</file>
<type>jar</type>
<classifier>sources</classifier>
</artifact>
</artifacts>
</configuration>
</execution>
</executions>
</plugin>
</plugins>
</build>
</project>
Would like to point out that a profile can also be used (to get around the build source directory being un-customizable). The solution is described at https://sudonull.com/post/1197-Lombok-sourcesjar-and-convenient-debug
Add the following to the pom.xml
properties:
<origSourceDir>${project.basedir}/src/main/java</origSourceDir>
<sourceDir>${origSourceDir}</sourceDir>
<delombokedSourceDir>${project.build.directory}/delombok</delombokedSourceDir>
</properties>
Profile and build section changes:
<profiles>
<profile>
<id>build</id>
<properties>
<sourceDir>${delombokedSourceDir}</sourceDir>
</properties>
</profile>
</profiles>
<build>
<sourceDirectory>${sourceDir}</sourceDirectory>
<plugins>
<plugin>
<groupId>org.projectlombok</groupId>
<artifactId>lombok-maven-plugin</artifactId>
<version>1.18.20.0</version>
<executions>
<execution>
<id>delombok</id>
<phase>generate-sources</phase>
<goals>
<goal>delombok</goal>
</goals>
<configuration>
<addOutputDirectory>false</addOutputDirectory>
<sourceDirectory>${origSourceDir}</sourceDirectory>
<outputDirectory>${delombokedSourceDir}</outputDirectory>
</configuration>
</execution>
</executions>
</plugin>
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-source-plugin</artifactId>
<version>3.0.1</version>
<executions>
<execution>
<id>attach-sources</id>
<goals>
<goal>jar</goal>
</goals>
</execution>
</executions>
</plugin>
Execute with mvn clean install -Pbuild
This should solve the "Library source does not match the bytecode for class" error in IntelliJ and allow seamless debugging in most cases.
Ref: "Delombok plugin + profile in maven"
Both of the answers are flawed for multi-module projects or pure pom projects, because there are no sources, so you will have to create an empty directory, and it'll produce an empty .jar.
There is a simple (but a bit more complex) way to achieve functionality you want: make your own Maven Plugin.
Sounds overly complicated, but we can re-use maven-sources-plugin and with MOJO's inheritance update necessary parts:
import java.util.List;
import java.util.stream.Collectors;
import org.apache.maven.plugins.annotations.LifecyclePhase;
import org.apache.maven.plugins.annotations.Mojo;
import org.apache.maven.plugins.annotations.Parameter;
import org.apache.maven.plugins.source.SourceJarNoForkMojo;
import org.apache.maven.project.MavenProject;
/**
* This goal bundles all the sources into a jar archive, but uses delomboked sources.
*/
#Mojo(name = "jar-no-fork", defaultPhase = LifecyclePhase.VERIFY, threadSafe = true)
public class EnhancedSourceJarNoForkMojo extends SourceJarNoForkMojo {
#Parameter(property = "<some-prefix>.useDelombokSources", defaultValue = "true")
protected boolean useDelombokSources;
#Parameter(property = "<some-prefix>.delombokSourcesLocation", defaultValue = "delombok")
protected String delombokSourcesLocation;
#Override
protected List<String> getSources(MavenProject p) {
// if user doesn't want delomboked sources, use default algorithm
List<String> sources = super.getSources(p);
if (!useDelombokSources) {
return sources;
}
// typically, sources' list will contain: [src/main/java, target/generated_sources].
// replace src/main/java if it's present with delombok-generated sources
String target = p.getBuild().getDirectory();
return super.getSources(p)
.stream()
.map(s -> s.endsWith("java") ? String.format("%s/%s", target, delombokSourcesLocation) : s)
.collect(Collectors.toList());
}
}
Gist with pom.xml routine is available here.
I have a Maven project which I'm trying to package, but I've noticed that all my Java test classes (but none of my Scala test classes) and generated Avro test classes are ending up in the jar.
Folder structure looks fine:
I also noticed that if I add junit as a dependency with <scope>test</scope>, my tests won't compile as it can't find the junit classes, so it looks like Maven is treating all my code including tests as being part of main.
Pom:
<?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.me</groupId>
<artifactId>proj</artifactId>
<version>1.0.0</version>
<properties>
<log4j.version>2.8.1</log4j.version>
</properties>
<dependencies>
...
</dependencies>
<build>
<plugins>
<plugin>
<groupId>org.scalatest</groupId>
<artifactId>scalatest-maven-plugin</artifactId>
<executions>
<execution>
<id>test</id>
<goals>
<goal>test</goal>
</goals>
</execution>
</executions>
</plugin>
<plugin>
<groupId>net.alchim31.maven</groupId>
<artifactId>scala-maven-plugin</artifactId>
<version>3.2.1</version>
<executions>
<execution>
<id>scala-compile-first</id>
<phase>process-resources</phase>
<goals>
<goal>add-source</goal>
<goal>compile</goal>
</goals>
</execution>
<execution>
<id>scala-test-compile</id>
<phase>process-test-resources</phase>
<goals>
<goal>testCompile</goal>
</goals>
</execution>
</executions>
<configuration>
<scalaVersion>2.11.8</scalaVersion>
</configuration>
</plugin>
<plugin>
<groupId>org.apache.avro</groupId>
<artifactId>avro-maven-plugin</artifactId>
<version>1.8.1</version>
<executions>
<execution>
<phase>generate-sources</phase>
<goals>
<goal>schema</goal>
</goals>
<configuration>
<sourceDirectory>${project.basedir}/src/test/resources/</sourceDirectory>
<outputDirectory>${project.basedir}/src/test/java</outputDirectory>
</configuration>
</execution>
</executions>
</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>
<executions>
<execution>
<phase>compile</phase>
<goals>
<goal>compile</goal>
</goals>
</execution>
</executions>
</plugin>
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-source-plugin</artifactId>
<executions>
<execution>
<id>attach-sources</id>
<goals>
<goal>jar</goal>
</goals>
</execution>
</executions>
</plugin>
</plugins>
</build>
</project>
Figured it out.
The issue was with the avro-maven-plugin.
It's configuration had sourceDirectory and outputDirectory, both of which had test source paths.
<configuration>
<sourceDirectory>${project.basedir}/src/test/resources/</sourceDirectory>
<outputDirectory>${project.basedir}/src/test/java</outputDirectory>
</configuration>
Apparently these were interfering with the compiler plugin which thought that these directories were main source directories and compiled them along with the rest of the main classes. This also explains why my tests were failing to compile when the junit dependency was given a test scope.
The solution was to use testSourceDirectory and testOutputDirectory instead:
<configuration>
<testSourceDirectory>${project.basedir}/src/test/resources/</testSourceDirectory>
<testOutputDirectory>${project.basedir}/src/test/java</testOutputDirectory>
</configuration>
mvn clean install -Dmaven.test.skip=true -X
When trying to get failsafe bound to the lifecycle, nothing is executed at all. I have read this guide and this related question, and according to this information, it should be possible to make maven execute an the goal integration-test of failsafe in the integration-test, when I specify it in the build/pluginManagement/plugins-section in the pom.xml like this:
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-failsafe-plugin</artifactId>
<version>2.17</version>
<configuration>
<includes>
<include>**/*IT</include>
</includes>
</configuration>
<executions>
<execution>
<id>failsafe-integration-tests</id>
<phase>integration-test</phase>
<goals>
<goal>integration-test</goal>
</goals>
</execution>
<execution>
<id>failsafe-verify</id>
<phase>verify</phase>
<goals>
<goal>verify</goal>
</goals>
</execution>
</executions>
</plugin>
Unfortunately, this does not force maven to run failsafe:integration-test at all (neither with mvn integration-test nor mvn verify)
But if I try to use failsafe with the plugin-specification like this (from here with added configuration):
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-failsafe-plugin</artifactId>
<version>2.17</version>
<executions>
<execution>
<id>integration-test</id>
<goals>
<goal>integration-test</goal>
<goal>verify</goal>
</goals>
<phase>integration-test</phase>
<configuration>
<includes>
<include>**/*IT</include>
</includes>
</configuration>
</execution>
</executions>
</plugin>
At least maven compile failsafe:integration-test runs. But unfortunately, this does not call pre- and post-integration-test. I am struggeling for this for a while now, and have no clue - it should be bound as it is.
Does anybody know why this happens, or how I can fix it?
The thing you did is to define it only in pluginManagement but you have to run it really like this. The definition in pluginManagement is good practice to pin the version of the plugin.
<project>
[...]
<build>
<plugins>
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-failsafe-plugin</artifactId>
<executions>
<execution>
<goals>
<goal>integration-test</goal>
<goal>verify</goal>
</goals>
</execution>
</executions>
</plugin>
</plugins>
</build>
[...]
</project>
Apart from that it's not necessary to give include rules for the maven-failsafe-plugin cause it has already defaults defined so no need for that.