Is there a maven plugin to install the project? - maven

I'm new with Maven, I just finished to read the Sonatype guide and I'm very satisfied by the functions that maven makes available. I created an application distribution (.zip) package and I would like to know if there is a manner to use maven as an installer.
I don't mean the installation that maven does into the local repository, what I mean is explained by the following example:
I've a folder with a jar file, an .sql script, a /lib and obviously a pom.xml file.
I would like that maven installs this project for me when I execute the "mvn" command.
So maven should:
- Copy the jar file in the ${TOMCAT_HOME}\webapps directory.
- Execute the sql script on the postgresql database
- Copy the \lib directory in c:\myLibs
- etc etc
During this process it should also make some checks (example TOMCAT_HOME is set on the system? Postgres is turned on? etc.) and ask to the user some parameter (example "The installation will reset the database do you want to continue?" or "Please insert the database password: ".
Is there a maven plugin that helps to do this? If not is there an application alike maven specialized to create "installer" ? Is it a standard, widespread application?
Thanks a lot for your help!

Try:
mvn deploy.
Add to your pom
<distributionManagement>
<repository>
<id>sonatype.internal</id>
<name>Internal Release Repository</name>
<url>http://sonatypeAddress:sonatypePort/context</url>
</repository>
</distributionManagement>
Plugins section:
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-scm-plugin</artifactId>
<configuration>
<tag>${build.tag}</tag>
<username>${scm.username}</username>
<password>${scm.password}</password>
</configuration>
</plugin>
antrun plugin - and make what you want.
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-antrun-plugin</artifactId>
<version>1.7</version>
<dependencies>
...
</dependencies>
<executions>
<execution>
<id>install</id>
<phase>install</phase>
<configuration>
<target>
<delete dir="mylocalization" />
<copy file="target/out/my.jar" tofile="mylocalication" />
<copy todir="mylocalization/doc">
<fileset dir="target/doc" />
</copy>
<copy todir="mylocalization/somethingMore">
<fileset dir="target/more">
<include name="a.txt" />
<include name="b*.txt" />
</fileset>
</copy>
</target>
</configuration>
<goals>
<goal>run</goal>
</goals>
</execution>
</executions>
</plugin>
See also maven-wagon

Related

Axis wsdl2java maven plugin with xmlbeans doesn't include resources folder

I'm using axis2 to re-generate the client code for an updated webservice that I need to use, for a legacy application.
Being a legacy application I would like to avoid changing the code that has been already written, and re-generate the classes as they were generated who-know-how-many years ago by the eclipse plugin, but this time using maven instead of eclipse.
So I seen that they were generated using axis2 and xmlbeans, and I produced the configuration in the maven plugin:
<plugin>
<groupId>org.apache.axis2</groupId>
<artifactId>axis2-wsdl2code-maven-plugin</artifactId>
<version>1.5.6</version>
<executions>
<execution>
<id>TheirsWs</id>
<goals>
<goal>wsdl2code</goal>
</goals>
<phase>generate-sources</phase>
<configuration>
<packageName>it.theirs.ws</packageName>
<wsdlFile>${basedir}/src/main/resources/theirWs.wsdl</wsdlFile>
<generateServerSide>false</generateServerSide>
<databindingName>xmlbeans</databindingName>
<unpackClasses>true</unpackClasses>
</configuration>
</execution>
</executions>
</plugin>
What happen now is a very nice thing.
The plugin generate a .class file in the generated-sources / axis2 / wsdl2code / resource folder, However it is not added by maven to the final package, causing a ClassNotFoundException when calling the webservice.
I solve the problem by adding the resource folder into the JAR using the maven default feature of including and excluding folder. The solution for your case will be:
<build>
<!-- This will the MAVEN to copy the entire folder, you can copy only the .class files -->
<resources>
<resource>
<directory>${project.build.directory}/generated-src/resources</directory>
<includes>
<include>**/*</include>
</includes>
</resource>
</resources>
<plugin>
<groupId>org.apache.axis2</groupId>
<artifactId>axis2-wsdl2code-maven-plugin</artifactId>
<version>1.5.6</version>
<executions>
<execution>
<id>TheirsWs</id>
<goals>
<goal>wsdl2code</goal>
</goals>
<phase>generate-sources</phase>
<configuration>
<packageName>it.theirs.ws</packageName>
<wsdlFile>${basedir}/src/main/resources/theirWs.wsdl</wsdlFile>
<generateServerSide>false</generateServerSide>
<databindingName>xmlbeans</databindingName>
<!-- I add this line just to be easy to referenciate the souce -->
<outputDirectory>${project.build.directory}/generated-src</outputDirectory>
<unpackClasses>true</unpackClasses>
</configuration>
</execution>
</executions>
</plugin>
Had the same problem, i changed the Ant build.xml buildfile from:
<target depends="pre.compile.test" name="compile.src" if="jars.ok">
<javac debug="on" memoryMaximumSize="256m" memoryInitialSize="256m" fork="true" destdir="${classes}" srcdir="${src}">
<classpath refid="axis2.class.path"/>
</javac>
</target>
To:
<target depends="pre.compile.test" name="compile.src" if="jars.ok">
<javac debug="on" memoryMaximumSize="256m" memoryInitialSize="256m" fork="true" destdir="${classes}" srcdir="${src}">
<classpath refid="axis2.class.path"/>
</javac>
<copy todir="${classes}">
<fileset dir="${resources}"/>
</copy>
</target>
The new Copy task add all the resources to the target classes folder so the generated Jar will include them.
Hope it helps.

Ant - Zip Multiple Folders

I'm trying to run an Ant job within Maven to look at a folder, and based on how many folders are in that folder, to create x number of zip files with the name of the folder. I have it working manually, but it would be nice if I didn't have to edit the pom each time I added a new folder to this structure.
<configuration>
<target name="zip">
<zip destfile="root/sub1/sub1.jar">
<zipfileset dir="root/sub1/unpacked/" includes="**" ></zipfileset>
</zip>
</target>
</configuration>
If I were to add sub2 to the root dir, I would like it to be picked up automagically, and create a sub2.jar file (yes, I'm aware I'm using .jar, but the program that is taking these files expects .jar files, but they're not jar files in that they contain any Java code, they're just zip files with jar extensions)
I've tried this
Thanks I had a look at the first link, but perhaps I'm doing it wrong
<target name="checkDir">
<foreach target="zip" param="theFile">
<dirset dir="root" casesensitive="yes">
<include name="**"/>
</dirset>
</foreach>
</target>
<target name="zip">
<!-- <zip destfile="root/${theFile}/${theFile}.jar">
<zipfileset dir="root/${theFile}/unpacked/" includes="**" ></zipfileset>
</zip> -->
<echo message="${theFile}"/>
</target>
I just get
[INFO] --- maven-antrun-plugin:1.7:run (process-javascript-plugin) # war---
[INFO] Executing tasks
zip:
[echo] ${theFile}
[INFO] Executed tasks
Still doesn't seem to be working.
pom.xml
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-antrun-plugin</artifactId>
<version>1.7</version>
<executions>
<execution>
<id>process-cartridges</id>
<phase>compile</phase>
<configuration>
<target>
<ant antfile="root/build-main.xml"/>
</target>
</configuration>
</execution>
</executions>
</plugin>
build-main.xml
<?xml version="1.0" encoding="UTF-8" ?>
<project>
<target name="checkDir">
<foreach target="zip" param="theFile">
<dirset dir="root" casesensitive="yes">
<include name="**"/>
</dirset>
</foreach>
</target>
<target name="zip">
<zip destfile="root/${theFile}/${theFile}.jar">
<zipfileset dir="root/${theFile}/unpacked/" includes="**" />
</zip>
<echo message="TESTZIP ${theFile}"/>
</target>
</project>
Doesn't seem to be working. Am I missing anything?
You could use the foreach task of Ant to do this, combining the answers from those two posts: Ant: How to execute a command for each file in directory? and Calling foreach in maven-antrun-plugin.
However, you can also have a Maven solution using the iterator-maven-plugin to iterate over all sub-folders and then use the maven-jar-plugin to make the jar:
<plugin>
<groupId>com.soebes.maven.plugins</groupId>
<artifactId>iterator-maven-plugin</artifactId>
<version>0.3</version>
<executions>
<execution>
<phase>package</phase>
<goals>
<goal>iterator</goal>
</goals>
<configuration>
<folder>root/</folder>
<pluginExecutors>
<pluginExecutor>
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-jar-plugin</artifactId>
<version>2.6</version>
</plugin>
<goal>jar</goal>
<configuration>
<classesDirectory>root/#item#/unpacked</classesDirectory>
<outputDirectory>root/#item#</outputDirectory>
<finalName>#item#.jar</finalName>
</configuration>
</pluginExecutor>
</pluginExecutors>
</configuration>
</execution>
</executions>
</plugin>
This is bound to the package phase. It will iterate over all direct subfolders of the root folder and invoke the jar plugin with the given configuration. #item# is used to refer to the current directory name.

Making maven do file copying between building and running

Revised Question (old question below):
Problem: When building and running a Jenkins plugin project in NetBeans using Maven, Java class loader used by log4j does not find some files (like configuration file, a custom appender, JDBC driver). They need to be copied to another location under target, and then they are found.
The solution I think I want is this: I want to give maven an extra command line argument(s), configured in NetBeans. This should make maven do extra step after building and before running anything. The step can either be the file copying (specified in pom.xml or by the command arguments), or it can be running a script (specified in pom.xml or by the command line arguments).
What to add to pom.xml? Some maven plugin?
Old Question (for reference)
I have a maven project for "my-jenkins-plugin". I need to use log4j with it. I currently have log4j.xml at this path:
./src/main/resources/log4j.xml
When I do clean&build in Netbeans, it gets copied to these places:
./target/classes/log4j.xml
./target/generated-classes/emma/classes/log4j.xml
./target/my-jenkins-plugin/WEB-INF/classes/log4j.xml
However, log4j does not find the file from any of these locations. I need to manually copy it to this location:
./target/work/webapp/WEB-INF/classes/log4j.xml
And then it works as expected.
More details: Maven 2, Netbeans 7.2. It's standard Jenkins plugin, project originally created with mvn hpi:create, and Netbeans uses Jetty to run Jenkins. Classpath used when running under NetBeans is java.class.path=C:\work\maven\boot\classworlds-1.1.jar (which is an existing jar) and I haven't found a way to add anything to this classpath, but if I add log4j.xml to root of that jar file, it is also found and works (obviously this is not a satisfactory solution). I know if log4j works or not simply by looking at console output, either it's correct log lines, or the dreaded log4j:WARN No appenders could be found for logger (TestLog). log4j:WARN Please initialize the log4j system properly. error and nothing else.
Question: How can I have either
the log4j.xml found in the first set of locations,
or log4j.xml found in a location outside target dir, like C:\log4j\log4j.xml
or make maven and/or netbeans to copy log4j.xml to a location where it is found now
or any other nice way to let me give my plugin log4j.xml after clean&build automatically, when debugging with NB?
You could use the Maven Ant plugin to run an Ant script that did the copying, or use the Maven resources plugin, which seems aimed at your exact use case of copying stuff to the output directory.
Also be aware that you can parameterize your build as described here (ignore the Jenkins part of that title, the answer relates to general Maven usage).
You could use this plugin in a profile:
<pluginRepositories>
<pluginRepository>
<id>evgenyg</id>
<name>Evgeny Goldin repo</name>
<url>http://evgenyg.artifactoryonline.com/evgenyg/repo/com/github/goldin/</url>
</pluginRepository>
</pluginRepositories>
<profiles>
<profile>
<id>copy</id>
<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>generate-resources</phase>
<goals>
<goal>copy</goal>
</goals>
<configuration>
<resources>
<resource>
<targetPath>${project.build.outputDirectory}/work/webapp/WEB-INF/classes/</targetPath>
<directory>${project.basedir}/src/main/resources</directory>
<includes>
<include>log4j.xml</include>
</includes>
</resource>
</resources>
</configuration>
</execution>
</executions>
</plugin>
</plugins>
</build>
</profile>
</profiles>
To activate: mvn -Pcopy generate-resources
You can use copy artifact plugin. As in hudson.
This is how I got maven to copy .class and .jar files to new location before executing hpi:run goal. The log4j.xml is still copied in my Java code in a static{} block before instantiating log4j. To use this profile, I added -P netbeans to maven command line args in Netbeans:
Profile and plugin definition in pom.xml:
<profiles>
<profile>
<id>netbeans</id>
<build>
<plugins>
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-antrun-plugin</artifactId>
<version>1.7</version>
<executions>
<execution>
<id>copy</id>
<phase>compile</phase>
<configuration>
<target>
<ant antfile="${basedir}/log4j/ant.xml">
<target name="log4jcopy"/>
</ant>
</target>
</configuration>
<goals>
<goal>run</goal> <!-- means antrun:run -->
</goals>
</execution>
</executions>
</plugin>
</plugins>
</build>
</profile>
</profiles>
Build XML for ant, log4j/ant.xml:
<project default="log4jcopy">
<target name="log4jcopy">
<echo message="Copying class files so that log4j finds them at runtime."/>
<copy verbose="true"
todir="target/work/webapp/WEB-INF/lib">
<fileset
dir="log4j"
includes="mysql-connector-java-5.1.6.jar" />
</copy>
<copy verbose="true"
todir="target/work/webapp/WEB-INF/classes/hyde/jenkins/myplugin">
<fileset
dir="target/classes/hyde/jenkins/plugins/myplugin"
includes="LogAppender*.class" />
</copy>
</target>
</project>

bring -f option to multi module

there is -f option in maven, that allows to specify alternate pom.xml file. Is there a possibility, that I can also bring this behaviour to the executed modules? Now it looks like, that when I have this structure: projectA: pom.xml pom.xml2
projectB: pom.xml pom.xml2
And when I run maven with -f pom.xml2 option as reactor with projectB specified as module, it looks like that it picks pom.xml2 from the projectA, and it picks pom.xml from projectB. Is there a way, how can I propagate the -f option to the modules?
Thanks for answering.
Because we can specified pom file in module definition.1
Here's an example for using alternative pom file in module.
<modules>
<module>child1/pom-jdk14.xml</module>
<module>child2/pom-jdk14.xml</module>
</modules>
As Jörn Horstmann comments I would try lots of things to get this working with profiles in one pom.
If that's not possible the only way I can think of to get this working is to bypass the normal maven mechanism by using a "switching pom" with profiles. This pom is put as pom.xml in each module and has a profile for each of your pom.xml2 (or others) and in that profile executes another maven build f.e. via the antrun-plugin with the -f for the pom you need:
<profile>
<id>xml2</id>
<build>
<plugins>
<plugin>
<artifactId>maven-antrun-plugin</artifactId>
<executions>
<execution>
<id>build pom.xml2</id>
<phase>prepare-package</phase> <!-- whatever suits you -->
<configuration>
<target>
<echo level="info" message="Building pom.xml2..." />
<exec executable="cmd" dir=".">
<arg value="/c" />
<arg value="mvn" />
<arg value="-f" />
<arg value="pom.xml2" />
<arg value="install" /> <!-- enter which phase you need -->
</exec>
</target>
</configuration>
<goals>
<goal>run</goal>
</goals>
</execution>
</executions>
</plugin>
</plugins>
</build>
</profile>

Integrating ant resource generation targets into a Maven build

I'm currently working on a fairly large project that has been migrated from Ant to Maven. There are no problems with the actual build process (it compiles and packages the source code fine).
The problem is that I also have a lot of targets that generate additional resources for the project (compile LessCSS, generate & upload documentation, generate tld files for custom tags and functions etc.). I am not sure how I should handle these tasks. Let's take the target that builds CSS&JS as an example (the others are more or less similar, but not connected). It looks like this (simplified):
<target name="build.css_js">
<concat destfile="${webapp.dir}/scripts/main.js">
<fileset dir="${webapp.dir}/scripts/src" includes="*.js"/>
</concat>
<!-- build css files from less sources -->
<taskdef name="lesscss" classname="com.asual.lesscss.LessEngineTask" classpathref="libraries" />
<lesscss input="${webapp.dir}/syles/src/input.less" output="${webapp.dir}/styles/output.css" />
</target>
In the pom.xml I have the following plugin set up:
<plugin>
<artifactId>maven-antrun-plugin</artifactId>
<executions>
<execution>
<phase>generate-resources</phase>
<configuration>
<tasks>
<echo message="Hello World from pom.xml"/>
<ant target="build.css_js"/>
</tasks>
</configuration>
<goals>
<goal>run</goal>
</goals>
</execution>
</executions>
</plugin>
The dependencies I'm using are no longer in our SVN repository (since they are managed by Maven), so I switched the libraries variable to point to the Maven repo:
<property name="lib.dir" location="${env.HOMEPATH}/.m2/repository" />
This is not good, as that path may be valid only on my machine. I don't know any other way to reference the libraries from the Maven repository and I need them to run the ant targets.
Is my approach ok or is there a better way of doing things?
How do I get over the library problem?
Some resources are needed when packaging the project but some are not. Is there a lifecycle phase that is out of scope for compile/package? I found the site lifecycle which I think fits my needs.
Ideally, I should give up on the ant build file altogether, but I'm not sure it's worth the effort of making the scripts run as maven plugins (I currently have no idea how to do that). What do you think about this?
I'm new to Maven so any suggestions are appreciated.
Generally embedding antrun calls is not ideal, but if you've not found a suitable plugin to do what you need then I wouldn't worry about it. If the processing is fairly simple it is actually quite easy to embed it in a Maven plugin yourself, see this example for help getting started.
If you are going with antrun, and the dependency jars have already been installed to your Maven repository, you can configure the antrun plugin to use those jars in its execution by adding them as dependencies of the plugin configuration. This means the dependencies will be resolved and available for use, but not be visible to your project (useful to help avoid accidental inclusion). To then access them in a portable way you can use:
<property name="lib.dir" location="${settings.localRepository}" />
Alternatively you can use some of the other properties available to expose the Maven classpaths to the antrun plugin, for example ${maven.compile.classpath} See the antrun documentation for more details.
If you have multiple discrete executions for ant, you can configure them individually in the antrun plugin and specify a suitable id for each one. The example below shows two executions, both bound to the process-resources phase. Of course you need to supply some actual goals.
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-antrun-plugin</artifactId>
<executions>
<execution>
<id>build-css</id>
<phase>generate-resource</phase>
<configuration>
<target>
...
</target>
</configuration>
<goals>
<goal>run</goal>
</goals>
</execution>
<execution>
<id>build-js</id>
<phase>generate-resource</phase>
<configuration>
<target>
...
</target>
</configuration>
<goals>
<goal>run</goal>
</goals>
</execution>
</executions>
<dependencies>
<dependency>
<groupId>some.group.id</groupId>
<artifactId>artifactId</artifactId>
<version>1.4.1</version>
</dependency>
<dependency>
<groupId>another.group.id</groupId>
<artifactId>anotherId</artifactId>
<version>1.0.1</version>
</dependency>
</dependencies>

Resources