How do I execute simple ant call through maven? - maven

My project runs perfectly fine with following commands:
C:\project\<project_name>\ant -lib ant\lib -buildfile applications/<sub-project-path>/ant/build.xml deploy
However, if I wrap this command either in maven-antrun-plugin or exec-maven-plugin in pom, I get all kinds of path issues.
For maven-antrun-plugin, it seems the certain properties can not be loaded due to path issue. In exec-maven-plugin, it seems that ant target never got passed in correctly.
Can someone please advice how I can apply this in a pom file? Much appreciated.
This is my pom for exec:
<build>
<plugins>
<plugin>
<groupId>org.codehaus.mojo</groupId>
<artifactId>exec-maven-plugin</artifactId>
<version>1.2.1</version>
<executions>
<execution>
<phase>process-resources</phase>
<goals>
<goal>exec</goal>
</goals>
<configuration>
<executable>ant</executable>
<workingDirectory>${basedir}</workingDirectory>
<arguments>
<argument>'-lib ant/lib'</argument>
<argument>'-buildfile $basedir/<project-path>/build.xml'</argument>
<argument>deploy</argument>
</arguments>
</configuration>
</execution>
</executions>
</plugin>
</plugins>
</build>

Haven't tried it, but you could do something similar as documented in the maven antrun plugin example.
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-antrun-plugin</artifactId>
<version>1.7</version>
<executions>
<execution>
<id>ant</id>
<phase>process-resources</phase>
<configuration>
<target>
<ant antfile="${basedir}/<project-path>/build.xml">
<target name="deploy"/>
</ant>
</target>
</configuration>
<goals>
<goal>run</goal>
</goals>
</execution>
</executions>
</plugin>
Not sure what library you want to pass as argument in -lib in your snippet above, but the same can be declared as plugin dependencies.
Do note that this plugin does not care about the existence of an ant installation on your system. It downloads necessary ant libraries.

You should pass needed dependencies directly into antrun plugin declaration, right after <executions> element.
<plugin>
<groupId>org.codehaus.mojo</groupId>
<artifactId>exec-maven-plugin</artifactId>
<version>1.2.1</version>
<executions>
...
</executions>
<dependencies>
<dependency>
<groupId>ant-contrib</groupId>
<artifactId>ant-contrib</artifactId>
<version>${ant-contrib.version}</version>
<exclusions>
<exclusion>
<groupId>ant</groupId>
<artifactId>ant</artifactId>
</exclusion>
</exclusions>
</dependency>
<dependency>
<groupId>org.apache.tomcat</groupId>
<artifactId>jasper</artifactId>
<version>${tomcat.compile.version}</version>
</dependency>
<dependency>
<groupId>com.sun</groupId>
<artifactId>tools</artifactId>
<version>${java.version}.0</version>
<scope>system</scope>
<systemPath>${jdk.home}/tools.jar</systemPath>
</dependency>
</dependencies>
</plugin>
I've included some libraries that I use in our project, so that you have an example. Note, that if your build uses some non-standard ( i.e. something outside java.lang ) Java API classes, you have to pass tools.jar as a dependency.
Also, if you use ant-contrib do not forget to exclude ant as a dependency, because it is dependent on some ancient version of ant and you will get a version collision.
Another annoying thing is that dependency assigned directly to plugin execution are not part of POM's <dependencyManagement>, so you have to spell out precise versions. One workaround is to declare version properties in the same place as your central <dependencyManagement> and use the properties instead of hardcoded versions.

Related

Integration testing Maven jar in a Jetty container

I have a Maven project which produces a jar file that is meant to be used in a web service. It has integration tests which use the jetty-maven-plugin to run.
In order to run the integration tests on the compiled jar file, I've had to create a dependency with <systemPath>${project.build.directory}/${project.build.finalName}.${project.packaging}</systemPath>. The integration tests run as I had hoped, using the compiled jar file and correctly creating the web-app out of the src/test directory.
So in terms of this projects build, this setup works very well.
The problem is that the POM file, which is deployed during the release process, still has the systemPath dependency. This means that projects which use the jar are reporting an error during the build. The error says that the jar file "must specify an absolute path". These builds don't fail, but the logs are cluttered and misleading.
I'm looking to remove this systemPath from the POM which is deployed to our Maven repository. How can we do this?
For reference, here is the relevant portion of the project's POM.
<build>
<plugins>
<plugin>
<groupId>org.eclipse.jetty</groupId>
<artifactId>jetty-maven-plugin</artifactId>
<version>9.0.7.v20131107</version>
<configuration>
<webAppSourceDirectory>${project.basedir}/src/test/webapp</webAppSourceDirectory>
<classesDirectory>${project.build.testSourceDirectory}</classesDirectory>
<useTestClasspath>true</useTestClasspath>
</configuration>
<dependencies>
<dependency>
<groupId>${project.groupId}</groupId>
<artifactId>${project.artifactId}</artifactId>
<version>${project.version}</version>
<scope>system</scope>
<systemPath>${project.build.directory}/${project.build.finalName}.${project.packaging}</systemPath>
</dependency>
</dependencies>
<executions>
<execution>
<id>start-jetty</id>
<phase>pre-integration-test</phase>
<goals>
<goal>run</goal>
</goals>
<configuration>
<scanIntervalSeconds>0</scanIntervalSeconds>
<daemon>true</daemon>
</configuration>
</execution>
<execution>
<id>stop-jetty</id>
<phase>post-integration-test</phase>
<goals>
<goal>stop</goal>
</goals>
</execution>
</executions>
</plugin>
</plugins>
</build>
Jetty's documentation regarding <classesDirectory> reads:
Location of your compiled classes for the webapp. [...]
So, this should be ${project.build.testOutputDirectory} rather than ${project.build.testSourceDirectory}, shouldn't it?
<useTestClasspath> isn't mentioned in Jetty's doc.
Is it possible to install the dependency and use <scope>provided? Since with that:
[the dependency] is only available on the compilation and test classpath, and is not transitive.
The solution was a slight modification from Gerold Broser's answer.
Here are the relevant sections:
<plugin>
<groupId>org.eclipse.jetty</groupId>
<artifactId>jetty-maven-plugin</artifactId>
<version>9.1.5.v20140505</version>
<configuration>
<webAppSourceDirectory>${project.basedir}/src/test/webapp</webAppSourceDirectory>
<classesDirectory>${project.build.testOutputDirectory}</classesDirectory>
</configuration>
<dependencies>
<dependency>
<groupId>${project.groupId}</groupId>
<artifactId>${project.artifactId}</artifactId>
<version>${project.version}</version>
<scope>runtime</scope>
</dependency>
</dependencies>
</plugin>

Maven - how to verify that dependencies compiled with specific Java level (1.7 for example)?

For example, Java Maven project have ben compiled with maven-compiler-plugin with target level 1.7 have number of dependencies.
How to verify that those dependencies compiled with some specific Java target level as well (1.7 for example)?
As suggested in the comments, i have used Extra Enforcer Rules as additional dependency to Maven enforcer plugin that provides extra rules, as a solution.
The usage of this functionality described here, and specifically in my code it looks like that:
<properties>
<extra-enforcer-rules>1.0-beta-4</extra-enforcer-rules>
</properties>
<dependencies>
<dependency>
<groupId>org.codehaus.mojo</groupId>
<artifactId>extra-enforcer-rules</artifactId>
<version>${extra-enforcer-rules}</version>
</dependency>
</dependencies>
<build>
<pluginManagement>
<plugins>
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-enforcer-plugin</artifactId>
<version>1.4</version>
<executions>
<execution>
<id>enforce-bytecode-version</id>
<goals>
<goal>enforce</goal>
</goals>
<configuration>
<rules>
<enforceBytecodeVersion>
<maxJdkVersion>1.7</maxJdkVersion>
</enforceBytecodeVersion>
</rules>
<fail>true</fail>
</configuration>
</execution>
</executions>
<dependencies>
<dependency>
<groupId>org.codehaus.mojo</groupId>
<artifactId>extra-enforcer-rules</artifactId>
<version>${extra-enforcer-rules}</version>
</dependency>
</dependencies>
</plugin>
</plugins>
</pluginManagement>
</build>

Maven dependency on a file not artifact

Disclaimer: New to Maven and skimmed the maven documentation
How to configure Maven to look at files to determine what happens in a phase?
I am using the cxf-codegen-plugin to generate sources. This is working correctly when I remove the .java files and execute mvn clean generate-sources. However when I update the wsdl/schema that cxf uses to generate the code, the sources are not recreated. I don't want to have to remember to delete the .java files.
Thanks for taking the time to consider my question.
Relevant excerpt from my pom is below.
<plugins>
<plugin>
<groupId>org.apache.cxf</groupId>
<artifactId>cxf-codegen-plugin</artifactId>
<version>${cxf.version}</version>
<executions>
<execution>
<id>cxf-java</id>
<phase>compile</phase>
<configuration>
<sourceRoot>${basedir}/src/main/cxf-generated</sourceRoot>
<wsdlOptions>
<wsdlOption>
<wsdl>${basedir}/src/main/resources/wsdl/DCMotor.wsdl</wsdl>
</wsdlOption>
</wsdlOptions>
<vmArgs>
<vmArg>-Djavax.xml.accessExternalSchema=all</vmArg>
</vmArgs>
</configuration>
<goals>
<goal>wsdl2java</goal>
</goals>
</execution>
</executions>
<dependencies>
<dependency>
<groupId>xerces</groupId>
<artifactId>xercesImpl</artifactId>
<version>2.9.1</version>
</dependency>
</dependencies>
</plugin>
</plugins>

Liquibase with Maven

I want to launch Liquibase for a Java EE - project, so I can make easy DB-Updates at the production server.
I have problems understanding what do i need for the start. I read at many examples that you need to download the liquibase-core, extract it and put the .jar to your PATH. I think that this is not needed for Maven.
To include the dependencies (the core and the liquibase-maven-plugin) at the pom.xml should be enough/ should be the same?
<dependency>
<groupId>org.liquibase</groupId>
<artifactId>liquibase-maven-plugin</artifactId>
<version>2.0.5</version>
<type>maven-plugin</type>
</dependency>
<dependency>
<groupId>org.liquibase</groupId>
<artifactId>liquibase-core</artifactId>
<version>2.0.5</version>
</dependency>
This is probably a silly question, but I have hardly experience with Maven and none with Liquibase.
In my opinion you was a little bit confused with the method to add liquibase to your project. We shouldn't understand liquibase as a simple dependency, it is a maven plugin .
I think that could be clearly if you see some of my config files to understand better what I'm referring to:
pom.xml:
<build>
<sourceDirectory>src</sourceDirectory>
<pluginManagement>
<plugins>
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-compiler-plugin</artifactId>
<version>3.6.2</version>
<configuration>
<source>1.8</source>
<target>1.8</target>
<excludes>
<exclude>**/test/*</exclude>
<exclude>**/test/me/*</exclude>
</excludes>
</configuration>
</plugin>
<plugin>
<artifactId>maven-war-plugin</artifactId>
<version>3.1.0</version>
<configuration>
<warSourceDirectory>WebContent</warSourceDirectory>
<failOnMissingWebXml>false</failOnMissingWebXml>
</configuration>
<dependencies>
<dependency>
<groupId>org.codehaus.groovy</groupId>
<artifactId>groovy-eclipse-compiler</artifactId>
<version>2.9.2-01</version>
</dependency>
<dependency>
<groupId>org.codehaus.groovy</groupId>
<artifactId>groovy-eclipse-batch</artifactId>
<version>2.4.3-01</version>
</dependency>
</dependencies>
</plugin>
<plugin>
<groupId>org.liquibase</groupId>
<artifactId>liquibase-maven-plugin</artifactId>
<version>3.5.3</version>
<configuration>
<propertyFile>src/tv/be/persistence/liquibase/code/dsv.properties</propertyFile>
</configuration>
<executions>
<execution>
<phase>process-resources</phase>
<goals>
<goal>update</goal>
</goals>
</execution>
</executions>
</plugin>
</plugins>
</pluginManagement>
</build>
dsv.properties:
driver: com.mysql.jdbc.Driver
classpath: [local_path]/mysql-connector-java/5.1.41/mysql-connector-java-5.1.41.jar
url: jdbc:mysql://[db_server_ip]:3306/schema_db
username: user1
password: masterkey
changeLogFile: src/tv/be/persistence/liquibase/code/master.xml
contexts=local
Take attention to dsv.properties file. Each liquibase context needs one proper properties file like that to specify schema and changelog. That provides the ability to work with different environments (dsv,local,test,pro,...) in real time and apply the changes only in the environment/context specified.
Project folder:
That structure is very clean for our team because we have all changelog organized by version and functions, procedures and views separated from root database changes but the greatest thing here is that every change has the issue/task code associated and we can trace everything so easily.
mvn:
To execute liquibase plugin you should execute that mvn command:
mvn liquibase:update
You also can update automatically the database because of liquibase pom's plugin param:
<execution>
<phase>process-resources</phase>
<goals>
<goal>update</goal>
</goals>
</execution>
We use liquibase in several projects and without deeping in the pros of use it, have database version control, history, common logic of diferents projects and maintenance as mandatory for our development team.

Invoke a jar file in the M2 repository

I have a project, in which I want to invoke another Jar file in M2 repo during the post execution phase of the current project.
Sample skeleton of my POM
<plugin>
<groupId>org.codehaus.mojo</groupId>
<artifactId>exec-maven-plugin</artifactId>
<version>1.1</version>
<executions>
<execution>
<id>exec-one</id>
<phase>verify</phase>
<configuration>
executable>java</executable>
<arguments> <argument>-jar</argument>
<argument>JarToInvoke.jar</argument>
</arguments>
<**workingDirectory**>/C:/path to repo</workingDirectory>
</configuration>
<goals>
<goal>exec</goal>
</goals>
</execution>
</executions>
<dependencies> <dependency>
<groupId>GroupId of JarToInvoke</groupId>
<artifactId>JarToInvoke</artifactId>
<version>1.0.0-SNAPSHOT</version>
</dependency>
</dependencies>
</plugin>
</plugins>
I tried with maven-exec-plugin, but having the following issues;
Where I need to specify to JarToInvoke dependency ? As a project dependency or as a exec-plugin dependency ?
With hard coding the working directory(/C:/path to repo), I am able to invoke the JarToInvoke artifact. But it is not a good solution, because finally this project should run in any m/c with different OS's. So how can I make the exec-plugin to search for the JarToInvoke artifact in the M2 repo of the project(default classpath) ?
3.While hard coding the M2 repo path in the working directory, I was able to invoke the JarToInvoke artifact. But while running the JarToInvoke artifact, it throws another dependency issue, some of the log4j dependencies to the JarToInvoke could not find. I made the JarToInvoke as a shaded jar and it work as expected. But it is not a permanent or good solution(Because the shaded jar size is of 35 MB). How can I instruct the exec-plugin to look for the dependent Jars in M2 repo.
Please share your suggestions. Thanks in Advance.
This example page from the Exec plugin's documentation describes what you want I think.
If you could use the exec:java goal instead of exec:exec, finding the JVM is taken care of for you. You can also pull in either plugin dependencies or project dependencies by changing the includeProjectDependencies and includePluginDependencies configuration options of the plugin.
<plugin>
<groupId>org.codehaus.mojo</groupId>
<artifactId>exec-maven-plugin</artifactId>
<version>1.1</version>
<executions>
<execution>
<id>exec-one</id>
<phase>verify</phase>
<configuration>
<includeProjectDependencies>false</includeProjectDependencies>
<includePluginDependencies>true</includePluginDependencies>
<executableDependency>
<groupId>GroupId of JarToInvoke</groupId>
<artifactId>JarToInvoke</artifactId>
</executableDependency>
<!-- Look up the main class from the manifest inside your dependency's JAR -->
<mainClass>com.example.Main</mainClass>
<arguments>
<!-- Add any arguments after your JAR here --->
</arguments>
</configuration>
<goals>
<goal>java</goal>
</goals>
</execution>
</executions>
<dependencies>
<dependency>
<groupId>GroupId of JarToInvoke</groupId>
<artifactId>JarToInvoke</artifactId>
<version>1.0.0-SNAPSHOT</version>
</dependency>
</dependencies>
</plugin>
The only disadvantage is that you have to explicitly specify the main class in the JAR to run. You can look this up by opening up the manifest in the dependency JAR and read the Main-Class attribute.
If you really need to use exec:exec, you could use the Maven Dependency Plugin's copy-dependencies goal to copy dependencies from your local repository to a predefined location (such as ${project.build.directory}/exec-jars) and then you can feed this directory in the exec plugin's workingDirectory configuration option.
Probably an easier way to locate the absolute path to the jar file would be to use maven-dependency-plugin with properties goal.
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-dependency-plugin</artifactId>
<version>2.3</version>
<executions>
<execution>
<goals>
<goal>properties</goal>
</goals>
</execution>
</executions>
</plugin>
<plugin>
<groupId>org.codehaus.mojo</groupId>
<artifactId>exec-maven-plugin</artifactId>
<version>1.1</version>
<executions>
<execution>
<id>exec-one</id>
<phase>verify</phase>
<configuration>
<executable>java</executable>
<arguments>
<argument>-jar</argument>
<argument>${GroupIdofJarToInvoke:JarToInvoke:jar}</argument>
</arguments>
<workingDirectory>/C:/path to repo</workingDirectory>
</configuration>
<goals>
<goal>exec</goal>
</goals>
</execution>
</executions>
</plugin>
</plugins>
<dependencies>
<dependency>
<groupId>GroupIdofJarToInvoke</groupId>
<artifactId>JarToInvoke</artifactId>
<version>1.0.0-SNAPSHOT</version>
</dependency>
<dependencies>

Resources