Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Support schema bindings on Java 9 #120

Closed
nipafx opened this issue Apr 26, 2017 · 83 comments
Closed

Support schema bindings on Java 9 #120

nipafx opened this issue Apr 26, 2017 · 83 comments
Assignees
Milestone

Comments

@nipafx
Copy link
Contributor

nipafx commented Apr 26, 2017

When running on Java 9, schema bindings are apparently not applied - instead the XSD's namespace is used to determine the package.

Description

It makes no difference whether this block is present in the XSD...

<xsd:annotation>
	<xsd:appinfo>
		<jaxb:schemaBindings>
			<jaxb:package name="com.pany.pack.age" />
		</jaxb:schemaBindings>
	</xsd:appinfo>
</xsd:annotation>

... or this block in a bindings.xjb ...

<jaxb:bindings schemaLocation="that/other/schema.xsd" node="/xsd:schema">
	<jaxb:schemaBindings>
		<jaxb:package name="com.pany.pack.age" />
	</jaxb:schemaBindings>
</jaxb:bindings>

... in both cases, the binding is ignored.

Experiments

I observed that the xjc command line tool in Java 8 and 9 exhibits the expected behavior and that the difference between the Maven run on Java 8 and 9 was that the former uses rt.jar as JAXB API, while the latter uses the plugin's dependency javax.xml.bind:jaxb-api.

It took me a while but eventually I got the Java 9 Maven build to say Java JAXB API is loaded from the [jrt:/java.xml.bind], i.e. it used the Java 9 module java.xml.bind but that still didn't do the job.

Sources

Maybe one of these can help (I'm shooting in the dark here, could be utterly irrelevant):

  • JEP 255 (merges Selected Xerces 2.11.0 Updates into JAXP)
  • JEP 268 (develops a standard XML Catalog API that supports the OASIS XML Catalogs standard, v1.1)
  • Apache Camel had another issue and "resolved" it by using org.apache.cxf:cxf-xjc-plugin instead - maybe they're doing something differently?

Related to #114.

@highsource
Copy link
Owner

Java 9 is generally not supported yet.

@highsource
Copy link
Owner

See also #114.

@nipafx
Copy link
Contributor Author

nipafx commented Apr 27, 2017

The question is whether that will change. 😃 (And if so, when.)

@aggregat4
Copy link

@highsource Hi Lexi! Boris from Disy here. Do you already have a plan for Java 9 compatibility? Is there any way we can support work on this? (Bounty, Contract work, ...) Or if you have any pointers to potentially necessary implementation changes we could evaluate whether we can invest some time into it.

@highsource
Copy link
Owner

@aggregat4 Hi Boris. :)

I don't have any plans for Java 9 yet, so I can't say anything specific. :(

I think the best would be if some of your devs could check what the specific problems with Java 9 are. We could then think of how to solve them.

@nipafx
Copy link
Contributor Author

nipafx commented May 26, 2017

I looked at this long and hard together with @aggregat4 but we did not make any meaningful progress on the plugin. What we found out:

  • the xjc command line tool works on Java 8 and Java 9 as expected
  • the API used by the plugin (org.glassfish.jaxb:jaxb-xjc:2.2.11) works as expected if updated to Java 9 compatible version org.glassfish.jaxb:jaxb-xjc-jdk9:2.3.0-b170127.1453
  • using that version with the plugin does not work

As it stands I assume I am not using the API in the exact same way as the plugin does (although I tried to copy it). Maybe you can have a look? These two projects might help:

@aggregat4
Copy link

@highsource our current state of investigation on this issues is the following:

  • As noted by @nicolaiparlog above we have created a testcase to demonstrate that the issue exists for the plugin
  • We were not able to reproduce the issue by making a small test program that uses the XJC API in a way that is similar to how the jaxb2 plugin does it
  • We debugged the jaxb2 pluging trying to identify a potential cause for the difference in behaviour, but were sadly unsuccessful

Our question now is: Could we count on some support from your side to assist in identifying the problem? Would there be any way to motivate you to do this (monetary? cake? ;) )? If so, when would you have time?

If you don't see a possibility there, we will probably write a minimal maven plugin ourselves that just shells out to the XJC command line tool.

@highsource
Copy link
Owner

This will be solved (no additional motivation required), but I can't promise a specific date.
I'll prioritize it over other tasks.

To be sure - the specific problem you have is that bindings not applied, correct?

@nipafx
Copy link
Contributor Author

nipafx commented Jun 28, 2017

That's great news! 😃

To be sure - the specific problem you have is that bindings not applied, correct?

Yes. I just opened #126 to share what I've got so far, including a test case showing that class and package names are ignored. The binding generating is...Set methods is ignored as well (not visible in that PR).

@highsource
Copy link
Owner

I am positively puzzled. Bindings seem to be processed (wrong element names produce an error) but not applied.

@highsource
Copy link
Owner

For some reason when schema is loaded, jaxb:schemaBindings is not parsed to BISchemaBinding. Internally, schema loaded uses JAXB for parsing. so jaxb:schemaBindings should be unmarshalled to BISchemaBinding, but this is not happening.

Digging further I've found that there are differences in rootMap of the JAXB context. Normally it should be:

{["http://java.sun.com/xml/ns/jaxb","factoryMethod"=com.sun.xml.bind.v2.runtime.ClassBeanInfoImpl@1e8ce150],["http://java.sun.com/xml/ns/jaxb","inlineBinaryData"=com.sun.xml.bind.v2.runtime.ClassBeanInfoImpl@604f2bd2],["http://java.sun.com/xml/ns/jaxb","javaType"=com.sun.xml.bind.v2.runtime.ClassBeanInfoImpl@1d3ac898],["http://java.sun.com/xml/ns/jaxb/xjc","javaType"=com.sun.xml.bind.v2.runtime.ClassBeanInfoImpl@1b73be9f],["http://java.sun.com/xml/ns/jaxb","class"=com.sun.xml.bind.v2.runtime.ClassBeanInfoImpl@628c4ac0],["http://java.sun.com/xml/ns/jaxb","property"=com.sun.xml.bind.v2.runtime.ClassBeanInfoImpl@7b84fcf8],["http://java.sun.com/xml/ns/jaxb/xjc","substitutable"=com.sun.xml.bind.v2.runtime.ClassBeanInfoImpl@30b19518],["http://java.sun.com/xml/ns/jaxb","globalBindings"=com.sun.xml.bind.v2.runtime.ClassBeanInfoImpl@363042d7],["http://java.sun.com/xml/ns/jaxb","typesafeEnumMember"=com.sun.xml.bind.v2.runtime.ClassBeanInfoImpl@366ac49b],["http://java.sun.com/xml/ns/jaxb","schemaBindings"=com.sun.xml.bind.v2.runtime.ClassBeanInfoImpl@6ad59d92],["http://www.w3.org/2001/XMLSchema","annotation"=com.sun.xml.bind.v2.runtime.ClassBeanInfoImpl@56f0cc85],["http://java.sun.com/xml/ns/jaxb","dom"=com.sun.xml.bind.v2.runtime.ClassBeanInfoImpl@62e20a76],["http://java.sun.com/xml/ns/jaxb/xjc","dom"=com.sun.xml.bind.v2.runtime.ClassBeanInfoImpl@2cc44ad],["http://java.sun.com/xml/ns/jaxb","typesafeEnumClass"=com.sun.xml.bind.v2.runtime.ClassBeanInfoImpl@44b3606b]}

But it is:

{["","factoryMethod"=com.sun.xml.bind.v2.runtime.ClassBeanInfoImpl@5f7eee96],["","inlineBinaryData"=com.sun.xml.bind.v2.runtime.ClassBeanInfoImpl@3a36cd5],["","javaType"=com.sun.xml.bind.v2.runtime.ClassBeanInfoImpl@53f0d09c],["http://java.sun.com/xml/ns/jaxb/xjc","javaType"=com.sun.xml.bind.v2.runtime.ClassBeanInfoImpl@47acd13b],["","class"=com.sun.xml.bind.v2.runtime.ClassBeanInfoImpl@6f8e9d06],["","property"=com.sun.xml.bind.v2.runtime.ClassBeanInfoImpl@77d381e6],["http://java.sun.com/xml/ns/jaxb/xjc","substitutable"=com.sun.xml.bind.v2.runtime.ClassBeanInfoImpl@2272cbb0],["","globalBindings"=com.sun.xml.bind.v2.runtime.ClassBeanInfoImpl@3f6f3cc],["","typesafeEnumMember"=com.sun.xml.bind.v2.runtime.ClassBeanInfoImpl@180b3819],["","schemaBindings"=com.sun.xml.bind.v2.runtime.ClassBeanInfoImpl@733c464f],["http://www.w3.org/2001/XMLSchema","annotation"=com.sun.xml.bind.v2.runtime.ClassBeanInfoImpl@47272cd3],["","dom"=com.sun.xml.bind.v2.runtime.ClassBeanInfoImpl@73fbdf68],["http://java.sun.com/xml/ns/jaxb/xjc","dom"=com.sun.xml.bind.v2.runtime.ClassBeanInfoImpl@32f1fafe],["","typesafeEnumClass"=com.sun.xml.bind.v2.runtime.ClassBeanInfoImpl@236eccd1]}

Note that schemaBindings does not have namespace. This is probably the reason why it is not parsed.

Now the question is, why namespaces are missing. Namespace is provided by package-info.java. Maybe it is missing somehow?

@highsource
Copy link
Owner

Indeed,

XmlSchema xs = reader().getPackageAnnotation(XmlSchema.class,clazz,this);

Returns null.
Obviously the reader somehow does not return the @XmlSchema package annotation, probably can't read package-info.class for whatever reason.

highsource added a commit that referenced this issue Jul 3, 2017
com.sun.tools.xjc.reader.xmlschema.bindinfo.package-info package.
@highsource
Copy link
Owner

@nicolaiparlog
@aggregat4

Seems like I've managed to fix it. I guess there was a classloader issue which prevented annotations from com.sun.tools.xjc.reader.xmlschema.bindinfo.package-info to be loaded properly.

I've added preloading of this packaged and it worked. Now I can build the java-9 test project on JDK 9.

Please check if this works for you (build from the java-9 branch).

Don't close yet, I want to check why episode fails. But not today.

@nipafx
Copy link
Contributor Author

nipafx commented Jul 6, 2017

I tried your changes (more precisely 1948a6b) and it indeed passes the test I wrote. Using it on the actual project failed, though:

[ERROR] : Provider class com.sun.xml.bind.v2.ContextFactory could not be instantiated:
javax.xml.bind.JAXBException: ClassCastException: attempting to cast
jar:file:/home/parlog/.m2/repository/javax/xml/bind/jaxb-api/2.3.0-b170201.1204/jaxb-api-2.3.0-b170201.1204.jar!/javax/xml/bind/JAXBContext.class
to jrt:/java.xml.bind/javax/xml/bind/JAXBContext.class.
Please make sure that you are specifying the proper ClassLoader.

I did not have time to look into it yet or to reproduce it with a simple test case. Do you have an idea what could be going on here?

@nipafx
Copy link
Contributor Author

nipafx commented Jul 14, 2017

By and large it looks good, but the problem above (as well as another one) persist. I hope to have some time next week to create a minimal, self-contained demonstration.

@highsource
Copy link
Owner

would be great

@estronque
Copy link

I found a similar problem about the schema bindings are apparently not applied. If same xsd file has several point in the filename for example STRANGE_PREFIX.FILE_NAME.XSD the xjc work but not applied the globalBindings like choiceContentProperty. I tested with java8 and java7.

@nipafx
Copy link
Contributor Author

nipafx commented Aug 1, 2017

To give some context, we have 95 Maven projects that use this plugin, 71 of which rely on bindings. Before I opened this issue we could build the 24 non-binding projects. With your changes, we could build 68 of the remaining 71. 👍

Class Cast Exception

One of the remaining three projects threw the error above:

[ERROR] : Provider class com.sun.xml.bind.v2.ContextFactory could not be instantiated:
javax.xml.bind.JAXBException: ClassCastException: attempting to cast
jar:file:/home/parlog/.m2/repository/javax/xml/bind/jaxb-api/2.3.0-b170201.1204/jaxb-api-2.3.0-b170201.1204.jar!/javax/xml/bind/JAXBContext.class
to jrt:/java.xml.bind/javax/xml/bind/JAXBContext.class.
Please make sure that you are specifying the proper ClassLoader.

It took me a while to figure out that the easiest fix is to no longer add the java.xml.bind module to the Maven process. It's required with 0.13.2 but I assume the update to jaxb-api-2.3.0-b170201.1204 made that unnecessary. It's weird that the clash only happened in one project (it's the JAXB-heaviest, though) but I didn't investigate why.

Stubborn Bindings

In the two remaining projects the plugin continued to not honor the bindings. We spent some time looking at it but eventually pulled the plug and just made it work without them (it was just about a handful isSet... methods). I did not generate a self-contained example, so I can't really provide further information.

There is another project that is even heavier on JAXB, though, so I may have to face the music eventually. In that case, I'll be back with more information.

What Now?

Bindings generally work now and I'm happy with the situation. 😃 I think this issue can be closed once the solution is merged into master. I would file any further problems as a bug then.

@dzmitryh
Copy link

Hey folks, thanks at first for your efforts to make it complaint with java 9.
However even with plugin that built from java 9 branch(correct me if I'm wrong it haven't released yet) I'm getting this:

ERROR] Failed to execute goal org.jvnet.jaxb2.maven2:maven-jaxb2-plugin:0.13.3-SNAPSHOT:generate (default) on project some-project: Execution default of goal org.jvnet.jaxb2.maven2:maven-jaxb2-plugin:0.13.3-SNAPSHOT:generate failed: Prefix '' is already bound to '' -> [Help 1]

any clues what I can do with it ?

@nipafx
Copy link
Contributor Author

nipafx commented Feb 18, 2018

That problem has something to do with episode files. I have no clue what those are and what they're used to, but the solution is to put <epsiode>false</episode> into the plugin configuration. (Sorry for not being more precise, I don't have it in front of me right now.)

@dzmitryh
Copy link

@nicolaiparlog thx for the tip. Applied your suggestion and it works! Thx a lot.

@dzmitryh
Copy link

@highsource Hi again. Just a quick question. Are there any plans to release java-9 branch of this plugin ? Thx in advance.

@highsource
Copy link
Owner

In principle, yes, I consider adding Java 9 support.

@highsource
Copy link
Owner

There's progress. Build under Java 9 slowly starts to work. Most of the project can be build under Java 9 now, around half of the test projects work. I'll continue working on it the next days.

@highsource
Copy link
Owner

@nicolaiparlog @ptahchiev @aznan2 Please try building the maste branch under Java 9:

mvn clean install -Pall -DperformRelease

Works for me now.

@aznan2
Copy link

aznan2 commented May 21, 2018

The build works using a normal mvn clean install, but fails when adding the -Pall-flag: https://gist.github.com/aznan2/290dc67df51893db21e06a1d9a2eee12

@highsource
Copy link
Owner

@aznan2 Hm, I wonder how comes that you have 0.9.2-SNAPSHOT as version in the failing test project.

[ERROR] Error resolving dependency resource [Dependency {groupId=org.jvnet.jaxb2.maven2, artifactId=maven-jaxb2-plugin-tests-MAVEN_JAXB2_PLUGIN-53-a, version=0.9.2-SNAPSHOT, type=jar, classifier=null, resource=a.xsd}].

@aznan2
Copy link

aznan2 commented May 21, 2018

@highsource It seems the catalog file in tests/MAVEN_JAXB2_PLUGIN-53/b/src/main/resources/catalog.cat contains the line

PUBLIC "http://maven-jaxb2-plugin/samples/episode/a" "maven:org.jvnet.jaxb2.maven2:maven-jaxb2-plugin-tests-MAVEN_JAXB2_PLUGIN-53-a:jar::0.9.2-SNAPSHOT!/a.xsd"

If I change 0.9.2 to 0.14.0 the build works.

highsource added a commit that referenced this issue May 21, 2018
@highsource
Copy link
Owner

@aznan2 Ah, right. Then it's clear why it's failing for you and not for me: I've got this snapshot version from the (very) old builds. I've corrected this, please try again.

@aznan2
Copy link

aznan2 commented May 21, 2018

@highsource Yes, it works now. Woo!

@kevemueller
Copy link

Just compiled master inside Eclipse with JDK10 and am using it in my project. Both manual as well as automated (m2e) runs are working fine. The bindings.jxb file is properly applied.
Thanks for all the hard work you have put into this project!

Initial issues with the automated run (m2e) I could fix by replacing
--add-modules=ALL-SYSTEM (throws API incompatibility exception as rt loads bundled jaxb)
to
--add-modules=java.xml.ws.annotation (otherwise Eclipse won't start)

I suggest you push a release, so you get a wider coverage of bugs.

highsource added a commit that referenced this issue May 31, 2018
highsource added a commit that referenced this issue May 31, 2018
highsource added a commit that referenced this issue May 31, 2018
highsource added a commit that referenced this issue May 31, 2018
@highsource highsource modified the milestones: 0.14.x, 0.14.0 May 31, 2018
highsource added a commit that referenced this issue May 31, 2018
highsource added a commit that referenced this issue May 31, 2018
@adlmez
Copy link

adlmez commented May 31, 2018

+1

@adlmez
Copy link

adlmez commented May 31, 2018

Thanks a lot !

@highsource
Copy link
Owner

@aggregat4 @paroxysm @adlmez @aznan2 @kevemueller

I've just released maven-jaxb2-plugin version 0.14.0 to the Central Maven Repo. Will appear there in an hour or so.

Please test it. maven-jaxb2-plugin or maven-jaxb23-plugin should work under Java 9 as well as 1.7 and 1.8.

maven-jaxb20-plugin, maven-jaxb22-plugin, maven-jaxb22-plugin should work under 1.7 and 1.8.

Java 1.6 is no longer supported.

@paroxysm
Copy link

@highsource cheers, will test soon.

@dmostert-gresham
Copy link

Hi Guys,

@highsource is multiple namespaces supported at the moment? Also, one importing another?

If so, do I need a special setting to enable it?

@highsource
Copy link
Owner

@divanmostert Multiple namespaces should be no problem. Do you experience any difficulties? Please open a separate issue if you do.

@dmostert-gresham
Copy link

Ok, thanks - just scaling down my problem, so will be in touch if I can't resolve it.

@pnabbefeld
Copy link

pnabbefeld commented Sep 27, 2018

Hello, just stumbling in because I've got an error message because of "com.sun.org.apache.xml.internal.resolver.tools.CatalogResolver" being unaccessible as a superclass of MavenCatalogResolver - the internal class is not exported within Java 9 by default, and it seems it's no more available in JDK10 (looked only at src.jar, as I don't really use it, yet).

For JDK 9, I added these parameters to .mvn/jvm.config:
--add-opens java.base/java.lang=ALL-UNNAMED
--add-exports java.xml/com.sun.org.apache.xml.internal.resolver.tools=ALL-UNNAMED
--add-exports java.xml/com.sun.org.apache.xml.internal.resolver=ALL-UNNAMED
--illegal-access=deny

Plugin dependency:
<dependency>
<groupId>org.glassfish.jaxb</groupId>
<artifactId>jaxb-xjc-jdk9</artifactId>
<version>2.3.0.1</version>
</dependency>

This combination works for me (I know, the dependency is mentioned in the thread before, but so it's easier to copy for others looking here for support ;-) )

@darmbrust
Copy link

Just in case anyone stumbles over this bug, while trying to figure out their unexpected element (uri: errors with JDK 9, 10 or 11, there is something broken in the jdk that is making it ignore the package-info.java file in some cases. This question finally got me to a solution:

https://stackoverflow.com/questions/52157040/jaxb-package-info-ignored-when-using-java-10

and the magic solution, if you are using this plugin:

<packageLevelAnnotations>false</packageLevelAnnotations>

since there seems to be a nasty regression in the jdk, or something about how maven is setting up the classloader when I run my code inside a mojo.

For me, the kicker was I could unmarshal my XML using classes generated from schema by maven, if I ran my code within eclipse. But, if I ran my code as a maven plugin, it failed. The way they are searching for the package-info.java file doesn't work when the classes are loaded by the maven class loader.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
Development

No branches or pull requests