Closed pvandenbrink closed 9 years ago
I have noticed this CCE too.
It occurs inside the SchemaGenerator, which could mean that the classpath surrounding the SchemaGenerator execution is wrong (or at least not the one expected by SchemaGen). Apparently, the line at com.sun.source.util.Trees.getJavacTrees(Trees.java:88)
produces com.sun.tools.javac.api.JavacTrees
but the calling method expects a com.sun.source.util.Trees
instead.
However, I have not been able to reproduce this error in the Integration Tests. This is probably something repeated elsewhere as well; if other folks have had this problem I would be interested in finding out any potential solutions (i.e. which dependencies are actually required and which are prohibited).
Hey Lennart, I got the same exception. I can send you my maven project in a ZIP file, so you can reproduce it. I work on mac / java8. Thibault.
I have observed this problem whenever schemagen
has difficulty parsing a file as JAX-B. The following class is an example:
package org.testing.xml;
import javax.xml.bind.annotation.XmlElement;
import javax.xml.bind.annotation.XmlRootElement;
@XmlRootElement
public class MyType {
@XmlElement(required = true)
private String name;
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
}
which fails because
Class has two properties of the same name "name"
Another way to reproduce this bug is for schemagen
to attempt to parse files which aren't even supposed to be JAX-B classes.
So .. this CCE seems to occur instead of a normal JAXB exception along the lines of "the annotations on class X are incorrect"?
With my simple test case, Maven generates this error (using the latest 2.2-SNAPSHOT plugin):
Failed to execute goal org.codehaus.mojo:jaxb2-maven-plugin:2.2-SNAPSHOT:schemagen (default) on project test-jaxb:
+=================== [SchemaGenerator Error '<unknown>']
|
| SchemaGen did not complete its operation correctly.
|
| To re-create the error (and get a proper error message), cd to:
| /home/chris/Programs/omnifone/test-jaxb
| ... and fire the following on a command line/in a shell:
|
| schemagen -encoding UTF-8 -d /home/chris/Programs/omnifone/test-jaxb/target/schemagen-work/compile_scope -classpath /home/chris/Programs/omnifone/test-jaxb/src/main/java/ -episode /home/chris/Programs/omnifone/test-jaxb/target/generated-resources/schemagen/META-INF/sun-jaxb.episode src/main/java/org/testing/xml/MyType.java
|
| The following source files should be processed by schemagen:
| 0: file:/home/chris/Programs/omnifone/test-jaxb/src/main/java/org/testing/xml/MyType.java
| 1: file:/home/chris/Programs/omnifone/test-jaxb/src/main/java/org/testing/xml/package-info.java
|
+=================== [End SchemaGenerator Error]: java.lang.AssertionError: java.lang.ClassCastException: com.sun.tools.javac.api.JavacTrees cannot be cast to com.sun.source.util.Trees
-> [Help 1]
Executing the command suggested above produces the following:
$ schemagen -encoding UTF-8 -d /home/chris/Programs/omnifone/test-jaxb/target/schemagen-work/compile_scope -classpath /home/chris/Programs/omnifone/test-jaxb/src/main/java/ -episode /home/chris/Programs/omnifone/test-jaxb/target/generated-resources/schemagen/META-INF/sun-jaxb.episode src/main/java/org/testing/xml/MyType.java
Class has two properties of the same name "name"
this problem is related to the following location:
at org.testing.xml.MyType.getName(src/main/java/org/testing/xml/MyType.java:12)
at org.testing.xml.MyType(src/main/java/org/testing/xml/MyType.java:6)
this problem is related to the following location:
at org.testing.xml.MyType.name(src/main/java/org/testing/xml/MyType.java:9)
at org.testing.xml.MyType(src/main/java/org/testing/xml/MyType.java:6)
So this schemagen
error is the correct one:
Class has two properties of the same name "name"
The ClassCastException
seems to happen when Maven tries to handle this error. Re-running Maven with the -e
switch generates the following stack trace:
at org.codehaus.mojo.jaxb2.schemageneration.AbstractXsdGeneratorMojo.printSchemaGenCommandAndThrowException(AbstractXsdGeneratorMojo.java:798)
at org.codehaus.mojo.jaxb2.schemageneration.AbstractXsdGeneratorMojo.performExecution(AbstractXsdGeneratorMojo.java:445)
at org.codehaus.mojo.jaxb2.AbstractJaxbMojo.execute(AbstractJaxbMojo.java:200)
at org.apache.maven.plugin.DefaultBuildPluginManager.executeMojo(DefaultBuildPluginManager.java:132)
at org.apache.maven.lifecycle.internal.MojoExecutor.execute(MojoExecutor.java:208)
... 19 more
Caused by: java.lang.RuntimeException: java.lang.AssertionError: java.lang.ClassCastException: com.sun.tools.javac.api.JavacTrees cannot be cast to com.sun.source.util.Trees
at com.sun.tools.javac.main.Main.compile(Main.java:553)
at com.sun.tools.javac.api.JavacTaskImpl.doCall(JavacTaskImpl.java:129)
at com.sun.tools.javac.api.JavacTaskImpl.call(JavacTaskImpl.java:138)
at com.sun.tools.jxc.SchemaGenerator$Runner.compile(SchemaGenerator.java:261)
at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:62)
at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)
at java.lang.reflect.Method.invoke(Method.java:497)
at com.sun.tools.jxc.SchemaGenerator.run(SchemaGenerator.java:166)
at org.codehaus.mojo.jaxb2.schemageneration.AbstractXsdGeneratorMojo.performExecution(AbstractXsdGeneratorMojo.java:332)
... 22 more
Caused by: java.lang.AssertionError: java.lang.ClassCastException: com.sun.tools.javac.api.JavacTrees cannot be cast to com.sun.source.util.Trees
at com.sun.source.util.Trees.getJavacTrees(Trees.java:88)
at com.sun.source.util.Trees.instance(Trees.java:77)
at com.sun.tools.jxc.model.nav.ApNavigator.getLocation(ApNavigator.java:451)
at com.sun.tools.jxc.model.nav.ApNavigator.getMethodLocation(ApNavigator.java:420)
at com.sun.tools.jxc.model.nav.ApNavigator.getMethodLocation(ApNavigator.java:83)
at com.sun.xml.bind.v2.model.impl.GetterSetterPropertySeed.getLocation(GetterSetterPropertySeed.java:118)
at com.sun.xml.bind.v2.model.impl.PropertyInfoImpl.getLocation(PropertyInfoImpl.java:328)
at com.sun.xml.bind.v2.runtime.IllegalAnnotationException.convert(IllegalAnnotationException.java:122)
at com.sun.xml.bind.v2.runtime.IllegalAnnotationException.build(IllegalAnnotationException.java:106)
at com.sun.xml.bind.v2.runtime.IllegalAnnotationException.<init>(IllegalAnnotationException.java:79)
at com.sun.xml.bind.v2.model.impl.ClassInfoImpl.link(ClassInfoImpl.java:1275)
at com.sun.xml.bind.v2.model.impl.ModelBuilder.link(ModelBuilder.java:454)
at com.sun.tools.jxc.api.impl.j2s.JavaCompilerImpl.bind(JavaCompilerImpl.java:98)
at com.sun.tools.jxc.ap.SchemaGenerator.process(SchemaGenerator.java:110)
at com.sun.tools.javac.processing.JavacProcessingEnvironment.callProcessor(JavacProcessingEnvironment.java:794)
at com.sun.tools.javac.processing.JavacProcessingEnvironment.discoverAndRunProcs(JavacProcessingEnvironment.java:705)
at com.sun.tools.javac.processing.JavacProcessingEnvironment.access$1800(JavacProcessingEnvironment.java:91)
at com.sun.tools.javac.processing.JavacProcessingEnvironment$Round.run(JavacProcessingEnvironment.java:1035)
at com.sun.tools.javac.processing.JavacProcessingEnvironment.doProcessing(JavacProcessingEnvironment.java:1176)
at com.sun.tools.javac.main.JavaCompiler.processAnnotations(JavaCompiler.java:1170)
at com.sun.tools.javac.main.JavaCompiler.compile(JavaCompiler.java:856)
at com.sun.tools.javac.main.Main.compile(Main.java:523)
... 31 more
Caused by: java.lang.ClassCastException: com.sun.tools.javac.api.JavacTrees cannot be cast to com.sun.source.util.Trees
at com.sun.source.util.Trees.getJavacTrees(Trees.java:86)
... 52 more
My guess would be that there is some kind of dependency issue within the plugin itself. Perhaps a mismatch between the version of JAXB contained within the JDK, the version of JAXB contained within the plugin, and the version(s?) of JAXB required by some of the plugin's other dependencies? Personally, I also suspect that requiring JAXB 2.2.11 is slightly ambitious.
I've managed to get the plugin to build successfully by downgrading to JAXB 2.2.7 and then replacing the Glassfish implementation with:
<dependency>
<groupId>com.sun.xml.bind</groupId>
<artifactId>jaxb-xjc</artifactId>
<version>${jaxb.version}</version>
</dependency>
<dependency>
<groupId>com.sun.xml.bind</groupId>
<artifactId>jaxb-jxc</artifactId>
<version>${jaxb.version}</version>
</dependency>
<dependency>
<groupId>org.jvnet.staxex</groupId>
<artifactId>stax-ex</artifactId>
<scope>test</scope>
</dependency>
However, the resulting plugin then fails with the following exception when building the test project:
Caused by: java.lang.RuntimeException: java.lang.NoClassDefFoundError: com/sun/source/util/Trees
at com.sun.tools.javac.main.Main.compile(Main.java:469)
at com.sun.tools.javac.api.JavacTaskImpl.call(JavacTaskImpl.java:132)
at com.sun.tools.jxc.SchemaGenerator$Runner.compile(SchemaGenerator.java:257)
at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:57)
at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)
at java.lang.reflect.Method.invoke(Method.java:606)
at com.sun.tools.jxc.SchemaGenerator.run(SchemaGenerator.java:163)
at org.codehaus.mojo.jaxb2.schemageneration.AbstractXsdGeneratorMojo.performExecution(AbstractXsdGeneratorMojo.java:332)
... 22 more
Caused by: java.lang.NoClassDefFoundError: com/sun/source/util/Trees
at com.sun.tools.jxc.model.nav.ApNavigator.getLocation(ApNavigator.java:450)
at com.sun.tools.jxc.model.nav.ApNavigator.getMethodLocation(ApNavigator.java:419)
at com.sun.tools.jxc.model.nav.ApNavigator.getMethodLocation(ApNavigator.java:83)
at com.sun.xml.bind.v2.model.impl.GetterSetterPropertySeed.getLocation(GetterSetterPropertySeed.java:118)
at com.sun.xml.bind.v2.model.impl.PropertyInfoImpl.getLocation(PropertyInfoImpl.java:328)
at com.sun.xml.bind.v2.runtime.IllegalAnnotationException.convert(IllegalAnnotationException.java:122)
at com.sun.xml.bind.v2.runtime.IllegalAnnotationException.build(IllegalAnnotationException.java:106)
at com.sun.xml.bind.v2.runtime.IllegalAnnotationException.<init>(IllegalAnnotationException.java:79)
at com.sun.xml.bind.v2.model.impl.ClassInfoImpl.link(ClassInfoImpl.java:1275)
at com.sun.xml.bind.v2.model.impl.ModelBuilder.link(ModelBuilder.java:454)
at com.sun.tools.jxc.api.impl.j2s.JavaCompilerImpl.bind(JavaCompilerImpl.java:98)
at com.sun.tools.jxc.ap.SchemaGenerator.process(SchemaGenerator.java:110)
at com.sun.tools.javac.processing.JavacProcessingEnvironment.callProcessor(JavacProcessingEnvironment.java:793)
at com.sun.tools.javac.processing.JavacProcessingEnvironment.discoverAndRunProcs(JavacProcessingEnvironment.java:722)
at com.sun.tools.javac.processing.JavacProcessingEnvironment.access$1700(JavacProcessingEnvironment.java:97)
at com.sun.tools.javac.processing.JavacProcessingEnvironment$Round.run(JavacProcessingEnvironment.java:1029)
at com.sun.tools.javac.processing.JavacProcessingEnvironment.doProcessing(JavacProcessingEnvironment.java:1163)
at com.sun.tools.javac.main.JavaCompiler.processAnnotations(JavaCompiler.java:1108)
at com.sun.tools.javac.main.JavaCompiler.compile(JavaCompiler.java:824)
at com.sun.tools.javac.main.Main.compile(Main.java:439)
... 30 more
Caused by: java.lang.ClassNotFoundException: com.sun.source.util.Trees
at org.codehaus.plexus.classworlds.strategy.SelfFirstStrategy.loadClass(SelfFirstStrategy.java:50)
at org.codehaus.plexus.classworlds.realm.ClassRealm.unsynchronizedLoadClass(ClassRealm.java:271)
at org.codehaus.plexus.classworlds.realm.ClassRealm.loadClass(ClassRealm.java:247)
at org.codehaus.plexus.classworlds.realm.ClassRealm.loadClass(ClassRealm.java:239)
... 50 more
Do you know where the com.sun.source.util.Trees
class is supposed to be obtained from?
I have been debugging quite a bit inside the SchemaGen sources to try to understand why this CCE even occurs. I would actually suspect that it is the error text collector which plays us the prank. Note that the actual error message is presented on the console in a vaguely tree-like manner.
Will keep on checking internals and get back.
WRT the JAXB RI included in the plugin by default: Since the JAXB RI is not identical to the one used internally within the JDK, I believe it is not so ambitious to use the latest released version. Besides, if users feel like another version of the JAXB RI when executing their XJC or SchemaGen they can simply include that dependency and fire away. This strategy seemed to work fine with the 1.x version of the jaxb2-maven-plugin, but if we find problems that requires fixing we will look at them.
Hm. Ok; will attempt with earlier versions of the RI to see if we can have a better yield with them.
com.sun.source.util.Trees
is an interface in the compiler API to represent Abstract Syntax Trees. The error may actually be related to differing versions of the JDK.
http://docs.oracle.com/javase/7/docs/jdk/api/javac/tree/com/sun/source/tree/Tree.html
Ah. Of course - it is in the tools.jar
.
Will include it in the ClassPath of the plugin and run again.
Dynamically added tools.jar
to the class path of the tool execution.
I have tested the latest checkin (commit 9d98a90) and no ClassCastExceptions were raised.
It would appear that this issue is closed.
I would appreciate you validating the result of the build.
Hmm, I don't think that this is fixed yet; my test project is still throwing ClassCastException
. tools.jar
is also a transitive dependency of org.glassfish.jaxb:jaxb-xjc
and so is still being included in the jaxb2-maven-plugin
. When I exclude this dependency, the ClassCastException
is replaced by NoClassDefFoundError
.
FWIW, my test project is the same as the project from issue #10 except that MyType
is:
@XmlRootElement
public class MyType {
@XmlElement(required = true)
private String name;
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
}
I'm not sure that (i.e. that the com.sun:tools dependency was included transitively) is significant. While I have excluded the com.sun:tools
from the jab-xjc too now, the com.sun.tools dependency is used only as a placeholder for the tools.jar file within the installed JDK. The jaxb-xjc pom contains this dependency:
<dependency>
<groupId>com.sun</groupId>
<artifactId>tools</artifactId>
<scope>system</scope>
</dependency>
System dependencies only act as a placeholder for including a JAR which is already present in the system. Therefore, we may compile against a tools.jar of a certain version, but the one which will be included in the runtime class path is the tools.jar file on the system where the maven process runs. Also, the local tools.jar is not normally included in maven's class path - so the j-m-p uses an URLClassLoader set in the ThreadContext scope in the ToolExecutionEnvironment. That URLClassLoader loads in the tools.jar. You should find a log entry in build log (if you run in debug mode) saying something like:
This line should be present in your log; the alternative is that an Exception is thrown claiming that the local tools.jar file could not be found. Hence, it should be the local tools.jar file which is included in the tool's class path.
Yes, I definitely have that DEBUG line. But I still have the CCE too:
[DEBUG] Imported: org.apache.maven.toolchain < plexus.core
[DEBUG] com.sun.istack:istack-commons-tools:jar:2.21:compile
[DEBUG] com.sun:tools:jar:1.6:system
[DEBUG] Included: com.sun.istack:istack-commons-tools:jar:2.21
[DEBUG] Included: com.sun:tools:jar:1.6
[DEBUG] Found 'tools.jar' at [/usr/java/jdk1.7.0_80/lib/tools.jar]: true
| [awt.toolkit]: sun.awt.X11.XToolkit
[ERROR] +=================== [End SchemaGenerator Error]: java.lang.AssertionError: java.lang.ClassCastException: com.sun.tools.javac.api.JavacTrees cannot be cast to com.sun.source.util.Trees
Caused by: java.lang.RuntimeException: java.lang.AssertionError: java.lang.ClassCastException: com.sun.tools.javac.api.JavacTrees cannot be cast to com.sun.source.util.Trees
at com.sun.tools.javac.main.Main.compile(Main.java:469)
at com.sun.tools.javac.api.JavacTaskImpl.call(JavacTaskImpl.java:132)
at com.sun.tools.jxc.SchemaGenerator$Runner.compile(SchemaGenerator.java:261)
at com.sun.tools.jxc.SchemaGenerator.run(SchemaGenerator.java:166)
What's bothering me here is that com.sun.source.util.Trees
is an abstract base class of com.sun.tools.javac.api.JavacTrees
, and both classes exist in tools.jar
. So the fact that an instance of JavacTrees
exists to be cast in the first place should imply that tools.jar
has already been loaded into another class-loader. Perhaps the problem is that this class-loader is not available to Maven? IIRC, a class loaded by one class-loader is not assignment-compatible with the same class loaded by a different class-loader.
I have run some Jaxb-aware entity projects with the 2.2-SNAPSHOT version of the J-M-P, and I can't reproduce your class cast exception as per the above. I have run the projects on Mac OS X and Linux using JDK 8 (and some JDK 7). These projects do not contain any JAXB annotation errors (as far as I know), though, so if the CCE is a symptom of a JAXB annotation problem it may have slipped me.
I have also built the plugin itself on Mac OS X using JDK 8 and Linux using JDK 8, JDK 7 and JDK 6. Could you send me a template project where the problem occurs?
Like I mentioned, I assembled the source files from my comment in issue #10 into a trivial Maven project:
pom.xml
src/main/java/org/testing/TestJaxb.java
src/main/java/org/testing/xml/MyType.java
src/main/java/org/testing/xml/package-info.java
Then I moved the @XmlElement
annotation on MyType
to the field:
@XmlRootElement
public class MyType {
@XmlElement(required = true)
private String name;
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
}
and updated the POM to use jaxb2-maven-plugin:2.2-SNAPSHOT
. Building this project resulted in the following error:
Failed to execute goal org.codehaus.mojo:jaxb2-maven-plugin:2.2-SNAPSHOT:schemagen (default) on project test-jaxb:
+=================== [SchemaGenerator Error '<unknown>']
|
| SchemaGen did not complete its operation correctly.
|
| To re-create the error (and get a proper error message), cd to:
| E:\workspace\testing\test-jaxb
| ... and fire the following on a command line/in a shell:
|
| schemagen -encoding UTF-8 -d E:\workspace\testing\test-jaxb\target\schemagen-work\compile_scope -classpath /E:/workspace/testing/test-jaxb/src/main/java/ -episode E:\workspace\testing\test-jaxb\target\generated-resources\schemagen\META-INF\sun-jaxb.episode src\main\java\org\testing\xml\MyType.java
|
| The following source files should be processed by schemagen:
| 0: file:/E:/workspace/testing/test-jaxb/src/main/java/org/testing/xml/MyType.java
| 1: file:/E:/workspace/testing/test-jaxb/src/main/java/org/testing/xml/package-info.java
|
+=================== [End SchemaGenerator Error]: java.lang.NoClassDefFoundError: com/sun/source/util/Trees: com.sun.source.util.Trees
And now that you have also removed tools.jar
as a transitive dependency from jaxb-xjc
, my ClassCastException
has become NoClassDefFoundError
instead.
BTW, trying to build the plugin on Windows resulted in this integration test error:
[INFO] Building: xjc-handles-spaces-in-filenames\pom.xml
[INFO] run script verify.groovy
[INFO] ..FAILED (7.2 s)
[INFO] The post-build script did not succeed. Missing required pattern: [\| \[
\p{Digit}+\]: src\Q\\Emain\Q\\Exsd\Q\\Eaddress.xsd]. Expression: foundSourceArgument. Values: foundSourceArgument = false
[INFO] ..SUCCESS (3.0 s)
[INFO] -------------------------------------------------
[INFO] Build Summary:
[INFO] Passed: 29, Failed: 1, Errors: 0, Skipped: 0
[INFO] -------------------------------------------------
[ERROR] The following builds failed:
[ERROR] * xjc-handles-spaces-in-filenames\pom.xml
[INFO] -------------------------------------------------
I have been able to generate the Exception above.
It seems to be thrown when JAXB encounters incorrect annotations.
I will make the plugin wrap the exception and try to dig out the proper error message from SchemaGen.
It seems to be thrown when JAXB encounters incorrect annotations.
Well, I wouldn't want to assume that was the only way of triggering it just yet. But it is the way that I've found.
Fixed in 6057152
SchemaGenerator internally loads some classes in the ToolProvider.getSystemToolClassLoader()
, and adding those packages to the ClassRealm of the Jaxb2-Maven-Plugin resolved the CCEs.
In version 2.1 the jaxb2 maven plugin generates a ClassCastException during schemagen for our project. Version 1.6 does not have this problem.
Stacktrace: