Запуск DevMode завершился неудачей в проекте GWT JSNI

У меня возникла странная проблема с отладкой в ​​режиме gwt dev.

Ниже описана оболочка JSNI, которую я пишу https://github.com/sillysachin/GWTAMChart

Это довольно маленький и простой проект с большим количеством кода JSNI, JavaScriptObject и JSON. Он охватывает популярную библиотеку графиков amcharts. Он хорошо работает при отладке в SuperDevMode и в Production.

Однако я не могу отладить проект в Internet Explorer с помощью Dev Mode Debugging.

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)

2 ответа

Решение

Проблемный класс 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

Кажется, вы столкнулись с ограничением наложенных типов - только один подтип JavaScriptObject может реализовать любой данный интерфейс:

На практике это означает, что только один тип JavaScriptObject может реализовывать любой данный интерфейс, но любое количество типов, отличных от JavaScriptObject, также может реализовывать этот интерфейс.

Глядя на ваш код, это ограничение нарушается: AmChartJSO инвентарь IsAmChart, но AmCoordinateChartJSO инвентарь IsAmCoordinateChart который расширяется IsAmChart - и, следовательно, две JSO реализуют один и тот же интерфейс. Если я правильно понимаю это ограничение, вы не сможете даже создать подкласс JSO, который реализует интерфейс.

Я сделал быстрый тест, и этот код тоже не работает:

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() {
    }
}

За аналогичным бесполезным исключением:

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)

Пожалуйста, смотрите эту ветку в списке рассылки GWT для обходных путей и общего обсуждения этой проблемы.


Выгрузить сгенерированные файлы классов самостоятельно

Для дальнейшего использования вы можете создать дамп class подал, установив gwt.dev.classDump системное свойство (-Dgwt.dev.classDump=true). Смотрите эту вики-страницу для получения дополнительной информации. По умолчанию классы записываются в rewritten-classes папка (в вашем случае это будет war/rewritten-classes). Занятия организованы по пакетам, поэтому поиск JavaScriptObject$ это просто: rewritten-classes/com/google/gwt/core/client/JavaScriptObject$.class,

Теперь все, что вам нужно сделать, это разобрать его - я использовал плагин Bytecode Outline для Eclipse и получил байт-код JavaScriptObject$.class,

Чтобы узнать, какие методы были продублированы, я могу просто загрузить class файл с загрузчиком классов, и пусть JVM выяснит это... Но я чувствовал себя ленивым, поэтому я просто grep Эд для public final synthetic в байт-код и запустить uniq -D чтобы увидеть только дублированные записи.

Это происходит в режиме разработки при использовании JSNI. Так как режим super dev напрямую отлаживается в браузере с помощью чистого java-скрипта, строгого приведения типов нет и ошибок нет. Где, как и в режиме разработки, выполняется код Java, и из-за строгого приведения типов вы получите исключение формата класса. Там безрезультатно. Та же проблема и с старшими чартами. Если он хорошо работает в режиме производства и в режиме супер разработчика, вам не стоит об этом беспокоиться. Надеюсь, поможет.

Другие вопросы по тегам