1

An Ant build executes wsimport prior to creating a jar which includes the generated classes. After upgrading various libraries in the project, to include jaxws, the task which creates the jar fails. The reported error is "Cause: the class org.apache.tools.ant.taskdefs.Jar was not found"

I'm upgrading an old project to use newer versions of various libraries. I've been gradually upgrading the libraries in the project. I perform an Ant build each time to isolate any compile time errors. Thus far the upgrades haven't had a major impact, though the libraries I've replaced are things like logging, e-mail, and etc.

Now I've reached the jaxws libraries. We're coming from version 2.1 and going to 2.2.7. After a few cycles of upgrading the libraries and updating the build file with newer versions, the deployed WAR seems to function correctly as the WSDL is responding.

As part of the build process the service is deployed. Subsequently an Ant task performs wsimport to generate Java classes corresponding to the WSDL. The generated classes are then used to create a jar.

It is here that the process now breaks with an exception from Ant. The first visible exception is "java.lang.ClassNotFoundException: org.apache.tools.ant.util.DateUtils". Running the process again in verbose mode generates "Problem: failed to create task or type jar" as an earlier exception in the trace.

I've fiddled with things like setting ANT_HOME per a post involving jaxb. I've also tried different JDKs - open vs Oracle. Changing various classpath entries in the build file hasn't had a positive effect.

What I have discovered is that I can execute each task independently in the proper sequence. The jar task normally has a depends statement involving the wsimport task. In prior use this worked fine. Now it seems as though the hand-off between the tasks is causing something to break.

I did try integrating the wsimport execution into the jar task. No change. I can't seem to narrow down whether the issue is with the wsimport task, the jar task, or some underlying environment configuration. It's especially strange as various other tasks in the build prior to this point work just fine.

The environment is RHEL 7, open JDK 1.7, ant 1.9.4. I also have an Oracle JDK 1.8 available.

build.xml:

<path id="jaxws.classpath">
    <pathelement location="${java.home}/../lib/tools.jar"/>
    <fileset dir="${jar.dir}">
      <include name="jaxws-tools.jar"/>
    </fileset>
  </path>

<taskdef name="wsimport" classname="com.sun.tools.ws.ant.WsImport">
    <classpath refid="jaxws.classpath"/>
  </taskdef>

  <path id="processing.service.classpath">
    <pathelement location="${java.home}/../lib/tools.jar"/>
    <fileset dir="${jar.dir}">
      <include name="activemq-core-5.4.3.jar"/>
      <include name="jaxb-impl.jar"/>
      <include name="jaxb-xjc.jar"/>
      <include name="jaxrpc.jar"/>
      <include name="jaxws-rt.jar"/>
      <include name="jaxws-tools.jar"/>
      <include name="jms.jar"/>
      <include name="jsr181-api.jar"/>
      <include name="policy.jar"/>
      <include name="slf4j-api-1.7.26.jar"/>
    </fileset>
  </path>

<target name="generate-processing-client" depends="setup">
    <waitfor maxwait="60" maxwaitunit="second">
        <http url="${serviceurl}?wsdl"/>
    </waitfor>
    <wsimport debug="true" verbose="true" keep="true" package="x.x.x.service.processing.client" destdir="${build.classes.dir}" wsdl="${serviceurl}?wsdl">
    </wsimport>
  </target>

<target name="jar-processing-client" depends="generate-processing-client" unless="skip.service.clients">
    <jar basedir="${build.classes.dir}" destfile="${jar.dir}/agard-processing-client.jar" includes="x/x/x/service/processing/client/**"/>
  </target>

Stacktrace:

jar-processing-client:
Caught an exception while logging the end of the build.  Exception was:
java.lang.NoClassDefFoundError: org/apache/tools/ant/util/DateUtils
    at org.apache.tools.ant.DefaultLogger.formatTime(DefaultLogger.java:330)
    at org.apache.tools.ant.DefaultLogger.buildFinished(DefaultLogger.java:177)
    at org.apache.tools.ant.Project.fireBuildFinished(Project.java:2087)
    at org.apache.tools.ant.Main.runBuild(Main.java:872)
    at org.apache.tools.ant.Main.startAnt(Main.java:235)
    at org.apache.tools.ant.launch.Launcher.run(Launcher.java:280)
    at org.apache.tools.ant.launch.Launcher.main(Launcher.java:109)
Caused by: java.lang.ClassNotFoundException: org.apache.tools.ant.util.DateUtils
    at java.net.URLClassLoader$1.run(URLClassLoader.java:360)
    at java.net.URLClassLoader$1.run(URLClassLoader.java:349)
    at java.security.AccessController.doPrivileged(Native Method)
    at java.net.URLClassLoader.findClass(URLClassLoader.java:348)
    at java.lang.ClassLoader.loadClass(ClassLoader.java:430)
    at sun.misc.Launcher$AppClassLoader.loadClass(Launcher.java:323)
    at java.lang.ClassLoader.loadClass(ClassLoader.java:363)
    ... 7 more
There has been an error prior to that:
/home/x/git/x/etc/ant/services/processing.xml:132: Problem: failed to create task or type jar
Cause: the class org.apache.tools.ant.taskdefs.Jar was not found.
Action: Check that the component has been correctly declared
        and that the implementing JAR is in one of:
        -/usr/share/ant/lib
        -/home/x/.ant/lib
        -a directory added on the command line with the -lib argument

Do not panic, this is a common problem.
It may just be a typographical error in the build file or the task/type declaration.
The commonest cause is a missing JAR.

This is not a bug; it is a configuration problem

    at org.apache.tools.ant.UnknownElement.getNotFoundException(UnknownElement.java:499)
    at org.apache.tools.ant.UnknownElement.makeObject(UnknownElement.java:431)
    at org.apache.tools.ant.UnknownElement.maybeConfigure(UnknownElement.java:163)
    at org.apache.tools.ant.Task.perform(Task.java:347)
    at org.apache.tools.ant.Target.execute(Target.java:435)
    at org.apache.tools.ant.Target.performTasks(Target.java:456)
    at org.apache.tools.ant.Project.executeSortedTargets(Project.java:1393)
    at org.apache.tools.ant.Project.executeTarget(Project.java:1364)
    at org.apache.tools.ant.helper.DefaultExecutor.executeTargets(DefaultExecutor.java:41)
    at org.apache.tools.ant.Project.executeTargets(Project.java:1248)
    at org.apache.tools.ant.Main.runBuild(Main.java:851)
    at org.apache.tools.ant.Main.startAnt(Main.java:235)
    at org.apache.tools.ant.launch.Launcher.run(Launcher.java:280)
    at org.apache.tools.ant.launch.Launcher.main(Launcher.java:109)

I've also encountered errors relating to the manifest when I build the entire project. The jar task doesn't define a manifest. Adding manifest entries to the jar task seemed to remove that as an issue. When I execute only the jar task I receive the jar taskdef error above.

Caused by: java.lang.ClassNotFoundException: org.apache.tools.ant.util.DateUtils
    at java.net.URLClassLoader$1.run(URLClassLoader.java:360)
    at java.net.URLClassLoader$1.run(URLClassLoader.java:349)
    at java.security.AccessController.doPrivileged(Native Method)
    at java.net.URLClassLoader.findClass(URLClassLoader.java:348)
    at java.lang.ClassLoader.loadClass(ClassLoader.java:430)
    at sun.misc.Launcher$AppClassLoader.loadClass(Launcher.java:323)
    at java.lang.ClassLoader.loadClass(ClassLoader.java:363)
    ... 7 more
There has been an error prior to that:
/home/x/git/alerting/build.xml:114: The following error occurred while executing this line:
/home/x/git/alerting/build.xml:63: The following error occurred while executing this line:
/home/x/git/alerting/etc/ant/services/processing.xml:132: Could not find default manifest: /org/apache/tools/ant/defaultManifest.mf

Update

I reverted several of the jaxws and jaxb libraries. This returned the build to a working state. I've subsequently added the newer versions of the libraries, each time running the build process. I identified the need to include items like jaxb-core-2.2.7, which oddly aren't available in the jaxws-ri-2.2.7 distribution. There are still issues with the build process as I proceed with upgrading the libraries. The current stack I'm receiving is as follows:

Caused by: java.lang.IllegalAccessError: tried to access field com.sun.xml.bind.marshaller.SAX2DOMEx.nodeStack from class com.sun.tools.ws.wsdl.parser.DOMBuilder
    at com.sun.tools.ws.wsdl.parser.DOMBuilder.comment(DOMBuilder.java:136)

It seems very strange that these errors are occurring during what should be a rather simple jar task.

Update

I've been placing the new libraries in the same folder as the old ones. I thought this may cause an issue with the classpath. I decided to isolate the new libraries from the old by placing them in a separate directory. I copied in the other libraries I haven't yet updated. The issue with Ant still persists. I've isolated it to the wsimport task. I'm wondering if it isn't something to do with the classpath set by the taskdef.

Update

I've been digging through the wsimport Ant task sources. The closest thing I've seen thus far in the call hierarchy resides in WsTask2.java. They're changing the classloader. In tracking this down, it appears that the classpath should be that of the Ant tool. There are cases of reading the java.class.path and few which alter it.

It's still unclear why I'm experiencing this issue in my environment with these versions of software. I looked at the history of this project on github and didn't see any obvious sign of a bug related to this issue being fixed.

        ClassLoader old = Thread.currentThread().getContextClassLoader();
        Thread.currentThread().setContextClassLoader(this.getClass().getClassLoader());
        try {
            ok = runInVm(getCommandline().getJavaCommand().getArguments(), logstr);
        } finally {
            Thread.currentThread().setContextClassLoader(old);
        }

Update

I've confirmed the issue is not specific to my environment. I moved the source code and libraries to another server which is installed with RHEL 6. The build still fails with the same error.

I went back to my development machine and attempted to replace the JAXWS libraries with a higher version. I tried 2.2.8, 2.2.10, and 2.3.0. Of course with 2.3.0 I had to change to a 1.8 JDK. The issue persists.

  • Check this answer: https://stackoverflow.com/a/27744879/3348112 – CAustin Jul 22 '19 at 22:41
  • RHEL 7 doesn't seem to offer ant-optional. I was able to install all of the other ant libraries like ant-junit. No change to the issue. – falconluvr64 Jul 23 '19 at 15:50
  • FWIW I came across this SO earlier, which made me look at setting ANT_HOME. Prior my environment did not define that setting. https://stackoverflow.com/questions/14523042/ant-cant-find-an-ant-class-dateutils-while-building – falconluvr64 Jul 23 '19 at 15:57
  • I just located this report which indicates "... ProtectedTask from istack-commons is messing up with Ant class loader, so that it can't find its core classes" https://bugzilla.redhat.com/show_bug.cgi?id=1542899 – falconluvr64 Jul 23 '19 at 23:48
  • I know that the contents of istack-commons-runtime.jar is integrated into jaxb-impl.jar. As the bugzilla report indicates ProtectedTask is the cause. Normally that class appears in istack-commons-tools.jar which I don't have in my project. I have located the same classes within jaxb-xjc.jar. – falconluvr64 Jul 24 '19 at 00:02
  • I've been trying to remove jaxb-xjc from the classpath of wsimport. The classpath before the wsimport task is the ant directory. When wsimport executes it seems to determine a different classpath, which is not defined in the build file or explicitly passed as an argument to the task. I'm unable to test if removing ProtectedTask solves the issue. – falconluvr64 Jul 24 '19 at 01:09

0 Answers0