Run some or all sections of an ant file - java

Is there a way to specify an ANT file to run only one/some/all of its sections?

Split your build into appropriate targets so that you can call individual targets separately, and then you can specify the target you want to run from the command line.
Personally I like having "real" targets without any dependencies (which I can run independently) and then "fake" targets which are just dependent on the real ones, for convenience (e.g. "clean-build"). The alternative of having test depend on compile etc always ends up getting in the way for me :(

You can group targets together using dependencies:
<target name="A">
<target name="B">
<target name="C" depends="A,B">
runs
A, B, then C.
You can also chain these to arbitrary depth. For example you could create an empty target "D" that depends on A, B which will only run A and B.

<project....
<target name="all">
...
</target>
<target name="some">
...
</target>
</project>
run
ant all
or
ant some

Define appropriate targets in your build file and then run
ant 'target name'
to run that particular one. You will have to configure target dependencies such that the ones you want to run separately can do so correctly.
It's a good practise to define these top-level targets with a description.
<target name="clean" description="Cleans up built artifacts">
Then you can run
ant -projecthelp
and this will display the targets with descriptions, thus telling you what targets are available. This will make life a lot easier further down the road, when you've forgotten what targets you've defined.

Related

Does the Gradle javaCompile task always recompile all java classes (including unchanged?)

I can get an ant compile to only rebuild java classes that have changed, but I can't get Gradle to do so.
I have a project with the structure
root
/src/main/java
/pkg1/File1.java
/pkg2/File2.java
/build.gradle
/build.xml (for comparing against ant)
File1 and File2 are not dependent on each other. File1 and File2 contain correct package information
my build.gradle file only has 1 line
apply plugin: 'java'
Ant: When I do a ant compile it creates two .class files File1.class and File2.class. When I change File2.java and recompile only File2 gets rebuilt. This is the behavior I expect?
Gradle: When I do a gradle compileJava it creates two .class files File1.class and File2.class. When I change only File2.java and recompile both File1 and File2 are rebuilt. Why is File1 recompiled here?
Could this be due to a configuration issue? Or is it just not possible with Gradle at the moment? Perhaps it's a bad idea to this in the first place, if so, why?
For completeness the ant file looks something like this :
<property name="src" location="src/main/java/"/>
<property name="build" location="build"/>
<target name="init">
<tstamp/>
<mkdir dir="${build}"/>
</target>
<target name="compile" depends="init" description="compile the source " >
<javac srcdir="${src}" destdir="${build}" includeDestClasses="true"/>
</target>
Gradle doesn't support incremental Java compilation at this time. In other words, if any input of the JavaCompile task changes, all sources will be recompiled. I do expect incremental compilation to be supported in a future release. Until then, compile time can be improved by spreading sources over multiple source sets (which effectively means multiple compile tasks) and projects. The former helps to make up-to-date checks more effective, the latter allows for parallel compilation when running with --parallel.
UPDATE: Gradle now supports incremental building since 2015.
I know this is an old post. Still answering for letting people know about this great and wonderful feature.
The incremental task for gradle is in incubation stage.
Please go through:
https://docs.gradle.org/current/userguide/custom_tasks.html#incremental_tasks
http://gradle.org/feature-spotlight-incremental-builds/
https://docs.gradle.org/current/dsl/org.gradle.api.tasks.incremental.IncrementalTaskInputs.html

Compiling an eclipse GWT project from the command line, without eclipse: compile error

We got a GWT project in Eclipse, that otherwise works.
Now I want to have a script that runs on the server, which pulls the latest version from source control and compiles it on the server and deploys it.
This will save us a lot of manual work and allow us to deploy new version when on a connection with limited bandwidth (since we won't have to upload the application to the server).
After pulling the latest version of the source code, the script tries to compile the code using the following command:
java -cp "/path/eclipse/plugins/com.google.gwt.eclipse.sdkbundle_2.5.0.v201211121240-rel-r42/gwt-2.5.0/*:/path/company/projects/pull-compile-deploy/X/X/src:/path/company/projects/pull-compile-deploy/X/X/war/WEB-INF/lib/*" com.google.gwt.dev.Compiler nl.company.projects.X
Compiling module nl.company.projects.X
Finding entry point classes
[ERROR] Unable to find type 'nl.company.projects.X.client.XMain'
[ERROR] Hint: Previous compiler errors may have made this type unavailable
[ERROR] Hint: Check the inheritance chain from your module; it may not be inheriting a required module or a module may not be adding its source path entries properly
All source code is in /path/company/projects/pull-compile-deploy/X/X/src and all used .jars (except for the GWT stuff) are in /path/company/projects/pull-compile-deploy/X/X/war/WEB-INF/lib/. Obviously something goes wrong.
Questions: The file /path/company/projects/pull-compile-deploy/X/X/src/nl/company/projects/X/client/XMain.java does exist and should imho be in the classpath?!
Anyone Any idea what might go wrong here?
Is it maybe possible to see in some log exactly the commands that eclipse executes for compilation? I looked at the build.xml that eclipse can export, but it seems that does not contain a target to compile for production.
something else: apperantly GWT expects the X.gwt.xml to be at /path/company/projects/pull-compile-deploy/X/X/src/nl/company/project/X.gwt.xml, whereas eclipse put it in /path/company/projects/pull-compile-deploy/X/X/src/nl/company/project/X/X.gwt.xml (i.e. nested one directory deeper), I fixed this by creating a symbolic link.
Further Edit:
Since one answer focused on how I invoked the compilation tools, I have rewritten that in Ant, see below.
The problem remains of course.
<!-- Compile the source using javac. -->
<target name="compile" depends="init">
<javac srcdir="src/" destdir="bin/">
<classpath refid="project.classpath"/>
</javac>
</target>
<!-- Use the GWT-compiler. -->
<target name="gwt-compile" depends="compile">
<java failonerror="true" fork="true" classname="com.google.gwt.dev.Compiler">
<classpath>
<path refid="project.classpath"/>
<pathelement location="src/"/>
<pathelement location="bin/"/>
</classpath>
<jvmarg value="-Xmx512M"/>
<arg value="${module.name}"/>
</java>
</target>
Anything wrong with the above Ant-script?
module.name = nl.company.projects.X and the path with refid="project.classpath" contains all used libraries aswell as the GWT libraries (gwt-user.jar, gwt-dev.jar and validation-api-1.0.0.GA(-source).jar).
The XMain class inherits nothing (other than from Object) and only implements EntryPoint (which is included in the gwt-user.jar). So I do not think the problem is related to the second hint that the compiler gives.
Any ideas?
GWT requires you to javac your classes, it needs both the *.java and the *.class files.
This has not always been the case, and should change back in the future (see https://code.google.com/p/google-web-toolkit/issues/detail?id=7602 for instance), but for now that's the state of affair: you need to javac before you can com.google.gwt.dev.Compiler.
javac -cp "/path/eclipse/plugins/com.google.gwt.eclipse.sdkbundle_2.5.0.v201211121240-rel-r42/gwt-2.5.0/*:/path/company/projects/pull-compile-deploy/X/X/war/WEB-INF/lib/*" -sourcepath /path/company/projects/pull-compile-deploy/X/X/src /path/company/projects/pull-compile-deploy/X/X/src/nl/company/projects/X.java -d /path/company/projects/pull-compile-deploy/X/X/bin
java -cp "/path/eclipse/plugins/com.google.gwt.eclipse.sdkbundle_2.5.0.v201211121240-rel-r42/gwt-2.5.0/*:/path/company/projects/pull-compile-deploy/X/X/src:/path/company/projects/pull-compile-deploy/X/X/bin:/path/company/projects/pull-compile-deploy/X/X/war/WEB-INF/lib/*" com.google.gwt.dev.Compiler nl.company.projects.X
(please double-check the above commands before use)
EDIT: (in response to your "question" re. the X.gwt.xml): GWT expects the X.gwt.xml at nl/company/projects/X.gwt.xml because that's what you told it to use: module.name = nl.company.projects.x. If the file is at nl/company/projects/X/X.gt.xml then use nl.company.projects.X.X as the module name. Using a symbolic link here is likely to be the problem: the source path for the module (search for <source at https://developers.google.com/web-toolkit/doc/latest/DevGuideOrganizingProjects#DevGuideModuleXml) will then be nl/company/projects/client and thus won't include nl/company/projects/X/client where your XMain class lives; it's this unavailable to the GWT compiler.
That said, I totally agree with SSR: use a decent build tool: Ant, Maven, Gradle, Make, whatever, it'll make your life so much easier. A build tool that manages dependencies (Ant+Ivy, Maven, Gradle) is even better IMO.
Why would you put yourself through such non-standard build exercise like this.
If it is non-academic project then USE maven. If you find maven difficult then use ant.
Examples for both type are provided by GWT team - http://code.google.com/p/google-web-toolkit/source/browse/#svn%2Ftrunk%2Fsamples.
Note - maven has plugins to do most of the stuff you are trying in standardized way.

ant BeforeTargets

In MSBuild there is a BeforeTargets attribute you can add to a target that allows you to run a target before the base target without having to alter the base target. I was wondering if ANT supported this kind of functionality, or am I stuck having to redefine all my targets when I want to execute a target before another one ?
Thanks,
Raul
You can use the depends attribute in (N)Ant:
<target name="target3" depends="target1,target2">
which is same as DependsonTargets in MsBuild I suppose. I would strongly discourage you from using Before/After Targets. If I run a target, after seeing the build file, and see that some extra target is run before / after it eventhough I did not see anything being said about the other targets, I would be very confused and sometimes, this can cause harm.
In MSBuild 4.0, there are BeforeTargets and AfterTargets attributes for targets. These specify a list of targets that are to be run before/after another target.
This is actually quite nice for specifying something to occur after a target defined in another targets file you don't have control over (such as Microsoft.Common.targets).
Example:
<Import Project="Microsoft.Common.targets" />
<Target Name="GetSourceFiles" BeforeTargets="Build">
<Message Text="GetSourceFiles now executing" />
... execute your source control operations ...
</Target>
<Target Name="CopyOutputsForPublishing" AfterTargets="Build">
<Message Text="CopyOutputsForPublishing now executing" />
... execute your copying operations ...
</Target>
I've found these quite helpful.
Much more at:
http://blogs.msdn.com/b/visualstudio/archive/2010/02/18/build-extensibility-with-net-framework-4.aspx

Troubleshooting "failed to create task or type foreach" when using <foreach>

I'm trying to use the foreach loop in an Ant script but I get the message: Problem: failed to create task or type foreach Cause: The name is undefined.
I don't understand why this doesn't work. It is not a 3rd party library. It is a standard task that would be part of the latest version of Ant (1.8).
<target name="parse">
<echo message="The first five letters of the alphabet are:"/>
<foreach param="instance" list="a,b,c,d,e">
</foreach>
</target>
It is a standard task that would be
part of the latest version of Ant
(1.8).
No, it's not. At least I can't find it in the list of core and optional tasks in the ant manual.
It seems to be part of the ant-contrib project and thus needs to be installed separately.
I had the same issue under eclipse with various versions of ant.
Add this into your code WITHOUT adding parameters under eclipse (do not specify any classpath) :
<taskdef resource="net/sf/antcontrib/antcontrib.properties" classpath="/path/to/ant-contrib/ant-contrib-1.0b3.jar"/>
have you ever considered <script>? in this tag you can use some famous script language like javascript and python. they can also interact with the Project, Task... Object of Ant, which means you can set/get the properties and even excute another task. look at this example which comes from the book "java development with ant"
<project name="script_example" default="test-random">
<description>
Use a script task to generate a random number, then
print it
</description>
<target name="random">
<script language="javascript"><![CDATA[
//NB: an unqualified Math is the JavaScript object
var r=java.lang.Math.random();
var num = Math.round(r*10);
project.setNewProperty("random", num);
self.log("Generated random number " + num, project.MSG_DEBUG);
]]>
</script>
</target>
<target name="test-random" depends="random">
<echo>Random number is ${random}</echo>
</target>
</project>
I can't find the foreach task in the Ant 1.8 manual - where is it? I only know the task from ant-contrib, and it requires to specify the 'target' attribute: http://ant-contrib.sourceforge.net/tasks/tasks/foreach.html
You haven't defined a target to call:
<foreach param="instance" list="a,b,c,d,e" target="processListItem" />
alternatively:
<for param="instance" list="a,b,c,d,e" >
<sequential>
<!-- Do Something with #{instance} -->
</sequential>
</for>

Is it possible to exclude some targets from Ant targets while executing the script?

In ant if want to execute more than one target, we can do it like this,
ant target1 target2 target3
Other way could be, create target4 like
<target name="target4" depends="target1,target2,target3" />
but the problem is, one of my target definition is:
<target name="buildApp" depends="init,copy-all-requiredfiles-local,wait-to-merge,compile,createWAR,deployAll"/>
and if i want to execute buildApp then it will run all associated targets too, as obvious.
Is it possible to execute the buildApp target without executing deployAll target?
A possibility would be add a condition to your deployAll target like this.
<target name="depolyAll" unless="doNotDeploy">
...
</target>
Then when you want to run buildApp without deployAll on the commandline just do
ant -DdoNotDeploy=true buildAll
btw. note that unless just checks if the property is set. Not what the value is.
But this behaviour should be documented and is a little obscure.
I would consider explicitly creating a second build target e.g. buildAllWithoutDeploy which just misses the deploy target
Why not create another target for it?
<target name="buildAppNoDeploy" depends="init,copy-all-requiredfiles-local,wait-to-merge,compile,createWAR"/>

Categories

Resources