ant to maven conversion: correct approach? - maven

I am tasked with converting a java project which is created with ant to maven.
This is how the project is set up.
All the sources are stored in src directory.
ant's compiling target is to compile the entire src directory.
ant's packaging target has several sub-targets.
Each target has different jars which has include or exclude directories.
This is the approach that I took.
Find out all dependencies. Store them in DependencyManagement section of parent pom
Create a module and copy entire src directory.
compiled it.
Tried to create separate modules for different jar files.
Problem: the files are in-separable. Most of the files are depending on other files. I tried separating them. It results in creating cyclic dependencies. Hence, this step failed.
Use different profiles and maven-jar-plugin to include or exclude packages.
Question 1 when I tried this mvn install -P profile1,profile2, target has only jar file for profile2. They both have maven-jar-plugin and each has different finalName.
<profile>
<id>profile1</id>
<build>
<plugins>
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-jar-plugin</artifactId>
<configuration>
<includes>
<include>**/src/.../profile1/**</include>
<finalName>profile1-lib</finalName>
</configuration>
</plugin>
</plugins>
</build>
</profile>
Is there a different command or am I doing something wrong?
Question 2 one of the lib has several image files in it.
The above approach does not copy the image files in the result jar.
I understand maven wants all resources in resources directory. I will move the images, but for now I am trying to include them in the jar.
I added maven-resources-plugin.
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-resources-plugin</artifactId>
<version>3.0.2</version>
<executions>
<execution>
<phase>validate</phase>
<goals>
<goal>copy-resources</goal>
</goals>
<configuration>
<outputDirectory>${basedir}/target/classes</outputDirectory>
<resource>
<directory>src/main/java/jpl/mipl/mdms/FileService/komodo/ui/savannah/subscription/util/resources</directory>
</resource>
</resources>
</configuration>
</execution>
</executions>
</plugin>
When I run mvn install -P profile1, I can see the logs saying Copying # resources.
I can also see them being copied to target/classes. the path that I gave to the plug-in. But they are all copied to that directory.
I want to retain the structure, and the result jar still doesn't have it.
Answer: I have to move them to resources directory. maven is strict.
Anything that I should be doing differently?
Extra Question Am I using the correct plug-ins? Or is there more efficient plug-ins that I should be using?
Thank you.

Answer to Question1 : You have missed the </includes> tag.(Probably because of the stackoverflow formatting!). I am not sure whether you can execute a maven command on two profiles at a time. when you do so, only the second profile gets executed. Try executing the command on each profile separately.
Answer to Question2: You have missed the <resources> opening tag.(Probably because of the stackoverflow formatting!). Moreover, if you want to retain the structure, you can mention the structure too in the <outputDirectory> tag, something like the below:
<outputDirectory>${basedir}/target/classes/src/main/java/jpl/mipl/mdms/FileService/komodo/ui/savannah/subscription/util/resources</outputDirectory>
This may look insane!, but may work if you have few resources directory. If you have more resources, then this may become cumbersome. But anyways, check whether this can be helpful!

Related

Maven Dynamically Exclude File

I have a Java project where I need to build 2 versions of the same EAR.
1 version needs to include all java files.
1 version needs to include all java files, except for one particular java file.
Right now I can achieve this by simply doing a normal Maven build to create the all inclusive EAR.
To build the EAR that excludes that 1 .java file, I just add an exclusion to the maven-compiler-plugin in my POM.xml file.
<build>
<plugins>
<plugin>
<artifactId>maven-compiler-plugin</artifactId>
<version>2.5.1</version>
<configuration>
<source>1.7</source>
<target>1.7</target>
<excludes>
<exclude>**/AggregatorMessageBean.java</exclude>
</excludes>
</configuration>
</plugin>
</plugins>
</build>
While this approach gives me what I need, it seems like there should be a better way to do this.
For instance, can I pass some kind of argument into Maven that will dictate whether or not that single Java file should be excluded or not?
It would be even better if I was able to build both versions from a single build, but I know I'm probably already pushing Maven beyond it's intended usage.
Has anyone ever had experience with dynamically excluding Java source files from a build?

Export OSGi bundles to a specific folder using maven

Can anyone plz guide me how can I copy the generated OSGi bundle to a different location on the disk?
I am using maven for building the OSGi bundle.
Complete Solution: Update on 9th Jan, 2014:
I got a better approach and updated the pom.xml with following plugin:
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-dependency-plugin</artifactId>
<version>2.8</version>
<executions>
<execution>
<id>copy-installed</id>
<phase>install</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>some-other-place</outputDirectory>
</configuration>
</execution>
</executions>
</plugin>
This was able to copy once the bundle generation was done an I could give the destination folder too.
When do you want to copy your bundle?
Assuming you have a project generating the bundle, then it should be available in your target folder, and will also be installed (running mvn install) in your local repository (~/.m2/repository/...).
You could just use a cp command to copy it wherever you want.
Deploying it to a test folder as part of the build is not necessarily a great idea: you're making your build dependent on machine specific settings or magic injected properties. That said, if you wanted to do that anyway, I'll use the following approach:
have a separate maven project which depends on the bundle and just deploys it wherever you like
define a property specifying the target directory (you can pass it on the command line, define it in your settings.xml or provide a default value for in your pom.xml)
use the maven-dependency-plugin:copy-dependency goal in your deployment project to copy your bundle
Guess this question is not really related to OSGi, more to maven... maybe you could have a look at the maven resources plugin, specifically http://maven.apache.org/plugins/maven-resources-plugin/examples/copy-resources.html which helps you copying arbitrary resources.

How to hot deploy JSP changes in maven app?

I have a maven web application. I am using springsource tool suite and its built in tc fabric server.
Every time I make any changes I have to do mvn clean install and restart the server. Even for the JSP changes.
Is there any way I can just make JSP changes and they are reflected in the browser on refresh like a regular web app (not maven app).
I have searched over internet but no success as yet.
Still No clue about it. It makes the development process extremely slow. I looked into jrebel but its not free and I am not looking for hot deploy of classes but just the hot deploy of JSP's, javascripts, css etc.
I currently use a profile to copy JSPs to my target dir, which I call from Eclipse once i need the JSPs updated.
You could also copy classfiles like this by adding executions.
<profile>
<id>copyJsps</id>
<build>
<plugins>
<plugin>
<artifactId>maven-resources-plugin</artifactId>
<version>2.5</version>
<configuration>
<outputDirectory>${basedir}/target/app/WEB-INF/jsp</outputDirectory>
<resources>
<resource>
<directory>src/main/webapp/WEB-INF/jsp</directory>
<filtering>true</filtering>
</resource>
</resources>
</configuration>
</plugin>
</plugins>
</build>
</profile>
Use: mvn resources:copy-resources -PcopyJsps
You can use Eclipse Filesync plugin to achieve this. You can configure plugin to map maven output folder to Application server directory
I know this is not maven way but it works.
Maybe this question will give some more insights.
This is my simple solution (workaround?) while using JBoss on Linux. It should also be valid for Tomcat or any other container that supports exploaded war's.
1. Use mvn war:inplace to create an exploaded war in src/main/webapp.
This will copy classes and lib there. You don't need to repeat this step if you're just changing JSP (or other /webapp/ files).
Alternatively you can create symlinks to classes and lib in src/main/webapp/WEB-INF:
cd src/main/webapp/WEB-INF
ln -s ../../../../target/classes
mvn package
ln -s ../../../../target/*/WEB-INF/lib
2. In the deployment directory create a symlink to src/main/webapp:
cd $DEPLOYMEN_DIR
ln -s $MYAPP_DIR/src/main/webapp myapp.war
This makes changes to JSP and other webapp files instantly available.
If you want to see the changes in your classes then you can trigger a reload of the application only my modifying web.xml. On you can run this script to monitor trigger the restart:
#!/bin/bash
while sleep 1; do
if [[ -n $(find WEB-INF/classes -newer WEB-INF/web.xml -type f) ]];then
date
touch WEB-INF/web.xml
fi
done
Run it from the src/main/webapp/ directory.
Note on JBoss AS 7: Here to trigger a reload you need to create a myapp.war.dodeploy file instead of touching web.xml
You can clean and copy the static files easy with the clean and resources plugins, but it won't work for the JSP files always. If the java source in the JSP files being copied introduces a new dependency you are not going to copy it to the lib folder. In that case, the app will break with a ClassNotFoundException.
Even if it is copied it can still break because the server has to be configured to scan the folder with dependencies and refresh the classpath. And that is the start of hot deployment I believe (details).
Try with Vinay's suggestion also. Judging by his answer it seems that the tc server supports scanning of dependencies by default, and with proper maven build this might be a satisfying solution.
To clean and copy the static files from your source directory to where it is deployed:
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-clean-plugin</artifactId>
<version>2.5</version>
<executions>
<execution>
<id>clean-loaded</id>
<phase>compile</phase>
<goals>
<goal>clean</goal>
</goals>
<configuration>
<excludeDefaultDirectories>true</excludeDefaultDirectories>
<filesets>
<fileset>
<directory>${path.server.input}</directory>
<followSymlinks>false</followSymlinks>
<useDefaultExcludes>false</useDefaultExcludes>
<includes>
<include>**/*.jsp</include>
<include>**/*.js</include>
<include>**/*.html</include>
<include>**/*.css</include>
<include>**/*.png</include>
<include>**/*.gif</include>
<include>**/*.jpg</include>
<include>**/*.jpeg</include>
</includes>
</fileset>
</filesets>
</configuration>
</execution>
</executions>
</plugin>
<plugin>
<artifactId>maven-resources-plugin</artifactId>
<version>2.6</version>
<executions>
<execution>
<id>copy-compile-output</id>
<phase>compile</phase>
<goals>
<goal>copy-resources</goal>
</goals>
<configuration>
<outputDirectory>${path.server.input}</outputDirectory>
<overwrite>true</overwrite>
<includeEmptyDirs>true</includeEmptyDirs>
<filtering>true</filtering>
<resources>
<resource>
<directory>${path.jsp.source}</directory>
<targetPath>${path.element.jsp.deploy}</targetPath>
<includes>
<include>**/*.jsp</include>
</includes>
</resource>
<resource>
<directory>${path.static.source}</directory>
<targetPath>${path.element.static.deploy}</targetPath>
<includes>
<include>**/*.js</include>
<include>**/*.html</include>
<include>**/*.css</include>
<include>**/*.png</include>
<include>**/*.gif</include>
<include>**/*.jpg</include>
<include>**/*.jpeg</include>
</includes>
</resource>
</resources>
</configuration>
</execution>
</executions>
</plugin>
add this to your properties section:
<path.server.input>ABSOLUTE_PATH_TO_DEPLOYED_WEBAPP_ROOT</path.server.input>
<path.jsp.source>ABSOLUTE_PATH_TO_JSP_SOURCE_ROOT</path.jsp.source>
<path.static.source>ABSOLUTE_PATH_TO_STATIC_SOURCE_ROOT</path.static.source>
<path.element.jsp.deploy>REALTIVE_PATH_TO_JSP_DEPLOY_ROOT</path.element.jsp.deploy>
<path.element.static.deploy>REALTIVE_PATH_TO_STATIC_DEPLOY_ROOT</path.element.static.deploy>
Properties that start with path must be absolute paths or start with a ${project.basedir} or similar. Properties that start with path.element are relative paths meaning that they must not be prepended with a / or start with another property that is an absoulte path. That is so because resources plugin copies in outputDirectory/targetPath (resources:copy-resources,
resource)
In my experience, IDE's usually bind their clean-and-build UI action to the compile phase. Also IDE's usually have a way to map a shell command or maven custom goal to be visible from it's UI menu.
To run with clean-and-build
The plugins are already bound to the compile phase. To ensure that clean plugin will run before resources plugin at the end of the compile phase, place them together at the end of your plugins section. It doesn't matter if a plugin is defined twice, just make sure that when reading the pom from top, the first clean plugin definition comes before the first resources plugin definition.
To run as separate action
Change under the execution tag for both like this:
<id>default-cli</id>
<phase>never</phase>
and now it won't be run in compile phase but by invoking from command line:
mvn clean:clean resources:copy-resources
In this case the placement of plugin definitions in pom is irrelevant, since you are defining their order with command arguments order. If this suits you your IDE most probably has a way to map this command as a custom goal visible from it's UI menu.
In both cases, I recommend backing-up the project folder when running for the first time.

Xcode Maven Plugin : adding extra headers

The Xcode Maven Plugin from http://sap-production.github.io/xcode-maven-plugin/site is a nice maven plugin for people who like maven and wan't to avoid some pain with xcode dependencies, framework creation and such.
It creates and installs lib and headers in the repository.
The headers are bundled in a .tar file during the process.
For some reason, I need to edit the tar file and add a few files in it before installing.
But as I'm quite the noob regarding maven, I need some help !
How can I modify on a byproduct of Maven before it is installed ? I suppose I can write some script that add some files to the .taf, but how can I be sure it's executed prior the installation ?
#Redwarp - It's been a while since this question was asked, but I'll offer up an answer.
You can configure a Maven plug-in's goal to be executed during a particular phase in the Maven build lifecycle.
Pick a phase that's executed before the install phase. Package may be the best phase for you to edit your tar file and add your required files.
The following is just a generalized example (the focus should be on phase and goal):
<project>
...
<build>
<plugins>
<plugin>
<groupId>com.sap.prd.mobile.ios.mios</groupId>
<artifactId>xcode-maven-plugin</artifactId>
<version>1.12.0</version>
<extensions>true</extensions>
<executions>
<execution>
<id>do-something</id>
<phase>package</phase>
<configuration>
...
</configuration>
<goals>
<goal>plugin-goal</goal>
</goals>
</execution>
</executions>
</plugin>
</plugins>
</build>
...
</project>
Find the plug-ins that suit your needs and bind their goals to the appropriate Maven lifecycle phases...which there's a good chance that you have already figured out by this point.

How to include resources from war to another maven project

I have a maven project , which needs to copy webapp/WEB-INF/ resources from another maven project which is packaged as a war .
How do I do it ?
PLease suggest
As Bittrance said, you should use the maven dependency plugin.
The better way is to create project that include all your shared resources, probably a type zip, which is build up with the assembly plugin. This is the good "maven way". It's a better solution than unpacking a war.
Then, refer it
<dependency>
<groupId>com.mygroup/groupId>
<artifactId>my-dependencies</artifactId>
<version>1.0.0</version>
<type>zip</type>
</dependency>
Next, you use the maven dependency plugin to unpack your resources, in the directory of your choice (probably WEB-INF/ ?)
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-dependency-plugin</artifactId>
<executions>
<execution>
<id>unpack-cfg-test-resources</id>
<goals>
<goal>unpack-dependencies</goal>
</goals>
<phase>resources</phase>
<configuration>
<outputDirectory>${project.build.directory}/WEB-INF/</outputDirectory>
<includeArtifacIds>my-resources</includeArtifacIds>
<excludeTypes>pom</excludeTypes>
<excludeTransitive>true</excludeTransitive>
</configuration>
</execution>
</executions>
</plugin>
I'm not realy sure of this code snippet (written for another purpose), but this is an example.
For more information, please follow this link : http://maven.apache.org/plugins/maven-dependency-plugin/
If you can't shared a common-project including your files, you can unpack war including only ftl (or whatever you want), but it's not a realy clean solution ;)
There is a lot of posts that deal with this subject :
Unzip dependency in maven
...
Just try with the keywords maven-dependency-plugin, unpack :)
Hope that will help you.
I can see some alternatives:
Use external references in your version control system to point all repos to the same files.
The Maven Dependency module can copy and unpack project dependencies. From there, you can use the Maven Assembly plugin (or Ant targets) to include parts of that dependency in your own installation.
At least for the FTL files, perhaps you could package them in a separate Jar file and then load them as resources through the class loader.
If the resources are filtered, you may get into problem with solution 1 if you want the filtered version and 2, 3 if you want the source version.
Hope this helps.
(This assumes your dependent project is java (jar) and not another web app, if it is a webapp I think the solution is similar).
I suggest a (slightly) different approach:
Instead of reading resources from war, add this to your war pom, to generate a jar in the artifact as well as a war:
<!-- maven war plugin config -->
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<configuration>
...
<attachClasses>true</attachClasses>
<classesClassifier>some-string</classesClassifier>
</configuration>
<artifactId>maven-war-plugin</artifactId>
<version>3.0.0</version>
</plugin>
...
<resources>
<!-- This is for inclusion in the jar, so dependent module can load it -->
<resource>
<targetPath>some-path</targetPath>
<directory>src/main/webapp/path...</directory>
<includes>
<include>your-resource</include>
</includes>
</resource>
</resources>
And this to your consuming pom, so the generated jar will be loaded:
<dependency>
<groupId>com.company</groupId>
<artifactId>...</artifactId>
<classifier>some-string</classifier>
</dependency>
Then you will be able to load the resources the usual way (getResourceAsStream("some-path/your-resource"))

Resources