How to replace a complete property file with another while maven build - maven

I am having email.properties(development) in my application under resources folder. This file has to be overwrite another file (email.properties for production) during maven build. Could you please suggest steps to achieve this. I have gone through some process to change values with in property file by using tokens. But that is not my actual requirement, if I keep tokens like mail.id={your.mail} i am unable to use it in my local host because i am not doing any maven build and deploying war file in my JBOSS for localhost.

You can use the maven resources plugin to overwrite the resource with another one
<plugin>
<artifactId>maven-resources-plugin</artifactId>
<executions>
<execution>
<id>copy-properties</id>
<phase>compile</phase>
<goals>
<goal>copy-resources</goal>
</goals>
<configuration>
<outputDirectory>${project.build.outputDirectory}</outputDirectory>
<resources>
<resource>
<directory>src/main/resources/prod</directory>
<includes>
<include>environment.properties</include>
</includes>
</resource>
</resources>
<overwrite>true</overwrite>
</configuration>
</execution>
</executions>
</plugin>
You can bind it to a profile in case you don't always need an overwrite.

Related

Maven: use jar from URL as a source for resources

Dealing with a legacy project, I have the need to load text resources from a jar at an URL.
The text resources will be then filtered and included in the output; those resources come from a released artifact.
From resource-plugin I see it is only possible to give a number of directories; would it be possible to load resources as I need?
I want to do somthing like this, but using a remote jar instead of the oher project in the workspace:
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-resources-plugin</artifactId>
<executions>
<execution>
<id>copy-resources</id>
<phase>process-resources</phase>
<goals>
<goal>copy-resources</goal>
</goals>
<configuration>
<outputDirectory>${project.build.directory}/${project.build.finalName}</outputDirectory>
<resources>
<resource>
<directory>../<another project on the same workspace>/src/main/filtered-resources</directory>
<filtering>true</filtering>
</resource>
</resources>
</configuration>
</execution>
</executions>
</plugin>
</plugins>
Remote resource plugin, as suggested in one of the answer doesn't work because no file from the imported bundle ends up in target; there is no way I can produce the original bundle using remote resource plugin (it's a legacy projetc still in use and completely out of my control).
I think the Maven Remote Resources Plugin will suit your needs.
EDIT:
Snippet obtained from the usage page of the plugin. That XML fragment will attach the plugin to the generate-sources phase (choose a different one if it doesn't fit your needs), will download the apache-jar-resource-bundle artifact and uncompress its contents into ${project.build.directory}/maven-shared-archive-resources.
For better results is recommended that the resources artifact had been created using the bundle goal of the same plugin.
<!-- Turn this into a lifecycle -->
<plugin>
<artifactId>maven-remote-resources-plugin</artifactId>
<version>1.4</version>
<executions>
<execution>
<id>process-remote-resources</id>
<phase>generate-sources</phase>
<goals>
<goal>process</goal>
</goals>
<configuration>
<resourceBundles>
<resourceBundle>org.apache:apache-jar-resource-bundle:1.0</resourceBundle>
</resourceBundles>
</configuration>
</execution>
</executions>
</plugin>
EDIT 2: Alternative Solution using AntRun
If your artifacts don't suit Maven needs and you need something more customized, then using AntRun plugin you could get it somehow:
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-antrun-plugin</artifactId>
<version>1.7</version>
<executions>
<execution>
<id>download-remote-resources</id>
<goals>
<goal>run</goal>
</goals>
<configuration>
<target>
<get src="URL of the resource" dest="${project.build.directory}" />
<unzip src="${project.build.directory}/filename.[jar|zip|war]" dest="${project.build.directory}/${project.build.finalName}" />
</target>
</configuration>
</execution>
</executions>
</plugin>

mvn clean package, I want to copy the created jar to the current directory

I want to update my pom.xml so that when someone uses: mvn clean package, the generated jar file is copied to the current directory. I'm looking at the maven plugin copy-resources, but i'm not sure how to specify the current directory, is there an operating system agnostic way to do this? Would like it to also work on windows, if possible
<plugin>
<artifactId>maven-resources-plugin</artifactId>
<version>2.4.3</version>
<executions>
<execution>
<id>copy-resources</id>
<!-- here the phase you need -->
<phase>validate</phase>
<goals>
<goal>copy-resources</goal>
</goals>
<configuration>
<outputDirectory>${basedir}</outputDirectory>
<resources>
<resource>
<directory>target/Test-0.0.1-SNAPSHOT.jar</directory>
<filtering>true</filtering>
</resource>
</resources>
</configuration>
</execution>
</executions>
</plugin>
Thanks
If by current directory you mean ${project.basedir} then yes you can do this easily. Just make sure you use ${build.finalName}.jar as the file name part as it will properly get the main artifact of a project with <packaging> set to jar (the default).
<execution>
<id>copy-resources</id>
<!-- here the phase you need -->
<phase>validate</phase>
<goals>
<goal>copy-resources</goal>
</goals>
<configuration>
<outputDirectory>${project.basedir}</outputDirectory>
<resources>
<resource>
<!-- Get main artifact -->
<directory>target/${build.finalName}.jar</directory>
<!-- Don't filter binary files -->
<filtering>false</filtering>
</resource>
</resources>
</configuration>
</execution>
If you wanted to do the current working directory instead you should be able to do it using ${user.dir} as the outputDirectory

Configure encoding for different filetypes in maven?

I use the maven-resource-plugin to filter some resources in my maven project. In my parent project I have:
<project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
In a sub project I have a test.properties file which is a plain java properties file with default encoding=ISO-8859-1. This file contains:
aboutText=Version ${project.version} © 2012 blabla
To make sure this file filters correctly I have split the maven-resource-plugin into separate executions each with its encoding:
<plugin>
<artifactId>maven-resources-plugin</artifactId>
<configuration>
<nonFilteredFileExtensions>
<nonFilteredFileExtension>ico</nonFilteredFileExtension>
<nonFilteredFileExtension>jar</nonFilteredFileExtension>
</nonFilteredFileExtensions>
</configuration>
<executions>
<execution>
<id>filter-properties-files</id>
<phase>generate-resources</phase>
<goals>
<goal>copy-resources</goal>
</goals>
<configuration>
<!-- java properties files are encoded in ISO-8859-1 so when
filtering those files we stick with that encoding. -->
<encoding>ISO-8859-1</encoding>
<outputDirectory>${basedir}/after</outputDirectory>
<resources>
<resource>
<filtering>true</filtering>
<directory>${basedir}/before</directory>
<includes>
<include>**/*.properties</include>
</includes>
</resource>
</resources>
</configuration>
</execution>
<execution>
<id>filter-non-properties-files</id>
<phase>generate-resources</phase>
<goals>
<goal>copy-resources</goal>
</goals>
<configuration>
<encoding>${project.build.sourceEncoding}</encoding>
<outputDirectory>${basedir}/after</outputDirectory>
<resources>
<resource>
<filtering>true</filtering>
<directory>${basedir}/before</directory>
<includes>
<include>**/*.product</include>
<include>**/*.inf</include>
</includes>
</resource>
</resources>
</configuration>
</execution>
</executions>
</plugin>
This seems overkill and I have a feeling that I am either not using the plugin correctly or that this problem should be handled in another way. Maybe stick to encoding special characters in properties files directly:
aboutText=Version ${project.version} \u00a9 2012 blabla
?
The question is an invaluable answer in itself, as apparently the complicated procedure the author provides is the only way to configure different encodings for various filtered file types. The example given, however, is specific to the author's non-standard use-case, and glosses over a few important details, without which actual use of the example is fraught with gotchas:
It isn't obvious, but in the author's example the default resource copying goal resources is still enabled and runs in addition to the two defined goals!
You'll notice that the author used the lifecycle phase generate-resources instead of the default process-resources. This is a trick to get around the first point above; by making the two copy-resources goals occur in an earlier lifecycle phase, the resources are copied according to the given rules, and then when the default-resources goal comes along the original resource copying is left intact, apparently because its overwrite setting defaults false. But it would be better to disable altogether the default-resources execution.
The author provides an outputDirectory declaration. It would be natural to think that the author only provided this because a custom output directory was desired; after all, the resources goal provides a default value for this setting. Strangely, though, for the copy-resources goal this setting is actually required! There is a standard Maven variable ${project.build.outputDirectory} which can be used as the value, however.
Building on the author's own example in the question, here is a cut-and-paste way to filter properties files using ISO-8859-1, copy other files without filtering, and prevent the default resource copying from occurring; all using the standard source and target directories:
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-resources-plugin</artifactId>
<version>2.7</version>
<executions>
<execution>
<!-- Turn off default resource copying. -->
<id>default-resources</id>
<phase />
</execution>
<execution>
<!-- Filter resources in properties files. -->
<id>filter-properties-files</id>
<phase>process-resources</phase>
<goals>
<goal>copy-resources</goal>
</goals>
<configuration>
<encoding>ISO-8859-1</encoding>
<outputDirectory>${project.build.outputDirectory}</outputDirectory>
<resources>
<resource>
<directory>src/main/resources</directory>
<filtering>true</filtering>
<includes>
<include>**/*.properties</include>
</includes>
</resource>
</resources>
</configuration>
</execution>
<execution>
<!-- Do not do property substitution in files that are not properties files, such as binary files. -->
<id>copy-other-resources</id>
<phase>process-resources</phase>
<goals>
<goal>copy-resources</goal>
</goals>
<configuration>
<outputDirectory>${project.build.outputDirectory}</outputDirectory>
<resources>
<resource>
<directory>src/main/resources</directory>
<filtering>false</filtering>
<excludes>
<exclude>**/*.properties</exclude>
</excludes>
</resource>
</resources>
</configuration>
</execution>
</executions>
</plugin>
Update: After more research, I believe that instead of disabling the default execution, one could simply modify the default execution to ignore properties files, and add filtering of properties files as an additional execution. Moreover if the resources goal were used instead of copy-resources, there would be no need to indicate an output directory or a phase, as resources:resources automatically binds to the process-resources phase and outputs to ${project.build.outputDirectory}. Note that I've updated to version 3.1.0 of the plugin, so perhaps some of these options were not available in the version I used above. I have not tested this new, shorter configuration.
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-resources-plugin</artifactId>
<version>3.1.0</version>
<executions>
<execution>
<!-- Ignore properties files by default. -->
<id>default-resources</id>
<configuration>
<resources>
<resource>
<directory>${project.basedir}/src/main/resources</directory>
<excludes>
<exclude>**/*.properties</exclude>
</excludes>
</resource>
</resources>
</configuration>
</execution>
<execution>
<!-- Filter resources in properties files using ISO-8859-1. -->
<id>filter-properties-files</id>
<goals>
<goal>resources</goal>
</goals>
<configuration>
<encoding>ISO-8859-1</encoding>
<resources>
<resource>
<directory>${project.basedir}/src/main/resources</directory>
<filtering>true</filtering>
<includes>
<include>**/*.properties</include>
</includes>
</resource>
</resources>
</configuration>
</execution>
</executions>
</plugin>
Maybe someone could test this new configuration and let me know if it works the same as the original one I gave above.
You are right that you have to configure executions... You could get away with two executions rather that the three you seem to be using if you were following the standard directory layout but you seem to be putting files from ${basedir}/before into ${basedir}/after so the default execution of resources:resources coupled with adding multiple resources to the build section will not work for you.
The encoding of filtered files was an oversight in the original pom model specification and will likely be fixed in some as yet unspecified version of Maven

Files got overwritten in maven project when building a war

I'm building a web application project using maven, and packaging is set to "war". I also use YUI compressor plugin to compress javascript codes in the webapp directory. I've set up the YUI compressor like this:
<plugin>
<groupId>net.alchim31.maven</groupId>
<artifactId>yuicompressor-maven-plugin</artifactId>
<version>1.3.0</version>
<executions>
<execution>
<phase>process-resources</phase>
<goals>
<goal>compress</goal>
</goals>
</execution>
</executions>
<configuration>
<excludes>
<exclude>**/ext-2.0/**/*.js</exclude>
<exclude>**/lang/*.js</exclude>
<exclude>**/javascripts/flot/*.js</exclude>
<exclude>**/javascripts/jqplot/*.js</exclude>
</excludes>
<nosuffix>true</nosuffix>
<force>true</force>
<jswarn>false</jswarn>
</configuration>
</plugin>
If I do: mvn process-resources, src/main/webapp will get copied over to target/webapp-1.0/ directory, and javacripts are compressed. However, when I run mvn install, all the compressed javascripts are overwritten, apparently the packaging process copies the content from main/webapp one time before building the war file.
How can I get around this?
As you noticed, the /src/main/webapp dir (aka warSourceDirectory) contents is not copied into the project dir for packaging until the war plugin executes during the package phase. When the war plugin completes the archive is already built; too late to modify those resources. If the .js files you want to compress were moved into another directory (outside of /src/main/webapp) then you could do something like the below.
To test, I created a ${basedir}/src/play directory with a couple of files in it. I used the resource plugin for the example; you'd replace that config with the YUI compressor plugin config you needed and simply add the <webResource> element to your war plugin config as shown below; more info in the war plugin examples. My war ended up with the additional files right where I wanted them.
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-resources-plugin</artifactId>
<executions>
<execution>
<id>copy-resources</id>
<phase>process-resources</phase>
<goals><goal>copy-resources</goal></goals>
<configuration>
<outputDirectory>${project.build.directory}/tmpPlay</outputDirectory>
<resources>
<resource>
<directory>${project.basedir}/src/play</directory>
<includes>
<include>**/*</include>
</includes>
</resource>
</resources>
</configuration>
</execution>
</executions>
</plugin>
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-war-plugin</artifactId>
<executions>
<execution>
<id>default-war</id>
<configuration>
<webResources>
<resource>
<directory>${project.build.directory}/tmpPlay</directory>
<targetPath>WEB-INF/yourLocationHere</targetPath>
<includes>
<include>**/*</include>
</includes>
</resource>
</webResources>
</configuration>
</execution>
</executions>
</plugin>
I think #user944849 answer is the correct answer, at least one of the correct answers. Another way of archiving this is to exclude the modified javascript directory from maven-war-plugin configuration, e.g.:
<plugin>
<artifactId> maven-war-plugin </artifactId>
<configuration>
<warSourceExcludes>**/external/ dojo/**/*.js </warSourceExcludes>
</configuration>
</plugin>
this will tell maven-war-plugin not to copy from the excluded directory, but since the modified javascript directory is already there, the war file still contains the javascript directory, BUT with the modified, in this case, compressed javascript codes.
in your execution directive, set the phase for applying your compression and copying to be install and that will hopefully do the trick. the code should be something like this:
<executions>
<execution>
....
<phase>install</phase>
....
</execution>
<executions>
Here is my solution, simply add an antrun plugin which updates the packaged war file using the processed outputs, which binds to the package phase:
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-antrun-plugin</artifactId>
<executions>
<execution>
<id>package</id>
<phase>package</phase>
<configuration>
<target>
<zip basedir="${project.build.directory}/${project.build.finalName}"
destfile="${project.build.directory}/${project.build.finalName}.war"
update="true">
</zip>
</target>
</configuration>
<goals>
<goal>run</goal>
</goals>
</execution>
</executions>
</plugin>

maven copy bat file close to the jar

I am currently developing an maven based application. I want to make a bat file to run final jar. I've wrote bat file with call to java -jar... and put it into src/main/resources/runners folder. I also do not want to add this file to jar, so i excluded it from resources plugin. The problem is that bat is not copied. I've copypasted maven-resources-plugin configuration from their site, it does not work. However, i want copy bat only while calling jar:jar.
Application is hosted here, so you can see details there. I tried to bind copying as such:
<plugin>
<artifactId>maven-resources-plugin</artifactId>
<version>2.5</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</outputDirectory>
<resources>
<resource>
<directory>src/main/runners</directory>
</resource>
</resources>
</configuration>
</execution>
</executions>
</plugin>
Also tried <phase>package</phase> and <goal>jar</goal> (and <goal>jar:jar</goal>). No effect.
By the way: where can i read about maven phases and goals more detailed, then in official documentation (understood nothing from it)?
You could use the pre-integration-test phase, which will only be run if your jar was succesfully created by the build. You will then need to run a build through integration-test, verify, install, or deploy to ensure that the copy-resources is run.
<plugin>
<artifactId>maven-resources-plugin</artifactId>
<version>2.5</version>
<executions>
<execution>
<id>copy-builders</id>
<!-- here the phase you need -->
<phase>pre-integration-test</phase>
<goals>
<goal>copy-resources</goal>
</goals>
<configuration>
<outputDirectory>${project.build.directory}</outputDirectory>
<resources>
<resource>
<directory>src/main/runners</directory>
</resource>
</resources>
</configuration>
</execution>
</executions>
</plugin>
You can read more about the lifecycle at: http://maven.apache.org/guides/introduction/introduction-to-the-lifecycle.html.

Resources