"can't write to read-only destination file" with ANT - 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.

Related

Maven antrun plugin missing target task after combining from multiple profiles

This is quite an interesting problem I have 2 profiles as defined below. I'm using Maven 3.6.3 with the latest Java 11.
<profiles>
<profile>
<id>assembly-unzip</id>
<build>
<plugins>
<plugin>
<artifactId>maven-antrun-plugin</artifactId>
<executions>
<execution>
<phase>validate</phase>
<goals>
<goal>run</goal>
</goals>
<configuration>
<target>
<unzip src="src1.zip" dest="dest10" />
<copy file="copy1.txt" todir="dest11"/>
</target>
</configuration>
</execution>
</executions>
</plugin>
</plugins>
</build>
</profile>
<profile>
<id>assembly-get</id>
<build>
<plugins>
<plugin>
<artifactId>maven-antrun-plugin</artifactId>
<executions>
<execution>
<phase>validate</phase>
<goals>
<goal>run</goal>
</goals>
<configuration>
<target>
<mkdir dir="download" />
<get src="src20" dest="dest"/>
<unzip src="dest/src20}" dest="dest"/>
<get src="src21" dest="dest"/>
<unzip src="dest/src21}" dest="dest"/>
</target>
</configuration>
</execution>
</executions>
</plugin>
</plugins>
</build>
</profile>
</profiles>
When I activate BOTH profiles, I get from (-X) that Maven combines the 2 antrun plugin configurations into a single configuration that looks like this:
<configuration>
<exportAntProperties default-value="false"/>
<failOnError default-value="true"/>
<localRepository>${localRepository}</localRepository>
<mavenProject default-value="${project}"/>
<pluginArtifacts>${plugin.artifacts}</pluginArtifacts>
<session default-value="${session}"/>
<skip default-value="false">${maven.antrun.skip}</skip>
<sourceRoot>${sourceRoot}</sourceRoot>
<target>
<mkdir dir="download"/>
<get src="src20" dest="dest"/>
<unzip src="dest/src20}" dest="dest"/>
<get src="src21" dest="dest"/>
<unzip src="dest/src21}" dest="dest"/>
<copy file="copy1.txt" todir="dest11"/>
</target>
<testSourceRoot>${testSourceRoot}</testSourceRoot>
<versionsPropertyName default-value="maven.project.dependencies.versions"/>
</configuration>
What's missing from the combined configuration is:
<unzip src="src1.zip" dest="dest10" />
I've tried this multiple times in different ways and the long and short of it is that it seems like if the from the 1st profile that Maven processes has an task (for example) then any tasks in the of the 2nd profile will be ignored and NOT part of the combined configuration. Please be aware that i'm just using as an example. I've tried it with other tasks and see the same behavior.
Any thoughts?
You can do two things:
Use an <id> to each of your execution: without it, you get the default, and that's what maven use to determine duplicate configuration items when it merge them.
Use combine.children and so on. I would advise you not to do that, but you may read more on blog.sonatype.com or at maven.apache.org.
You could also directly use the power of ant, create target and invoke it conditionally using condition.

Jacoco coverage of unit test code

I'm converting an ANT build to Maven. I don't use Sonar.
In Maven, Jacoco doesn't seem to report about coverage of the unit tests themselves, while ANT does. I've been trying to get this for my Maven build as well, but I haven't been able to find anything.
It seems like I should add an <include> to the prepare-agent goal, but I'm not sure what to include. I've tried src/test/java/* and all kinds of variations on that theme, but none works.
How can I configure Jacoco in Maven such that it does report the coverage of unit test code?
Turns out, the only way to do this, is to use the maven-antrun-plugin.
There's no need to add an <include> to the prepare-agent goal, because all information is present in the jacoco.exec file it generates, including the unit test code.
The report goal doesn't include it, though, and it can't be configured to use it either. You would need to specifically set the classfiles and sourcefiles properties, and the Maven Jacoco plugin won't let you do this.
Hence, you need the Maven Antrun plugin, and configure and call it from there.
<plugins>
<plugin>
<groupId>org.jacoco</groupId>
<artifactId>jacoco-maven-plugin</artifactId>
<version>${jacoco.version}</version>
<executions>
<execution>
<id>default-prepare-agent</id>
<goals>
<goal>prepare-agent</goal>
</goals>
</execution>
</executions>
</plugin>
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-antrun-plugin</artifactId>
<version>1.7</version>
<executions>
<execution>
<id>default-report</id>
<phase>package</phase>
<goals>
<goal>run</goal>
</goals>
<configuration>
<target>
<taskdef name="report" classname="org.jacoco.ant.ReportTask" classpathref="maven.plugin.classpath" />
<report>
<executiondata>
<file file="${project.build.directory}/jacoco.exec" />
</executiondata>
<structure name="Coverage">
<classfiles>
<fileset dir="${project.build.directory}/classes"/>
<fileset dir="${project.build.directory}/test-classes"/>
</classfiles>
<sourcefiles encoding="UTF-8">
<fileset dir="src/main/java"/>
<fileset dir="src/test/java"/>
</sourcefiles>
</structure>
<check failonviolation="true" violationsproperty="violation">
<rule element="BUNDLE">
<limit counter="INSTRUCTION" value="COVEREDRATIO" minimum="0.95" />
</rule>
</check>
<html destdir="${project.build.directory}/jacoco-internal"/>
</report>
</target>
</configuration>
</execution>
</executions>
<dependencies>
<dependency>
<groupId>org.jacoco</groupId>
<artifactId>org.jacoco.ant</artifactId>
<version>${jacoco.version}</version>
</dependency>
</dependencies>
</plugin>
</plugins>

Maven: mavent--ant-run does not support attribute

Currently I'm working on a maven build script and my next issue is to copy source files into a target folder. I found this thread and it works fine unless I don't use the 'flattern' attribute. I know that the computer makes all things right, but I wonder why the build will fail.
Here my code using the maven antrun plugin:
<build>
<plugins>
<plugin>
<artifactId>maven-antrun-plugin</artifactId>
<version>1.7</version>
<executions>
<execution>
<phase>process-resources</phase>
<configuration>
<target>
<copy todir="${project.basedir}/target" flattern="true" overwrite="true">
<fileset dir="${project.basedir}/src/main"/>
</copy>
</target>
</configuration>
<goals>
<goal>run</goal>
</goals>
</execution>
</executions>
</plugin>
</plugins>
</build>
The error message I get is
[ERROR] Failed to execute goal org.apache.maven.plugins:maven-antrun-plugin:1.7:run (default) on project setup_core: An Ant BuildException has occured: copy doesn't support the "flattern" attribute
[ERROR] around Ant part ...<copy todir="C:\Projekte\CQ5_Migration\setup\core_upload/target" overwrite="true" flattern="true">... # 4:101 in C:\Projekte\CQ5_Migration\setup\core_upload\target\antrun\build-main.xml: The <copy> type doesn't support the "flattern" attribute.
[ERROR] -> [Help 1]
Have I overseen somthing and if so what is/are the missing fact(s)?
Thanks again for your help :-)
It should be "flatten" not "flattern".
Remove the 'r'.

Upload file via Ant FTP task in Maven

I'm trying to upload a file using an Ant task. If I use Ant directly the file is uploaded, but if I call the ant task via Maven (using the maven-antrun-plugin) I get the following error:
An Ant BuildException has occured: The following error occurred while executing this line:
/home/me/proj/build.xml:15: Problem: failed to create task or type ftp
Cause: the class org.apache.tools.ant.taskdefs.optional.net.FTP was not found.
This looks like one of Ant's optional components.
Action: Check that the appropriate optional JAR exists in
-ANT_HOME/lib
ant-commonsnet.jar is clearly available to Ant:
$ ls $ANT_HOME/lib | grep ant-commons-net
ant-commons-net.jar
Is the Ant classpath defined separately for maven-antrun-plugin, or am I missing something?
ant-commons-net.jar is clearly available to Ant
Yes, but Maven and the maven-antrun-plugin is not using your local Ant install.
Is the Ant classpath defined separately for maven-antrun-plugin, or am I missing something?
The way to use Ant Tasks not included in Ant's default jar is documented in Using tasks not included in Ant's default jar (which should definitely help):
To use Ant tasks not included in the
Ant jar, like Ant optional or custom
tasks you need to add the dependencies
needed for the task to run to the
plugin classpath and use the
maven.plugin.classpath reference if
needed.
<project>
<modelVersion>4.0.0</modelVersion>
<artifactId>my-test-app</artifactId>
<groupId>my-test-group</groupId>
<version>1.0-SNAPSHOT</version>
<build>
<plugins>
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-antrun-plugin</artifactId>
<version>1.6</version>
<executions>
<execution>
<id>ftp</id>
<phase>deploy</phase>
<configuration>
<target>
<ftp action="send" server="myhost" remotedir="/home/test" userid="x" password="y" depends="yes" verbose="yes">
<fileset dir="${project.build.directory}">
<include name="*.jar" />
</fileset>
</ftp>
<taskdef name="myTask" classname="com.acme.MyTask" classpathref="maven.plugin.classpath"/>
<myTask a="b"/>
</target>
</configuration>
<goals>
<goal>run</goal>
</goals>
</execution>
</executions>
<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-nodeps</artifactId>
<version>1.6.5</version>
</dependency>
</dependencies>
</plugin>
</plugins>
</build>
</project>
As Pascal has mentioned, the maven-antrun-plugin is not using the ant specified by your $ANT_HOME environment variable, and the configuration that he's mentioned is probably the best way to do it consistently from a pure maven perspective.
However, the jar can be stored in $USER_HOME/.ant/lib instead of $ANT_HOME/lib, these jars should be available on the classpath for any instance of ant that is run by that user.
Note that your ant script cannot assume that the jars are present, and that the jars are only placed on the classpath at startup, so if the script defines a setup target to download the jars into $USER_HOME/.ant/lib, then this target would have to be run in a "separate-ant-session", before and is invoked again to execute the task that depends on the jar.
The only potential benefit that you may derive from this approach is that the Ant script may be runnable from maven and Ant.
There is a classpath property which can be set in <tasks> section of maven-antrun-plugin.
For instance,
<property name="classpath" refid="maven.compile.classpath"/>

How to run an ant target from Maven2?

How do i run a specific target with the antrun-plugin from the command line?
mvn antrun:run doesn't make it run.
<project>
...
<build>
<plugins>
...
<plugin>
<artifactId>maven-antrun-plugin</artifactId>
<executions>
<execution>
<id>myExecution</id>
<phase>deploy</phase>
<goals>
<goal>run</goal>
</goals>
<configuration>
<tasks>
<ant target="myTarget" inheritRefs="true">
...
</ant>
</tasks>
</configuration>
</execution>
</executions>
<dependencies>
...
</dependencies>
</plugin>
...
</plugins>
...
</build>
...
</project>
How do i run a specific target with the antrun-plugin from the command line?
To strictly answer this question, you can't, and you don't.
What you can do is either:
1. provide a plugin-level configuration
<plugin>
<artifactId>maven-antrun-plugin</artifactId>
<configuration>
....
</configuration>
</plugin>
And this configuration will be used when invoking the plugin (regardless of how the plugin is invoked: from the cli, a part of the lifecycle).
2. provide an execution-level configuration (which is what you did)
<plugin>
<artifactId>maven-antrun-plugin</artifactId>
<executions>
<execution>
<id>myExecution</id>
<phase>deploy</phase>
<goals>
<goal>run</goal>
</goals>
<configuration>
<tasks>
<ant target="myTarget" inheritRefs="true">
...
</ant>
</tasks>
</configuration>
</execution>
</executions>
</plugin>
And then invoke the phase to which the plugin is bound (deploy in this case).
3. provide an execution-level configuration for the special default-cli execution Id
<plugin>
<artifactId>maven-antrun-plugin</artifactId>
<executions>
<execution>
<id>default-cli</id>
<configuration>
<tasks>
<ant target="myTarget" inheritRefs="true">
...
</ant>
</tasks>
</configuration>
</execution>
</executions>
</plugin>
As of Maven 2.2.0 (see MNG-3401), goals invoked directly from the command line can be configured in the POM separately from other plugin invocations using a special executionId called default-cli. In other words, the above configuration would be only used when invoking the plugin from the command line.
But in any case, you can't invoke a specific Ant target inside a configuration element. You could maybe mess with profiles to implement something approaching but, if you really want to go this direction, my advice would be to use Ant.
References
Guide to Configuring Default Mojo Executions
You can, by being sneaky.
In pom.xml:
...
<plugin>
<artifactId>maven-antrun-plugin</artifactId>
<version>1.7</version>
<configuration>
<target>
<ant target="trampoline" />
</target>
</configuration>
</plugin>
...
In build.xml:
...
<target name="trampoline">
<echo message="Executing target '${mvnAntTarget}'"/>
<antcall target="${mvnAntTarget}" />
</target>
<target name="testTarget">
<echo message="Yay, I'm a test target.."/>
</target>
....
And then, by running:
$ mvn antrun:run -DmvnAntTarget=testTarget
The Ant's testTarget will be run.
Refer to the example at : http://docs.codehaus.org/display/MAVENUSER/Antrun+Plugin
Basically write your ant targets in a regular build.xml.
Then define a single <target> under configuration where you dynamically decide what is the buildFile name and targetName and do a
<ant andfile="${buildFile}" target="${targetName}" inheritAll="true" inheritRefs="true"/>
I'm not too sure that's the reason it doesn't work but the syntax you're using is deprecated. You should have something like:
<configuration>
<target name="myTarget">
<!--
Place any Ant task here. You can add anything
you can add between <target> and </target> in a
build.xml.
-->
</target>
<configuration>
More details here:
http://maven.apache.org/plugins/maven-antrun-plugin/usage.html

Resources