我遇到了gwt dev模式调试的奇怪问题。
以下是我写的https://github.com/sillysachin/GWTAMChart
的JSNI包装器这是一个相当小而简单的项目,包含大量JSNI,JavaScriptObject和JSON代码。它包含了流行的amcharts图表库。在SuperDevMode和Production中调试时,它运行良好。
但是我无法使用开发模式调试在Internet Explorer中调试项目。
java.lang.ClassFormatError:类文件中的重复方法名称和签名com / google / gwt / core / client / JavaScriptObject $
抛出的主要异常并没有帮助我确定代码的哪一部分正在破坏!!!!!
java.lang.ClassFormatError: Duplicate method name&signature in class file com/google/gwt/core/client/JavaScriptObject$
at java.lang.ClassLoader.defineClass1(Native Method)
at java.lang.ClassLoader.defineClass(ClassLoader.java:800)
at java.lang.ClassLoader.defineClass(ClassLoader.java:643)
at com.google.gwt.dev.shell.CompilingClassLoader.findClass(CompilingClassLoader.java:1142)
at com.google.gwt.dev.shell.CompilingClassLoader.loadClass(CompilingClassLoader.java:1215)
at java.lang.ClassLoader.loadClass(ClassLoader.java:358)
at java.lang.Class.forName0(Native Method)
at java.lang.Class.forName(Class.java:270)
at com.google.gwt.dev.shell.JsValueGlue.set(JsValueGlue.java:220)
at com.google.gwt.dev.shell.ModuleSpaceOOPHM.doInvoke(ModuleSpaceOOPHM.java:130)
at com.google.gwt.dev.shell.ModuleSpace.invokeNative(ModuleSpace.java:589)
at com.google.gwt.dev.shell.ModuleSpace.invokeNativeVoid(ModuleSpace.java:315)
at com.google.gwt.dev.shell.ModuleSpace.onLoad(ModuleSpace.java:359)
at com.google.gwt.dev.shell.OophmSessionHandler.loadModule(OophmSessionHandler.java:200)
at com.google.gwt.dev.shell.BrowserChannelServer.processConnection(BrowserChannelServer.java:530)
at com.google.gwt.dev.shell.BrowserChannelServer.run(BrowserChannelServer.java:368)
at java.lang.Thread.run(Thread.java:745)
答案 0 :(得分:1)
有问题的类是AmChartJSO
实现IsAmChart
接口 - 所有方法都在JavaScriptObject$
中声明了两次。来自字节码的片段:
public final synthetic com_amcharts_api_IsAmChart_setVersion(Ljava/lang/String;)V
ALOAD 0
ALOAD 1
INVOKESTATIC com/amcharts/jso/AmChartJSO$.setVersion$ (Lcom/amcharts/jso/AmChartJSO;Ljava/lang/String;)V
RETURN
MAXSTACK = 2
MAXLOCALS = 2
// access flags 0x1011
public final synthetic com_amcharts_api_IsAmChart_setVersion(Ljava/lang/String;)V
ALOAD 0
ALOAD 1
INVOKESTATIC com/amcharts/jso/AmChartJSO$.setVersion$ (Lcom/amcharts/jso/AmChartJSO;Ljava/lang/String;)V
RETURN
MAXSTACK = 2
MAXLOCALS = 2
您似乎遇到了叠加类型的限制 - only one JavaScriptObject subtype can implement any given interface:
实际上,这意味着只有一个JavaScriptObject类型可以实现任何给定的接口,但是任何数量的非JavaScriptObject类型也可以实现该接口。
查看您的代码时,此限制已被破坏:AmChartJSO
实现IsAmChart
,但AmCoordinateChartJSO
实现了扩展IsAmCoordinateChart
的{{1}} - 因此两个JSO实施相同的界面。如果我正确理解了这个限制,你甚至不能创建一个实现接口的JSO子类。
我做了一个快速测试,这段代码也失败了:
IsAmChart
同样无用的例外:
public class Test extends JavaScriptObject implements TakesValue<String> {
protected Test() {
}
@Override
public final void setValue(String value) {
}
@Override
public final String getValue() {
return null;
}
}
public class Test2 extends Test {
protected Test2() {
}
}
请参阅this thread on GWT's mailing list了解此问题的解决方法和一般性讨论。
为了将来参考,您可以通过设置java.lang.NullPointerException: null
at com.google.gwt.dev.shell.CompilingClassLoader$MySingleJsoImplData.findOverloadUsingErasure(CompilingClassLoader.java:703)
at com.google.gwt.dev.shell.CompilingClassLoader$MySingleJsoImplData.<init>(CompilingClassLoader.java:593)
at com.google.gwt.dev.shell.CompilingClassLoader.<init>(CompilingClassLoader.java:980)
at com.google.gwt.dev.shell.ShellModuleSpaceHost.onModuleReady(ShellModuleSpaceHost.java:137)
at com.google.gwt.dev.shell.ModuleSpace.onLoad(ModuleSpace.java:340)
at com.google.gwt.dev.shell.OophmSessionHandler.loadModule(OophmSessionHandler.java:200)
at com.google.gwt.dev.shell.BrowserChannelServer.processConnection(BrowserChannelServer.java:526)
at com.google.gwt.dev.shell.BrowserChannelServer.run(BrowserChannelServer.java:364)
at java.lang.Thread.run(Thread.java:745)
系统属性(class
)来转储生成的gwt.dev.classDump
字段。有关详细信息,请参阅this wiki page。默认情况下,类会写入-Dgwt.dev.classDump=true
文件夹(在您的情况下,它将是rewritten-classes
)。这些类按包进行组织,因此查找war/rewritten-classes
非常简单:JavaScriptObject$
。
现在,您需要做的就是反汇编它 - 我使用了Bytecode Outline plugin for Eclipse并获得了rewritten-classes/com/google/gwt/core/client/JavaScriptObject$.class
的字节码。
为了找出哪些方法是重复的,我可以使用类加载器加载JavaScriptObject$.class
文件并让JVM弄清楚...但我感觉很懒,所以我只是class
在字节码中编辑grep
并运行uniq -D
以仅查看重复的条目。
答案 1 :(得分:0)
使用JSNI时,在dev模式下会发生这种情况。由于super dev模式在浏览器中使用纯java脚本直接调试,因此没有严格的类型转换并且不会产生错误。在开发模式下,java代码运行,并且由于严格的类型转换,您将获得类格式异常。没有用。与highcharts一样的问题也是如此。如果它在生产和超级开发模式下运行良好,那么你不应该担心它。希望它有所帮助。