Work currently uses ANT and need to migrate to MAVEN. As stated above , I need to run same profile but with different parameters each time.
Present Ant Code Example :
<target name = SomeTarget>
<var name = "PROP" value="123">
<antcall target = "OutTarget1">
<var name = "PROP" value="145">
<antcall target = "OutTarget1">
</target>
<target name ="OutTarget1">
<!-- some java code -->
<!-- run .SQL files -->
<!-- some java code on that again -->
<\target>
Doesn't seem like even with maven antrun plugin antcall is supported.
Work requires I create all targets as profiles in pom.xml. Now I can simply repeat the "OutTarget1" code in execution part of a profile for each time there is a new property. But that makes it quite hard to debug. And there's a ton of a t targets calling other targets.
If it was just one antcall , I add the parameter in launch configuration. I have no idea how to achieve this when it's same parameter but different values each time.
P.S. Added what OutTarget does. It's basically the same process but with diff values each time.
I don't think what you're trying to do is a good approach, but if it's urgent...have you considered using different settings-[X].xml, with the same profile defined differently and launch maven pointing to them?
Related
I´m a pretty new to ant and I´m trying to send an email within an ant-target which is called by Java. I´m using the Netbeans IDE.
Ant:
<project name="AntTargets" default="main" basedir=".">
<description>Builds, tests, and runs the project AntTargets.</description>
<import file="nbproject/build-impl.xml"/>
<target name="run" depends="jar">
<java classpathref="AntTargets.classpath" fork="true" classname="Client" />
</target>
<target name="main">
<echo message="******************[MAIN]******************"/>
<property file="nbproject/build.properties"/>
<property name="to" value="${builder}" />
<property name="from" value="${builder}" />
<property name="server" value="${server}" />
<property name="port" value="${port}" />
<mail mailhost="${server}" mailport="${port}" subject="Test build">
<from address="${from}"/>
<replyto address="${to}"/>
<to address="test#domain.de"/>
<message>The build has been completed</message>
</mail>
<echo message="Email to ${to} from ${from} has been sent using the server ${server} on port ${port}."/>
</target>
</project>
Java:
import java.io.File;
import org.apache.tools.ant.Project;
import org.apache.tools.ant.ProjectHelper;
public class AntTargets {
public static void main(String[] args) {
//get new file
File buildFile = new File("build.xml");
//create new project
Project p = new Project();
p.setUserProperty("ant.file", buildFile.getAbsolutePath());
p.init();
//initialize helper
ProjectHelper helper = ProjectHelper.getProjectHelper();
p.addReference("ant.projectHelper", helper);
//parse and execute
helper.parse(p, buildFile);
p.executeTarget(p.getDefaultTarget());
}
}
When I execute the ant part directly, the properties file is found, read and works overall but the mail-part gives me this error:
Failed to send email: javax.mail.internet.MimeMessage
build.xml:16:
java.lang.ClassNotFoundException: javax.mail.internet.MimeMessage
When I call it with java I get:
Reference AntTargets.classpath not found.
BUILD FAILED (total time: 0 seconds)
I would greatly appreciate any help and tip overall.
The issue is Ant doesn't know what AntTargets.classpath is.
You must define a classpath variable and give it id="AntTargets.classpath. In this path variable you should define the physical locations of the libraries you use. (You should look to creating path variables to reduce redundancies in code, particularly when you want to use the same path in different ant targets.)
Here's an example: Let's say that your project requires the Gson library at runtime.
First, create a path for that library. Let's assume you have your libraries in a lib directory.
<path id="library.gson-2.8.0.classpath">
<pathelement location="${basedir}/lib/gson-2.8.0.jar"/>
</path>
Do the same for other dependencies as well.
Next, create a path that will contain all these dependencies, so you can refer to all the dependencies as one variable. This will be your AntTargets.classpath
<path id="AntTargets.classpath">
<path refid="library.gson-2.8.0.classpath"/>
...... <!-- Add paths for your other dependencies by refid here-->
</path>
Now, when you use AntTargets.classpath Ant will know what that is and use it to run your jar.
I notice that you use this in the run target, so if you're trying to run the Client class from your own jar, include that in your classpath as well.
Also keep in mind that "Client" may not be enough information--you must provide the fully qualifying name of the class, including package names, e.g. something like "com.package.Client".
EDIT:
I just noticed the exception you're getting from running directly with Ant. You need to include the javax.mail library in this path variable we create. That should resolve that issue.
EDIT 2:
I seem to have misunderstood. I thought that your ant task was trying to call your Java program which would send the mail, but it couldn't since it didn't know where the javax.mail.jar is, and so I instructed you to add it to the classpath.
But what you want to do is:
Use the Ant mail task to send a mail.
And in the Java you want to read the build file and execute the target that sends the mail.
Here's some information on that: mail is an Ant Task that requires the javax.mail library, if you want to use certain arguments. Looking at a few questions like this and this, I see that you should put ${ANT_HOME}/lib, i.e. where your ant.jar is, so that Ant's classloader can pick it up and use it. In that case, if my assumption about what you want is correct, then you should be able to get rid of AntTargets.classpath, because really, your build file doesn't need to know how you call any of it's targets.
I need to switch to Ant, I managed to compile and install the Android apk file but I didn't manage to transmit the property or a specific target to the referenced library.
My code on the build.xml in the referenced library :
<echo message="Property value is '${foo.dist}'" />
<target name="AfficherVersionAnt">
<echo message="Version d'Ant utilisée : ${ant.version}"/>
</target>
The same code is functional when I put it in the starting package.
<property name="foo.dist" value="true"/>
(and for the target, if I launch with the target)
My ant configuration was generated with :
"C:\Program Files (x86)\Android\android-sdk\tools\android" update project -p "D:\project"
And I don't see where I could set a link
Can someone help me ? I would need global variables or something like this
In eclipse you can define your own variables for ant
Go to external tools configuration > your profile > environnement, and define new environnement variable.
My build begins by defining 2 properties files, importing another build XML, and then commencing with all my other targets & tasks:
build.main.xml:
<project name="${proj.name}" default="assemble" basedir=".">
<!-- BASIC CONFIGURATIONS -->
<!-- Define build properties. -->
<property file="build.main.properties"/>
<property file="build.app.properties"/>
<!-- Imports. -->
<import file="${alt.build.file}"/>
<!-- Rest of buildscript omitted for brevity... -->
</project>
build.app.properties:
proj.name=test-proj
alt.build.file=build.app.xml
It seems that build.main.xml cannot seem to see/find any properties defined inside build.app.properties; specifically:
It cannot resolve ${proj.name}, and when I add the build.main.xml file to the Eclipse Ant view, the name of the build shows up as ${proj.name}
It cannot find build.app.xml imported from build.main.xml
What's going on here? Do ant builds only get to import one properties file or something?!? Where could I start troubleshooting?
Edit: using Eclipse editor my buildscript does not have any red/highlighted syntax errors that might be causing the ant plugin to work incorrectly, etc.
Edit: I am noticing issues with properties defined inside the build.main.properties to. If I try to echo them they don't get noticed by Ant either...
The Ant project name cannot be itself a property for the reason Jochen mentioned in his comment.
Try running your script with the -v option to see more logging. I have used a technique very similar to your <import file="${alt.build.file}"/> to branch my script based on the db platform, so there should be no problem with it.
I wondered if your property files are in the same directory then your build script is.
I have this in my build.xml:
<target depends="build-jar" name="proguard">
<taskdef resource="proguard/ant/task.properties" classpath="tools/proguard4.6/lib/proguard.jar" />
<proguard configuration="ant/proguard.conf" />
</target>
It works fine.
Inside the configuration file (i.e "ant/proguard.conf") I'm trying to access properties defined in this build.xml file but I'm always getting this kind of error:
Value of system property 'jar.final_name' is undefined in '<jar.final_name>' in line 1 of file '.......\ant\proguard.conf'
The error is clear. Question is how I do what I'm trying to?
If I'd do it the "Embedded ProGuard configuration options" way I could use these properties like any other property in build.xml, but I'm trying to keep the files separate.
How do I do that then?
By default, Ant doesn't provide a way to set java system properties for its tasks. You can only specify -D options in the ANT_OPTS system variable when starting Ant itself.
I'll consider supporting the use of Ant properties in referenced ProGuard configurations (being the developer of ProGuard).
For the time being, an acceptable solution might be to specify input and output jars in Ant's XML-style:
<proguard configuration="ant/proguard.conf">
<injar name="${injar}" />
<outjar name="${outjar}" />
<libraryjar name="${java.home}/lib/rt.jar" />
</proguard>
This part of the configuration is more closely tied to the Ant script anyway.
We have an Apache ANT script to build our application, then check in the resulting JAR file into version control (VSS in this case). However, now we have a change that requires us to build 2 JAR files for this project, then check both into VSS.
The current target that checks the original JAR file into VSS discovers the name of the JAR file through some property. Is there an easy way to "generalize" this target so that I can reuse it to check in a JAR file with any name? In a normal language this would obviously call for a function parameter but, to my knowledge, there really isn't an equivalent concept in ANT.
I would suggest to work with macros over subant/antcall because the main advantage I found with macros is that you're in complete control over the properties that are passed to the macro (especially if you want to add new properties).
You simply refactor your Ant script starting with your target:
<target name="vss.check">
<vssadd localpath="D:\build\build.00012.zip"
comment="Added by automatic build"/>
</target>
creating a macro (notice the copy/paste and replacement with the #{file}):
<macrodef name="private-vssadd">
<attribute name="file"/>
<sequential>
<vssadd localpath="#{file}"
comment="Added by automatic build"/>
</sequential>
</macrodef>
and invoke the macros with your files:
<target name="vss.check">
<private-vssadd file="D:\build\File1.zip"/>
<private-vssadd file="D:\build\File2.zip"/>
</target>
Refactoring, "the Ant way"
It is generally considered a bad idea to version control your binaries and I do not recommend doing so. But if you absolutely have to, you can use antcall combined with param to pass parameters and call a target.
<antcall target="reusable">
<param name="some.variable" value="var1"/>
</antcall>
<target name="reusable">
<!-- Do something with ${some.variable} -->
</target>
You can find more information about the antcall task here.
Take a look at Ant macros. They allow you to define reusable "routines" for Ant builds. You can find an example here (item 15).
Also check out the subant task, which lets you call the same target on multiple build files:
<project name="subant" default="subant1">
<property name="build.dir" value="subant.build"/>
<target name="subant1">
<subant target="">
<property name="build.dir" value="subant1.build"/>
<property name="not.overloaded" value="not.overloaded"/>
<fileset dir="." includes="*/build.xml"/>
</subant>
</target>
</project>
You can use Gant to script your build with groovy to do what you want or have a look at the groovy ant task.