Maven 2.x Antrun Plugin

<taskdef/> seems ignoring classpath

Details

  • Type: Bug Bug
  • Status: Closed Closed
  • Priority: Major Major
  • Resolution: Not A Bug
  • Affects Version/s: 1.2
  • Fix Version/s: 1.6
  • Component/s: None
  • Labels:
    None
  • Environment:
    Fedora
  • Testcase included:
    yes
  • Number of attachments :
    1

Description

I'm trying to run xdoclet in ant build file called from antrun plugin. The build file is very simple:

<project name="testcase" default="run">

	<property name="maven.repository" value="set repository location here!"/>
	<property name="destdir" value="target/generated-sources"/>
	
	<path id="xdoclet.classpath">
		<fileset dir="${maven.repository}">
			<include name="commons-collections/commons-collections/3.1/commons-collections-3.1.jar"/>
			<include name="commons-logging/commons-logging/1.0.4/commons-logging-1.0.4.jar"/>
			<include name="jboss/jboss-j2ee/4.0.2/jboss-j2ee-4.0.2.jar"/>
			<include name="xjavadoc/xjavadoc/1.1/xjavadoc-1.1.jar"/>
			<include name="xdoclet/xdoclet/1.2.3/xdoclet-1.2.3.jar"/>
			<include name="xdoclet/xdoclet-ejb-module/1.2.3/xdoclet-ejb-module-1.2.3.jar"/>
		</fileset>
	</path>
	
	<target name="run">
		<!-- print classplath -->
		<property refid="xdoclet.classpath" name="cp"/>
		<echo message="xdoclet.classpath: ${cp}"/>
	
		<!-- define ejbdoclet task -->
		<taskdef classname="xdoclet.modules.ejb.EjbDocletTask" classpathref="xdoclet.classpath" name="ejbdoclet"/>
	
		<!-- run ejbdoclet -->
		<ejbdoclet destdir="${destdir}">
			<fileset includes="**/*Bean.java" dir="${basedir}/src/main/java"/>
			<remoteinterface/>
		</ejbdoclet>

	</target>
</project>

When executed directly from command (ant -Dmaven.repository=/home/javor/.m2/repository) it works fine. But fails when embedded in antrun:

<plugin>
        <artifactId>maven-antrun-plugin</artifactId>
        <version>1.2-SNAPSHOT</version>
        <executions>
          <execution>
            <phase>generate-sources</phase>
            <goals>
              <goal>run</goal>
            </goals>
            <configuration>
            	<tasks>
                	<ant inheritRefs="true" inheritall="true" antfile="build.xml">
                		<property name="maven.repository" value="${settings.localRepository}"/>
                	</ant>
            	</tasks>
            </configuration>
          </execution>
        </executions>
</plugin>

Maven output:

...
[INFO] [antrun:run {execution: default}]
[INFO] Executing tasks
 
run:
[INFO] ------------------------------------------------------------------------
[ERROR] BUILD ERROR
[INFO] ------------------------------------------------------------------------
[INFO] Error executing ant tasks
 
Embedded error: The following error occurred while executing this line:
/home/javor/workspace/testcase/build.xml:26: Can't create a remoteinterface element under ejbdoclet. Make sure the jar file containing the corresponding subtask class is on the classpath specified in the <taskdef> that defined {2}.
...

Could you show me any workaround or put a bit of light on that problem?

Issue Links

Activity

Hide
Dan Tran added a comment -

when set refid="maven.plugin.classpath" in taskdef,
maven throws this error

Reference maven.plugin.classpath not found.

Show
Dan Tran added a comment - when set refid="maven.plugin.classpath" in taskdef, maven throws this error Reference maven.plugin.classpath not found.
Hide
Dan Tran added a comment -

work around of refid. Here is the discussion on maven user list

think you have two problems - first, I don't think you can use the
reference directly in your ant script (though I don't know why).
Instead, you need to de-reference by setting it to a property value.
Something like this:

<property name="cp1"
refid="maven.dependency.classpath"/>
<echo message="maven.dependency.classpath is ${cp1}"/>
<echo message=""/>

<property name="cp2" refid="maven.compile.classpath"/>
<echo message="maven.compile.classpath is ${cp2}"/>
<echo message=""/>

<property name="cp3" refid="maven.runtime.classpath"/>
<echo message="maven.runtime.classpath is ${cp3}"/>
<echo message=""/>

<property name="cp4" refid="maven.test.classpath"/>
<echo message="maven.test.classpath is ${cp4}"/>
<echo message=""/>

<property name="cp5" refid="maven.plugin.classpath"/>
<echo message="maven.plugin.classpath is ${cp5}"/>
<echo message=""/>

Secondly, you appear to want a directory value (perhaps basedir?),
rather than a path-like structure like the classpath.

Hope this is helpful...

-Margaret

Show
Dan Tran added a comment - work around of refid. Here is the discussion on maven user list think you have two problems - first, I don't think you can use the reference directly in your ant script (though I don't know why). Instead, you need to de-reference by setting it to a property value. Something like this: <property name="cp1" refid="maven.dependency.classpath"/> <echo message="maven.dependency.classpath is ${cp1}"/> <echo message=""/> <property name="cp2" refid="maven.compile.classpath"/> <echo message="maven.compile.classpath is ${cp2}"/> <echo message=""/> <property name="cp3" refid="maven.runtime.classpath"/> <echo message="maven.runtime.classpath is ${cp3}"/> <echo message=""/> <property name="cp4" refid="maven.test.classpath"/> <echo message="maven.test.classpath is ${cp4}"/> <echo message=""/> <property name="cp5" refid="maven.plugin.classpath"/> <echo message="maven.plugin.classpath is ${cp5}"/> <echo message=""/> Secondly, you appear to want a directory value (perhaps basedir?), rather than a path-like structure like the classpath. Hope this is helpful... -Margaret
Hide
Kenney Westerhof added a comment -

First, use the xdoclet-maven-plugin. It's an extension to the antrun plugin that contains all
the needed xdoclet dependencies.

Second, you only need to put a path reference in a property to be able to print it; using it in a refid= / classpathref attribute in
an ant task should work just fine, which it does, since the ejbdoclet is recognized, just not the remoteinterface tag.

I've tried to reproduce this issue, but the first failure was that xjavadoc/xjavadoc/.. couldn't be found.
The groupId for xjavadoc is xdoclet, so i replaced xjavadoc/xjavadoc by xdoclet/xjavadoc and it worked fine.

I get the idea that your xdoclet jars are corrupt or of the wrong version. Can you check that

 unzip -l ~/.m2/repository/xdoclet/xdoclet-ejb-module/1.2.3/xdoclet-ejb-module-1.2.3.jar|grep xdoclet.modules.ejb.intf.RemoteInterfaceSubTask

produces output?

Show
Kenney Westerhof added a comment - First, use the xdoclet-maven-plugin. It's an extension to the antrun plugin that contains all the needed xdoclet dependencies. Second, you only need to put a path reference in a property to be able to print it; using it in a refid= / classpathref attribute in an ant task should work just fine, which it does, since the ejbdoclet is recognized, just not the remoteinterface tag. I've tried to reproduce this issue, but the first failure was that xjavadoc/xjavadoc/.. couldn't be found. The groupId for xjavadoc is xdoclet, so i replaced xjavadoc/xjavadoc by xdoclet/xjavadoc and it worked fine. I get the idea that your xdoclet jars are corrupt or of the wrong version. Can you check that
 unzip -l ~/.m2/repository/xdoclet/xdoclet-ejb-module/1.2.3/xdoclet-ejb-module-1.2.3.jar|grep xdoclet.modules.ejb.intf.RemoteInterfaceSubTask
produces output?
Hide
Brian Yoffe added a comment -

I can explain, I think, why you are getting the error, but I cannot provide a solution.

Basically, if you look at the ModuleFinder class inside of xdoclet, you'll find the following code:

91 public static void initClasspath(Class clazz)
92 {
93 if (System.getProperty("xdoclet.class.path") == null) {
94 try { 95 classpath = ((AntClassLoader) clazz.getClassLoader()).getClasspath(); 96 }
97 catch (ClassCastException e) { 98 classpath = System.getProperty("java.class.path"); 99 }
100 }
101 else { 102 classpath = System.getProperty("xdoclet.class.path"); 103 }
104 }

This initialized classpath with a list of jars, which are then cracked open in ModuleFinder.findModules.
Here, META-INF/xdoclet.xml is opened, if found, and modules, such as ejbdoclet are added to xdoclet. Basically, "java.class.path"
contains only the classworlds-1.1.jar, so no modules get added.

An option might be to set the xdoclet.class.path system property prior to executing this to the plugin classpath, but I dont know how to:
1) Set a system property from a maven pom
2) Set a system property using ant

Further, I'm not confident that it's a good idea to set system properties in this fashion.

The right approach, I think, would be to use the xdoclet maven plugin, however, you cannot use the xdoclet plugin with the antrun plugin, which is very problematic.

This can be found at http://jira.codehaus.org/browse/MANTRUN-37

Show
Brian Yoffe added a comment - I can explain, I think, why you are getting the error, but I cannot provide a solution. Basically, if you look at the ModuleFinder class inside of xdoclet, you'll find the following code: 91 public static void initClasspath(Class clazz) 92 { 93 if (System.getProperty("xdoclet.class.path") == null) { 94 try { 95 classpath = ((AntClassLoader) clazz.getClassLoader()).getClasspath(); 96 } 97 catch (ClassCastException e) { 98 classpath = System.getProperty("java.class.path"); 99 } 100 } 101 else { 102 classpath = System.getProperty("xdoclet.class.path"); 103 } 104 } This initialized classpath with a list of jars, which are then cracked open in ModuleFinder.findModules. Here, META-INF/xdoclet.xml is opened, if found, and modules, such as ejbdoclet are added to xdoclet. Basically, "java.class.path" contains only the classworlds-1.1.jar, so no modules get added. An option might be to set the xdoclet.class.path system property prior to executing this to the plugin classpath, but I dont know how to: 1) Set a system property from a maven pom 2) Set a system property using ant Further, I'm not confident that it's a good idea to set system properties in this fashion. The right approach, I think, would be to use the xdoclet maven plugin, however, you cannot use the xdoclet plugin with the antrun plugin, which is very problematic. This can be found at http://jira.codehaus.org/browse/MANTRUN-37
Hide
Frédéric Chuong added a comment -

Here is how to define the system property from Antrun before the XDoclet task:

<script language="beanshell" classpathref="maven.plugin.classpath" manager="bsf" setbeans="false"><![CDATA[

    // workaround for XDoclet dependency on AntClassLoader

    System.setProperty(
        "xdoclet.class.path",
        project.getReference("maven.plugin.classpath").toString()
    );

]]></script>

<taskdef name="webdoclet" classname="xdoclet.modules..." classpathref="maven.plugin.classpath"/>

<webdoclet ...>
   ...
</webdoclet>

Of course you need to add the required bsf/bsh/ant... dependencies to the plugin dependencies.

Show
Frédéric Chuong added a comment - Here is how to define the system property from Antrun before the XDoclet task:
<script language="beanshell" classpathref="maven.plugin.classpath" manager="bsf" setbeans="false"><![CDATA[

    // workaround for XDoclet dependency on AntClassLoader

    System.setProperty(
        "xdoclet.class.path",
        project.getReference("maven.plugin.classpath").toString()
    );

]]></script>

<taskdef name="webdoclet" classname="xdoclet.modules..." classpathref="maven.plugin.classpath"/>

<webdoclet ...>
   ...
</webdoclet>
Of course you need to add the required bsf/bsh/ant... dependencies to the plugin dependencies.
Hide
Benson Margulies added a comment -

The EJB plugin requires additional dependencies on ant which are not included in the plugin classpath by default. Add them to the plugin execution with <dependency> elements.

Show
Benson Margulies added a comment - The EJB plugin requires additional dependencies on ant which are not included in the plugin classpath by default. Add them to the plugin execution with <dependency> elements.

People

Vote (8)
Watch (6)

Dates

  • Created:
    Updated:
    Resolved: