Tuesday, November 04, 2008

How to use custom ant tasks in a WTP generic ant publisher

Before creating the Eclipse Pluto Server Plug-in, I had an Ant script to publish my portlets to a Pluto server. That Ant script used the Maven2 ant tasks to download the needed Pluto ant task jar and its dependencies. This Pluto ant task is needed to rewrite the portlet's web.xml so that it contains the Pluto server's invoker of the portlet. When I first created the plug-in and needed a way to get the Pluto ant task jar, I looked for how to include it with the plug-in jar but I couldn't figure out how to expose it to the Pluto ant publisher script I created as part of the WTP generic server definition. So, I used the Maven2 stuff I already had, and it worked pretty well for me. However, it was never ideal.

Recently, actually by accident, I figured out how to make ant tasks in a plug-in available to a WTP ant publisher. I stumbled upon the Eclipse ant extension point documentation, specifically, the part about Extra Ant Classpath Entries. Not sure how I missed this before, but it's basically all right there. There's also the org.eclipse.ant.core.antTasks extension point which allows you to expose ant tasks to your ant scripts in Eclipse. Since it wasn't immediately obvious to me at first, I thought I would post how I got it working. It's actually quite simple once you know what extension points to work with.

Here's what I added to the Pluto Server Plug-in plugin.xml to define the Pluto ant task

<extension point="org.eclipse.ant.core.antTasks">
<antTask name="pluto.assemble"

But of course this ant task has dependencies. To make it's dependencies available to it, you'll just need to add extraClasspathEntries

<extraClasspathEntries library="lib/castor-1.1.1.jar" eclipseRuntime="false" />
<extraClasspathEntries library="lib/cglib-full-2.0.2.jar" eclipseRuntime="false" />
<extraClasspathEntries library="lib/commons-beanutils-1.7.0.jar" eclipseRuntime="false" />
<extraClasspathEntries library="lib/commons-cli-1.0.jar" eclipseRuntime="false" />
<extraClasspathEntries library="lib/commons-digester-1.8.jar" eclipseRuntime="false" />
<extraClasspathEntries library="lib/commons-io-1.3.1.jar" eclipseRuntime="false" />
<extraClasspathEntries library="lib/commons-lang-1.0.jar" eclipseRuntime="false"/>
<extraClasspathEntries library="lib/commons-logging-1.0.jar" eclipseRuntime="false"/>
<extraClasspathEntries library="lib/commons-logging-api-1.1.jar" eclipseRuntime="false"/>
<extraClasspathEntries library="lib/pluto-descriptor-api-1.1.6.jar" eclipseRuntime="false"/>
<extraClasspathEntries library="lib/pluto-descriptor-impl-1.1.6.jar" eclipseRuntime="false"/>
<extraClasspathEntries library="lib/pluto-util-1.1.6.jar" eclipseRuntime="false"/>
<extraClasspathEntries library="lib/xercesImpl-2.6.2.jar" eclipseRuntime="false"/>
<extraClasspathEntries library="lib/xmlParserAPIs-2.6.2.jar" eclipseRuntime="false"/>

I'm not quite sure why, but the eclipseRuntime attribute needs to be set to false to get this to work. The docs say

eclipseRuntime - indicates whether this extra classpath entry should only be considered for builds run in the same VM as Eclipse. The implied value is true, when not specified.

So I can only guess that this means that the WTP ant publisher doesn't run in the same VM as Eclipse? Anyhow, I tried it both ways, and it only worked with the value of false.

From my ant publisher script, nothing special, I just reference the pluto.assemble task (I gave it that name). Here's the snippet where I use it:

<target name="assemble" if="portletxml.exists">

<pluto.assemble webxml="${module.dir}/WEB-INF/web.xml"
destfile="${webxml.with.portlet.mapping.file}" />

Previously I had to define the task with a <taskdef> tag, but I no longer need that.

No comments: