Closed MarcinMalczewski closed 7 years ago
Hello, I work on oVirt project together with @gregsheremeta and we're facing the exact same issue.
We have a big GWT application using GWTP MVP framework and some other dependencies, including GIN and GWT Bootstrap. We're currently on GWT 2.6.1 and everything compiles and works OK.
After upgrading to GWT 2.8.0, compilation always (consistently) fails on internal error:
[INFO] Compiling module org.ovirt.engine.ui.webadmin.WebAdmin
[INFO] [ERROR] An internal compiler exception occurred
[INFO] com.google.gwt.dev.jjs.InternalCompilerException: Error constructing Java AST
[INFO] at com.google.gwt.dev.jjs.impl.GwtAstBuilder.translateException(GwtAstBuilder.java:3944)
[INFO] at com.google.gwt.dev.jjs.impl.GwtAstBuilder$AstVisitor.endVisit(GwtAstBuilder.java:1567)
[INFO] at org.eclipse.jdt.internal.compiler.ast.MessageSend.traverse(MessageSend.java:1043)
[INFO] at org.eclipse.jdt.internal.compiler.ast.MessageSend.traverse(MessageSend.java:1031)
[INFO] at org.eclipse.jdt.internal.compiler.ast.MessageSend.traverse(MessageSend.java:1040)
[INFO] at org.eclipse.jdt.internal.compiler.ast.MethodDeclaration.traverse(MethodDeclaration.java:357)
[INFO] at org.eclipse.jdt.internal.compiler.ast.TypeDeclaration.traverse(TypeDeclaration.java:1360)
[INFO] at com.google.gwt.dev.jjs.impl.GwtAstBuilder.processImpl(GwtAstBuilder.java:3887)
[INFO] at com.google.gwt.dev.jjs.impl.GwtAstBuilder.process(GwtAstBuilder.java:3918)
[INFO] at com.google.gwt.dev.javac.CompilationStateBuilder$CompileMoreLater$UnitProcessorImpl.process(CompilationStateBuilder.java:129)
[INFO] at com.google.gwt.dev.javac.JdtCompiler$CompilerImpl.process(JdtCompiler.java:384)
[INFO] at org.eclipse.jdt.internal.compiler.Compiler.processCompiledUnits(Compiler.java:546)
[INFO] at org.eclipse.jdt.internal.compiler.Compiler.compile(Compiler.java:458)
[INFO] at com.google.gwt.dev.javac.JdtCompiler.doCompile(JdtCompiler.java:1092)
[INFO] at com.google.gwt.dev.javac.CompilationStateBuilder$CompileMoreLater.compile(CompilationStateBuilder.java:325)
[INFO] at com.google.gwt.dev.javac.CompilationStateBuilder.doBuildFrom(CompilationStateBuilder.java:548)
[INFO] at com.google.gwt.dev.javac.CompilationStateBuilder.buildFrom(CompilationStateBuilder.java:479)
[INFO] at com.google.gwt.dev.javac.CompilationStateBuilder.buildFrom(CompilationStateBuilder.java:465)
[INFO] at com.google.gwt.dev.cfg.ModuleDef.getCompilationState(ModuleDef.java:423)
[INFO] at com.google.gwt.dev.Precompile.precompile(Precompile.java:222)
[INFO] at com.google.gwt.dev.Precompile.precompile(Precompile.java:202)
[INFO] at com.google.gwt.dev.Precompile.precompile(Precompile.java:143)
[INFO] at com.google.gwt.dev.Compiler.compile(Compiler.java:204)
[INFO] at com.google.gwt.dev.Compiler.compile(Compiler.java:155)
[INFO] at com.google.gwt.dev.Compiler.compile(Compiler.java:144)
[INFO] at com.google.gwt.dev.Compiler$1.run(Compiler.java:118)
[INFO] at com.google.gwt.dev.CompileTaskRunner.doRun(CompileTaskRunner.java:55)
[INFO] at com.google.gwt.dev.CompileTaskRunner.runWithAppropriateLogger(CompileTaskRunner.java:50)
[INFO] at com.google.gwt.dev.Compiler.main(Compiler.java:125)
[INFO] Caused by: java.lang.NullPointerException
[INFO] at com.google.gwt.dev.javac.JdtUtil.join(JdtUtil.java:67)
[INFO] at com.google.gwt.dev.javac.JdtUtil.asDottedString(JdtUtil.java:59)
[INFO] at com.google.gwt.dev.jjs.impl.ReferenceMapper.createType(ReferenceMapper.java:275)
[INFO] at com.google.gwt.dev.jjs.impl.ReferenceMapper.get(ReferenceMapper.java:146)
[INFO] at com.google.gwt.dev.jjs.impl.GwtAstBuilder$AstVisitor.endVisit(GwtAstBuilder.java:1559)
[INFO] ... 27 more
[INFO] [ERROR] at OptionsPopupPresenterWidget.java(30): getView().getPublicKeyEditor()
[INFO] org.eclipse.jdt.internal.compiler.ast.MessageSend
The relevant source is OptionsPopupPresenterWidget.java line 30:
registerHandler(getView().getPublicKeyEditor().addChangeHandler(new ChangeHandler() { .. }));
Maven dependency tree is following:
[INFO] --- maven-dependency-plugin:2.8:tree (default-cli) @ webadmin ---
[INFO] org.ovirt.engine.ui:webadmin:war:4.2.0-SNAPSHOT
[INFO] +- com.google.gwt:gwt-user:jar:2.8.0:provided
[INFO] | +- com.google.jsinterop:jsinterop-annotations:jar:1.0.1:provided
[INFO] | +- com.google.jsinterop:jsinterop-annotations:jar:sources:1.0.1:provided
[INFO] | +- javax.validation:validation-api:jar:1.0.0.GA:provided
[INFO] | +- javax.validation:validation-api:jar:sources:1.0.0.GA:provided
[INFO] | +- javax.servlet:javax.servlet-api:jar:3.1.0:provided
[INFO] | \- org.w3c.css:sac:jar:1.3:provided
[INFO] +- com.google.gwt:gwt-dev:jar:2.8.0:provided
[INFO] | +- com.google.code.gson:gson:jar:2.6.2:provided
[INFO] | +- org.ow2.asm:asm:jar:5.0.3:provided
[INFO] | +- org.ow2.asm:asm-util:jar:5.0.3:provided
[INFO] | | \- org.ow2.asm:asm-tree:jar:5.0.3:provided
[INFO] | +- org.ow2.asm:asm-commons:jar:5.0.3:provided
[INFO] | +- colt:colt:jar:1.2.0:provided
[INFO] | +- ant:ant:jar:1.6.5:provided
[INFO] | +- commons-collections:commons-collections:jar:3.2.2:provided
[INFO] | +- commons-io:commons-io:jar:2.4:provided
[INFO] | +- com.ibm.icu:icu4j:jar:50.1.1:provided
[INFO] | +- tapestry:tapestry:jar:4.0.2:provided
[INFO] | +- net.sourceforge.htmlunit:htmlunit:jar:2.19:provided
[INFO] | | +- org.apache.commons:commons-lang3:jar:3.4:provided
[INFO] | | +- org.apache.httpcomponents:httpclient:jar:4.5:provided
[INFO] | | | \- org.apache.httpcomponents:httpcore:jar:4.4.1:provided
[INFO] | | +- org.apache.httpcomponents:httpmime:jar:4.5.1:provided
[INFO] | | +- net.sourceforge.htmlunit:htmlunit-core-js:jar:2.17:provided
[INFO] | | +- xerces:xercesImpl:jar:2.11.0:provided
[INFO] | | | \- xml-apis:xml-apis:jar:1.4.01:provided
[INFO] | | +- net.sourceforge.nekohtml:nekohtml:jar:1.9.22:provided
[INFO] | | +- net.sourceforge.cssparser:cssparser:jar:0.9.18:provided
[INFO] | | +- commons-logging:commons-logging:jar:1.2:provided
[INFO] | | \- org.eclipse.jetty.websocket:websocket-client:jar:9.2.13.v20150730:provided
[INFO] | | \- org.eclipse.jetty.websocket:websocket-common:jar:9.2.13.v20150730:provided
[INFO] | | \- org.eclipse.jetty.websocket:websocket-api:jar:9.2.13.v20150730:provided
[INFO] | +- org.eclipse.jetty:jetty-webapp:jar:9.2.14.v20151106:provided
[INFO] | | +- org.eclipse.jetty:jetty-xml:jar:9.2.14.v20151106:provided
[INFO] | | \- org.eclipse.jetty:jetty-servlet:jar:9.2.14.v20151106:provided
[INFO] | | \- org.eclipse.jetty:jetty-security:jar:9.2.14.v20151106:provided
[INFO] | +- org.eclipse.jetty:jetty-servlets:jar:9.2.14.v20151106:provided
[INFO] | | +- org.eclipse.jetty:jetty-continuation:jar:9.2.14.v20151106:provided
[INFO] | | +- org.eclipse.jetty:jetty-http:jar:9.2.14.v20151106:provided
[INFO] | | +- org.eclipse.jetty:jetty-util:jar:9.2.14.v20151106:provided
[INFO] | | \- org.eclipse.jetty:jetty-io:jar:9.2.14.v20151106:provided
[INFO] | +- org.eclipse.jetty:jetty-annotations:jar:9.2.14.v20151106:provided
[INFO] | | +- org.eclipse.jetty:jetty-plus:jar:9.2.14.v20151106:provided
[INFO] | | | \- org.eclipse.jetty:jetty-jndi:jar:9.2.14.v20151106:provided
[INFO] | | \- javax.annotation:javax.annotation-api:jar:1.2:provided
[INFO] | \- org.eclipse.jetty:apache-jsp:jar:9.2.14.v20151106:provided
[INFO] | +- org.eclipse.jetty:jetty-server:jar:9.2.14.v20151106:provided
[INFO] | +- org.eclipse.jetty.toolchain:jetty-schemas:jar:3.1.M0:provided
[INFO] | \- org.mortbay.jasper:apache-jsp:jar:8.0.9.M3:provided
[INFO] | \- org.mortbay.jasper:apache-el:jar:8.0.9.M3:provided
[INFO] +- com.google.gwt:gwt-servlet:jar:2.8.0:runtime
[INFO] +- org.gwtbootstrap3:gwtbootstrap3:jar:0.8.1:provided
[INFO] +- org.gwtbootstrap3:gwtbootstrap3-extras:jar:0.8.1:provided
[INFO] +- com.gwtplatform:gwtp-mvp-client:jar:1.6:provided
[INFO] | +- com.gwtplatform:gwtp-clients-common:jar:1.6:provided
[INFO] | +- com.gwtplatform:gwtp-mvp-shared:jar:1.6:provided
[INFO] | +- org.apache.velocity:velocity:jar:1.7:provided
[INFO] | \- com.google.code.findbugs:jsr305:jar:3.0.1:provided
[INFO] +- com.gwtplatform:gwtp-processors:jar:1.6:provided
[INFO] +- com.google.inject:guice:jar:4.1.0:provided
[INFO] | +- javax.inject:javax.inject:jar:1:provided
[INFO] | +- aopalliance:aopalliance:jar:1.0:provided
[INFO] | \- com.google.guava:guava:jar:19.0:provided
[INFO] +- com.google.inject.extensions:guice-assistedinject:jar:4.1.0:provided
[INFO] +- com.google.gwt.inject:gin:jar:2.1.2:provided
[INFO] +- org.ovirt.engine.ui:uicommonweb:jar:4.2.0-SNAPSHOT:provided
[INFO] | +- org.ovirt.engine.core:searchbackend:jar:4.2.0-SNAPSHOT:provided
[INFO] | \- org.ovirt.engine.ui:uicompat:jar:4.2.0-SNAPSHOT:provided
[INFO] +- org.ovirt.engine.ui:gwt-common:jar:4.2.0-SNAPSHOT:provided
[INFO] +- org.ovirt.engine.ui:uicompat:test-jar:tests:4.2.0-SNAPSHOT:test
[INFO] | +- org.ovirt.engine.core:common:jar:4.2.0-SNAPSHOT:provided
[INFO] | | +- org.hibernate:hibernate-validator:jar:4.2.0.Final:provided
[INFO] | | \- org.jboss.modules:jboss-modules:jar:1.1.1.GA:provided
[INFO] | +- org.ovirt.engine.core:common:jar:sources:4.2.0-SNAPSHOT:provided
[INFO] | +- org.ovirt.engine.core:compat:jar:sources:4.2.0-SNAPSHOT:provided
[INFO] | \- org.ovirt.engine.core:searchbackend:jar:sources:4.2.0-SNAPSHOT:provided
[INFO] +- org.ovirt.engine.ui:frontend:jar:4.2.0-SNAPSHOT:compile
[INFO] +- org.ovirt.engine.ui:gwt-extension:jar:4.2.0-SNAPSHOT:compile
[INFO] +- org.ovirt.engine.ui:gwt-aop:jar:4.2.0-SNAPSHOT:provided
[INFO] +- javax.xml.bind:jaxb-api:jar:2.1:provided
[INFO] | +- javax.xml.stream:stax-api:jar:1.0-2:provided
[INFO] | \- javax.activation:activation:jar:1.1:provided
[INFO] +- org.jboss.spec.javax.servlet:jboss-servlet-api_3.1_spec:jar:1.0.0.Final:provided
[INFO] +- org.jboss.spec.javax.servlet.jstl:jboss-jstl-api_1.2_spec:jar:1.0.3.Final:provided
[INFO] | +- org.jboss.spec.javax.el:jboss-el-api_2.2_spec:jar:1.0.1.Final:provided
[INFO] | +- org.jboss.spec.javax.servlet:jboss-servlet-api_3.0_spec:jar:1.0.1.Final:provided
[INFO] | +- org.jboss.spec.javax.servlet.jsp:jboss-jsp-api_2.2_spec:jar:1.0.1.Final:provided
[INFO] | \- xalan:xalan:jar:2.7.1.jbossorg-2:provided
[INFO] | \- xalan:serializer:jar:2.7.1.jbossorg-2:provided
[INFO] +- org.jboss.spec.javax.ejb:jboss-ejb-api_3.1_spec:jar:1.0.2.Final:provided
[INFO] +- org.jboss.spec.javax.enterprise.concurrent:jboss-concurrency-api_1.0_spec:jar:1.0.0.Final:provided
[INFO] +- org.aspectj:aspectjweaver:jar:1.8.10:provided
[INFO] +- org.slf4j:slf4j-api:jar:1.7.5:provided
[INFO] +- org.ovirt.engine.core:utils:jar:4.2.0-SNAPSHOT:provided
[INFO] | +- org.ovirt.engine.api:ovirt-engine-extensions-api:jar:0.0.0-SNAPSHOT:provided
[INFO] | +- org.ovirt.engine.core:extensions-manager:jar:4.2.0-SNAPSHOT:provided
[INFO] | +- commons-beanutils:commons-beanutils:jar:1.9.2:provided
[INFO] | +- org.ovirt.engine.core:compat:jar:4.2.0-SNAPSHOT:provided
[INFO] | +- org.ovirt.otopi:otopi:jar:1.5.2:provided
[INFO] | +- org.ovirt.ovirt-host-deploy:ovirt-host-deploy:jar:1.5.0:provided
[INFO] | +- org.apache.commons:commons-compress:jar:1.5:provided
[INFO] | | \- org.tukaani:xz:jar:1.2:provided
[INFO] | +- org.ovirt.engine.core:uutils:jar:4.2.0-SNAPSHOT:provided
[INFO] | | \- org.apache.sshd:sshd-core:jar:0.12.0:provided
[INFO] | | \- org.apache.mina:mina-core:jar:2.0.7:provided
[INFO] | +- commons-lang:commons-lang:jar:2.6:provided
[INFO] | +- commons-codec:commons-codec:jar:1.10:provided
[INFO] | +- commons-httpclient:commons-httpclient:jar:3.1:provided
[INFO] | +- org.codehaus.jackson:jackson-core-asl:jar:1.9.9:provided
[INFO] | +- org.codehaus.jackson:jackson-mapper-asl:jar:1.9.9:provided
[INFO] | +- org.springframework:spring-core:jar:4.2.4.RELEASE:provided
[INFO] | +- org.infinispan:infinispan-core:jar:5.2.5.Final:provided
[INFO] | | +- org.jgroups:jgroups:jar:3.2.7.Final:provided
[INFO] | | +- org.jboss.spec.javax.transaction:jboss-transaction-api_1.1_spec:jar:1.0.0.Final:provided
[INFO] | | +- org.jboss.marshalling:jboss-marshalling-river:jar:1.3.15.GA:provided
[INFO] | | +- org.jboss.marshalling:jboss-marshalling:jar:1.3.15.GA:provided
[INFO] | | +- org.jboss.logging:jboss-logging:jar:3.1.1.GA:provided
[INFO] | | \- org.jboss:staxmapper:jar:1.1.0.Final:provided
[INFO] | +- com.woorea:keystone-client:jar:3.1.1:provided
[INFO] | | +- com.woorea:openstack-client:jar:3.1.1:provided
[INFO] | | \- com.woorea:keystone-model:jar:3.1.1:provided
[INFO] | +- com.woorea:glance-client:jar:3.1.1:provided
[INFO] | | \- com.woorea:glance-model:jar:3.1.1:provided
[INFO] | +- com.woorea:cinder-client:jar:3.1.1:provided
[INFO] | | \- com.woorea:cinder-model:jar:3.1.1:provided
[INFO] | \- org.ebaysf.web:cors-filter:jar:1.0.1:provided
[INFO] +- org.ovirt.engine.core:branding:jar:4.2.0-SNAPSHOT:compile
[INFO] +- org.ovirt.engine.core:utils:test-jar:tests:4.2.0-SNAPSHOT:test
[INFO] +- junit:junit:jar:4.12:test
[INFO] | \- org.hamcrest:hamcrest-core:jar:1.3:test
[INFO] +- org.hamcrest:hamcrest-library:jar:1.3:test
[INFO] +- org.mockito:mockito-core:jar:2.6.5:test
[INFO] | +- net.bytebuddy:byte-buddy:jar:1.6.4:test
[INFO] | +- net.bytebuddy:byte-buddy-agent:jar:1.6.4:test
[INFO] | \- org.objenesis:objenesis:jar:2.5:test
[INFO] +- org.assertj:assertj-core:jar:2.2.0:test
[INFO] \- org.slf4j:slf4j-nop:jar:1.7.5:test
We have an explicit dependency on gwt-dev
with version consistent with other GWT artifacts. As for gwtp-mvp-client
we're using version 1.6
which depends on the correct gwt-dev
version 2.8.0
. Therefore, I don't believe that issue 9445 is related to this problem.
This seems like an internal GWT compiler / AST parser bug, possibly caused by the introduction of Java 8 support.
Can someone familiar with GWT internals elaborate on this exception? The problem seems to be that org.eclipse.jdt.internal.compiler.lookup.ReferenceBinding#compoundName
field is null, after being type-casted in com.google.gwt.dev.jjs.impl.ReferenceMapper
line 145.
Maybe @tbroyer or @rluble can point us to the problem, I'll try to modify the relevant source to see how it affects GWT compilation.
Looking at the code it seems that it expects a declared type binding or an array binding and at line ReferenceMapper.java:145 it expects it to be a declared type.
You can probably add before that line or at the beginning of createType
assert binding.compoundName != null
: "Expected a binding with a coupound name but got " + binding;
if you intuition is right we might be seeing here a binding for an intersection type or something other than a declared type binding.
Or you could just debug the compiler and look at the binding there. Or upload a small example that repros the case.
I think I've isolated the problem.
The offending code is following (non-relevant parts taken out):
public class OptionsPopupPresenterWidget extends AbstractModelBoundPopupPresenterWidget<EditOptionsModel, OptionsPopupPresenterWidget.ViewDef> {
public interface ViewDef extends AbstractModelBoundPopupPresenterWidget.ViewDef<EditOptionsModel> {
// notice the rather complex method type param (T) below
<T extends HasChangeHandlers & HasValue<String> & HasText> T getPublicKeyEditor();
}
@Override
public void init(EditOptionsModel model) {
super.init(model);
// following code triggers InternalCompilerException due to NPE on ReferenceBinding#compoundName
registerHandler(getView().getPublicKeyEditor().addChangeHandler(new ChangeHandler() {
@Override
public void onChange(ChangeEvent event) {
// stuff
}
}));
// following code works OK - extract the variable of expected type
HasChangeHandlers pkEditor = getView().getPublicKeyEditor();
registerHandler(pkEditor.addChangeHandler(new ChangeHandler() {
@Override
public void onChange(ChangeEvent event) {
// stuff
}
}));
}
}
It seems that AST parser struggles on getView().getPublicKeyEditor()
when used in another expression, e.g. having troubles to determine its return type. This is possibly due to the rather complex method type param (T) defined in ViewDef#getPublicKeyEditor
method.
Applying above workaround on OptionsPopupPresenterWidget.java
(lines 30 and 36 of original source) results in GWT 2.8.0 compilation pass.
@rluble I can try debugging the GWT compiler to see the actual binding type in use.
Thanks for your feedback!
My guess is that the intersection type from <T extends HasChangeHandlers & HasValue<String> & HasText>
is arriving at createType.
There is no need to debug I think, but it would serve as a confirmation. Also if you could upload a minimal repro case that would really help.
@tbroyer I don' t think it is a JDT bug.
TL;DR; As @vojtechszocs has conjectured, the failure here is due to properly handle a Java 7/8 feature (intersection types). Gory details below.
The code in GwtAstBuilder.java that inserts casts required due to type erasure (in method calls, field accesses, etc) do not expect the need to insert intersection casts. The example above tries to transform the code getView().getPublicKeyEditor()
into ((HasChangeHandlers & HasValue & HasText)getView().getPublicKeyEditor())
.
The code that inserts those casts does not really expect an intersection type (only classes, interfaces, enums and arrays are expected here), i.e. the ReferenceMapper which keeps track of the mapping between JDT IBindings and JType is completely unaware of intersection IBindings. GWT does not even model intersections as a JType, it just lowers the casts into a sequence of normal casts.
The quirk is that ReferenceMapper uses IBinding.constantPoolName() as a key and curiously enough the it has the value corresponding to the first type in the intersection. So it seems that depending on which type arrives first to reference mapper (if the intersection A&B&C or the type A) whether NPE occurs. The behaviour when the compiler does not crash results in code that perform less casts. The chances that those cast if emitted would actually fail in normal scenarios is very, very low so when the compiler does not crash the code is mostly correct.
@vojtechszocs, I uploaded https://gwt-review.googlesource.com/#/c/17801/ which is not ready for review (missing test) but it would be nice if you could test it on your project.
My guess is that the intersection type from
<T extends HasChangeHandlers & HasValue<String> & HasText>
is arriving at createType.
That is correct. I've debugged the GWT compiler - in ReferenceMapper#createType
method, the binding
arrives as:
HasValue<java.lang.String> & com.google.gwt.user.client.ui.HasText & com.google.gwt.event.dom.client.HasChangeHandlers
and it's indeed an org.eclipse.jdt.internal.compiler.lookup.IntersectionTypeBinding18
.
Also if you could upload a minimal repro case that would really help.
I've isolated the problem into the following example:
import com.google.gwt.event.dom.client.HasChangeHandlers;
import com.google.gwt.user.client.ui.HasValue;
public class Test {
<T extends HasChangeHandlers & HasValue<String>> T getFoo() {
return null; // not important at compile time
}
public Test() {
// following line causes compilation error
// binding at ReferenceMapper#createType is IntersectionTypeBinding18
// intersecting types are:
// 1, public interface HasValue<java.lang.String> extends java.lang.Object implements : TakesValue<java.lang.String>, HasValueChangeHandlers<java.lang.String>
// 2, public interface com.google.gwt.event.dom.client.HasChangeHandlers extends java.lang.Object implements : com.google.gwt.event.shared.HasHandlers
getFoo().setValue("");
}
}
// in code reachable from an entry point
new Test();
GWT does not even model intersections as a JType, it just lowers the casts into a sequence of normal casts.
This is very helpful to know.
ReferenceMapper uses IBinding.constantPoolName() as a key and curiously enough the it has the value corresponding to the first type in the intersection
That is due to IntersectionTypeBinding18#constantPoolName
override returning this.intersectingTypes[0].constantPoolName()
.
I'll look at the posted fix but please note I am definitely not an expert on GWT internals 😃
@rluble I've built GWT SDK - using tag 2.8.0
with your fix applied - and using the patched gwt-dev
dependency, the problem goes away 👍
Is there a chance of releasing this fix in GWT .z stream anytime soon?
In any case, many thanks for assisting with this issue!
I’ve migrated my project from GWT 2.7 to 2.8 and since then it compiles randomly (not very often). In most cases I get the following error:
Sometimes different part of code is indicated as source of error:
The dependency tree looks as follows:
Additional information:
The information posted in https://github.com/gwtproject/gwt/issues/9445 didn’t help to resolve the issue.