gwtproject / gwt

GWT Open Source Project
http://www.gwtproject.org
1.52k stars 376 forks source link

NPE in guava library compiling project in eclipse #6211

Closed dankurka closed 9 years ago

dankurka commented 9 years ago

Originally reported on Google Code with ID 6212

Found in GWT Release (e.g. 1.5.3, 1.6 RC):

GWT 2.2.0 Eclipse plugin

Encountered on OS / Browser (e.g. WinXP, IE6-7, FF3):

Windows7x64

Detailed description (please be as specific as possible):

I have 2 projects.  one is called 'model' and is a set of DTO objects.  One is a standard
GWT project (greeting service example for now) that tries to use some of the DTOs.
 Some of the DTOs work.  ie:

{{{
@RemoteServiceRelativePath("greet")
public interface GreetingService extends RemoteService {
  // this compiles ok 
  MyGoodObject go(String s);
}
}}}

However when I switch to other objects in the same 'model' project they do not work:

{{{
@RemoteServiceRelativePath("greet")
public interface GreetingService extends RemoteService {
  // this gives an NPE at compile time
  MyBadObject go(String s);
}
}}}

This leads me to believe that my project setup, eclipse plugin, etc are all ok and
that is is source code specific.  I can make small changes to the DTO objects if necessary
but right now i have no idea where to start.  The 'MyBadObject' in this case is a gigantic
object graph and walking down it object by object by hand would be very painful.

The Exception at compile time:

{{{
Compiling module com.acme2.GwtTest2
   Compiling 5 permutations
      Compiling permutation 0...
      [ERROR] An internal compiler exception occurred
com.google.gwt.dev.jjs.InternalCompilerException: Unexpected error during visit.
    at com.google.gwt.dev.jjs.ast.JVisitor.translateException(JVisitor.java:108)
    at com.google.gwt.dev.jjs.ast.JVisitor.accept(JVisitor.java:146)
    at com.google.gwt.dev.jjs.ast.JVisitor.acceptWithInsertRemoveImmutable(JVisitor.java:169)
    at com.google.gwt.dev.jjs.ast.JClassType.traverse(JClassType.java:63)
    at com.google.gwt.dev.jjs.ast.JVisitor.accept(JVisitor.java:124)
    at com.google.gwt.dev.jjs.ast.JVisitor.accept(JVisitor.java:119)
    at com.google.gwt.dev.jjs.impl.GenerateJavaScriptAST$CreateNamesAndScopesVisitor.visit(GenerateJavaScriptAST.java:286)
    at com.google.gwt.dev.jjs.ast.JClassType.traverse(JClassType.java:60)
    at com.google.gwt.dev.jjs.ast.JVisitor.accept(JVisitor.java:124)
    at com.google.gwt.dev.jjs.ast.JVisitor.accept(JVisitor.java:119)
    at com.google.gwt.dev.jjs.impl.GenerateJavaScriptAST$CreateNamesAndScopesVisitor.visit(GenerateJavaScriptAST.java:286)
    at com.google.gwt.dev.jjs.ast.JClassType.traverse(JClassType.java:60)
    at com.google.gwt.dev.jjs.ast.JVisitor.accept(JVisitor.java:143)
    at com.google.gwt.dev.jjs.ast.JProgram.traverse(JProgram.java:1268)
    at com.google.gwt.dev.jjs.ast.JVisitor.accept(JVisitor.java:124)
    at com.google.gwt.dev.jjs.ast.JVisitor.accept(JVisitor.java:119)
    at com.google.gwt.dev.jjs.impl.GenerateJavaScriptAST.execImpl(GenerateJavaScriptAST.java:2256)
    at com.google.gwt.dev.jjs.impl.GenerateJavaScriptAST.exec(GenerateJavaScriptAST.java:2022)
    at com.google.gwt.dev.jjs.JavaToJavaScriptCompiler.compilePermutation(JavaToJavaScriptCompiler.java:311)
    at com.google.gwt.dev.jjs.UnifiedAst.compilePermutation(UnifiedAst.java:136)
    at com.google.gwt.dev.CompilePerms.compile(CompilePerms.java:192)
    at com.google.gwt.dev.ThreadedPermutationWorkerFactory$ThreadedPermutationWorker.compile(ThreadedPermutationWorkerFactory.java:49)
    at com.google.gwt.dev.PermutationWorkerFactory$Manager$WorkerThread.run(PermutationWorkerFactory.java:73)
    at java.lang.Thread.run(Thread.java:662)
Caused by: java.lang.NullPointerException
    at com.google.gwt.thirdparty.guava.common.collect.Interners$WeakInterner.intern(Interners.java:69)
    at com.google.gwt.dev.util.StringInterner.intern(StringInterner.java:40)
    at com.google.gwt.dev.js.ast.JsScope.maybeMangleKeyword(JsScope.java:63)
    at com.google.gwt.dev.js.ast.JsScope.declareName(JsScope.java:96)
    at com.google.gwt.dev.jjs.impl.GenerateJavaScriptAST$CreateNamesAndScopesVisitor.visit(GenerateJavaScriptAST.java:322)
    at com.google.gwt.dev.jjs.ast.JMethod.traverse(JMethod.java:296)
    at com.google.gwt.dev.jjs.ast.JVisitor.accept(JVisitor.java:143)
    ... 22 more
         [ERROR] at Object.java(85): public Object clone();

            com.google.gwt.dev.jjs.ast.JMethod
         [ERROR] at Object.java(26): class Object 
            com.google.gwt.dev.jjs.ast.JClassType
         [ERROR] at RemoteServiceProxy.java(42): abstract class RemoteServiceProxy
extends Object implements SerializationStreamFactory, ServiceDefTarget, HasRpcToken

            com.google.gwt.dev.jjs.ast.JClassType
         [ERROR] at GreetingService_Proxy.java(14): final class GreetingService_Proxy
extends RemoteServiceProxy implements GreetingServiceAsync 
            com.google.gwt.dev.jjs.ast.JClassType
         [ERROR] at com.google.gwt.dev.jjs.ast.JProgram(0): <JProgram>
            com.google.gwt.dev.jjs.ast.JProgram
      [ERROR] Unrecoverable exception, shutting down
com.google.gwt.core.ext.UnableToCompleteException: (see previous log entries)
    at com.google.gwt.dev.jjs.JavaToJavaScriptCompiler.logAndTranslateException(JavaToJavaScriptCompiler.java:1136)
    at com.google.gwt.dev.jjs.JavaToJavaScriptCompiler.compilePermutation(JavaToJavaScriptCompiler.java:452)
    at com.google.gwt.dev.jjs.UnifiedAst.compilePermutation(UnifiedAst.java:136)
    at com.google.gwt.dev.CompilePerms.compile(CompilePerms.java:192)
    at com.google.gwt.dev.ThreadedPermutationWorkerFactory$ThreadedPermutationWorker.compile(ThreadedPermutationWorkerFactory.java:49)
    at com.google.gwt.dev.PermutationWorkerFactory$Manager$WorkerThread.run(PermutationWorkerFactory.java:73)
    at java.lang.Thread.run(Thread.java:662)
      [ERROR] Not all permutation were compiled , completed (0/5)
}}}

Note:  the exception points to an issue in Object.clone().  Many of my previously existing
model objects had clone methods implemented so I modified the gwt-emul code for Object.java
to include a clone() method as follows:

{{{
protected Object clone() throws CloneNotSupportedException {
  // note i also added an implementation of CloneNotSupportedException to the gwt-emul
library in source form
  throw new CloneNotSupportedException("Cloning not supported in client side javascript");
}
}}}

I'm going to start trying to pull down the source for the compiler and find out who
is trying to intern a null string but any help or pointers on how to get the compiler
running in the eclipse debugger would be appreciated.

Workaround if you have one:

None.

Links to relevant GWT Developer Forum posts:

None that i have found.

Reported by willjohnson3 on 2011-03-30 12:51:04

dankurka commented 9 years ago
I also get the same exception in GWT 2.1.1.

Reported by willjohnson3 on 2011-03-30 13:05:50

dankurka commented 9 years ago
finally got the compiler running in the debugger.  This turned out to be a problem with
the code obfuscator when trying to handle the clone() method i added to Object.java
in the emul tree.  The obfuscator has a special list of object types to obfuscate of
which Object is one of them (specialObfuscatedTypes).  If the method being translated
is in that class it assumes there is an entry in the method names map (specialObfuscatedIdents).
 since I added clone() it's not in the list of idents and this returns null which then
gets handed down to the interner.

setting the output type to 'pretty' seems to work around the issue for now.  it seems
like a simple 'if (null) return originalName' would fix the issue and allow people
to override Object.java and other types from the special types set.  i'll try to get
a patch together shortly.

Reported by willjohnson3 on 2011-03-31 16:43:33

dankurka commented 9 years ago
i think the following patch should do the job:

Index: src/com/google/gwt/dev/jjs/impl/GenerateJavaScriptAST.java
===================================================================
--- src/com/google/gwt/dev/jjs/impl/GenerateJavaScriptAST.java  (revision 9918)
+++ src/com/google/gwt/dev/jjs/impl/GenerateJavaScriptAST.java  (working copy)
@@ -2238,7 +2238,10 @@
     assert (specialObfuscatedIdents.containsKey(x.getName()));
     switch (output) {
       case OBFUSCATED:
-        return specialObfuscatedIdents.get(x.getName());
+        // make sure we allow end users to add methods to obfuscated types that don't

+        // have entries in the obfuscated idents table.  (ie adding clone() to Object.java)
GWT Issue# 6216
+        String tmp = specialObfuscatedIdents.get(x.getName());
+        return tmp == null ? x.getName() : tmp;
       case PRETTY:
         return x.getName() + "$";
       case DETAILED:

Reported by willjohnson3 on 2011-03-31 18:03:05

dankurka commented 9 years ago
I'm not sure what the right thing to do is wrt obfuscation but i have verified that
the above patch does fix the obfuscation bug and allows user code to add methods to
Object and other 'known' types without issue.  

Reported by willjohnson3 on 2011-04-04 13:48:05

dankurka commented 9 years ago

Reported by dankurka@google.com on 2013-06-02 19:11:01