spring-boot-maven-plugin reverts the property files after run - spring

This is the build configuration of my project in pom.xml, When I pack the project, the property files already changed with the selected profile properties, but when I run the project using maven-boot-plugin:run in Intellij IDEA, the property files changed to old style and the database connection raises exception. for example the normal application.properties has the below key :
spring.datasource.url=${datasourceUrl}
and after packing the project it is :
spring.datasource.url=url1
but after running spring boot plugin the property files changed to the first style.
<profiles>
<profile>
<id>Live</id>
<properties>
<datasourceUrl>url1</datasourceUrl>
</properties>
</profile>
<profile>
<id>Test</id>
<properties>
<datasourceUrl>url2</datasourceUrl>
</properties>
</profile>
</profiles>
<build>
<defaultGoal>install</defaultGoal>
<resources>
<resource>
<directory>${basedir}/src/main/resources</directory>
<filtering>true</filtering>
<includes>
<include>**/*.*</include>
</includes>
</resource>
</resources>
<plugins>
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-resources-plugin</artifactId>
<version>2.3</version>
<configuration>
<encoding>UTF-8</encoding>
</configuration>
<executions>
<execution>
<id>run</id>
<phase>package</phase>
<goals>
<goal>resources</goal>
</goals>
</execution>
</executions>
</plugin>
<plugin>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-maven-plugin</artifactId>
<executions>
<execution>
<id>repack</id>
<phase>package</phase>
<goals>
<goal>repackage</goal>
</goals>
</execution>
</executions>
</plugin>
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-dependency-plugin</artifactId>
<executions>
<execution>
<id>unpack</id>
<phase>generate-resources</phase>
<goals>
<goal>unpack</goal>
</goals>
<configuration>
<artifactItems>
<artifactItem>
mywar
<type>war</type>
<overWrite>false</overWrite>
<outputDirectory>${project.build.directory}/classes/static/</outputDirectory>
<includes>**/*</includes>
</artifactItem>
</artifactItems>
</configuration>
</execution>
</executions>
</plugin>
</plugins>
</build>

Related

maven toolchain in profile

If I define toolchain plugin in activated by default profile it's not working for some plugin such as maven-javadoc-plugin(for maven-compiler-plugin it is working) :
<profile>
<id>jdk-toolchain</id>
<activation>
<activeByDefault>true</activeByDefault>
</activation>
<build>
<plugins>
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-toolchains-plugin</artifactId>
<version>1.1</version>
<executions>
<execution>
<goals>
<goal>toolchain</goal>
</goals>
</execution>
</executions>
<configuration>
<toolchains>
<jdk>
<version>${project.javaVersion}</version>
<vendor>sun</vendor>
</jdk>
</toolchains>
</configuration>
</plugin>
</plugins>
</build>
</profile>
In other case it work perfect for all plugin:
<build>
<plugins>
...
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-toolchains-plugin</artifactId>
<version>1.1</version>
<executions>
<execution>
<goals>
<goal>toolchain</goal>
</goals>
</execution>
</executions>
<configuration>
<toolchains>
<jdk>
<version>${project.javaVersion}</version>
<vendor>sun</vendor>
</jdk>
</toolchains>
</configuration>
</plugin>
...
</plugins>
</build>
Why is this happening?
you have to bind the execution of your plugin into validate phase:
<executions>
<execution>
<phase>validate</phase>
<goals>
<goal>toolchain</goal>
</goals>
</execution>
</executions>

Spreading flyway profiles over phases

I'm trying to create separate profiles which using flyway-maven-plugin, but phase definition doesn't work properly. Which mean that when i use both profiles i have an error on execution because i guess "drop-create-database" using configuration from "migrate-database" thus it`s failed. Does anyone have an idea how to fix it?
<profiles>
<profile>
<id>drop-create</id>
<build>
<plugins>
<plugin>
<groupId>org.flywaydb</groupId>
<artifactId>flyway-maven-plugin</artifactId>
<version>3.1</version>
<configuration>
<driver>net.sourceforge.jtds.jdbc.Driver</driver>
<table>MIGRATION_LOG</table>
<sqlMigrationPrefix>EMP_</sqlMigrationPrefix>
<skip>false</skip>
</configuration>
<executions>
<execution>
<id>drop-create-database</id>
<!-- Need to garantee order of execution -->
<phase>package</phase>
<goals>
<goal>clean</goal>
<goal>migrate</goal>
</goals>
</execution>
</executions>
</plugin>
</plugins>
</build>
</profile>
<profile>
<id>migrate</id>
<build>
<plugins>
<plugin>
<groupId>org.flywaydb</groupId>
<artifactId>flyway-maven-plugin</artifactId>
<version>3.1</version>
<configuration>
<driver>net.sourceforge.jtds.jdbc.Driver</driver>
<table>MIGRATION_LOG</table>
<sqlMigrationPrefix>ALL_</sqlMigrationPrefix>
<skip>false</skip>
</configuration>
<executions>
<execution>
<id>migrate-database</id>
<phase>pre-integration-test</phase>
<goals>
<goal>migrate</goal>
</goals>
</execution>
</executions>
</plugin>
</plugins>
</build>
</profile>
</profiles>
You have to specify the configuration per execution instead of per plugin. Otherwise a later configuration for the same plugin will overwrite previous ones.
This means your pom.xml should look something like this:
<profiles>
<profile>
<id>drop-create</id>
<build>
<plugins>
<plugin>
<groupId>org.flywaydb</groupId>
<artifactId>flyway-maven-plugin</artifactId>
<version>3.1</version>
<executions>
<execution>
<id>drop-create-database</id>
<!-- Need to garantee order of execution -->
<phase>package</phase>
<goals>
<goal>clean</goal>
<goal>migrate</goal>
</goals>
<configuration>
<driver>net.sourceforge.jtds.jdbc.Driver</driver>
<table>MIGRATION_LOG</table>
<sqlMigrationPrefix>EMP_</sqlMigrationPrefix>
<skip>false</skip>
</configuration>
</execution>
</executions>
</plugin>
</plugins>
</build>
</profile>
<profile>
<id>migrate</id>
<build>
<plugins>
<plugin>
<groupId>org.flywaydb</groupId>
<artifactId>flyway-maven-plugin</artifactId>
<version>3.1</version>
<executions>
<execution>
<id>migrate-database</id>
<phase>pre-integration-test</phase>
<goals>
<goal>migrate</goal>
</goals>
<configuration>
<driver>net.sourceforge.jtds.jdbc.Driver</driver>
<table>MIGRATION_LOG</table>
<sqlMigrationPrefix>ALL_</sqlMigrationPrefix>
<skip>false</skip>
</configuration>
</execution>
</executions>
</plugin>
</plugins>
</build>
</profile>

Build maven jar from classes no java source

I want to build a maven jar artifact from classes. I don't have source files. These classes are originally in another artifact installed locally. I use maven-dependency-plugin to unpack the classes and put them in the target folder for this project/module.
It creates the jar.. but doesn't include the classes I just unpacked. Here's my pom:
<build>
...
<!-- unpack myjar1.jar and myjar2.jar -->
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-dependency-plugin</artifactId>
<version>2.8</version>
<executions>
<execution>
<id>unpack</id>
<phase>package</phase>
<goals>
<goal>unpack</goal>
</goals>
<configuration>
<artifactItems>
<artifactItem>
<groupId>com.company</groupId>
<artifactId>myjar1</artifactId>
<version>1.0</version>
<type>jar</type>
<overWrite>false</overWrite>
<outputDirectory>target/final</outputDirectory>
</artifactItem>
<artifactItem>
<groupId>com.company</groupId>
<artifactId>myjar2</artifactId>
<version>1.0</version>
<type>jar</type>
<overWrite>false</overWrite>
<outputDirectory>target/final</outputDirectory>
</artifactItem>
</artifactItems>
</configuration>
</execution>
</executions>
</plugin>
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-jar-plugin</artifactId>
<version>2.4</version>
<executions>
<execution>
<id>default</id>
<phase>package</phase>
<goals>
<goal>jar</goal>
</goals>
<configuration>
<classesDirectory>/path/to/target/final/folder</classesDirectory>
<includes>
<include>**</include>
</includes>
</configuration>
</execution>
</executions>
</plugin>
</plugins>
</build>
How can I include these classes into my final.jar?
I think the best solution is the maven-shade-plugin: create a pom.xml, add those 2 libraries as dependencies and configure the maven-shade-plugin.
Run mvn package and you have your merged project.
What Robert wrote above might be a workable solution too.. but I figured a different way out. I simply removed <includes> inside the maven-jar-plugin and it worked. I ran the build in eclipse by creating a build configuration and chose "debug" option. It spit out a lot of info about "configuration" which is otherwise not displayed.
Thanks!
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-jar-plugin</artifactId>
<version>2.4</version>
<executions>
<execution>
<id>default</id>
<phase>package</phase>
<goals>
<goal>jar</goal>
</goals>
<configuration>
<classesDirectory>path/to/final/folder</classesDirectory>
</configuration>
</execution>
</executions>
</plugin>
This worked!
Another approach is to set ouputDirectory to regular target/classes directory.
target/classes
So that unpacked classes plus your project classes will be avaialble in target/classes which can be bundled in to .jar using regular maven-jar-plugin by specifing **
Complete pom:
<build>
<plugins>
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-dependency-plugin</artifactId>
<version>2.8</version>
<executions>
<execution>
<id>unpack</id>
<phase>package</phase>
<goals>
<goal>unpack</goal>
</goals>
<configuration>
<artifactItems>
<artifactItem>
<groupId>a.b.c</groupId>
<artifactId>aaa</artifactId>
<type>jar</type>
<overWrite>true</overWrite>
<outputDirectory>target/classes</outputDirectory>
</artifactItem>
</artifactItems>
</configuration>
</execution>
</executions>
</plugin>
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-jar-plugin</artifactId>
<version>2.4</version>
<executions>
<execution>
<id>default</id>
<phase>package</phase>
<goals>
<goal>jar</goal>
</goals>
<configuration>
<includes>
<include>**</include>
</includes>
</configuration>
</execution>
</executions>
</plugin>
</plugins>
</build>

How can I copy an entire directory into another directory using Maven?

I want to know how to copy an entire directory into another directory using Maven without using the Mmaven antrun plugin.
You can use the Maven resources plugin.
As an example taken from their documentation:
<project>
...
<build>
<plugins>
<plugin>
<artifactId>maven-resources-plugin</artifactId>
<version>2.6</version>
<executions>
<execution>
<id>copy-resources</id>
<!-- here the phase you need -->
<phase>validate</phase>
<goals>
<goal>copy-resources</goal>
</goals>
<configuration>
<outputDirectory>${basedir}/target/extra-resources</outputDirectory>
<resources>
<resource>
<directory>src/non-packaged-resources</directory>
<filtering>true</filtering>
</resource>
</resources>
</configuration>
</execution>
</executions>
</plugin>
</plugins>
...
</build>
...
</project>
This would copy the content of the directory into the outputDirectory if I'm not mistaken.
You can use https://maven.apache.org/plugins/maven-dependency-plugin/examples/copying-artifacts.html
<?xml version="1.0" encoding="UTF-8"?>
<build>
<plugins>
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-dependency-plugin</artifactId>
<version>3.1.2</version>
<executions>
<execution>
<id>copy</id>
<phase>package</phase>
<goals>
<goal>copy</goal>
</goals>
</execution>
</executions>
<configuration>
<artifactItems>
<artifactItem>
<groupId>junit</groupId>
<artifactId>junit</artifactId>
<version>3.8.1</version>
<type>jar</type>
<overWrite>false</overWrite>
<outputDirectory>${project.build.directory}/alternateLocation</outputDirectory>
<destFileName>optional-new-name.jar</destFileName>
</artifactItem>
</artifactItems>
<outputDirectory>${project.build.directory}/wars</outputDirectory>
<overWriteReleases>false</overWriteReleases>
<overWriteSnapshots>true</overWriteSnapshots>
</configuration>
</plugin>
</plugins>
</build>

How to place the output jar into another folder with maven?

I'd like to place my output jar and jar-with-dependencies into another folder (not in target/ but in ../libs/).
How can I do that?
You can use the outputDirectory parameter of the maven-jar-plugin for this purpose:
<project>
...
<build>
<plugins>
...
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-jar-plugin</artifactId>
<version>2.3.1</version>
<configuration>
<outputDirectory>../libs</outputDirectory>
</configuration>
</plugin>
...
</plugins>
</build>
...
</project>
But as cdegroot wrote, you should probably better not fight the maven way.
If you want to copy the artifact into a directory outside your project, solutions might be:
maven-jar-plugin and configure outputDirectory
maven-antrun-plugin and copy task
copy-maven-plugin by Evgeny Goldin
Example for the copy-maven-plugin is:
<plugin>
<groupId>com.github.goldin</groupId>
<artifactId>copy-maven-plugin</artifactId>
<version>0.2.5</version>
<executions>
<execution>
<id>deploy-to-local-directory</id>
<phase>install</phase>
<goals>
<goal>copy</goal>
</goals>
<configuration>
<skipIdentical>false</skipIdentical>
<failIfNotFound>false</failIfNotFound>
<resources>
<resource>
<description>Copy artifact to another directory</description>
<targetPath>/your/local/path</targetPath>
<directory>${project.build.directory}</directory>
<includes>
<include>*.jar</include>
</includes>
</resource>
</resources>
</configuration>
</execution>
</executions>
</plugin>
Another way would be maven-resources-plugin (find the current version here):
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-resources-plugin</artifactId>
<version>3.0.2</version>
<executions>
<execution>
<id>copy-files-on-build</id>
<phase>package</phase>
<goals>
<goal>copy-resources</goal>
</goals>
<configuration>
<outputDirectory>${basedir}/[TO-DIR]</outputDirectory>
<resources>
<resource>
<directory>[FROM-DIR]</directory>
<!--<include>*.[MIME-TYPE]</include>-->
<filtering>false</filtering>
</resource>
</resources>
</configuration>
</execution>
</executions>
</plugin>
I would do it this way:
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-antrun-plugin</artifactId>
<version>1.8</version>
<executions>
<execution>
<phase>install</phase>
<configuration>
<target>
<copy file="target/${project.artifactId}-exec.jar" tofile="../../docker/${project.artifactId}.jar"/>
</target>
</configuration>
<goals>
<goal>run</goal>
</goals>
</execution>
</executions>
</plugin>
This technique worked well for me:
http://maven.apache.org/plugins/maven-dependency-plugin/examples/copying-artifacts.html
<project>
[...]
<build>
<plugins>
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-dependency-plugin</artifactId>
<version>2.10</version>
<executions>
<execution>
<id>copy</id>
<phase>package</phase>
<goals>
<goal>copy</goal>
</goals>
<configuration>
<artifactItems>
<artifactItem>
<groupId>junit</groupId>
<artifactId>junit</artifactId>
<version>3.8.1</version>
<type>jar</type>
<overWrite>false</overWrite>
<outputDirectory>${project.build.directory}/alternateLocation</outputDirectory>
<destFileName>optional-new-name.jar</destFileName>
</artifactItem>
</artifactItems>
<outputDirectory>${project.build.directory}/wars</outputDirectory>
<overWriteReleases>false</overWriteReleases>
<overWriteSnapshots>true</overWriteSnapshots>
</configuration>
</execution>
</executions>
</plugin>
</plugins>
</build>
[...]
</project>
I specially like the solution using maven-resources-plugin (see here) because is already included in maven, so no extra download is needed, and also is very configurable to do the copy at a specific phase of your project (see here to learn & understand about phases). And the best part of this approach is that it won't mess up any previous processes or build you had before :)
<project>
...
<build>
<plugins>
<plugin>
<artifactId>maven-resources-plugin</artifactId>
<version>3.2.0</version>
<executions>
<execution>
<id>copy-resources</id>
<!-- here the phase you need -->
<phase>validate</phase>
<goals>
<goal>copy-resources</goal>
</goals>
<configuration>
<outputDirectory>/dir/where/you/want/to/put/jar</outputDirectory>
<resources>
<resource>
<directory>/dir/where/you/have/the/jar</directory>
<filtering>false</filtering>
<includes>
<include>file-you-want-to.jar</include>
<include>another-file-you-want-to.jar</include>
</includes>
</resource>
</resources>
</configuration>
</execution>
</executions>
</plugin>
</plugins>
...
</build>
...
</project>
Of course you can also use interpolated variables like ${baseDir} and other good stuff like that all over your XML. And you could use wild cards as they explain here
Maven dependency plugin is perfectly capable of copying all dependencies and just built artifact in a custom location. Following example will copy all runtime dependencies and a built artifact in a two execution phases.
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-dependency-plugin</artifactId>
<version>3.3.0</version>
<executions>
<execution>
<id>copy-dependencies</id>
<phase>package</phase>
<goals>
<goal>copy-dependencies</goal>
</goals>
<configuration>
<includeScope>runtime</includeScope>
<outputDirectory>${project.build.directory}/jars</outputDirectory>
<overWriteReleases>false</overWriteReleases>
<overWriteSnapshots>false</overWriteSnapshots>
<overWriteIfNewer>true</overWriteIfNewer>
</configuration>
</execution>
<execution>
<id>copy-artifact</id>
<phase>package</phase>
<goals>
<goal>copy</goal>
</goals>
<configuration>
<artifactItems>
<artifactItem>
<groupId>${project.groupId}</groupId>
<artifactId>${project.artifactId}</artifactId>
<version>${project.version}</version>
<type>${project.packaging}</type>
</artifactItem>
</artifactItems>
<outputDirectory>${project.build.directory}/jars</outputDirectory>
<overWriteIfNewer>true</overWriteIfNewer>
</configuration>
</execution>
</executions>
</plugin>
While documentation of dependency plugin states in its documentation that in order to copy built artifact you have to use any phase after the package phase, that is not true if you are building jars. In that situation you can use package phase. At least in 3.3.0 version of plugin.

Resources