Thursday, May 5, 2016

Trouble with maven-jaxb2-plugin and Eclipse?

Does your build work with plain mvn but won't build in Eclipse (Mars.2)? Does the project fail with:

"Execution default of goal org.jvnet.jaxb2.maven2:maven-jaxb2-plugin:0.13.1:generate failed: A required class was missing while executing org.jvnet.jaxb2.maven2:maven-jaxb2-plugin:0.13.1:generate: com/sun/xml/bind/api/ErrorListener"
The reason for this is that there are two dependencies;

org.glassfish.jaxb:jaxb-xjc:jar:2.2.11

and
org.glassfish.jaxb:jaxb-runtime:jar:2.2.11


have a "malformed" parent pom. If you check the Eclipse error log it may have an error message like:

"The POM for org.glassfish.jaxb:jaxb-xjc:jar:2.2.11 is invalid, transitive dependencies (if any) will not be available, enable debug logging for more details"
The reason for this is the following section from their shared parent; com.sun.xml.bind.mvn:jaxb-parent:pom:2.2.11 :

   <profile>
            <id>default-tools.jar</id>
            <activation>
                <file>
                    <exists>${java.home}/../lib/tools.jar</exists>
                </file>
            </activation>
            <properties>
                <tools.jar>${java.home}/../lib/tools.jar</tools.jar>
            </properties>
        </profile>
        <profile>
            <id>default-tools.jar-mac</id>
            <activation>
                <file>
                    <exists>${java.home}/../Classes/classes.jar</exists>
                </file>
            </activation>
            <properties>
                <tools.jar>${java.home}/../Classes/classes.jar</tools.jar>
            </properties>
        </profile>
        <profile>
            <id>default-rt.jar</id>
            <activation>
                <file>
                    <exists>${java.home}/../jre/lib/rt.jar</exists>
                </file>
            </activation>
            <properties>
                <rt.jar>${java.home}/../jre/lib/rt.jar</rt.jar>
            </properties>
        </profile>
        <profile>       <!--todo: remove me-->
            <id>default-rt.jar-mac</id>
            <activation>
                <file>
                    <exists>${java.home}/../Classes/classes.jar</exists>
                </file>
            </activation>
            <properties>
                <rt.jar>${java.home}/../Classes/classes.jar</rt.jar>
            </properties>
        </profile>
where the incorrect java.home variable causes those two dependencies to be not loaded so the jaxb2 plugin won't have the classes to perform schema generation.

The maven environment resolves java.home environment variable from eclipse's JAVA_HOME environment variable which, if eclipse is run with a JRE, points to a non existent library.

To fix this you need to set the JAVA_HOME Environment variable. However it seems like the authors have had their JAVA_HOME point to the <path to JDK>/bin folder so in order to reach the jre and lib folder they had to use .. to get there. However the proper way to set up JAVA_HOME is the root directory of the installation. So either way you'll break something.

To fix this in turn you have to put the following parameter in eclipse.ini after --launcher.appendVmargs:
 
-startup
plugins/org.eclipse.equinox.launcher_1.3.100.v20150511-1540.jar
--launcher.library
plugins/org.eclipse.equinox.launcher.win32.win32.x86_64_1.1.300.v20150602-1417
-product
org.eclipse.epp.package.jee.product
--launcher.defaultAction
openFile
--launcher.XXMaxPermSize
256M
-showsplash
org.eclipse.platform
--launcher.XXMaxPermSize
256m
--launcher.defaultAction
openFile
--launcher.appendVmargs
-vm
<path to JDK>\bin\javaw.exe
-vmargs
-Dosgi.requiredJavaVersion=1.7
-Xms256m
-Xmx1024m

You should use the JDK runtime since it needs the tools.jar and it should be the absolute path.

To check the java_home parameter you can go to Help->About Eclipse->Installation Details button->Configuration tab and look for the java.home parameter. It should be pointing to your JDK installation.

If you only have the JDK installation on your machine you probably won't see this issue. But if you, as I have, a notorious IT department it might happen they install the JRE and your Eclipse installation will run with the JRE version instead for the JDK one. It won't help to put the tools.jar in the project since the plugins runs in a different classloader to prevent them to mix classes and versions with the project they are running in. So the plugin will still fail. Hope it helps!