Skip to Content »

GWT Task for Ant

  • September 9th, 2006
  • 1:01 am

I've been working on a small project using Google Web Toolkit, which is a pretty nice framework. However, it's not exactly easy to integrate into a normal build environment with ant, as it's based on command line utilities.

After a while, I got tired of it and wrote an Ant task which can compile GWT modules into javascript. I know that others have attempted the same, but as far as I could tell, they all required you to hardcode module names in build.xml, which is not very nice.

So, using the task I wrote, it's possible to generate javascript for a set of modules using a single task. Plus, it's a little faster when compiling more modules, as it doesn't have to restart the compiler completely every time.

Try it out. It's released under a GPL license.

Download

Files are hosted at the Google Code project

Documentation

The task can be used to compile any number of modules. It's not necessary to specify the module names directly. Instead, the task accepts filesets specifying the modules.
Place the ant-gwt.jar file in your project's lib dir, make sure that the gwt-*.jar files are there too, and use like this:

CODE:
  1. <path id="classpath">
  2.   <pathelement location="${srcdir}"/>
  3.   <pathelement location="${builddir}"/>
  4.   <fileset dir="lib">
  5.     <include name="*.jar"/>
  6.   </fileset>
  7. </path>
  8.  
  9. <target name="compile">
  10.   <javac ... />
  11.    
  12.   <taskdef resource="dk/contix/ant/gwt/ant-gwt.xml" classpathref="classpath" />
  13.   <gwtcompile destdir="www" optimize="true">
  14.     <fileset dir="src">
  15.       <include name="**/*.gwt.xml"/>
  16.     </fileset>
  17.   </gwtcompile>
  18. <target/>

Please note that the order of the classpath is important. If you get weird errors about files not being found, then ensure that the source directory is first, then the locally compiled classes, and then the jar files.

It's possible to enable some simple optimization by setting optimize="true" on gwtcompile. That will try to analyze the java files to see if any of the required files have been changed since last compile. Required files are all files which are included in the source tag in the .gwt.xml-files.

33 People had this to say...

Gravatar
  • Rostislav
  • September 25th, 2006
  • 10:56 am

Thank you for sharing such useful task. I think it should be published on ant.apache.org in optional task list.

By the way, could you provide sources for this task? Hope you don’t mind since you’ve released it under gpl.

Gravatar
  • recht
  • September 25th, 2006
  • 11:05 am

Actually the source files are included in the jar file – just expand the jar file with unzip, and you’ll get the .java file.

Gravatar
  • Rostislav
  • September 25th, 2006
  • 11:43 am

Oh, sorry. Thanks.

Gravatar
  • netice
  • November 14th, 2006
  • 9:41 am

I get errors

Buildfile: test.ant.xml

compile:

BUILD FAILED
/home/netice/tmp/1/test.ant.xml:32: Could not create type gwtcompile due to java.lang.ClassCastException: java.net.URLClassLoader

Total time: 1 second

my build file here:

test build file. This is used to package up your project as a jar,
if you want to distribute it. This isn’t needed for normal operation.

Gravatar
  • netice
  • November 14th, 2006
  • 11:43 am

the java.lang.ClassCastException throws
when casting ClassLoader to AntClassLoader
in the constructor.

what’s wrong with this?

Gravatar
  • netice
  • November 14th, 2006
  • 11:52 am

it seems that the object return by getClass().getClassLoader() is an instance of the class “java.net.URLClassLoader” which should not be cast to “AntClassLoader” or run into java.lang.ClassCastException.

my box is gentoo 2006.1 sun jdk1.5 gwt-1.1.10

Gravatar
  • Emilio
  • November 29th, 2006
  • 5:10 pm

Hi, I am using ant-gwt 1.1.0 in a project GWT 1.2.22. I have the following problems:

1) When the project is in path where there is directories with blank spaces obtains the following error:
[gwtcompile] java.net.URISyntaxException: Illegal character in path at index 18:
file:/C:/Documents and Settings/myUser/workspace/gwanted/src/org/gwanted/gwt/widget/chart/module.gwt.xml

How could I solve this problem?

2) Unable to find type ‘org.gwanted.gwt.sample.i18n.client.I18n’: Problem with multiple ANT-GWT tasks in same build.xml file

When different sequential tasks are sent from same build.xml, for example


The first Ant task is executed correctly: , but for the rest the following error is obtained: Unable to find type…

How could I solve this problem?

Gravatar
  • recht
  • November 30th, 2006
  • 7:58 pm

The first problem looks like a bug in GWT itself. However, the bug should have been fixed in 1.2, but maybe there’s been a regression.

Your code example doesn’t show up, but the problem might be that the classpath isn’t completely restored after a compile.

However, there shouldn’t be any need to call gwtcompile twice, just make sure you include all *.gwt.xml files in the gwtcompile task.

Gravatar
  • Emilio
  • December 1st, 2006
  • 5:07 pm

Hi, Referring to the first problem,
I’m testing a task java Ant with com.google.gwt.dev.GWTCompiler and works correctly. Is a problem of GWT 1.2?

Gravatar
  • Perry
  • December 4th, 2006
  • 8:02 pm

Great task!

It would be nice if JVM args could be provided as well. I am running out of memory when doing a gwtcompile so I need to specify the -Xmx.

Thanks!

Gravatar
  • recht
  • December 5th, 2006
  • 10:07 pm

My guess is that you need to add the arguments to ant instead. The GWT task does not launch any new java processes, so there’s no place to add vm arguments.

Try setting -Xmx in ANT_OPTS and run ant again.

Gravatar
  • Konstantin Andreev
  • February 22nd, 2007
  • 8:41 pm

Great work!
Thanks!

Gravatar
  • Jim
  • February 24th, 2007
  • 12:35 am

It had problems with the task on windows with a path that had spaces. For example “C:\Documents and Settings\Jim\My Documents\projects…”. I took a look at the source and fixed it. On line 100 change:
urls[i] = new File(cp[i]).toURL();
to:
urls[i] = new File(cp[i]).toURI().toURL();

Gravatar
  • Alexander Vasiljev
  • March 23rd, 2007
  • 8:52 am

I found the following bug:
1) if you compile several projects A, B, C
2) where A inherits C, B inherits C
3) C is i18n’lizes (don’t know if it is important or not)

then, when compiling A (OK), then B (OK), then C, you get an output as follows:

[gwtcompile] Compiling A
[gwtcompile] Output will be written into ...\A
[gwtcompile] Copying all files found on public path
[gwtcompile] Compilation succeeded
[gwtcompile] Compiling B
[gwtcompile] Output will be written into ...\B
[gwtcompile] Copying all files found on public path
[gwtcompile] Compilation succeeded
[gwtcompile] Compiling C
[gwtcompile] Output will be written into ...\C
[gwtcompile] Analyzing permutation #1
[gwtcompile] Rebinding A
[gwtcompile] Checking rule
[gwtcompile] [ERROR] Unable to find type 'A'
[gwtcompile] [ERROR] Hint: Previous compiler errors may have made this type unavailable
[gwtcompile] [ERROR] Hint: Check the inheritance chain from your module; it may not be inheriting a required module or a module may not be add
ing its source path entries properly

Due to the internal caching in GWTCompiler, I think.
The solution is to instantiate GWTCompiler for each GWT Module.

Gravatar
  • Alexander Vasiljev
  • March 23rd, 2007
  • 8:59 am

in the post above

[gwtcompile] Checking rule <generate-with class='com.google.gwt.i18n.rebind.LocalizableGenerator'/>

Anyway, thanks for a great piece of code, Recht!

Gravatar
  • Ovidiu Matan
  • April 30th, 2007
  • 12:54 pm

The gwt script provided a great help and it’s quite strange that Google itself didn’t provide such scripts.
For playing in a production mode usually a war file is needed with everything embedded. I’m copy paste here my build file for helping others that have same problem:

All you need to do is to make sure that you have a folders structure like this

.\
.\lib – containing: ant-gwt-1.1.2.jar, gwt-dev-windows.jar, gwt-servlet.jar, gwt-user.jar
.\src – your sources
.\descriptor – your web.xml that should look like this:

testHello
server.RandomQuoteServiceImpl

testHello
/Hello/RandomQuoteService

Resulting file will be .\dist\Hello.war and you have to move it in .\Tomcat\webapps
Note:

Gravatar
  • Ovidiu Matan
  • April 30th, 2007
  • 12:55 pm

It seems that I cannot past my generated build file here.

Gravatar
  • Davi d Barker
  • June 16th, 2007
  • 7:12 pm

I am seeing the same problem that Netice had seen. It seems getClass().getClassLoader() is returning a java.net.URLClassLoader and then being cast to AntClassLoader, and this results in java.lang.ClassCastException.

I see that others are not having this problem. Is this a java version issue? (I am using 1.5) Or does anyone know what I am doing wrong?

Gravatar
  • David Barker
  • June 18th, 2007
  • 4:31 am

I’m getting the error on line #98:
oldClassPath = ((AntClassLoader)getClass().getClassLoader()).getClassPath();

To break this down:
getClass() must be returning the static class for org.apache.tools.ant.Task.

So then, we are calling the static method inherited from java.lang.Class called getClassLoader() for org.apache.tools.ant.Task.

I don’t know what it should return, or how to control what it returns, but it seems to be returning a java.net.URLClassLoader

And when it gets java.net.URLClassLoader, it tries to cast it to org.apache.tools.an­t.AntClassLoader. That makes sense because org.apache.tools.ant.AntClassLoader does not derive from java.net.URLClassLoader.

But then how does this code seem to work for other people? Can anyone see what I am doing wrong?

Apache Ant version 1.6.5 compiled on June 2 2005
Buildfile: MyApplication.ant.xml
Detected Java version: 1.5 in: c:\sdks\jdk1.5.0_07\jre
Detected OS: Windows XP
parsing buildfile C:\src\MyApplication\MyApplication.ant.xml with URI = file:///C:/src/MyApplication/MyApplication.ant.xml
Project base dir set to: C:\src\MyApplication
dropping C:\tools\apache\apache-ant-1.6.5\lib from path as it doesn’t exist
parsing buildfile jar:file:/c:/tools/apache/apache-ant-1.6.5/lib/ant-gwt-1.1.2.jar!/dk/contix/ant/gwt/ant-gwt.xml with URI = jar:file:/c:/tools/apache/apache-ant-1.6.5/lib/ant-gwt-1.1.2.jar!/dk/contix/ant/gwt/ant-gwt.xml
parsing buildfile jar:file:/C:/tools/apache/apache-ant-1.6.5/lib/ant-gwt-1.1.2.jar!/dk/contix/ant/gwt/ant-gwt.xml with URI = jar:file:/C:/tools/apache/apache-ant-1.6.5/lib/ant-gwt-1.1.2.jar!/dk/contix/ant/gwt/ant-gwt.xml
Build sequence for target(s) `compile’ is [compile]
Complete build sequence is [compile, package, clean, all, buildwar, ]

compile:
[javac] com\MyApplication.gwt.xml skipped – don’t know how to handle it
[javac] com\client\.MyApplication.java.swp skipped – don’t know how to handle it
[javac] com\client\OtherServiceListService.java omitted as com/client/OtherServiceListService.class is up to date.
[javac] com\client\OtherServiceListServiceAsync.java omitted as com/client/OtherServiceListServiceAsync.class is up to date.
[javac] com\client\MyApplication.java omitted as com/client/MyApplication.class is up to date.
[javac] com\client\MyService.java omitted as com/client/MyService.class is up to date.
[javac] com\client\MyServiceAsync.java omitted as com/client/MyServiceAsync.class is up to date.
[javac] com\public\MyApplication.html skipped – don’t know how to handle it
[javac] com\server\MyServiceImpl.java omitted as com/server/MyServiceImpl.class is up to date.
[javac] com\server\ServletWrappingController.java omitted as com/server/ServletWrappingController.class is up to date.
[javac] spring-servlet.xml skipped – don’t know how to handle it
[javac] web.xml skipped – don’t know how to handle it

BUILD FAILED
C:\src\MyApplication\MyApplication.ant.xml:30:
Could not create type gwtcompile due to java.lang.ClassCastException: java.net.URLClassLoader
at org.apache.tools.ant.AntTypeDefinition.createAndSet(AntTypeDefinition.java:281)
at org.apache.tools.ant.AntTypeDefinition.icreate(AntTypeDefinition.java:196)
at org.apache.tools.ant.AntTypeDefinition.create(AntTypeDefinition.java:183)
at org.apache.tools.ant.ComponentHelper.createComponent(ComponentHelper.java:199)
at org.apache.tools.ant.ComponentHelper.createComponent(ComponentHelper.java:176)
at org.apache.tools.ant.UnknownElement.makeObject(UnknownElement.java:388)
at org.apache.tools.ant.UnknownElement.maybeConfigure(UnknownElement.java:158)
at org.apache.tools.ant.Task.perform(Task.java:363)
at org.apache.tools.ant.Target.execute(Target.java:341)
at org.apache.tools.ant.Target.performTasks(Target.java:369)
at org.apache.tools.ant.Project.executeSortedTargets(Project.java:1216)
at org.apache.tools.ant.Project.executeTarget(Project.java:1185)
at org.apache.tools.ant.helper.DefaultExecutor.executeTargets(DefaultExecutor.java:40)
at org.apache.tools.ant.Project.executeTargets(Project.java:1068)
at org.apache.tools.ant.Main.runBuild(Main.java:668)
at org.apache.tools.ant.Main.startAnt(Main.java:187)
at org.apache.tools.ant.launch.Launcher.run(Launcher.java:246)
at org.apache.tools.ant.launch.Launcher.main(Launcher.java:67)
Caused by: java.lang.ClassCastException: java.net.URLClassLoader
at dk.contix.ant.gwt.GWTCompileTask.(GWTCompileTask.java:98)
at sun.reflect.NativeConstructorAccessorImpl.newInstance0(Native Method)
at sun.reflect.NativeConstructorAccessorImpl.newInstance(NativeConstructorAccessorImpl.java:39)
at sun.reflect.DelegatingConstructorAccessorImpl.newInstance(DelegatingConstructorAccessorImpl.java:27)
at java.lang.reflect.Constructor.newInstance(Constructor.java:494)
at org.apache.tools.ant.AntTypeDefinition.createAndSet(AntTypeDefinition.java:273)
… 17 more
— Nested Exception —
java.lang.ClassCastException: java.net.URLClassLoader
at dk.contix.ant.gwt.GWTCompileTask.(GWTCompileTask.java:98)
at sun.reflect.NativeConstructorAccessorImpl.newInstance0(Native Method)
at sun.reflect.NativeConstructorAccessorImpl.newInstance(NativeConstructorAccessorImpl.java:39)
at sun.reflect.DelegatingConstructorAccessorImpl.newInstance(DelegatingConstructorAccessorImpl.java:27)
at java.lang.reflect.Constructor.newInstance(Constructor.java:494)
at org.apache.tools.ant.AntTypeDefinition.createAndSet(AntTypeDefinition.java:273)
at org.apache.tools.ant.AntTypeDefinition.icreate(AntTypeDefinition.java:196)
at org.apache.tools.ant.AntTypeDefinition.create(AntTypeDefinition.java:183)
at org.apache.tools.ant.ComponentHelper.createComponent(ComponentHelper.java:199)
at org.apache.tools.ant.ComponentHelper.createComponent(ComponentHelper.java:176)
at org.apache.tools.ant.UnknownElement.makeObject(UnknownElement.java:388)
at org.apache.tools.ant.UnknownElement.maybeConfigure(UnknownElement.java:158)
at org.apache.tools.ant.Task.perform(Task.java:363)
at org.apache.tools.ant.Target.execute(Target.java:341)
at org.apache.tools.ant.Target.performTasks(Target.java:369)
at org.apache.tools.ant.Project.executeSortedTargets(Project.java:1216)
at org.apache.tools.ant.Project.executeTarget(Project.java:1185)
at org.apache.tools.ant.helper.DefaultExecutor.executeTargets(DefaultExecutor.java:40)
at org.apache.tools.ant.Project.executeTargets(Project.java:1068)
at org.apache.tools.ant.Main.runBuild(Main.java:668)
at org.apache.tools.ant.Main.startAnt(Main.java:187)
at org.apache.tools.ant.launch.Launcher.run(Launcher.java:246)
at org.apache.tools.ant.launch.Launcher.main(Launcher.java:67)

Total time: 1 second

Gravatar

To netice & David Barker: I think you need to compile the whole project (including java files in the client, public and server directory) into the ${builddir}: that was my problem.

Gravatar
  • zotster
  • August 24th, 2007
  • 10:24 am

The ClassCastException is caused by using the latest version of ANT. I was seeing the same errors and concluded that AntClassLoader was no longer an implementation of URLClassLoader. Try using ANT 1.6.x. Ant 1.7.x will not work due to API changes.

Gravatar
  • acheren
  • August 29th, 2007
  • 8:40 am

how to pass the heap memory size argument to

[...] GWT Task for Ant [...]

Gravatar
  • Brian Reynolds
  • February 25th, 2008
  • 2:56 pm

I’m trying to run the gwtcompile task. We had it running just fine, but I upgraded my OS from Mac OS X 10.4.x to 10.5.x and upgraded Eclipse/MyEclipse to 3.3/6.0 which uses Ant 1.7, and now I’m getting the following error:
BUILD FAILED
/Users/breynolds/Documents/eclipseWorkspace/emergency/build.xml:57: Could not create type gwtcompile due to java.lang.LinkageError: loader constraints violated when linking org/apache/tools/ant/types/Path class

Any Ideas?

Gravatar
  • Daniel Bimschas
  • May 4th, 2008
  • 9:50 pm

I have the same problem as Brian Reynolds after switching my project from Windows to Mac OS X, does anyone have a clue?

Brian, did you find out?

Gravatar

Nice..works great. Was about to write one myself. Thought I’d check if anything was already out there first and found yours.

Gravatar
  • Kirill
  • February 20th, 2009
  • 10:57 am

You have “” instead of “” in the example code.

Gravatar
  • Kirill
  • February 20th, 2009
  • 11:01 am

Sorry, this posting form cuts the tags. Look at “target” tag closing. You have “target/” instead of “/target”.

Gravatar
  • mark thomas
  • April 8th, 2009
  • 3:39 pm

task fails with java.lang.InstantiationException: com.google.gwt.dev.GWTCompiler in GWT version 1.6.x

Gravatar
  • recht
  • April 16th, 2009
  • 1:09 pm

A new version for 1.6 has been released at Google Code. Check the download link above.

Gravatar
  • Naor
  • June 19th, 2009
  • 3:54 pm

after fixing all classpath issues i am getting “Unable to compile GWT”
any idea what to do next?

I am using GWT 1.6.4 and ant-gwt-1.2.jar

Gravatar

This post has helped me tremendously¡­making simple tasks simpler and the hard ones easy enough to understand.

Gravatar
  • coder
  • August 26th, 2010
  • 4:13 pm

Thanks for posting the source code, very helpful. :-)

Want your say?

* Required fields. Your e-mail address will not be published on this site

You can use the following XHTML tags:
<a href="" title=""> <abbr title=""> <acronym title=""> <b> <blockquote cite=""> <cite> <code> <del datetime=""> <em> <i> <q cite=""> <strike> <strong>