Maven antrun with sequential ant-contrib fails to run - ant

We have a special routine to explode files in a subfolder into extensions, which will be copied and jared into single extension files. For this special approach I wanted to use the maven-antrun-plugin, for the sequential iteration and jar packaging through the dirset, we need the library ant-contrib.
The upcoming plugin configuration fails with an error. What did I misconfigured? Thank you.
Plugin configuration
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-antrun-plugin</artifactId>
<version>1.6</version>
<executions>
<execution>
<phase>validate</phase>
<goals>
<goal>run</goal>
</goals>
<configuration>
<target>
<for param="extension">
<path>
<dirset dir="${basedir}/src/main/webapp/WEB-INF/resources/extensions/">
<include name="*" />
</dirset>
</path>
<sequential>
<basename property="extension.name" file="${extension}" />
<echo message="Creating JAR for extension '${extension.name}'." />
<jar destfile="${basedir}/target/extension-${extension.name}-1.0.0.jar">
<zipfileset dir="${extension}" prefix="WEB-INF/resources/extensions/${extension.name}/">
<include name="**/*" />
</zipfileset>
</jar>
</sequential>
</for>
</target>
</configuration>
</execution>
</executions>
<dependencies>
<dependency>
<groupId>ant-contrib</groupId>
<artifactId>ant-contrib</artifactId>
<version>1.0b3</version>
<exclusions>
<exclusion>
<groupId>ant</groupId>
<artifactId>ant</artifactId>
</exclusion>
</exclusions>
</dependency>
<dependency>
<groupId>org.apache.ant</groupId>
<artifactId>ant-nodeps</artifactId>
<version>1.8.1</version>
</dependency>
</dependencies>
</plugin>
Error
[ERROR] Failed to execute goal org.apache.maven.plugins:maven-antrun-plugin:1.6:run (default) on project extension-platform: An Ant BuildException has occured: Problem: failed to create task or type for
[ERROR] Cause: The name is undefined.
[ERROR] Action: Check the spelling.
[ERROR] Action: Check that any custom tasks/types have been declared.
[ERROR] Action: Check that any <presetdef>/<macrodef> declarations have taken place.
[ERROR] -> [Help 1]
[ERROR]
[ERROR] To see the full stack trace of the errors, re-run Maven with the -e switch.
[ERROR] Re-run Maven using the -X switch to enable full debug logging.
[ERROR]
[ERROR] For more information about the errors and possible solutions, please read the following articles:
[ERROR] [Help 1] http://cwiki.apache.org/confluence/display/MAVEN/MojoExecutionException

Therefore I wasted at least one hour to find the error a little hint below ...
I use maven3 and the rest as described above, BUT I have to use maven.dependency.classpath
instead of maven.plugin.classpath! Otherwise maven won't find the contrib tasks. Hope this helps anybody.

It looks like you're missing the taskdef that's needed to declare the ant-contrib tasks, so that Ant knows about them, hence this part of the error message:
Problem: failed to create task or type for
(It would perhaps be a little clearer if the failed task - 'for' - were quoted.)
One way to add the taskdef is to insert it immediately prior to the for loop:
<target>
<taskdef resource="net/sf/antcontrib/antlib.xml"
classpathref="maven.plugin.classpath" />
<for param="extension">
...

After wasting 2 hours and reading too many answers, this is what I need to check
http://www.thinkplexx.com/learn/howto/maven2/plugins/could-not-load-definitions-from-resource-antlib-xml-understanding-the-problem-and-fix-worklow
I printed all the maven classpaths using this
<property name="compile_classpath" refid="maven.compile.classpath"/>
<property name="runtime_classpath" refid="maven.runtime.classpath"/>
<property name="test_classpath" refid="maven.test.classpath"/>
<property name="plugin_classpath" refid="maven.plugin.classpath"/>
<echo message="compile classpath: ${compile_classpath}"/>
<echo message="runtime classpath: ${runtime_classpath}"/>
<echo message="test classpath: ${test_classpath}"/>
<echo message="plugin classpath: ${plugin_classpath}"/>
and checked which classpath contains antrib jar file. So I changed classpathhref to maven.runtime.classpath from maven.plugin.classpath
. So my taskdef is
<taskdef resource="net/sf/antcontrib/antcontrib.properties" classpathref="maven.runtime.classpath" />
and the dependencies
<dependency>
<groupId>ant-contrib</groupId>
<artifactId>ant-contrib</artifactId>
<version>1.0b3</version>
<exclusions>
<exclusion>
<groupId>ant</groupId>
<artifactId>ant</artifactId>
</exclusion>
</exclusions>
</dependency>
<dependency>
<groupId>org.apache.ant</groupId>
<artifactId>ant-nodeps</artifactId>
<version>1.8.1</version>
</dependency>

I too wasted several hours on this one, because antcontrib for task could not be found.
Finally, I found out that for task in not defined in antcontrib.properties, but in antlib.xml!
antcontrib.properties is a pre ant 1.6 way of doing things – the modern way is to use antlib.xml.
So, this is a maven 3.5, ant 1.8, working example:
<plugin>
<artifactId>maven-antrun-plugin</artifactId>
<dependencies>
<dependency>
<groupId>ant-contrib</groupId>
<artifactId>ant-contrib</artifactId>
<version>1.0b3</version>
<exclusions>
<exclusion>
<groupId>ant</groupId>
<artifactId>ant</artifactId>
</exclusion>
</exclusions>
</dependency>
</dependencies>
<execution>
<id>deploy_to_distrib_folder</id>
<phase>package</phase>
<configuration>
<target>
<taskdef resource="net/sf/antcontrib/antlib.xml" />
<macrodef name="deploy_extra_dir">
<attribute name="dir" />
<sequential>
<basename property="basename" file="#{dir}" />
<sync todir="${outputDir}/${basename}">
<fileset dir="#{dir}" />
</sync>
<var name="basename" unset="true" />
</sequential>
</macrodef>
<for param="dir">
<path>
<dirset dir="${project.build.directory}/maven-shared-archive-resources" includes="*" />
</path>
<sequential>
<deploy_extra_dir dir="#{dir}" />
</sequential>
</for>
</target>
</configuration>
<goals>
<goal>run</goal>
</goals>
</execution>
</plugin>
Hope this helps!

Related

Can't run PMD Apex code check using Ant and Ivy. NoClassDefFoundError

PMD 6.5.0
Need help with connecting PMD to Ant through Ivy. When I download the full package from https://pmd.github.io and just run it using Ant target everything works fine. But I don't want to add the PMD folder to the repo. So, I tried to add an Ivy dependency to the build. With JS everything works fine, but when adding an Apex dependency an error is thrown:
build.xml:216: java.lang.NoClassDefFoundError: apex/jorje/semantic/ast/AstNode
Ant's Build.xml
<target name="init">
<taskdef name="pmd" classname="net.sourceforge.pmd.ant.PMDTask"
classpathref="pmd.classpath"/>
</target>
<path id="pmd.classpath">
<fileset dir="${outputdir}/lib/">
<include name="*.jar"/>
</fileset>
</path>
<target name="pmd" depends="init">
<pmd shortFilenames="true">
<ruleset>pmdRulesets/jsCustomRuleset.xml</ruleset>
<formatter type="text" toFile="whaaaaaaat.txt" toConsole="true"/>
<fileset dir="src">
</fileset>
</pmd>
</target>
Ivy's xml
<dependencies>
<dependency org="com.aquivalabs.force.ant" name="antforce" rev="0.10" conf="tasks->default">
<exclude name="ant" />
<exclude name="ant-launcher" />
</dependency>
<dependency org="net.sourceforge.pmd" name="pmd-core" rev="6.5.0">
<artifact name="pmd-core" type="jar" />
<exclude name="pmd-core-6.5.0.pom" />
</dependency>
<dependency org="net.sourceforge.pmd" name="pmd-apex" rev="6.5.0">
<artifact name="pmd-apex" type="jar" />
</dependency>
<dependency org="net.sourceforge.pmd" name="pmd-apex-jorje" rev="6.5.0">
</dependency>
<dependency org="net.sourceforge.pmd" name="pmd-javascript" rev="6.5.0">
<artifact name="pmd-javascript" type="jar" />
</dependency>
</dependencies>

"can't write to read-only destination file" with ANT

Ant build fails with below error about "can't write to read-only destination file". Is this an issue with Windows permissions error or something with Ant?
BUILD FAILED
E:\app\jenkins\workspace\CardsAdmin\Test-Build2\ca_module\build.xml:32: The following error occurred while executing this line:
E:\app\jenkins\workspace\CardsAdmin\Test-Build2\ca_module\caRest\build.xml:116: Failed to copy E:\app\jenkins\workspace\CardsAdmin\Test-Build2\ca_module\caRest\WebContent\WEB-INF\tealeaf-w3c-dev.js to E:\app\jenkins\workspace\CardsAdmin\Test-Build2\ca_module\caRest\WebContent\WEB-INF\web\tealeaf-w3c-dev.js due to can't write to read-only destination file E:\app\jenkins\workspace\CardsAdmin\Test-Build2\ca_module\caRest\WebContent\WEB-INF\web\tealeaf-w3c-dev.js
Prior to ANT 1.8.2, it was able to copy files to read-only destinations. However, after 1.8.2 the behavior has changed.
So, in this case, you can force the copy task to make it work:
<copy force="true" todir="${web.home}/WEB-INF/web">
<fileset dir="${web.home}/WEB-INF">
<include name="*/.*"/> </fileset>
</copy>
In my case i had the problem with this configuration in my pom.xml, which throws that exception (can't write to read-only destination file) when i run mvn -Dmaven.test.skip=true clean package:
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-antrun-plugin</artifactId>
<version>3.0.0</version>
<executions>
<execution>
<goals>
<goal>run</goal>
</goals>
<phase>generate-sources</phase>
<configuration>
<target>
<echo force="true" file="${basedir}/src/main/resources/version.properties" message="test.version=${project.version}${line.separator}"/>
<echo force="true" file="${basedir}/src/main/resources/version.properties" message="test.build=${buildNumber}${line.separator}" append="true"/>
<echo force="true" file="${basedir}/src/main/resources/version.properties" message="test.timestamp=${timestamp}" append="true"/>
</target>
</configuration>
</execution>
</executions>
</plugin>
The key was to put force="true" in each "echo" tag.

Untar / Unzip *.tar.xz with ANT

I want to extract a tarball-file with *.tar.xz with ant.
But I can only find, bunzip2, gunzip, unzip and untar as goals in ant and none of it seems to work.
So how can I expand a tarball-file with *.tar.xz with ant?
The XZ format is not supported by the default Ant distribution, you'll need the Apache Compress Antlib.
Download the full Antlib with all the dependencies from here (add the three jars ant-compress,common-compress,xz in the lib directory of your ant), and use this task:
<target name="unxz">
<cmp:unxz src="foo.tar.xz" xmlns:cmp="antlib:org.apache.ant.compress"/>
<untar src="foo.tar" dest="."/>
<delete file="foo.tar"/>
</target>
You have to use this two-steps process because even with the additional ant library, the "xz" value is still not supported by the compression attribute of the untar task, the task you'll normally use to extract compressed tars.
In case somebody else like myself wants to do the same with maven managing ant.
<plugin>
<artifactId>maven-antrun-plugin</artifactId>
<version>1.7</version>
<dependencies>
<!-- Optional: May want to use more up to date commons compress, add this dependency
<dependency>
<groupId>org.apache.commons</groupId>
<artifactId>commons-compress</artifactId>
<version>1.10</version>
</dependency> -->
<dependency>
<groupId>org.apache.ant</groupId>
<artifactId>ant-compress</artifactId>
<version>1.4</version>
</dependency>
</dependencies>
<executions>
<execution>
<id>unpack</id>
<phase>generate-sources</phase>
<goals><goal>run</goal></goals>
<configuration>
<target name="unpack">
<taskdef resource="org/apache/ant/compress/antlib.xml" classpathref="maven.plugin.classpath"/>
<unxz src="${xz.download.file}" dest="${tar.unpack.directory}" />
<untar src="${tar.unpack.file}" dest="${final.unpack.directory}"/>
</target>
</configuration>
</execution>
</executions>
</plugin>

Run remote command via ssh using Maven3

I am using wagon-maven-plugin to scp my WAR file to the server. It works fine. My next step is to perform some commands on the server (mkdir, etc). Is there a plugin that helps me do that? Is there a way to work it out using wagon-maven-plugin?
I am relatively new to mvn. Any help would be appreciated.
Any suggestions?
I was able to run ssh commands with exec-maven-plugin. It is a powerful maven plugin to do all sorts of hack and also run commands. For anyone interested in the solution
<plugin>
<groupId>org.codehaus.mojo</groupId>
<artifactId>exec-maven-plugin</artifactId>
<version>1.2.1</version>
<executions>
<execution>
<phase>install</phase>
<goals>
<goal>exec</goal>
</goals>
</execution>
</executions>
<configuration>
<executable>sh</executable>
<arguments>
<!-- Shell script location -->
<argument>runscript.sh</argument>
<!-- arg #1 -->
<argument>${file_1}</argument>
</arguments>
</configuration>
</plugin>
Another solution I found was to run maven-antrun-plugin. I would not recommend it since it runs ANT tasks and there are a lot of dependencies to it. But its handy if you would need to run ant tasks via maven.
<plugin>
<inherited>false</inherited>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-antrun-plugin</artifactId>
<version>1.6</version>
<configuration>
<target>
<loadproperties srcFile="deploy.properties" />
<ftp action="send" server="server"
remotedir="/a/b" userid="usr"
password="pw" depends="no"
verbose="yes" binary="yes">
<fileset dir="modules/my-module/target">
<include name="file.zip" />
</fileset>
</ftp>
<!-- calls deploy script -->
<sshexec host="host" trust="yes"
username="usr" password="pw"
command="sh /my/script.sh" />
<!-- SSH -->
<taskdef name="sshexec"
classname="org.apache.tools.ant.taskdefs.optional.ssh.SSHExec"
classpathref="maven.plugin.classpath" />
<taskdef name="ftp"
classname="org.apache.tools.ant.taskdefs.optional.net.FTP"
classpathref="maven.plugin.classpath" />
</target>
</configuration>
...
<dependencies>
<dependency>
<groupId>commons-net</groupId>
<artifactId>commons-net</artifactId>
<version>1.4.1</version>
</dependency>
<dependency>
<groupId>ant</groupId>
<artifactId>ant-commons-net</artifactId>
<version>1.6.5</version>
</dependency>
<dependency>
<groupId>ant</groupId>
<artifactId>ant-jsch</artifactId>
<version>1.6.5</version>
</dependency>
<dependency>
<groupId>jsch</groupId>
<artifactId>jsch</artifactId>
<version>0.1.29</version>
</dependency>
</dependencies>
</plugin>
Hope that helps!

Ant in Ant in Maven: How to add optional tasks?

I'm trying to run junitreport task in Ant in Ant in Maven:
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-antrun-plugin</artifactId>
<executions combine.children="append">
<execution>
<id>reporting</id>
<phase>compile</phase><!--post-integration-test-->
<goals><goal>run</goal></goals>
<configuration>
<target>
<ant antfile="${basedir}/../tools/report/buildReports.xml">
<!--<property name="reports.dest.dir" value=""/>-->
<target name="reports"/>
</ant>
</target>
</configuration>
</execution>
</executions>
<dependencies>
<dependency>
<groupId>org.apache.ant</groupId>
<artifactId>ant-antunit</artifactId>
<version>1.2</version>
</dependency>
<dependency>
<groupId>ant-contrib</groupId>
<artifactId>ant-contrib</artifactId>
<version>1.0b2</version>
</dependency>
</dependencies>
</plugin>
However, I am getting this:
[ERROR] Failed to execute goal org.apache.maven.plugins:maven-antrun-plugin:1.6:run (reporting) on project jboss-as-testsuite-integration: An Ant BuildException has occured: The following error occurred while executing this line:
[ERROR] /home/ondra/work/AS-7/ozizka-as7/testsuite/tools/report/buildReports.xml:42: Problem: failed to create task or type junitreport
[ERROR] Cause: the class org.apache.tools.ant.taskdefs.optional.junit.XMLResultAggregator was not found.
[ERROR] This looks like one of Ant's optional components.
[ERROR] Action: Check that the appropriate optional JAR exists in
[ERROR] -ANT_HOME/lib
[ERROR] -the IDE Ant configuration dialogs
What should I add?
Oops. The class really wasn't present - it was in ant-junit. So the needed dependency is:
<dependency>
<groupId>ant</groupId>
<artifactId>ant-junit</artifactId>
<version>1.6.5</version>
</dependency>

Resources