1

When using the apache antrun plugin -- more formally known as maven-antrun-plugin -- it's possible (since 2010) to expose antrun properties to Maven using the configuration exportAntProperties set to true. This works great for "inlined" <target> code, which is what most online examples I've found use.

However, according to the antrun main project page, it's encouraged to use an external build.xml file instead of "inline" code, quoting:

"[...] it's encouraged to move all your Ant tasks to a build.xml file and just call it from the POM using Ant's <ant/> task."

... however, it seems much harder to access properties set through the build.xml file.

How do you access/retrieve a property from within a build.xml file from a Maven project? This works fine for inlined code, but external files are proving much more difficult.

Code:

pom.xml:

<?xml version="1.0" encoding="UTF-8"?>
<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
    <modelVersion>4.0.0</modelVersion>

    <name>Antrun Tests</name>
    <description>To test inline antrun tasks versus external antrun tasks</description>

    <groupId>org.example</groupId>
    <artifactId>antrun</artifactId>
    <version>1.0.0</version>
    <build>
        <defaultGoal>validate</defaultGoal>
        <plugins>
            <plugin>
                <groupId>org.apache.maven.plugins</groupId>
                <artifactId>maven-antrun-plugin</artifactId>
                <version>1.8</version>
                <executions>
                    <!-- Inline -->
                    <execution>
                        <id>inline-ant</id>
                        <goals><goal>run</goal></goals>
                        <phase>validate</phase>
                        <configuration>
                            <target name="inline-ant">
                                <property name="inline.ant" value="PASS"/>
                                <echo level="info">Ant scope:</echo>
                                <echo level="info">[inline.ant]:   (set to: ${inline.ant})</echo>
                            </target>
                            <exportAntProperties>true</exportAntProperties>
                        </configuration>
                    </execution>

                    <!-- External -->
                    <execution>
                        <id>external-ant</id>
                        <goals><goal>run</goal></goals>
                        <phase>validate</phase>
                        <configuration>
                            <target name="external-ant">
                                <ant antfile="build.xml"/>
                            </target>
                            <exportAntProperties>true</exportAntProperties>
                        </configuration>
                    </execution>

                    <!-- Echo results -->
                    <execution>
                        <id>results</id>
                        <goals><goal>run</goal></goals>
                        <phase>validate</phase>
                        <configuration>
                            <target name="results">
                                <!--
                                     Note: This conditional logic is superfluous!
                                     Ant can NOT set set a variable if it's already
                                     set! However, since Maven's default behavior allows
                                     this, I'm adding a clear, unnecessary guard as to
                                     not confuse causal onlookers. <3
                                -->
                                <!-- Set to failed if not set -->
                                <condition property="inline.ant" value="FAILED">
                                    <not><isset property="inline.ant"/></not>
                                </condition>
                                <condition property="external.ant" value="FAILED">
                                    <not><isset property="external.ant"/></not>
                                </condition>

                                <!-- Echo to console -->
                                <echo level="info">Maven scope:</echo>
                                <echo level="info">[inline.ant]:   ${inline.ant}</echo>
                                <echo level="info">[external.ant]: ${external.ant}</echo>
                            </target>
                            <exportAntProperties>true</exportAntProperties>
                        </configuration>
                    </execution>
                </executions>
            </plugin>
        </plugins>
    </build>
</project>

... and relevant build.xml:

<project default="external-ant">
    <target name="external-ant">
        <property name="external.ant" value="PASS"/>
        <echo level="info">Ant scope:</echo>
        <echo level="info">[external.ant]:   (set to: ${external.ant})</echo>
    </target>
</project>

Edit: I think this may actually be a side-effect of ant's <ant antfile="..."> task, and the antrun plugin is collateral damage to it.

For example, If I had access to <import file="..."/>, I believe it would work, but ant requires imports at the <project> level and antrun doesn't allow anything higher-level than the <target> level (<target> must be a child of <project>).

For example, even if I echo in the same exact ant target, I still can't see the properties, suggesting it a nuance of forcing people to use <ant antfile="..."> to begin with, conflicting with expected behavior, and conflicting with the "encouraged" use from antrun's documentation.

tresf
  • 7,103
  • 6
  • 40
  • 101
  • 1
    Is there a special reason not to migration to Maven completely instead of using Ant parts? – khmarbaise Jul 30 '21 at 18:20
  • @khmarbaise [yes](https://github.com/java-native/jssc/pull/93). In short, the maven profile selection is practically worthless for a cross-compiling and to add insult to injury, the maven system in general just doesn't handle conditional logic well (if at all) without authoring plugins. – tresf Jul 30 '21 at 18:25
  • The question why do you need conditions? On which level? What kind of cross compiling? – khmarbaise Jul 30 '21 at 18:44
  • @khmarbaise There is a link in my first reply in the word `yes`, hopefully this link provides adequate context to my answers to your questions. – tresf Jul 30 '21 at 19:00
  • Not really. So you are building platform dependent things like C/C++ via JNI (which will replaced by future newer JEP412 with JDK17?). Apart from all that can you give more concrete examples what the problems are ... ? Also it would be important to know those information might help to improve Maven 4.X ... – khmarbaise Jul 31 '21 at 11:16
  • `it would be important to know those information might help to improve Maven 4.X` I've worked with `make`, `CMake`, `ant` and `maven` so far, and Maven has proven the trickiest to me for non-java tasks. For starters, the profile classification should be able to match `os.arch` for `amd64` and `x86_64` equally. This way, providing flags to clang/cmake/etc such as `-arch x86_64` can be determined by a single profile. If this is not possible, then it I would at least like to see profile inheritance so that common properties can be set once and shared between two profiles. – tresf Jul 31 '21 at 19:22
  • In regards to JDK17 to replace JNI, from my understanding, that's more of a functional replacement to JNA rather than JNI since JNI still has the advantage of running precompiled code, natively (not under JIT). The project I linked could probably be just fine moving to JNA and then the Maven would work just fine, but I find it rude when opening questions like "special reason why" are presented so matter-of-fact, as if the question has no merit. I'd love to get rid of ant, but Maven has proven difficult for the aforementioned task. – tresf Jul 31 '21 at 19:30
  • Also, I'd like to add a note that the aforementioned project made a valiant attempt to use the `cmake-maven-project`, but it did [not scale properly](https://github.com/cmake-maven-project/cmake-maven-project/issues?q=is%3Aissue+author%3Atresf) and ultimately `antrun` was chosen for cmake invocation too. I'm sure loyal maven developers would write their own plugin, but that's not (personally) how I perceive a build system to be used for rather basic conditional tasks, which admittedly, may be a problem with my perspective. :/ – tresf Jul 31 '21 at 19:41

0 Answers0