I am using the copy-maven-plugin provided by com.github.goldin. I want to copy some files through Maven.
However, I don't want to hard code the path as the drive will be different. For example:
<build>
<plugins>
<plugin>
<groupId>com.github.goldin</groupId>
<artifactId>copy-maven-plugin</artifactId>
<version>0.2.5</version>
<executions>
<execution>
<id>create-archive</id>
<phase>test</phase>
<goals>
<goal>copy</goal>
</goals>
<configuration>
<resources>
<resource>
<targetPath>/../src/Server-Parent/src/test/resources</targetPath>
<file>/../src/Server-Parent/DB/src/test/resources/mongoDB.xml</file>
<destFileName>mongoDB.xml</destFileName>
</resource>
</resources>
</configuration>
</execution>
</executions>
</plugin>
</plugins>
</build>
When I hard code for example, C:\folder name\src\Server-Parent\src\test\resources it works perfectly from any Maven project. However as soon as I put ../src or /../src it contains problems.
Any ideas how I can fix this?
[ERROR] Failed to execute goal com.github.goldin:copy-maven-plugin:0.2.5:copy (c reate-archive) on project Server-Parent: Processing <resource> [Target p ath(s) [/../src/Server-Parent/src/test/resources], directory [C:/folder name\src/Server-Parent/DB/src/test/resources], dependencies []] fa iled with [java.lang.AssertionError]: [C:\folder name\src\Server-Parent\DB\sr c\test\resources] does not exist. Expression: d.directory -> [Help 1] [ERROR]
EDIT 2:
What I am trying to achive:
I have Server-Parent which is pom.xml containing pom value. Inside this is another Server-SubParent containing pom.xml pom value. Now inside this is Server-SubFunctionality containing jar.
Accoriding to your answer how can this be achived:
${project.basedir}
This are three projects where the Server-SubParent is a module of Server-Parent, but Server-SubParent is another pom containing another module containing the real functionality.
Server-Parent
<modelVersion>4.0.0</modelVersion>
<artifactId>Server-Parent</artifactId>
<packaging>pom</packaging>
<name>Server-Parent</name>
<modules>
<module>Server-Sub-Parent</module>
</modules>
Server-SubParent
<modelVersion>4.0.0</modelVersion>
<parent>
<groupId>com.server</groupId>
<artifactId>Server-Parent</artifactId>
<version>S06B1-RELEASE</version>
</parent>
<artifactId>Server-Sub-Parent</artifactId>
<packaging>pom</packaging>
<name>Server-Sub-Parent</name>
<modules>
<module>Server-Sub-ParentFunctionality</module>
</modules>
Server-Sub-Parent-Functionality
<parent>
<groupId>com.server</groupId>
<artifactId>Server-Sub-Parent</artifactId>
<version>S06B1-RELEASE</version>
</parent>
<artifactId>Server-Sub-Parent-Functionality</artifactId>
<packaging>jar</packaging>
<name>Server-Sub-Parent-Functionality</name>
Try using maven predefined variables.
<resource>
<targetPath>${project.basedir}/../src/Server-Parent/src/test/resources</targetPath>
<file>${project.basedir}/../src/Server-Parent/DB/src/test/resources/mongoDB.xml</file>
<destFileName>mongoDB.xml</destFileName>
</resource>
Some helpful variables
${project.basedir}
${project.build.directory}
${project.build.sourceDirectory}
more info here
Related
I have a multi-module maven project that is used to produce a single spring boot fat jar. My project looks something like this.
- Parent Module Aggergator
- A
- B
- C
- app <-- app.jar is the only thing I want to publish
In my case module A, B, C are only ever used by app and should not be published into maven repo. I have split up the app into multi-module project because it's a lot of code in the app and it's to work with that way.
Currently the app.jar will contain inside it a.jar, b.jar c.jar.
Is there a way to tell maven that the compiled classes from module A, B, C should just be inserted into app.jar classes folder without ever producing A.JAR, B.JAR, C.JAR?
I use the Maven Shade Plugin for my multi-module project; it creates a single JAR and extracts each module into it rather than creating multiple JAR files:
Parent pom.xml:
<?xml version="1.0" encoding="UTF-8"?>
<project xmlns="http://maven.apache.org/POM/4.0.0"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
<modelVersion>4.0.0</modelVersion>
<properties>
<maven.compiler.source>1.8</maven.compiler.source>
<maven.compiler.target>1.8</maven.compiler.target>
</properties>
<groupId>...</groupId>
<artifactId>pipeline</artifactId>
<version>1.0-SNAPSHOT</version>
<packaging>pom</packaging>
<modules>
<module>firehose</module>
<module>gson</module>
<module>lambda</module>
<module>mapper</module>
<module>model</module>
<module>receiver</module>
<module>redshift</module>
<module>reloader</module>
<module>s3</module>
<module>sns</module>
<module>sqs</module>
<module>systemstests</module>
<module>transaction</module>
<module>utility</module>
</modules>
<dependencies>
...
</dependencies>
<build>
<plugins>
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-shade-plugin</artifactId>
<version>3.1.1</version>
<executions>
<execution>
<phase>package</phase>
<goals>
<goal>shade</goal>
</goals>
<configuration>
<filters>
<filter>
<artifact>*:*</artifact>
<excludes>
<exclude>META-INF/*.SF</exclude>
<exclude>META-INF/*.DSA</exclude>
<exclude>META-INF/*.RSA</exclude>
</excludes>
</filter>
</filters>
</configuration>
</execution>
</executions>
</plugin>
</plugins>
</build>
</project>
Child pom.xml (the JAR):
<?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>
<parent>
<groupId>...</groupId>
<artifactId>pipeline</artifactId>
<version>1.0-SNAPSHOT</version>
</parent>
<artifactId>lambda</artifactId>
<dependencies>
...
</dependencies>
<build>
<plugins>
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-jar-plugin</artifactId>
<version>3.1.0</version>
<configuration>
<finalName>MyJar</finalName>
</configuration>
</plugin>
</plugins>
</build>
</project>
Here is a non answer.
Is there a way to tell maven that the compiled classes from module A,
B, C should just be inserted into app.jar classes folder without ever
producing A.JAR, B.JAR, C.JAR?
You could use the repackage goal of the spring boot maven plugin that flatten the dependencies into classes in the uber jar.
In my case module A, B, C are only ever used by app and should not be
published into maven repo.
Adding the modules in a local repository is really wanted to have a efficient and standard build.
Without that, you will need to compile systematically each module at each time you want to run your spring boot app.
While actually sometimes you need to build dependencies, but other times you don't need because these are already updated.
Or else you will be constraint to twist the default Maven way of work by adding manual tasks to compile from the spring boot module the other modules and to move the compiled classes into the spring boot module. Really not a gift for the people that will have to read/maintain this configuration.
I've got a Maven project (submodule of a parent project) which I need to create a "jar with dependencies" for. I added the maven-assembly-plugin to the pom.xml, but it didn't create the artifact. I've slowly stripped everything else out of the pom.xml, until all that's left is dependencies and this plugin, and it still won't create a jar with dependencies. Watching the output of mvn clean package it runs clean, compile, and jar but never runs the assembly plugin. I don't know why. Here's the pom.xml, can anyone spot the problem?
<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>project</groupId>
<artifactId>project-name</artifactId>
<version>1.0</version>
<name>project-name</name>
<properties>
<build.time>${maven.build.timestamp}</build.time>
<spring.framework.version>4.3.1.RELEASE</spring.framework.version>
<spring.security.version>4.1.1.RELEASE</spring.security.version>
<spring.webflow.version>2.4.2.RELEASE</spring.webflow.version>
<maven.compiler.source>1.8</maven.compiler.source>
<maven.compiler.target>1.8</maven.compiler.target>
</properties>
<build>
<sourceDirectory>${project.basedir}/src/java</sourceDirectory>
<resources>
<resource>
<directory>${project.basedir}/src/resources</directory>
</resource>
</resources>
<outputDirectory>${project.basedir}/target/classes</outputDirectory>
<plugins>
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-assembly-plugin</artifactId>
<version>3.0.0</version>
<configuration>
<descriptorRefs>
<descriptorRef>jar-with-dependencies</descriptorRef>
</descriptorRefs>
</configuration>
</plugin>
</plugins>
</build>
<dependencies>
[snip]
</dependencies>
</project>
Maven reference :
Assemble an application bundle or distribution from an assembly
descriptor. This goal is suitable either for binding to the lifecycle
or calling directly from the command line (provided all required files
are available before the build starts, or are produced by another goal
specified before this one on the command line).
The asssembly:single goal may be used in two ways :
either by binding it to the lifecycle
or by calling it directly from the command line
You do no one of them.
You can for example do it to bind the plugin execution to the package phase :
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-assembly-plugin</artifactId>
<version>3.0.0</version>
<configuration>
<phase>package</phase> <!-- bind to the packaging phase -->
<descriptorRefs>
<descriptorRef>jar-with-dependencies</descriptorRef>
</descriptorRefs>
</configuration>
</plugin>
Now the mvn package or mvn install command will create the jar with dependencies.
You can also keep your actual plugin configuration and run the mvn assembly:single command.
The second way allows to create the jar with dependencies on demand and not for every build.
Which may be desirable if the jar creation is a long task that doesn't need to be executed at each build.
I would like to configure a properties files depending on a profile, either ´dev´ or ´prod´, however the placeholders in the properties file are not replaced when executing the maven install goal.
Here is the pom file:
<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>abc.myproject</groupId>
<artifactId>myartifact</artifactId>
<packaging>war</packaging>
<version>0.1.0-SNAPSHOT</version>
<name>projectname</name>
<description>Site Description</description>
<url>http://www.myproject.abc</url>
<properties>
<project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
<maven.compiler.source>1.8</maven.compiler.source>
<maven.compiler.target>1.8</maven.compiler.target>
<maven-war-plugin.version>2.4</maven-war-plugin.version>
<tomcat-deploy-path>output</tomcat-deploy-path>
</properties>
<dependencies>
// various dependencies
</dependencies>
<build>
<finalName>v${project.artifactId}#${project.version}</finalName>
<filters>
<filter>src/main/resources/profiles/${build.profile.id}/mongo.properties</filter>
</filters>
<resources>
<resource>
<filtering>true</filtering>
<directory>src/main/resources</directory>
</resource>
</resources>
<plugins>
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-war-plugin</artifactId>
<version>${maven-war-plugin.version}</version>
<configuration>
<outputDirectory>${tomcat-deploy-path}</outputDirectory>
<failOnMissingWebXml>true</failOnMissingWebXml>
</configuration>
</plugin>
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-compiler-plugin</artifactId>
<version>3.0</version>
<configuration>
<source>${maven.compiler.source}</source>
<target>${maven.compiler.target}</target>
</configuration>
</plugin>
</plugins>
</build>
<profiles>
<profile>
<id>dev</id>
<activation>
<activeByDefault>true</activeByDefault>
</activation>
<properties>
<build.profile.id>dev</build.profile.id>
</properties>
</profile>
<profile>
<id>prod</id>
<properties>
<build.profile.id>prod</build.profile.id>
</properties>
</profile>
</profiles>
</project>
The placeholder mongo.properties file:
database.name=${database.name}
database.port=${database.port}
database.host=${database.host}
database.username=${database.username}
database.password=${database.password}
The profiles/dev/mongo.properties file:
database.name=mydatabase
database.port=27017
database.host=localhost
database.username=root
database.password=psw1
The directory structure is as follows:
> myproject
pom.xml
> src
> main
> java
> resource
> profiles
mongo.properties
> dev
mongo.properties
> prod
mongo.properties
> webapp
> test
I followed the instructions in this blog article: http://www.petrikainulainen.net/programming/tips-and-tricks/creating-profile-specific-configuration-files-with-maven/
I just tested your setup and it worked correctly: the file WEB-INF/classes/mongo.properties was correctly replaced.
The problem you are having revolves around the fact that you are outputting the final war inside a folder that is not under target. This is a very bad idea. Currently, the final WAR is generated inside the directory output, which corresponds to the property tomcat-deploy-path in your POM.
<tomcat-deploy-path>output</tomcat-deploy-path>
The big problem with such a setup is that running mvn clean will not delete that directory and subsequent builds won't override it, meaning the WAR will never be updated and you will keep an old obsolete WAR. I strongly suggest that you move this property under the Maven build directory, something like
<tomcat-deploy-path>${project.build.directory}/output</tomcat-deploy-path>
so that it is properly cleaned when running mvn clean.
As such, to resolve your problem, you should manually delete the folder output and rerun mvn clean install. It should generate a proper and new WAR.
Try using #..# instead of ${}, for example
database.name=#database.name#
For more info refer to: https://docs.spring.io/spring-boot/docs/1.4.x/reference/html/howto-properties-and-configuration.html
I have an Eclipse Maven Project (parent) that hosts three Maven MODULES (it's children). Only the child MODULES have code under "src/main/java/..." (i.e. the PARENT is just a stub place holder for the children).
Each MODULE is independent of one another... I just set it up that way to reduce clutter. =:)
Now the project structure didn't start out this way. Initially it was just one big PARENT and no child MODULES; and everything worked fine. But then I reorganized things within Eclipse (again to reduce clutter) using various moves/refactors, and things stopped working.
The Problem: My source code can't find imported classes now, so my dependency resolution became problematic somewhere. And the problem isn't just seen in Eclipse, but also when I run, say, 'mvn clean install' from the CLI. So I suspect something is wrong with the set of POM files that resulted from my moves/refactors.
Here they are (the PARENT and one CHILD). Am I missing something, or is something incorrect? Maybe I should check something Eclipse, too?
Note that I embedded a couple of little in-line questions inside the POM files below. :)
The PARENT pom.xml file:
<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>
<name>someName</name>
<packaging>pom</packaging>
<groupId>someParentGroupId</groupId>
<artifactId>someParentArtifactId</artifactId>
<version>0.0.1-SNAPSHOT</version>
<properties>
<jdk.version>1.7</jdk.version>
<example-core.version>0.9.3</example-core.version>
<!-- Intended to be used by some Child/Module.
I hope PARENT/CHILD POM inheritance works that way? -->
</properties>
<dependencies>
<!-- Dependencies are all in the Children/Modules -->
</dependencies>
<!-- ################### BUILD SETTINGS BEGIN ##################### -->
<build>
<pluginManagement>
<plugins>
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-compiler-plugin</artifactId>
<version>3.2</version>
<configuration>
<source>${jdk.version}</source>
<target>${jdk.version}</target>
</configuration>
</plugin>
</plugins>
</pluginManagement>
<plugins>
<plugin> <!-- Used to create an UBER/FAT-JAR. -->
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-shade-plugin</artifactId>
<version>2.3</version>
<executions>
<execution>
<phase>package</phase>
<goals>
<goal>shade</goal>
</goals>
</execution>
</executions>
<configuration>
<finalName>uber-${project.artifactId}-${project.version}</finalName>
</configuration>
</plugin>
</plugins>
</build>
<!-- ################### BUILD SETTINGS END ####################### -->
<modules>
<module>childModule1</module>
<module>childModule2</module>
<module>chileModule3</module>
</modules>
</project>
Example CHILD pom.xml file:
<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>
<parent>
<groupId>someParentGroupId</groupId>
<artifactId>someParentArtifactId</artifactId>
<version>0.0.1-SNAPSHOT</version>
</parent>
<artifactId>someChildArtifactId</artifactId>
<!-- I noticed this missing in the Children/Module POM. Is that okay?
<name>
</name>
-->
<dependencies>
<dependency>
<groupId>org.example.somgGroupId</groupId>
<artifactId>example-core</artifactId>
<version>${example-core.version}</version>
</dependency>
</dependencies>
</project>
Again, the problem seems simple. I can't resolve imports (so, naturally, my Classes have import-ralated errors).
Thank you in advance!
name is not a mandatory attribute in pom.xml.
I assume someChildArtifactId is given as an example. If not, the same artifact id should be used in the parent pom.
Provided two Maven projects: J (jar), W (war); both depend on one parent P (pom). The parent has a plugin, which must only run for the project "W".
How does one go about doing this:
without creating separate parent projects
without using a profile (so build must still be executed with mvn clean package)
J (jar)
<project>
<parent>
<artifactId>P</artifactId>
</parent>
<artifactId>J</artifactId>
<packaging>jar</packaging>
</project>
W (war)
<project>
<parent>
<artifactId>P</artifactId>
</parent>
<artifactId>W</artifactId>
<packaging>war</packaging>
</project>
P (pom)
<project>
<artifactId>P</artifactId>
<packaging>pom</packaging>
<build>
<plugins>
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-jar-plugin</artifactId>
<executions>
<execution>
<phase>package</phase>
<goals>
<goal>jar</goal>
</goals>
<configuration>
<classifier>classes</classifier>
</configuration>
</execution>
</executions>
</plugin>
</plugins>
</build>
</project>
I think you can achieve this using Profile Activation. Ideally, the activation condition would be something like "packaging type is war", but apparently, this condition cannot be implemented in Maven. However, in your case, there is a condition that can be implemented and that is probably equivalent in practice: "there is a src/main/webapp directory".
This is how your pom.xml might look like:
<profiles>
<profile>
<activation>
<file>
<exists>src/main/webapp</exists>
</file>
</activation>
<build>
[plugin configuration]
</build>
</profile>
</profiles>
One way to do this would be to place the plugin in the parent pom within <pluginManagement> section. Thereafter specify the plugin in the project(s) that you want it to run.
In your case, you would specify the plugin for project J and not W.
P
<build>
...
<pluginManagement>
<plugins>
<plugin>
<groupId>...</groupId>
<artifactId>...</artifactId>
... other plugin details ...
</plugin>
</plugins>
</pluginManagement>
...
</build>
J
<build>
...
<plugins>
<plugin>
<groupId>...</groupId>
<artifactId>...</artifactId>
<plugin>
</plugins>
...
</build>
Short answer: Maven doesn't appear to have a good way to do what you're trying to do. I've spent a fair amount of time trying to solve a similar problem and haven't found anything satisfactory.
You've already discovered two of the possible solutions: introduction of an additional parent pom for the wars (perhaps the additional pom extends the original parent so you don't have to duplicate all of its config), or duplicating the jar plugin config in all of the war poms. As you've said, neither of these is ideal.
Another possibility is to use the maven-assembly-plugin instead of the jar plugin to build the classified jar for the war projects. The assembly plugin is not included in the default lifecycles for either jar or war packaging, so you could configure it in the parent's <pluginManagement> section and then only reference it in the war projects as Raghuram described. If you need a custom assembly descriptor you will probably want to follow the sharing the assembly descriptors example.