How can I make Ant use JAXB 2.2.x instead of Java

2020-07-28 11:33发布

问题:

I'm in the process of updating a legacy application to use Java 6 SE instead of Java 5 SE. The app uses JAXB, and under Java 5 SE it have the JAXB reference implementation jars on the classpath. When I moved to Java 6 SE (update 38), I hit a few bumps (see linked Stackoverflow question) that I resolved with some help.

So the next thing that is causing trouble is the project Ant build script. When the Ant compile task executes, it picks up the embedded version of JAXB that comes with Java 6 SE rather than the version from the jars that I have included on the classpath (the JAXB 2.2.6 release). I believe Java 6 SE includes JAXB 2.1.x. This is causing compile time error like this:

[javac] location: @interface javax.xml.bind.annotation.XmlElementRef
[javac]     @XmlElementRef(name = "abbrev", type = JAXBElement.class, required = false)

In this case, the 'required' attribute did not exist in for the @XmlElementRef in JAXB 2.1.x, but it does in 2.2.x.

How can I change my Ant build script so that it picks up the JAXB 2.2.6 jars from the build classpath instead of the classes that are packed inside the Java 6 SE JDK?


UPDATE: Solution based on Peter's answer

<target name="compile" depends="clean">
    <javac deprecation="on" 
            classpathref="prj.classpath" 
            srcdir="${src}" 
            destdir="${build.dir}" 
            debug="on" 
            debuglevel="lines,vars,source" 
            source="1.6">
        <compilerarg value="-Djava.endorsed.dirs=${lib.ext.dir}/jaxb"/>
    </javac>
</target>

回答1:

I believe concept of endorsed library folder is your friend.

Namely switch:

<compilerarg value="-Djava.endorsed.dirs=/some/path/lib/endorsed"/>

Those jars present in the endorsed are to be considered prio to any other classes loaded (I believe).

For more complete sample see the correct answer on: How to make Ant prefer classes from a linked JAR over JDK classes?



回答2:

Just add jaxb 2.2 implementation (e.g. jaxb-impl.2.2.5) to the compiler's classpath

<compilerarg value="-cp path_to_jaxb2_jar"/>

that will be enough, JAXB will automatically disover the new JAXB provider by information from jar's META-INF/services/ and use it instead of default internal provider. See JAXBContext.newInstance API "Discovery of JAXB implementation"