Rectangle 27 233

The -p or -projecthelp option does exactly this, so you can just try:

ant -p build.xml

The -projecthelp option prints out a list of the build file's targets. Targets that include a description attribute are listed as "Main targets", those without a description are listed as "Other targets", then the "Default" target is listed ("Other targets" are only displayed if there are no main targets, or if Ant is invoked in -verbose or -debug mode).

ant
<target name="help">     <java classname="org.apache.tools.ant.Main">         <arg value="-projecthelp" />         <arg value="-buildfile" />         <arg value="${ant.file}" />     </java> </target>

I think it's worth noting that ant -p will only show targets that have descriptions. To show every target associated with a build.xml file, you need to run ant -p -v Also, ant -p build.xml is redundant. ant -p will do the same thing, and if you're not in the build.xml directory, you'll need to use ant -p -buildfile path/to/build.xml, anyway.

the target name="help" thing works fine, but not when run within Eclipse Ant environment (it just hangs, but -diagnostics or others are ok with it) :-( (no vm fork, Kepler with ant 1.8.4 (2014-05-22) and also tried with ant 1.9.4 (2014-04-29)) (just if you ask yourself ... I was creating a standalone ant env which I'd like to test within Eclipse ... of course I've got my Ant View there)

How can I get a list of build targets in Ant? - Stack Overflow

ant
Rectangle 27 22

flatten="true" - Ignore directory structure of source directory, copy all files into a single directory, specified by the todir attribute. The default is false.

Ant - copy only file not directory - Stack Overflow

ant
Rectangle 27 26

-v gives lot of output. Just ant -p works fine :)

we need to use -p cominded with -v If we require all targets (by all targets i mean the targets without description in them as well) . if Only the main targets is required ( by Main targets i mean the ones with description in them ) using -p alone does the trick.

I couldn't see the targets that i need with only -p, this works perfect.

How can I get a list of build targets in Ant? - Stack Overflow

ant
Rectangle 27 21

Use condition tests to establish if files are present. Then have a target for each true condition

<target name="go" depends="file-checks, do-something-with-first-file, do-something-with-second-file"/>

<target name="file-checks">
   <available file="/home/doc/somefile"  property="first.file.found"/>
   <available file="/usr/local/somefile" property="second.file.found"/>
</target>

<target name="do-something-with-first-file" if="first.file.found">
   ???
</target>

<target name="do-something-with-second-file" if="second.file.found">
   ???
</target>

Check the existence file in ant - Stack Overflow

ant
Rectangle 27 21

Use condition tests to establish if files are present. Then have a target for each true condition

<target name="go" depends="file-checks, do-something-with-first-file, do-something-with-second-file"/>

<target name="file-checks">
   <available file="/home/doc/somefile"  property="first.file.found"/>
   <available file="/usr/local/somefile" property="second.file.found"/>
</target>

<target name="do-something-with-first-file" if="first.file.found">
   ???
</target>

<target name="do-something-with-second-file" if="second.file.found">
   ???
</target>

Check the existence file in ant - Stack Overflow

ant
Rectangle 27 13

The -p or -projecthelp option does exactly this, so you can do:

ant -p build.xml

You can make a target to invoke this like:

<target name="help">
    <java classname="org.apache.tools.ant.Main">
        <arg value="-projecthelp" />
        <arg value="-buildfile" />
        <arg value="${ant.file}" />
    </java>
</target>

which you can then set as the default, so just typing ant will list the available targets.

small suggestion. make "help" target as default. As a result running "ant" will invoke "help" target that will print all available targets.

How can I get a list of build targets in Ant? - Stack Overflow

ant
Rectangle 27 4

I would do that with an external build.xml file allowing you to define multiple target combined with antcall and so using one additional dummy target, just to check the second condition.

and the build.xml

<?xml version="1.0" encoding="UTF-8"?>
    <project name="SkipIt" default="main">
       <target name="main" unless="${A}">
          <antcall target="secondTarget"></antcall>
       </target>
       <target name="secondTarget" unless="${B}">
          <echo>A is not true and B is not true</echo>
       </target>
     </project>

Alternative solution if you only have 2 conditions: using the <skip> configuration attribute for one condition (i.e. maven stuff) and the unless (i.e. ant stuff) for the other condition:

<plugin>
    <artifactId>maven-antrun-plugin</artifactId>
    <version>1.7</version>
    <executions>
        <execution>
            <id>skiptThisConditionally</id>
            <phase>test</phase>
            <configuration>
                <skip>${A}</skip>
                <target name="anytarget" unless="${B}">
                    <echo>A is not true and B is not true</echo>
                </target>
            </configuration>
            <goals>
                <goal>run</goal>
            </goals>
        </execution>
    </executions>
</plugin>

ant - maven-antrun-plugin skip target if any of two possible condition...

maven ant conditional maven-antrun-plugin
Rectangle 27 66

You could do this with profiles...

If you really wanted to use two separate profiles and customize the JAR plugin to include and exclude patterns of class and package names, you could easily do this by putting something like this in your POM:

<profiles>
  <profile>
    <id>everything</id>
    <build>
      <plugins>
        <plugin>
          <artifactId>maven-jar-plugin</artifactId>
          <configuration>
            <classifier>everything</classifier>
            <includes>
              <include>**/*</include>
            </includes>
          </configuration>
        </plugin>
      </plugins>
    </build>
  </profile>
  <profile>
    <id>only-library</id>
    <build>
      <plugins>
        <plugin>
          <artifactId>maven-jar-plugin</artifactId>
          <configuration>
            <classifier>only-library</classifier>
            <excludes>
              <exclude>**/Main*</exclude>
            </excludes>
          </configuration>
        </plugin>
      </plugins>
    </build>
  </profile>
</profiles>

Aside: If that seems like a lot of configuration, polyglot Maven's support for Groovy POMs is just about ready. It will cut the line count down considerably.

You would put this at the end of your pom.xml (withing the project element), and it adds two profiles. The first profile "everything" is really just there to demonstrate the configuration. This "everything" profile is unnecesary because it simply duplicates the behavior of the default JAR plugin jar goal execution. The second profile "only-library" excludes any class in any package that starts with the text "Main". To invoke these profiles:

mvn package -Peverything
mvn package -Ponly-library

I tested this against the sample application that ships with Chapter 6 of Maven by Example, and running either of these commands will produce a JAR file in ${basedir}/target that has a classifier. Since the JAR plugin's jar goal is bound to the package phase in the default maven lifecycle, these two profiles are going to modify the configuration for this plugin.

Or, you could do this with two JAR plugin executions...

If you need to create two JARs without using profiles. You can bind the JAR plugin's jar goal to the package lifecycle phase multiple times and use different configuration for each configured execution. If you configure two separate executions, each execution has an execution-specific configuration block so you can supply a unique identifier and include/exclude pattern for each execution.

Here is the build element you would use to add both custom JARs to the lifecycle phase "package". Doing this on a project with packaging "jar" would result in the jar goal being run three times. Once as the default lifecycle binding, and then twice for two custom, classified JARs.

<build>
    <plugins>
      <plugin>
        <artifactId>maven-jar-plugin</artifactId>
        <executions>
          <execution>
            <id>only-library</id>
            <goals><goal>jar</goal></goals>
            <phase>package</phase>
            <configuration>
              <classifier>only-library</classifier>
              <excludes>
                <exclude>**/Main*</exclude>
              </excludes>
            </configuration>
          </execution>
          <execution>
            <id>everything</id>
            <goals><goal>jar</goal></goals>
            <phase>package</phase>
            <configuration>
              <classifier>everything</classifier>
              <includes>
                <include>**/*</include>
              </includes>
            </configuration>
          </execution>
        </executions>
      </plugin>
    </plugins>
  </build>

If you are not talking about including a different set of classes in each artifact, you'll want to use Maven Assemblies. If you want to know the details of assemblies, there is a chapter listed at the end of this answer from Maven: The Complete Reference. Frankly, i don't think that this particular chapter is a good introductory reference; in fact, I've had numerous reports that this chapter is nearly unreadable (and we're working to fix that). If you are looking to use assemblies, I'd recommend the Maven Assembly Plugin's documentation. In the left-hand nav menu you'll see a list of sample assembly descriptors.

Disclaimer: (Please) don't do this. If you are creating two difference JARs with two different set of classes I strongly recommend that you split the project up into two interdependent modules.

While you can do this with profiles, it is going to be easier for you to split the project into two (actually three). Longer term there are going to be challenges that you are going to face as your application scales. You will be responsible for figuring out this manual list of classes and packages to be included in each of your classified JARs.

There is minimal overhead to having a simple parent project that references two separate modules. If you look at the free Maven by Example book, we show how to make the transition between a single-module and a multi-module project. Chapters 3-5 focus on single module projects, and Chapter 6 shows you how you would combine these single module components into a larger multi-module project.

You question involves the following topics, here are some links that will provide more details for each:

Thanks for the detailed answer. I'd like to stay away from using package patterns. Seems like a maintenance headache if other devs come in and don't necessarily know the patterns that need to be used.

Ant to Maven - multiple build targets - Stack Overflow

ant build maven target
Rectangle 27 66

You could do this with profiles...

If you really wanted to use two separate profiles and customize the JAR plugin to include and exclude patterns of class and package names, you could easily do this by putting something like this in your POM:

<profiles>
  <profile>
    <id>everything</id>
    <build>
      <plugins>
        <plugin>
          <artifactId>maven-jar-plugin</artifactId>
          <configuration>
            <classifier>everything</classifier>
            <includes>
              <include>**/*</include>
            </includes>
          </configuration>
        </plugin>
      </plugins>
    </build>
  </profile>
  <profile>
    <id>only-library</id>
    <build>
      <plugins>
        <plugin>
          <artifactId>maven-jar-plugin</artifactId>
          <configuration>
            <classifier>only-library</classifier>
            <excludes>
              <exclude>**/Main*</exclude>
            </excludes>
          </configuration>
        </plugin>
      </plugins>
    </build>
  </profile>
</profiles>

Aside: If that seems like a lot of configuration, polyglot Maven's support for Groovy POMs is just about ready. It will cut the line count down considerably.

You would put this at the end of your pom.xml (withing the project element), and it adds two profiles. The first profile "everything" is really just there to demonstrate the configuration. This "everything" profile is unnecesary because it simply duplicates the behavior of the default JAR plugin jar goal execution. The second profile "only-library" excludes any class in any package that starts with the text "Main". To invoke these profiles:

mvn package -Peverything
mvn package -Ponly-library

I tested this against the sample application that ships with Chapter 6 of Maven by Example, and running either of these commands will produce a JAR file in ${basedir}/target that has a classifier. Since the JAR plugin's jar goal is bound to the package phase in the default maven lifecycle, these two profiles are going to modify the configuration for this plugin.

Or, you could do this with two JAR plugin executions...

If you need to create two JARs without using profiles. You can bind the JAR plugin's jar goal to the package lifecycle phase multiple times and use different configuration for each configured execution. If you configure two separate executions, each execution has an execution-specific configuration block so you can supply a unique identifier and include/exclude pattern for each execution.

Here is the build element you would use to add both custom JARs to the lifecycle phase "package". Doing this on a project with packaging "jar" would result in the jar goal being run three times. Once as the default lifecycle binding, and then twice for two custom, classified JARs.

<build>
    <plugins>
      <plugin>
        <artifactId>maven-jar-plugin</artifactId>
        <executions>
          <execution>
            <id>only-library</id>
            <goals><goal>jar</goal></goals>
            <phase>package</phase>
            <configuration>
              <classifier>only-library</classifier>
              <excludes>
                <exclude>**/Main*</exclude>
              </excludes>
            </configuration>
          </execution>
          <execution>
            <id>everything</id>
            <goals><goal>jar</goal></goals>
            <phase>package</phase>
            <configuration>
              <classifier>everything</classifier>
              <includes>
                <include>**/*</include>
              </includes>
            </configuration>
          </execution>
        </executions>
      </plugin>
    </plugins>
  </build>

If you are not talking about including a different set of classes in each artifact, you'll want to use Maven Assemblies. If you want to know the details of assemblies, there is a chapter listed at the end of this answer from Maven: The Complete Reference. Frankly, i don't think that this particular chapter is a good introductory reference; in fact, I've had numerous reports that this chapter is nearly unreadable (and we're working to fix that). If you are looking to use assemblies, I'd recommend the Maven Assembly Plugin's documentation. In the left-hand nav menu you'll see a list of sample assembly descriptors.

Disclaimer: (Please) don't do this. If you are creating two difference JARs with two different set of classes I strongly recommend that you split the project up into two interdependent modules.

While you can do this with profiles, it is going to be easier for you to split the project into two (actually three). Longer term there are going to be challenges that you are going to face as your application scales. You will be responsible for figuring out this manual list of classes and packages to be included in each of your classified JARs.

There is minimal overhead to having a simple parent project that references two separate modules. If you look at the free Maven by Example book, we show how to make the transition between a single-module and a multi-module project. Chapters 3-5 focus on single module projects, and Chapter 6 shows you how you would combine these single module components into a larger multi-module project.

You question involves the following topics, here are some links that will provide more details for each:

Thanks for the detailed answer. I'd like to stay away from using package patterns. Seems like a maintenance headache if other devs come in and don't necessarily know the patterns that need to be used.

Ant to Maven - multiple build targets - Stack Overflow

ant build maven target
Rectangle 27 58

I have tested it, It works. try to add following element in <javac></javac> section:

<compilerarg value="-Xlint:unchecked"/>

Yeah! This was helpful. Thanks. The compiler claims about the use of java.util.Vector and java.util.HashSet. Since they are obsolete I have to look for equivalent types. Any suggestions?

@Benny: The uses of java.util.Vector should be replaced by java.util.List/java.list.ArrayList

@Lukasz Where should i given property in Build.gradle. I got the error in Android Studio

compilation - How to recompile with -Xlint:unchecked in Ant build task...

ant compilation target build.xml
Rectangle 27 16

Try specifying the complete path to the script in the ant target:

<target name="test">
  <exec executable="/bin/bash">
    <arg value="/complete/path/to/input.sh"/>
    <arg value="/tmp"/>
  </exec>
</target>

This is equivalent to issuing the following command in the shell:

/bin/bash /complete/path/to/input.sh /tmp

<arg value="..."/> denotes an argument. So you have 2 arguments to /bin/bash, path to script & /tmp. If your script doesn't make use of extra arguments passed to bin/bash, then those would be ignored.

If your script input.sh is located in /tmp, you can either say

<exec executable="/bin/bash">
    <arg value="/tmp/input.sh"/>
  </exec>
<exec dir="/tmp" executable="/bin/bash">
    <arg value="input.sh"/>
  </exec>

unix - Executing Shell Script through ant - Stack Overflow

unix ant
Rectangle 27 5

Here are some general guidelines (not rules, Ant is quite liberal):

  • a build.xml is generally designed to be run on a specific project, so it is not 'imported' in other builds
  • the import task is generally used to share some comme piece of build mechanic, not a piece of build workflow like you are doing. For instance a target to build jar, parameterized by some properties like the target directory.
  • the subant and ant tasks are preferred used to trigger builds of other project

So here is what would look like a build.xml for project D:

<project name="CommonJava" default="makeCommonJavaJar" basedir=".">

    <target name="build-deps">
        <ant antfile="../Common/build.xml" target="makeCommonJar"/>
        <ant antfile="../CommonAndroid/build.xml" target="makeAndroidJar"/>
    </target>

    <target name="makeCommonJavaJar" depends="build-deps">
        <mkdir dir="build" />
        <jar jarfile="./build/commonjava.jar" includes="*.class" />
    </target>

</project>

Perfect... I came to the same conclusion yesterday as well. This is exactly what I was looking for.

java - Building other, dependent projects with Ant - Stack Overflow

java ant build target
Rectangle 27 22

Your first thought is the correct one. Split the 2 pieces into 2 projects.

The maven philosophy is that each project should build one and only artifact (jar, war, whatever)

You could probably hack something together so that you only have one maven project building 2 atrifacts, but it would be a hack.

You can call ant from maven, so if you really want to do this, then I suggest you start looking at the maven ant plugin. The artifact id is "maven-antrun-plugin"

Ant to Maven - multiple build targets - Stack Overflow

ant build maven target
Rectangle 27 22

Your first thought is the correct one. Split the 2 pieces into 2 projects.

The maven philosophy is that each project should build one and only artifact (jar, war, whatever)

You could probably hack something together so that you only have one maven project building 2 atrifacts, but it would be a hack.

You can call ant from maven, so if you really want to do this, then I suggest you start looking at the maven ant plugin. The artifact id is "maven-antrun-plugin"

Ant to Maven - multiple build targets - Stack Overflow

ant build maven target
Rectangle 27 25

Maybe have a target like below in encompassing ant file:

<target name="all">
     <ant antfile="antFile1" target="clean" />
     <ant antfile="antFile2" target="create" />
     ...
</target>

Create an ant file to run other ant files - Stack Overflow

ant
Rectangle 27 20

Move your condition out of the <target />, as your target probably isn't invoked.

<condition property="isWindows">
                    <os family="windows" />
 </condition>

 <condition property="isLinux">
                    <os family="unix" />
 </condition>

Using ant to detect os and set property - Stack Overflow

ant
Rectangle 27 20

Move your condition out of the <target />, as your target probably isn't invoked.

<condition property="isWindows">
                    <os family="windows" />
 </condition>

 <condition property="isLinux">
                    <os family="unix" />
 </condition>

Using ant to detect os and set property - Stack Overflow

ant
Rectangle 27 10

I like the macrodef solution if indeed it is more efficient than the target one, but I use a var unset=true to force a resetting of the variable, like:

<macrodef name="echoTimestamp">
   <sequential>
      <var name="current.time" unset="true"/>
         <tstamp>
            <format property="current.time" pattern="yyyy-MM-dd HH:mm:ss" />
         </tstamp>
         <echo message="${current.time}" />
   </sequential> 
</macrodef>
<echoTimestamp />
<sleep seconds="3"/>
<echoTimestamp />

Note that the var task is not from core ant, but ant-contrib.

Output several timestamps in ant - Stack Overflow

ant timestamp
Rectangle 27 13

The quirky syntax using conditions on the target (described by Mads) is the only supported way to perform conditional execution in core ANT.

ANT is not a programming language and when things get complicated I choose to embed a script within my build as follows:

<target name="prepare-copy" description="copy file based on condition">
    <groovy>
        if (properties["some.condition"] == "true") {
            ant.copy(file:"${properties["some.dir"]}/true", todir:".")
        }
    </groovy>
</target>

ANT supports several languages (See script task), my preference is Groovy because of it's terse syntax and because it plays so well with the build.

Apologies, David I am not a fan of ant-contrib.

Ant if else condition? - Stack Overflow

ant
Rectangle 27 191

<target name="check-abc">
    <available file="abc.txt" property="abc.present"/>
</target>

<target name="do-if-abc" depends="check-abc" if="abc.present">
    ...
</target>

Available is a non so obvious name for what it does. I got further confused by the fact that google shows people writing their own tags

didnt seem to work with Ant 1.6.2 .

it may work, but does not seem like a good solution if you need to apply to a large number of files

In case anyone wondered, the if and unless attributes only enable or disable the target to which they are attached, i.e. the target's dependencies are always executed. Otherwise it would not work to depend on a target that sets the property you're checking for.

Ant task to run an Ant target only if a file exists? - Stack Overflow

file ant build-automation