jsonschema2pojo
jsonschema2pojo copied to clipboard
Add support for maven toolchains
https://maven.apache.org/guides/mini/guide-using-toolchains.html
We ran into a wall recently with applications transitioning from java8 to java11 because we make use of maven toolchains. However, jsonschema2pojo fails because it doesn't support toolchains and tries to operate on the wrong version of java. To reproduce this scenario you must have your default java be set to java 8 and have configured compiler to java 11 via toolchains. In this case, jsonschema2pojo will fail with the following error:
02:52:27 [ERROR] Failed to execute goal org.jsonschema2pojo:jsonschema2pojo-maven-plugin:1.0.1:generate (default) on project foo: Execution default of goal org.jsonschema2pojo:jsonschema2pojo-maven-plugin:1.0.1:generate failed: An API incompatibility was encountered while executing org.jsonschema2pojo:jsonschema2pojo-maven-plugin:1.0.1:generate: java.lang.UnsupportedClassVersionError: com/example/Example has been compiled by a more recent version of the Java Runtime (class file version 55.0), this version of the Java Runtime only recognizes class file versions up to 52.0
02:52:27 [ERROR] -----------------------------------------------------
02:52:27 [ERROR] realm = plugin>org.jsonschema2pojo:jsonschema2pojo-maven-plugin:1.0.1
02:52:27 [ERROR] strategy = org.codehaus.plexus.classworlds.strategy.SelfFirstStrategy
02:52:27 [ERROR] urls[0] = file:/home/jenkins/.m2/repository/org/jsonschema2pojo/jsonschema2pojo-maven-plugin/1.0.1/jsonschema2pojo-maven-plugin-1.0.1.jar
Do you have any idea what change is actually needed in this project? It's not clear to me why (in the error you pasted) the jsonschema2pojo plugin generate
goal is trying to access a compiled class com/example/Example
.
The issue is that because this plugin doesn’t support toolchains that it simply uses the JDK that’s set by your default shell. Typically JAVA_HOME.
So when your default is java 8 and you have a toolchains setup to be java11 for everything in your maven project then it fails with this error.
There’s some specific logic needed in your maven plugin to support toolchains. You’d need to look at some existing plugins that already support toolchains for an example.
The compiled class com/example/Example was compiled by java 11. My default jdk is java8 and my toolchains is set to java11. This compiled class is referenced in the json schema that’s being used to generate new code with this plugin. If this plugin supported toolchains then it would work.
The only other work around is to make sure your default jdk is always newer than any referenced class file but that’s not always possible. It’s sometimes necessary to support transition periods where you’re mixing java versions in a sane way to allow for migration from one to the other. That’s where toolchains helps.
I'm wondering if the problem here is actually that we are reading class files when we have no need to do so. How exactly is the Example class referenced in your schema? And what version of jsonschema2pojo are you using?
I have so far failed to ascertain how tool chains would be supported. My guess is that we need to use a different class loader, provided by Maven (one that's populated with compiled classes appropriate to the current active toolchain). However, I also wonder if we are loading a class files when we actually don't need to. If we encounter existingJavaType (for instance) we can use the fully qualified name directly without loading the class.
Been playing around with this for a bit. I've tried several versions of jsonschema2pojo (0.4.22, 0.5.1, 1.0.2) and they all exhibit this behavior. If I force-change (locally) the JAVA_HOME to be Java 11, as @brentryan alludes to, it builds, but that's actually forcing the incorrect behavior for other things that should depend on Java 8.
existingJavaType is great, and resolved my external Java class problem, too, but that's not related to the toolchain.
I recently discovered maven toolchains, and it's especially useful with new java versions dropping every month. However I'm facing this issue as well. To possibly answer your question @joelittlejohn: In my case the class being loaded is the custom annotator class, which is being compiled with a newer version of java than the one the maven build process is running and thus jsonschema2pojo is using. I also agree with your guess that the class loader will need to be changed to the one of the java version provided by the maven toolchain.
Leaving some references for toolchain support being added:
- https://github.com/spring-projects/spring-boot/pull/18732
- https://maven.apache.org/plugins/maven-toolchains-plugin/toolchains/custom.html
I would be open to contributing the relevant changes if that's alright.