I decided to investigate how to use jaxb2-maven-plugin 2.4 with Java 11. It’s still not easy to make these things working together but this time I was more lucky (see my previous attempt with Java 10) and here is a ready-to-use receipt how to do it!
Versions
Java version:
$ java --version openjdk 11.0.2 2019-01-15 OpenJDK Runtime Environment 18.9 (build 11.0.2+9) OpenJDK 64-Bit Server VM 18.9 (build 11.0.2+9, mixed mode)
Maven version:
$ mvn --version Apache Maven 3.5.2 Maven home: /usr/share/maven Java version: 11.0.2, vendor: Oracle Corporation Java home: .../jdk-11.0.2 Default locale: pl_PL, platform encoding: UTF-8 OS name: "linux", ..., family: "unix"
pom.xml
With Java 11 (most likely the same would work with Java 10) we need to explicitly add dependencies required to have working JAXB, because many things were removed from Java in version 11:
- project dependecies: JAXB API, JAXB runtime, javax.activation package
- jaxb2-maven-plugin dependencies: xjc, javax.activation package
Moreover we need to explicitly declare some Maven plugins to make sure we’re using latest versions of these plugins which are ready for Java 11.
Please note the <sources> tag in configuration section for jaxb2-maven-plugin. It consists of 2 elements. One is the path to the desired XSD (src/main/xsd/your-file.xsd) – change it according to your requirements. The other element (src/main/xsd/dummy.xsd) is a workaround for some strange issue jaxb2-maven-plugin has when working with Java 11.
<?xml version="1.0" encoding="UTF-8"?> <project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd"> <modelVersion>4.0.0</modelVersion> <groupId>...</groupId> <artifactId>...</artifactId> <version>...</version> <packaging>jar</packaging> <properties> <project.build.sourceEncoding>UTF-8</project.build.sourceEncoding> <maven.compiler.source>11</maven.compiler.source> <maven.compiler.target>11</maven.compiler.target> </properties> <dependencies> ... <dependency> <groupId>javax.xml.bind</groupId> <artifactId>jaxb-api</artifactId> <version>2.3.0</version> </dependency> <dependency> <groupId>org.glassfish.jaxb</groupId> <artifactId>jaxb-runtime</artifactId> <version>2.3.2</version> <scope>runtime</scope> </dependency> <dependency> <groupId>com.sun.activation</groupId> <artifactId>jakarta.activation</artifactId> <version>1.2.1</version> <scope>runtime</scope> </dependency> </dependencies> <build> <plugins> <plugin> <groupId>org.apache.maven.plugins</groupId> <artifactId>maven-compiler-plugin</artifactId> <version>3.8.0</version> <configuration> <release>11</release> </configuration> </plugin> <plugin> <groupId>org.apache.maven.plugins</groupId> <artifactId>maven-surefire-plugin</artifactId> <version>2.22.0</version> <configuration> <argLine>--illegal-access=permit</argLine> </configuration> </plugin> <plugin> <groupId>org.codehaus.mojo</groupId> <artifactId>jaxb2-maven-plugin</artifactId> <version>2.4</version> <executions> <execution> <id>xjc</id> <goals> <goal>xjc</goal> </goals> </execution> </executions> <configuration> <sources> <source>src/main/xsd/dummy.xsd</source> <source>src/main/xsd/your-file.xsd</source> </sources> <packageName>your.package</packageName> </configuration> <dependencies> <dependency> <groupId>org.glassfish.jaxb</groupId> <artifactId>jaxb-xjc</artifactId> <version>2.3.2</version> </dependency> <dependency> <groupId>com.sun.activation</groupId> <artifactId>jakarta.activation</artifactId> <version>1.2.1</version> </dependency> </dependencies> </plugin> </plugins> </build> </project>
Note that without the line 70 (<source>src/main/xsd/dummy.xsd</source>
) the build will fail with the following error:
[ERROR] Failed to execute goal org.codehaus.mojo:jaxb2-maven-plugin:2.4:xjc (xjc) on project ...: Prefix '' is already bound to '' -> [Help 1]
dummy.xsd
As far as I know the content of this file is just:
<xs:schema id="Dummy" xmlns:xs="http://www.w3.org/2001/XMLSchema"> <xs:element name="Dummy"> <xs:complexType> <xs:sequence> <xs:element name="test"/> </xs:sequence> </xs:complexType> </xs:element> </xs:schema>
You need to put this file into src/main/xsd
folder.
And now things are working!!! 🙂 Run maven and make use of model classes generated from XSD file.
The only difference comparing to case when using Java 8 is that now we see these warning messages as the very first lines printed when executing mvn package
command:
WARNING: An illegal reflective access operation has occurred WARNING: Illegal reflective access by com.google.inject.internal.cglib.core.$ReflectUtils$1 (file:/usr/share/maven/lib/guice.jar) to method java.lang.ClassLoader.defineClass(java.lang.String,byte[],int,int,java.security.ProtectionDomain) WARNING: Please consider reporting this to the maintainers of com.google.inject.internal.cglib.core.$ReflectUtils$1 WARNING: Use --illegal-access=warn to enable warnings of further illegal reflective access operations WARNING: All illegal access operations will be denied in a future release
My guess is this is not dangerous and it will be solved by newer Maven release.
You are a genius! Thank you! By the way, I do not need the dummy file.
Thanks! I’ve just put together what others had discovered. BTW: the need for this dummy XSD file may depend on content of your desired XSD file. Anyway, you can switch from jaxb2-maven-plugin to cxf-xjc-plugin and have exactly the same XSD-to-Java processing without any strange workarounds for Java 11 – https://artofcode.wordpress.com/2019/02/28/generating-classes-from-xsd-under-java-11-the-right-way/
Awesome, thank you! This worked for me. But I’m curious as to why the dummy file is needed?
Thank you very much! How do you understand use dummy.xsd?
dummy.xsd is an extra XSD file that you don’t need from your business/domain perspective. Actually I’ve discovered better solution to generate Java classes from XSD file with Maven under Java 11: https://artofcode.wordpress.com/2019/02/28/generating-classes-from-xsd-under-java-11-the-right-way/
In my scenario using “c**.xsd” and “bi**.xjb” files but its not properly generate the class due to not use ‘bi**.xjb’ file.
${schema.dir}
com.t….config.confbeans
${schema.dir}
Please I need to your suggestion.
Try this solution: https://artofcode.wordpress.com/2019/02/28/generating-classes-from-xsd-under-java-11-the-right-way/
Thank you for the tip. I am trying to generate from wsdl file but getting error as my wsdl has “soapenc:arrayType” complext data type. Can you please tell me a way to fix