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!

5 comments:

  1. I resolved this issue by removing any JREs from my Eclipse preferences (Java > Installed JREs) and only leaving the selected JDK there. Even though the JREs were not selected, they still cause the issue and have to be removed. I was able to leave the JREs on my system.

    ReplyDelete
    Replies
    1. When the plugin is run, the maven runtime resolves the global variable java.home by asking Eclipse what it is. This variable is set by eclipse on a global level, and if that's a JRE it tries to load the tools.jar and the JRE doesn't have the tools.jar so those dependencies will be "malformed" and thus not load and therefore will the plugin fail.

      Delete
  2. hI,
    I was wondering if could post the location of these files that you use in this post in the eclipse?

    ReplyDelete
    Replies
    1. The only file which you need to change is the eclipse.ini file. The other files are the pom.xml files of those artifacts posted.

      Delete
  3. Thank you very much.it worked for me.

    ReplyDelete