Full search and replace of strings in source files when copying resources - maven

I have some java source files that use a package prefix (they are emulating some JDK classes). I use these files with the prefix to run against some unit tests. If the tests pass I want to produce a jar that contains the source files but with the package prefix removed from all the java files.
I am using maven for builds. Does any one know of a way to do this? Essentially what I want is something like the resources plugin filtering feature, but that does proper search and replace (like: s/my.package.prefix.//g), rather than filtering on ${vars}.

You can also use
http://code.google.com/p/maven-replacer-plugin/
100% maven and doing exactly what you want and more

This can be solved with the antrun plugin. Firstly the sources need to be copied to the target directory, with:
<build>
...
<resources>
<resource>
<directory>src/main/java</directory>
<includes>
<include>**/*.java</include>
</includes>
</resource>
</resources>
...
</build>
Secondly you use the replace task of the antrun plugin to replace the files using the prepare package phase
<build>
...
<plugin>
<artifactId>maven-antrun-plugin</artifactId>
<executions>
<execution>
<phase>prepare-package</phase>
<configuration>
<tasks>
<replace token= "my.package.prefix." value="" dir="target/classes">
<include name="**/*.java"/>
</replace>
</tasks>
</configuration>
<goals>
<goal>run</goal>
</goals>
</execution>
</executions>
</plugin>
...
</build>
This will copy the source files to target/classes in the process-resources phase, do a search and replace on the files inplace in the target/classes directory in the prepare-package phase and finally they will jarred up in the package phase.

Related

How do I add a file to the artifact (jar or war) created by maven?

I have an antrun task (goal run on phase prepare-package) set up that creates a file and saves it in /target/foo.bar. How do I add that to the artifact that gets created by maven (depending on module, it could be a jar or a war file)?
I have tried it with resources, with the builder-helper plugin, and the jar plugin - no luck:
<resources>
<resource>
<directory>target</directory>
<includes>
<include>**/foo.bar</include>
</includes>
</resource>
</resources>
That doesn't seem to do anything.
<plugin>
<groupId>org.codehaus.mojo</groupId>
<artifactId>build-helper-maven-plugin</artifactId>
<version>3.0.0</version>
<executions>
<execution>
<id>attach-artifacts</id>
<phase>package</phase>
<goals>
<goal>attach-artifact</goal>
</goals>
<configuration>
<artifacts>
<artifact>
<file>${project.build.directory}/foo.bar</file>
<type>bar</type>
</artifact>
</artifacts>
</configuration>
</execution>
</executions>
</plugin>
According to debug output, this seems to install something extra in the repo, but doesn't add foo.bar to the artefact.
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-jar-plugin</artifactId>
<version>3.0.2</version>
<configuration>
<includes>
<include>../foo.bar</include>
</includes>
</configuration>
</plugin>
No observable effect, either. :(
(I assume this might work for the war file, but I'd prefer one way to do it for both artifact types, if possible - plus I really need this to work for the jars, too...)
Is there a way to do what I want to do?
(I'd prefer not saving my file in src/main/resources first; I thought the packaging processes would pick files up from the build directory after they were placed there anyway, but I suppose I misunderstood something...)
I had my file saved to project.build.directory. Changing that to project.build.outputDirectory means the jar plugin is picking it up, without the need of any other plugins. Unfortunately, that doesn't sort the war issue out... :(
I had a similar problem and stored the resulting artifact in
target/${project.name}-${project.version}/foo.war
To be more precise, I created the war from a directory using the ant target
<war warfile="target/${project.name}-${project.version}/foo.war" basedir="somedir" />
Then it was correctly added to the surrounding ear.

Maven 2.2.1: [Warning] JAR will be empty - no content was marked for inclusion

Maven 2.2.1
JDK - 1.6.0_45
[WARNING] JAR will be empty - no content was marked for inclusion!
BUILD SUCCESSFUL
But build creates jar with pom.xml but no class files.
On the maven source code this exception is thrown only when source directory is not found.
The build is working for all other developers except on my workstation and one more workstation
I have tried all the solutions provided for this issue on stack overflow.
My source directory is src/java.
I also created src/main/java as source still no result.
I am calling mvn -o jar:jar && call mvn -o antrun:run
-o is becuase at this point I am testing with some old jars.
<build>
<sourceDirectory>src/java</sourceDirectory>
<resources>
<resource>
<directory>${basedir}/src/java</directory>
<includes>
<include>**/*.xml</include>
<include>**/*.properties</include>
</includes>
</resource>
</resources>
<testResources>
<testResource>
<directory>${basedir}/src/test/resources</directory>
<includes>
<include>**/*.properties</include>
<include>**/*.xml</include>
</includes>
</testResource>
</testResources>
<plugins>
<plugin>
<artifactId>maven-compiler-plugin</artifactId>
<configuration>
<debug>true</debug>
<optimize>false</optimize>
<showDeprecation>true</showDeprecation>
<source>1.5</source>
<target>1.5 </target>
</configuration>
</plugin>
<plugin>
<artifactId>maven-surefire-plugin</artifactId>
<configuration>
<excludes>
<exclude>test*/temp/*.java</exclude>
<exclude>test*/support/*.java</exclude>
<exclude>test*/debug/*.java</exclude>
</excludes>
<includes>
<include>test*/**/AllTests.java</include>
</includes>
</configuration>
</plugin>
<plugin>
<artifactId>maven-antrun-plugin</artifactId>
<version>1.7</version>
<executions>
<execution>
<id>default-cli</id>
<phase>install</phase>
<configuration>
<target>
<copy file="${project.build.directory}/${artifactId}-${version}.jar"
todir="${user.home}/.m2/repository/${groupId}/${artifactId}/${version}" />
</target>
</configuration>
<goals>
<goal>run</goal>
</goals>
</execution>
</executions>
</plugin>
</plugins>
</build>
First follow the conventions in Maven which means your production sources code should be in src/main/java. You should also locate your resources like property files or other kind of files (like xml files) in your case to the proper location which is for production src/main/resources and for unit tests src/test/resources.
The first thing you should change is the directory structure for your project in the process in migration. That will save many hassles with configurations in Maven cause you are violating the convention over configuration paradigm.
Your unit tests code in src/test/java and follow the naming conventions for unit tests which means name your unit tests like *Test.java nothing more. You don't need to define a suite to run all the tests. If you follow the naming convention maven-surefire-plugin will do all the work for you.
Remove the antrun plugin from your pom configuration and use
mvn install
instead to install your produced jar into local repository. Based on the build life cycle you will compile, unit test and package your code into resulting jar files.
Usually in Maven there is no reason to call mvn jar:jar separately.
Apart from that all you should stop using Maven 2.2.1 cause it has defined End Of Life. Better start with Maven 3.X instead. But everything i wrote before is valid Maven 3.
I got Build Success but same error:
JAR will be empty - no content was marked for inclusion.
It was a test project and I realized that I had no "main" under "src". As soon as I corrected this, it was fixed. I am adding the wrong and right structure screenshots in the attachments:
right structure
wrong structure - missing main folder

How to include external source files in maven-jar-plugin

We are building a jar file from external(to the project) classes.
That works fine but we have not been able to figure out how to also include the external source files. I have tried using the "< includes >" tag but only end up with a manifest file in the final jar when used. I have looked at using the maven-resources-plugin but either I used it wrong or it doesn't work in my case. Here is a copy of our of code:
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-jar-plugin</artifactId>
<version>2.4</version>
<executions>
<execution>
<!-- <phase>generate-resources</phase> -->
<phase>clean</phase>
<goals>
<goal>jar</goal>
</goals>
<configuration>
<classesDirectory>${itendant.path}/web/rocket/WEB-INF/classes</classesDirectory>
<finalName>${itendant.jar.name}</finalName>
<outputDirectory>${itendant.jar.path}</outputDirectory>
</configuration>
</execution>
</executions>
</plugin>
Sources? Do you mean external dependencies? These should also be managed with maven, using mvn deploy:deploy-file as described on http://maven.apache.org/plugins/maven-deploy-plugin/usage.html , and imported in your pom.xml.
If you really mean external resources, then a proper resources declaration would be:
<project>
...
<build>
...
<resources>
<resource>
<directory> [your folder here] </directory>
</resource>
</resources>
...
</build>
...
</project>
You can have multiple tags if you have multiple resource directories, of course. Also note that building anything during clean is questionable, as clean is not run every build - package would be a better option.

Inject the Mercurial working directory changeset id such as (838cb9c0367e) into properties file via Maven?

We use Maven for our builds and Mercurial for our changesets. While our software has a major version handled already we would really like to be able to know what Mercurial changeset was used to build any server that runs our software.
Does anybody know of a way in Maven to grab the working directory's changeset in Mercurial and get it into a properties file or something so we can then display it somewhere in our application when sys admins do a "sanity check" against what version is currently running?
You could make an update hook which outputs the changeset ID into an unversioned .properties file:
[hooks]
update = echo changesetid=$HG_PARENT1 > version.properties
Advantage of this approach is that you can easily customize this value if needed, and the build stays independent of the versioning system (or lack thereof).
If you want to put something in the Maven build that generates it instead, have you looked at the Buildnumber Maven Plugin (hgchangeset goal) or Maven Mercurial Build Number Plugin?
Merge this to your pom.xml:
<project>
<build>
<resources>
<resource>
<directory>src/main/resources</directory>
<filtering>true</filtering>
</resource>
</resources>
<plugins>
<plugin>
<groupId>org.codehaus.mojo</groupId>
<artifactId>buildnumber-maven-plugin</artifactId>
<executions>
<execution>
<phase>validate</phase>
<goals>
<goal>hgchangeset</goal>
</goals>
</execution>
</executions>
</plugin>
</plugins>
</build>
</project>
Then make a .properties file in src/main/resources with a property set as ${changeSet}. For example:
revision = ${changeSet}
modificationTime = ${changeSetDate}
If you can intercept command output (into environment variable, f.e) hg id -i will be easy way. More complex ids can be constructed with hg log --template "..." tip
You could use Maven's antrun plugin to run a <exec> or <java> task which generates a properties file with that information. That's not very elegant, though.
You can also use https://github.com/volodya-lombrozo/hg-revision-plugin, if you need more properties, than org.codehaus.mojo.buildnumber-maven-plugin.
<build>
<resources>
<resource>
<directory>src/main/resources</directory>
<filtering>true</filtering>
</resource>
</resources>
<plugins>
<plugin>
<groupId>com.github.volodya-lombrozo</groupId>
<artifactId>hg-revision-plugin</artifactId>
<version>0.2</version>
<executions>
<execution>
<phase>validate</phase>
<goals>
<goal>
scan
</goal>
</goals>
</execution>
</executions>
</plugin>
</plugins>
</build>
Then you can use second properties:
hg.author=${hg.author}
hg.branch=${hg.branch}
hg.revision=${hg.rev}
hg.node=${hg.node}
hg.tags=${hg.tags}
hg.desc=${hg.desc}
hg.date=${hg.date}

how to assemble external artifacts into one global directory with the maven-assembly-plugin (or otherwise)

I am experimenting with Maven and I am trying to mavenize a project originally build with shell scripts.
With the Maven rule-of-thumb: one project, one artifact, I created the following structure:
<PROJECT>
<MODULE-1>
<MODULE-2>
<MODULE-3>
..
<MODULE-N>
<RESOURCES>
<DISTRIB>
The RESOURCES module is structured as follows:
<RESOURCES>/src/main/resources/<MODULE-1>/bin
<RESOURCES>/src/main/resources/<MODULE-1>/lib
<RESOURCES>/src/main/resources/<MODULE-1>/doc
<RESOURCES>/src/main/resources/<MODULE-2>/bin
<RESOURCES>/src/main/resources/<MODULE-2>/lib
<RESOURCES>/src/main/resources/<MODULE-2>/doc
...
<RESOURCES>/src/main/resources/<MODULE-N>/bin
<RESOURCES>/src/main/resources/<MODULE-N>/lib
<RESOURCES>/src/main/resources/<MODULE-N>/doc
The reason for doing it this way was that the resources above are needed at runtime, not compile-time and they are mostly property files, config files and shell scripts to invoke the various jar-files. For the final resources step, I wanted to combine the subdirectories into one global bin/lib/doc directory. However, I do not see an option in the assembly descriptor to strip of the prefix of the modules to get to what I want:
<RESOURCES>/target/resources/bin
<RESOURCES>/target/resources/lib
<RESOURCES>/target/resources/doc
where bin would contain all the files found in the /src/main/resources//bin directory, /src/main/resources//bin directory etc. Similarly for lib, doc.
My question: should I have a:
<MODULE-1>/src/external/resources/bin
<MODULE-1>/src/external/resources/lib
<MODULE-1>/src/external/resources/doc
...
<MODULE-N>/src/external/resources/bin
<MODULE-N>/src/external/resources/lib
<MODULE-N>/src/external/resources/doc
structure instead, that I would then access through a dependency-set? These files should not be part of the jar-file of the various modules and therefore cannot be stored in src/main/resources of their respective projects. Or is what I want to achieve doable by using some other maven plugin instead?
In the DISTRIB module I would combine the output of the RESOURCES module with the JAR-files and dependencies to create a directory structure that would then be used with a packaging tool (Solaris package and WiX installer).
Any help would be appreciated!
In the pom fort he resources module set the source directory to something other than /src/main/resources/ so that it does not copy them to the target folder. Then use the Maven Resources Plugin to copy the resource files to target/bin and target lib etc.
e.g.
<plugin>
<artifactId>maven-resources-plugin</artifactId>
<version>2.4.3</version>
<executions>
<execution>
<id>copy-resources</id>
<phase>generate-sources</phase>
<goals>
<goal>copy-resources</goal>
</goals>
<configuration>
<outputDirectory>target/bin/</outputDirectory>
<resources>
<resource>
<directory>src/external/resources/bin</directory>
<filtering>false</filtering>
</resource>
</resources>
</configuration>
</execution>
<execution>
<id>copy-resources</id>
<phase>generate-sources</phase>
<goals>
<goal>copy-resources</goal>
</goals>
<configuration>
<outputDirectory>target/lib/</outputDirectory>
<resources>
<resource>
<directory>src/external/resources/lib</directory>
<filtering>false</filtering>
</resource>
</resources>
</configuration>
</execution>
</executions>
</plugin>`

Resources