TeaVM — ещё один способ запускать Java в браузере

    Уважаемые читатели! Хочу поделиться с вами своим open-source проектом, над которым я работаю в своё свободное время уже достаточно давно, TeaVM. TeaVM представляет собой транслятор из байткода Java в JavaScript. Существует несколько попыток создать JVM на JavaScript, одна из самых удачных — Doppio. Однако, кроме академической, никакой ценности они не представляют, так как скорость интерпретации байт-кода оставляет желать лучшего. Более того, для интерпретации байткода необходимо как минимум загрузить этот байткод в браузер, а это вырождается в загрузку десятков мегабайт class-файлов.

    В отличие от них, TeaVM не интерпретирует байткод, а генерирует JavaScript, который выполняет ровно то, что делал бы байткод, будь он запущен в реальной JVM. Проще говоря, TeaVM декомпилирует байткод Java, но не обратно в Java, а в JavaScript. Разумеется, всё это верно до определённых пределов. Во-первых, в JavaScript попросту отсутствуют некоторые вещи, привычные Java-разработчикам, такие как потоки, полноценная поддержка Юникода (например, поддержка классов символов, регулярные выражения), блокирующий ввод-вывод. Во-вторых, это обусловлено требованиями, которые я предъявлял к компилятору. Например, в TeaVM очень ограничена поддержка reflection. Это следствие одного из преимуществ TeaVM — сравнительно небольшой размер генерируемого файла. Нет, TeaVM не генерирует минимально возможный JavaScript, однако и не станет генерировать огромные многомегабайтные скрипты на каждый чих. Reflection делает невозможным какой-либо статический анализ, поэтому было принято решение от него отказаться.

    Прежде чем я продолжу, я хочу для начала показать, на что способен TeaVM. Во-первых, он способен в реальном времени симулировать физику. Во-вторых, он ещё способен по этой физике рисовать красивые картинки в Canvas. Можно увидеть, что JavaScript-файлы сравнительно небольшие. Кстати, обсчёт физики я сам не реализовывал, я всего лишь взял имеющуюся библиотеку JBox2D.

    TeaVM задумывался как инструмент для разработчика, который был бы пригоден для разработки браузерных приложений на Java, а не как ещё один академический проект. Я считаю, что подобного рода инструмент должен обладать следующими характерными чертами:
    • Приемлемая скорость работы. Никто не будет ждать компилятор часами. А ещё лучше — очень быстрая скорость работы, чтобы разработчик не ждал по несколько минут ради того, чтобы посмотреть, сдвинулась ли кнопочка после его правок в коде.
    • Быстрый JavaScript.
    • Компактный JavaScript. Пользователь будет очень зол на разработчика, увидев, что страница беспричинно тянет за собой мегабайты JavaScript. Точнее, пользователь не будет смотреть на размер, но вот снижение скорости загрузки страницы заметит невооружённым взглядом.
    • Хорошая поддержка набора классов из JDK. Java — это не только язык программирования, но и набор классов из стандартной библиотеки, которые Java-разработчики привыкли использовать в своей повседневной работе.
    • Поддержка популярных систем сборки. Таковой в мире Java является, прежде всего, Maven, хотя в последнее время популярность набирает Gradle.
    • Поддержка популярных IDE: Eclipse, Netbeans, IntelliJ IDEA.
    • Возможность отладки кода, «запущенного» в TeaVM. Поверьте, очень неприятно отлаживать сгенерированный JavaScript, я лично пробовал.
    • Возможность интегрироваться с имеющимися библиотеками JavaScript и с API браузера.

    Всё вышеперечисленное так или иначе реализовано в TeaVM. Правда, я не могу вот так взять и реализовать всё сразу, поэтому из систем сборки пока поддерживается только Maven, а из IDE — Eclipse. В планах сделать поддержку остальных IDE и систем сборки.

    Создание проекта


    Я постарался сделать создание нового проекта как можно более простым. Для этого нужно всего лишь выполнить следующую команду в консоли:
    mvn -DarchetypeCatalog=local \
      -DarchetypeGroupId=org.teavm \
      -DarchetypeArtifactId=teavm-maven-webapp \
      -DarchetypeVersion=0.2.1 \
      archetype:generate
    

    Если вы — пользователь Windows, то вам необходимо будет слегка переписать данную команду. А ещё проще — взять соответствующие реквизиты и использовать их для создания нового Maven-проекта в IDE. Кстати, если ваша IDE — Eclipse, то есть смысл установить плагин из репозитория.

    С имеющимся проектом можно поиграться. Если есть вопросы, можно обратиться к документации. А если вы не нашли ответ на свой вопрос в документации, публикуйте его в виде issue в GitHub.

    Плагин к Eclipse


    Код для production генерируется системой сборки, однако при разработке каждый раз пересобирать проект не слишком удобно. Ведь для этого необходимо каждый раз запускать maven, то есть стартовать новую JVM, которой нужно время, чтобы прогреться. А значит, сборка будет осуществляться медленно. Запуская ту же сборку в уже прогретой JVM, в которой работает IDE, можно добиться существенного увеличения скорости сборки. Кроме того, в IDE возможно запускать сборку и публикацию JavaScript при изменении исходников. Таким образом можно добиться цикла, традиционного для обычного JavaScript — сохранили и обновили страницу в браузере. Собственно, эта возможность и реализована в плагине для Eclipse.

    Другим моментом, который я считаю необходимым, является автоматическая настройка проекта. Например, если в проект приходит новый участник, то очень не хочется заставлять его читать длинный мануал по настройке проекта в IDE, который, к тому же, содержит ошибки, поэтому придётся ещё и потратить своё время на помощь новичку. Или, если мне захотелось поработать над проектом на даче с ноутбука, то очень не хочется повторять те шаги, которые я уже когда-то проделал в офисе. Если же проект собирается Maven, то IDE откроет и настроит его так, как нужно. Я не хотел лишать этой возможности разработчиков, которые используют TeaVM, поэтому создал так же и конфигуратор для m2e. Это позволило добиться того, что разработчик должен всего лишь импортировать проект Maven или создать проект из архетипа, после чего проект можно запускать на готовом сервере и наслаждаться разработкой, как видно из туториала.

    Наконец, очень важной является возможность отлаживать код. В GWT есть DevMode, который запускает код в JVM и соединяется с браузером, передавая ему все нативные вызовы JavaScript. Однако, в связи с прекращением поддержки NPAPI в некоторых браузерах, стало невозможно дальше поддерживать плагин для браузеров, который принимал соединения и исполнял команды DevMode. Надо сказать, что это не разработчики GWT такие нехорошие, что не хотят переписывать плагин, это разработчики браузеров такие плохие, что не придумают, как же подружить JavaScript с синхронным вводом-выводом.

    В качестве альтернативы команда GWT предлагает использовать SuperDevMode, который
    основан на source maps. Source maps плохи тем, что разработчик вынужден отлаживать код не в том же месте, в котором он его пишет. Более того, браузер не предоставляет всех крутых фишек, которые доступны в IDE. Наконец, source maps попросту не могут переводить такие вещи, как имена переменных, полей, методов, классов.

    Как же я поступил? Если браузер понимает source maps, то пусть source maps понимает и IDE. Но только пусть это будут улучшенные source maps. В итоге, помимо стандартных source maps, TeaVM генерирует свою отладочную информацию, а так же содержит плагин, который позволяет этой отладочной информацией воспользоваться в Eclipse. Если хотите посмотреть, что получилось, можете сами попробовать.

    Подытоживая, хочу заметить, что плагин для Eclipse является не просто инструментом, а ещё и своего рода proof of concept, показывая, что на основе имеющегося в TeaVM функционала вполне возможно создавать плагины для IDE. Реализовать плагины к другим IDE теперь уже дело техники.

    Планы


    На самом деле, проекту ещё развиваться и развиваться. Планов много, вот лишь некоторые из них:
    • План на ближайшее время — реализовать альтернативный бэкенд для libGDX. GWT не вполне удовлетворяет авторов фреймворка, кроме того, TeaVM уже работает быстрее, и ещё есть простор для дальнейших оптимизаций.
    • Крутая библиотека для клиентской разработки. Сейчас всё, что есть, — это тонкие обёртки вокруг некоторых браузерных API. Разумеется, для разработки приложений нужно что-то поудобнее. TeaVM сам по себе никогда не включит каких-либо библиотек для разработки клиентских приложений. Это — совсем другой проект. Возможно, удастся взять готовую библиотеку, которая работает на том же GWT, и адаптировать её для TeaVM. Впрочем, уже есть один такой фреймворк, DukeScript, но мне категорически не нравится ни его реализация ни то, как он недокументирован; тем не менее, я включил его поддержку в TeaVM.
    • Автоматическая генерация асинхронного кода. Не нравится мне лапша из callback'ов. А в силу того, что блокирующие операции в JavaScript отсутствуют как класс, их можно эмулировать, специальным образом преобразуя код.
    • Множество оптимизаций. В движках JavaScript есть очень хорошие оптимизаторы, но они не всегда знают о коде то, что доступно статическому оптимизатору. В силу того, что TeaVM внутри использует представление SSA, различные оптимизации реализуются достаточно просто и безболезненно.
    • Реализовать ещё больше классов из JDK.
    • Реализовать поддержку инструкции INVOKEDYNAMIC, в частности, для того, чтобы можно было запускать лямбды из Java 8.
    • Подружить TeaVM с Kotlin и Scala. В самом байткоде, который они генерируют, нет ничего особенного и TeaVM отлично переводит его в JavaScript. Однако, рантаймы этих языков используют классы JDK, которые не реализованы в TeaVM. Решается это либо реализацией данных классов, либо переписывание соответствующей части рантайма.


    Почему не ...



    … GWT?


    Я достаточно много пишу на GWT, и я очень недоволен этим фреймворком. Идея генерировать JavaScript из исходников является крайне неудачной.
    • Необходимо плодить костыли на уровне системы сборки, чтобы правильно подключать исходники всех библиотек к системе сборки.
    • Нет поддержки других языков. Для некоторых языков, есть собственный аналоги GWT, например, Scala.js и нативная поддержка в Kotlin. Однако, у них есть другой недостаток: невозможность взаимодействия с существующими Java-библиотеками.
    • GWT никак не интегрировать с утилитами, преобразующими или генерирующими байткод.

    Помимо этого, у меня есть ряд претензий к тому, как реализован GWT, а именно:
    • Команда GWT фактически отказалась от поддержки DevMode — единственной возможности отлаживать код. Есть SuperDevMode, но он крайне неудобен.
    • GWT работает довольно-таки медленно. А тот факт, что он ещё и генерирует перестановки, делает сборку невыносимо долгой.
    • Идея держать сгенерированный JavaScript на отдельном сервере побуждает плодить костыли и натыкаться на всевозможные проблемы, связанные с тем, что ресурсы (картинки, CSS), RPC и код находятся на разных серверах во время отладки, но при этом на одном сервере — в боевых условиях.

    При этом писать на JavaScript мне не нравится тем более из-за динамической природы языка. Поэтому из двух зол я выбираю GWT, но мне хочется чего-то получше.

    … emscripten?


    На первый взгляд TeaVM очень похож на emscripten. Так почему я просто не перевожу байткод Java в LLVM? Ведь LLVM уже содержит готовую реализацию SSA. Всё дело в том, что LLVM очень низкоуровневый. Это хорошо, когда программа компилируется в нативный код, но вот когда она декомплилируется в высокоуровневый язык, получается некоторый оверхед. Ведь с JavaScript уже есть такие понятия, как поля, методы, GC. А в LLVM это всё пришлось бы снова эмулировать на JavaScript. Другая причина заключается в том, что TeaVM полностью написан на Java, компилятор можно, например, заэмбеддить, что не было бы возможным в случае в LLVM и emscripten. Наконец TeaVM использует чуть более мощные алгоритмы декомпиляции, чем emscripen.
    Ads
    AdBlock has stolen the banner, but banners are not teeth — they will be back

    More

    Comments 53

      +1
      > Команда GWT фактически отказалась от поддержки DevMode — единственной возможности отлаживать код.
      Почему? Я вот только-только начал регулярно писать на GWT и DevMode спасает :)
      Они как раз недавно обновили плагин для Chrome, для других браузеров, правда, забросили.
        +1
        Откуда инфа об обновлении плагина для Chrome? Я не слышал. А вот то, что плагин для Chrome уже несколько месяцев как перестал работать — это вполне себе объективная реальность. Вот приведу пару ссылок:
        pgt.de/2013/12/13/beyond-devmode-the-future-of-gwt-debugging/ lustforge.com/2014/06/12/restoring-the-chrome-gwt-devmode-plugin/
        Не помню точно где, но слышал информацию, что к 2.7 они вообще собираются убрать DevMode.

        А вообще, у DevMode есть ещё недостатки. Например, он долговато стартует. Ещё беда в том, что программа фактически работает в настоящей JVM, и иногда в ней нормально работает то, что не очень хорошо работает в GWT. Например, каково было однажды моё удивление, когда программа, нормально работавшая в DevMode, внезапно заглючила на проде. А оказалось вот: code.google.com/p/google-web-toolkit/issues/detail?id=1983
          0
          Я вчера отлаживал код в последнем хроме при помощи этого плагина :)
          Я уж не знаю, как он там заработал. Как минимум в маке и на винде работает.
            +1
            Скоро перестанет. Разработчики google chrome обещали полностью дропнуть NPAPI до конца 2014 года. Как видим, пользователям Linux повезло меньше всех.
          +1
          DevMode использовал NPAPI, от которого Chrome отказался. Можете почитать подробнее на английском.

          Выше привели ссылки, я не заметил.
          0
          а вместо GWT не пробовали посмотреть на ZK?
            0
            deleted
              +1
              Ну как бы их банально нельзя сравнивать, потому что ZK работает целиком на сервере, по принципу Vaadin. Соответственно, это трафик по любому поводу + хранение состояния формы на сервере, со всеми последствиями. А что такое GWT? По сути, разработчики слепили в одном продукте две разные технологии. С одной стороны, это компилятор из Java в JS, с другой — целый фреймворк для написания браузерных приложений. Можно вообще не использовать этот фреймворк, и всё равно писать на GWT. Например, уже приведённый мной пример с libGDX.

              Если сравнивать ZK с библиотекой виджетов от GWT, то да, первый побеждает. В этом аспекте GWT действительно ужасен. Однако, ZK не умеет в принципе делать того, что можно с GWT. Например, написать игру на Java и распространять её на как на Androd и iOS (через RoboVM), так и через браузер.
              +2
              Интересно, а что если байткод Java транслировать в asm.js? Мне кажется, получилась бы очень быстрая VM. :)
                0
                Нет, очень быстрая VM не получилась бы, хотя бы потому, что разработчики google chrome не согласны с идеей asm.js и не собираются включать его поддержку в свой браузер. Поддержка ams.js к тому же тянет за собой очень много сложностей. Скажем, придётся полностью написать GC, поддержку исключений, придумать, как сделать взаимодействие с нативным JS из asm.js. А так, скорость и сейчас очень радует.
                  0
                  asm.js уже очень давно поддерживается в chrome, более того поддержку обещали также в ИЕ12.
                    +1
                    Ну что же, наверное, в этом я был не прав. В любом случае, у меня вряд ли найдутся силы поддерживать ещё и asm.js, куда будет включаться разработка своего GC, поддержка исключений и поддержка со стороны эмуляции библиотеки JDK. Если у кого найдутся силы и желания — форкайте :-)
                      0
                      А можно узнать, откуда дровишки? Если вы про этот пост: Chrome 28 Beta: A more immersive web, everywhere то там лишь сказано, что asm.js бенчмарки стали быстрее в новой версии хрома относительно предыдущей за счет оптимизаций арифметики в Hydrogen IR (маркетологи такие маркетологи). Что касается полноценной поддержки asm.js с директивой 'use asm' и переключением на оптимизирующий компилятор сразу минуя стадию сборки type feedback как это делает OdinMonkey, то эта тема находится в полумертвом состоянии и пока никто браться за ее реализацию в команде v8 не планирует: Implement «use asm». Относительно firefox на данный момент хром медленнее примерно в 3 раза на asm.js коде, т.к. использует general purpose JIT для него.
                        0
                        Я узнал от opennet.

                        + После проверил на демки от Epic Games — Epic Citadel, которая до внедрения этой поддержки у меня просто висела медным тазом, а стало летать.

                        Но в любом случае, это лучше чем ничего.
                          0
                          Ну, они заоптимизили попросту арифметику, что дало эффект на число дробилки. Но, до полноценного asm.js там еще как до луны по перфомансу.
                      0
                      Разработчики asm.js планируют добавить поддержку GC и структур(typed object) — asmjs.org/faq.html
                      Но видимо это не скоро :( — необходимая фича(typed_objects) перехала из ES6 в ES7.
                      +1
                      Не получится еще и потому что asm.js заточен сугубо под число дробилки, быстрые строки/объекты/коллсайты не завезли. А в общем и целом мономорфный JS (который и получится в случае трансляции с типизированного языка) очень-очень хорошо оптимизируется современными JIT'ами.
                        +1
                        Кстати, мне пришла в голову мысль: если уж сам рантайм переписывать долго и муторно (да ещё и есть риск получить огромный JS), то почему бы не попытаться эвристически определять, какие методы можно транслировать в asm.js и выборочно оптимизировать действительно числодробительные методы. Скажем, в jbox2d их предостаточно. Я всё равно собирался делать инлайнинг и escape analysis, а они должны сильно поспособствовать образованию подобного рода asm.js-совместимых числодробилок.
                          0
                          Да, это вариант. С инлайнингом самому лучше не играться и отдать это на откуп JS-движку, т.к. есть вероятность увеличить полиморфность функции и как следствие увеличить количество bailout'ов, а в итоге v8 может вообще забить на оптимизацию такой функции , что выйдет только боком.
                            0
                            Без инлайнинга скорее всего будет мало смысла от эвристики с asm.js. Если с ним аккуратно поиграться, то можно и добиться прироста производительности. Я хотел использовать инлайнинг лишь для того, чтобы открыть простор для дальнейших оптимизаций, того же escape analysis или constant propagation вместе dead code elimination. Можно сделать откат инлайнинга, если после него не удалось сильно оптимизировать метод.
                              0
                              Да, можно попробовать такой механизм, главное что бы накладные расходы на рантайм-профайлинг и откат к незаинлайненой функции не были велики. А self-hosting планируете (с компиляцией в node-тулзу)? Был бы отличный полигон для выявления проблем.
                                0
                                Откат к незаинлайненной функции я не могу делать в рантайме, т.к. TeaVM — это AOT. Имеется в виду, во время компиляции я мог бы делать инлайнинг и смотреть, получилось ли после него сделать оптимизации. Если не получилось, откатывать инлайнинг и дальше уже отправлять исхоный SSA в генератор JS.

                                А что за self-хостинг?
                                  0
                                  Self-hosting является де-факто показателем зрелости компилятора. Это когда компилятор компилирует сам себя. Вики ссылка на всякий: Self-hosting.
                                    0
                                    К сожалению, достаточно сложно сделать самокомпиляцию TeaVM, потому что помимо собственно компиляции есть средства расширения компилятора, аналогичные generators в GWT. Допустим, я скомпилирую TeaVM и получу TeaVM.js. TeaVM.js могут подсунуть файл foo-library.jar, в котором предоставлено расширение. Как TeaVM.js загрузит это расширение? Ответ — оперативненько скомпилит его. Но с этим связан ряд сложностей, т.к. TeaVM изначально AOT, и пока я не вижу сильной необходимости делать JIT, т.к. это хоть и выглядит как крутая и интересная задача, но на практике никто не будет использовать такую возможность.
                      0
                      Это учебный проект? Сама по себе задача интересная, но вот с практической точки зрения ни один такой вариант не прокатывал.
                        +3
                        Почему же учебный? Вполне себе практический, я об этом в самом начале и пишу. И какой же такой вариант не прокатывал с практической точки зрения? Может, потому и не прокатывали, что авторы не ставили целью сделать практически полезный инструмент?
                        0
                        В своё время хотел использовать для этого ceylon. Он очень похож на джаву, и так же транслируется в js (вроде). Но времени им заняться небыло…
                          0
                          Ещё раз повторяю: трансляция из языка в язык — дело не слишком благодарное. Например, я показал свой бенчмарк разработчикам Kotlin, которые так же умеют генерировать JS, и они не смогли сделать такой же для сравнения? Почему? Потому что я использую JBox2D, написанную на Java, а не на Kotlin. А вот когда у меня всё-таки дойдут руки реализовать рантайм Kotlin'а, можно будет запускать в браузере приложения на Kotlin, которые используют библиотеки, написанные на Java.
                          0
                          У меня вопрос к автору: чем вам так не понравился superdevmode? По-моему с ним довольно просто дебажить, учитывая возможности хрома и фаирфокса.
                            0
                            Потому что
                            • Приходится переключаться между браузером и IDE при отладке, мне удобнее отлаживать код там же, где я его пишу.
                            • В IDE есть продвинутые средства навигации по коду, которых нет в браузере. Например, как в Chrome найти нужный класс по части имени? А как найти все реализации метода интерфейса или абстрактного класса? Это уж не говоря про то, что нельзя по Ctrl+Click перейти к нужному мне классу, имя которого я увидел в коде.

                            А FF так вообще очень неудобно сделали отображение стектрейса. Но для любителей дебажить в браузере TeaVM умеет генерировать обычные source maps.
                              0
                              А зачем переключаться? Ведь по сути дела у вас есть исходный код в дебагере браузера.
                                0
                                В дебаге браузера код, который отдаёт код-сервер GWT. Изменения в нём, очевидно, никак не могут быть сохранены на диск. Допустим, нашёл я причину баги и хочу поправить. Обратно в IDE? А потом обратно в браузер дебажить дальше?

                                Далее, для поиска баги мне нужно смотреть различные участки кода. В браузере мне приходится искать нужные файлы в дереве исходников.
                                  0
                                  Понял вашу мысль.Спасибо за ответ.

                                  В принципе можно попробовать заставить прокидывать дебаг инфу в IDE, написав плагин для браузера и IDE
                                    +1
                                    TeaVM уже так делает :-)
                                    0
                                    Скажите, а связка «IntelliJ Idea + CSS-X-Fire + GWTP + JS Debugger» не предоставляет такой возможности? (спрашиваю, потому как сам с GWT пока не работал)
                                      0
                                      Никогда в такой связке не работал. Знаю только, что в последних версиях IDEA сделали поддержку source maps, но я её пока не пробовал.
                              0
                              Нет поддержки других языков. Для некоторых языков, есть собственный аналоги GWT, например, Scala.js и нативная поддержка в Kotlin. Однако, у них есть другой недостаток: невозможность взаимодействия с существующими Java-библиотеками.


                              А при использовании серьезных Java библиотек не возникнет ли проблем с быстродействием?
                                +1
                                Это зависит от того, какие библиотеки используются. Примеры, которые я привёл в статье, использую JBox2D. Надо сказать, что обсчёт физики — это в принципе затратная штука, сложные сцены тормозят и на JVM. TeaVM генерирует достаточно быстрый код, наверное, очень близкий к практическому пределу.
                                0
                                Хороший проект — нужный! Желаю вам скорейшего роста опенсорс комьюнити.
                                  0
                                  Спасибо большое за пожелания!
                                  0
                                  А нет ли online где посмотреть — как у kotlin или go
                                  А так, всегда восхищался людям которые пишут такие большие проекты. Это вам не формочки в вебе выводить.

                                  Можно пример как TeaVM переведёт в javascript какой нибуть pojo — например такой, первое что в голову пришло — pastebin.com/TL9Qi4xZ

                                  Вы крутой) Удачи с проектом.
                                    +1
                                    Спасибо за похвалу :-)

                                    Да, это хорошая идея — сделать онлайн просмотр. К сожалению, это за час не сделается, но я буду работать в данном направлении и когда-нибудь сделаю подобного рода страничку. В перспективе может я научусь запускать через TeaVM сам TeaVM и javac, тогда такую демку можно будет сделать даже без компиляции на сервере. Но это дело совсем уж далёкого будущего.

                                    Pojo в JavaScript переводить нет особого смысла, потому что TeaVM нацелен на перевод кода, который что-то делает. Вот если с этим pojo что-то сделать в методе main, тогда можно получить JavaScript. Но нет, TeaVM не переводит в режиме один класс = один JS. TeaVM скомпилирует сам метод main, те методы pojo, которые были вызваны из main, а так же некоторый минимальный набор методов для поддержания работоспособности рантайма.

                                    А пока остаётся довольствоваться скомпиленными примерами онлайн и архетипом, с помощью которого можно за 5 секунд создать новый проект и поиграться. Благо, для сборки созданного проекта тоже нужно всего лишь запустить mvn clean package.
                                      0
                                      Спасибо за ответ, нет под рукой idea чтобы попробовать самому, но буду следить за вашим проектом — по мне выходит хорошая штука.

                                      А вообще как вы докатились до жизни такой, где брали инфу про jvm байт код и прочее в книжках этого к сожалению не пишут.
                                      Я давно пишу на java и сейчас решил подтянуть знания по java annotation preprocessor инфы очень мало даже на Eng где собственно и ищу.

                                      Может есть какая то книга(и) о которых я не знаю, где поднимаются темы наподобие этим. Хотя я вроде слежу за новинками — и в дробпоксе лежит книг 30 по java. Но ни в одной не затрагиваются такие вещи.
                                        0
                                        Не обязательно использовать для этого IDEA. Подойдут Eclipse и Netbeans, да и в блокнотике можно поиграться.

                                        Про байткод можно прочитать в VM Spec. Правда, там очень много всего о бинарном формате классов, о тонкостях работы самой JVM и т.д. Полезнее будет почитать шестую главу. Но это только после чтения прекрасного мануала по библиотеке ASM. Докатился я до этого давно, из-за того, что порой приходится на уровне байткода патчить поделия индусокодеров, в случае если нет исходников к jar-файлу. Впрочем, иногда с помощью ASM можно и просто делать крутое метапрограммирование.

                                        Я ещё со школы интересовался построением компиляторов, когда пытался ломать байсик ZX Spectrum. Уже позже, в институте, почитал книгу дракона. Она хоть и содержит устаревшие сведения, всё же полезна для понимания того, как работают компиляторы. В разрезе TeaVM полезны последние главы.

                                        Как узнал про SSA, точно не помню, но узнал при работе над TeaVM. По SSA в сети лежит огромное количество информации, начать можно с классики. Осторожно, в статье приведён неправильный алгоритм устранения φ-функций! Анализ графа вызовов я делал согласно статье Practical Virtual Method Call Resolution for Java, а алгоритм декомпиляции навеян Decompiling Java Bytecode: Problems, Traps and Pitfalls. Эти статьи я нашёл, когда думал, как сделать TeaVM и специально искал в сети полезную информацию по теме.

                                        По annotation processors ничего сказать не могу, не использовал. Вообще, считаю кодогенерацию не лучшей идеей (кстати, именно поэтому меня не устраивает DukeScript). Единственное место, где она пока оказалась действительно уместной — это в QueryDSL.
                                    0
                                    Идея отличная! А Вы один работаете? У Вас сейчас только плагин для Eclipse. А в сторону IDEA не смотрели? Как среда для Java разработки она помощнее Eclipse будет. (не холивара ради — сам активно Eclipse пользовался 4 года, даже плагин писал). Может и для неё плагин написать? А то что она платная, так для Ваших целей, я думаю, выделят бесплатную лицензию — у них, насколько я знаю, есть поддержка open source проектов.
                                    Ещё не понял на счёт поддержки source map в Вашей системе — как в итоге происходит debug? В IDEA есть поддержка source map и dubug в IDE (реализуется с помощью плагина к браузеру, пробовал в Chrome). Пока сырая, но к выходу новой версии (14-й), обещают реализовать.
                                    И как у Вас реализована поддержка Reflection? Ограничение GWT (иногда существенное) — практически полное отсутствие Reflection. Но можно, к примеру, перебрать аннотации к объекту или методу. В статье, Вы указали, что Reflection нет. Т.е. его нет совсем или какие-то возможности присутствуют?
                                      +1
                                      В сторону IDEA смотрел, но т.к. лично я работаю в Eclipse (и писал плагин прежде всего для того, чтобы мне самому было удобнее), и т.к. по интересующим меня темам нашёл больше документации именно для Eclipse, то и плагин написал для Eclipse. В будущих версиях сделаю плагин для IDEA.

                                      Дебаг происходит так. Плагин соединяется с Google Chrome (пока есть поддержка только для него) по remote debugging protocol. Remote debugging protocol общается в терминах JS — для брейкпоинтов принимает номера строк в скрипте, обратно отдаёт стектрейс и значения переменных, как они появляются в скрипте. Плагин умеет делать маппинг. Для этого ему нужна информация о том, какая строка в Java соответствует строке в JavaScript, аналогично с именами переменных, классов, полей и методов. Такой информацией обладает компилятор TeaVM, он её записывает в специальный файлик. Плагин читает этот файлик и знает, как маппить. Этот файлик — это не source maps, потому что в source maps сильно ограничены возможности.

                                      Далее, в Eclipse есть специальный API, который позволяет делать свои дебаггеры. Он посылает ему команды и ожидает от него различные события, такие как resume, suspend, terminate. Я реализую этот API и в нём показываю то, что получается после маппинга.

                                      Reflection почти не поддерживается. В перспективе можно сделать поддержку метаданных: чтение информации о методах и полях классов, аннотаций. Но вот вызов метод через reflection или реализовать Proxy не получится. Вместо этого в GWT предлагается использовать генераторы. В TeaVM есть аналогичный, который я пока не задокументировал.
                                      +1
                                      Оч. интересный проект. Сам давно пишу на GWT, писал даже к нему библиотеку для сериализации: code.google.com/p/gwt-streamer/ Не в восторге от платформы.
                                      Интересует несколько вещей:
                                      1. За счет чего все-таки достигается производительность? Разработчики GWT божились, что из .class нельзя получить эффективный JS, что и доказывают проекты вроде Eclipse Java2Script?
                                      2. Насколько я понял, проект должен включать в себя какой-нибудь API для работы с платформой браузера: DOM, Canvas, etc...?
                                      3. Есть какие-нибудь средства для включения нативного JS-кода, как например JSNI?
                                      4. Можно ли расширять или дополнять возможности поддерживаемого API Java не суясь в TeaVM? Что-то вроде GWT super-package?
                                      5. Поскольку в GWT отсутствует рефлексия, все объявления статические. Это напрямую дает легкий способ отсекать неиспользуемый код и обфусцировать его. Как обстоят дела в TeaVM? Таскается весь код или библиотека целиком?
                                        +1
                                        1. Я даже не знаю, как сказать. За счёт просто грамотного подхода. Почему разработчики GWT не осилили, я даже не знаю. Вот базовый алгоритм декомпиляции: github.com/konsoletyper/teavm/wiki/Decompilation Правда, до него байткод JVM преобразуется в SSA, этот SSA ещё немного оптимизируется и т.п.
                                        2. Да, есть тонкие обёртки вокруг некоторых браузерных объектов. Но это именно что тонкие обёртки, а не библиотека виджетов как в GWT.
                                        3. Есть возможность писать обёртки вокруг объектов JavaScript: github.com/konsoletyper/teavm/wiki/Interacting-with-JavaScript
                                        4. Можно, но только если это новые классы. Добавить метод к классу не получится.
                                        5. Да, то же самое в TeaVM. Как я и писал, я пожертвовал рефлексией ради возможность отсекать ненужный код. В целом TeaVM генерит немного больше JavaScript, чем GWT, но, как мне кажется, это из-за лишних скобок (пока не дошли руки научить TeaVM приоритету и ассоциативности), а так же из-за явных приведений чисел к целым с помощью операции |0.
                                          +1
                                          Круто! А сериализация объектов как сделана, если нет информации о полях? В GWT нужно было писать свой генератор, который вызывается на этапе компиляции и делает сериализатор для класса.

                                          Обертки можно генерировать автоматически из W3C IDL. По-моему так TypeScript по-началу делал.
                                            +1
                                            Сериализации нет, т.к. я позиционирую TeaVM исключительно как компилятор. Её нужно будет делать в виде отдельного проекта. В TeaVM информация о полях недоступна во время выполнения, но доступна во время компиляции, а так же есть различные механизмы встраивания в процесс компиляции, аналогичные генераторам.

                                            Обёртки из IDL я бы генерить не стал, ибо W3C IDL местами далеки от реальной жизни. Кроме того, всё равно придётся следить за соответствием этих обёрток возможностям JSO и вручную проставлять аннотации.
                                        +1
                                        Мне нравится подход. Надеюсь, он даст идее трансляции Java в JavaScript второе дыхание, потому что я слышал много негативных отзывов от разных людей о GWT, и почти не слышал позитивных. Сам я написал всего один реальный проект c использованием GWT, и не могу сказать, что так уж всё плохо. Сейчас хочу попробовать TeaVM для написания игрового приложения. Кстати, как вы смотрите на идею создания backend для PlayN?

                                        В GWT есть очень удобная возможность подменять класс на этапе генерации кода. Это требуется, когда трансляция какого-либо класса не может быть выполнена, но этот класс можно заменить native реализацией с проксированием вызовов. Такое возможно в TeaVM? Прежде всего интересует взаимодействие с графикой и звуком. Я знаю, что есть взаимодействие с JavaScript, но меня интересует именно подмена реализации, чтобы искодный код/байткод не нужно было модифицировать. Я почти ничего не знаю про JVM байткод, поэтому, возможно, вопрос глупый, и выделить отдельный класс из всего кода невозможно.
                                          +1
                                          На идею создания бэкэнда для PlayN смотрю положительно. Сам делаю бэкэнд для libGDX, думаю, после этого для PlayN будет совсем просто сделать.

                                          Сейчас нельзя подменять отдельные классы, можно подменять целый пакет (так сделана эмуляция классов JDK). Сделать доработку, чтобы можно было подменять отдельные классы, несложно.
                                          –1
                                          Неправильно вы назвали программу, т. к. уже есть icedtea-plugin (IcedTea) — плагин к браузеру для запуска Java-апплетов, во всяком случае есть пакет в Дебиане под названием icedtea-7-plugin

                                          Only users with full accounts can post comments. Log in, please.