Okay, there were two problems here.
First, Commons JXPath 1.2 had a dependency on ant-optional-1.5.1.jar,
which caused the NetBeans ant scripts to run using the JUnit 3.8 test
runner.
Second, ivy-impl.xml was computing the classpath based on every jar it
found in build/jar, and build/jar wasn't being cleaned. So, upgrading
the JXPath dependency to 1.3, which doesn't depend on ant-optional,
didn't fix the problem, unless you knew to also delete ant-
optional-1.5.1.jar from build/jar.
To fix, I upgraded the JXPath dependency to 1.3, and added the
following to build.xml:
<target name="-pre-init" depends="clean-build-libs"/>
<!-- Clean build libs so Ivy doesn't include stale jars in
classpath -->
<target name="clean-build-libs">
<deltree dir="${basedir}/${build.dir}/${lib.dir}"/>
</target>