- PVSM.RU - https://www.pvsm.ru -
Уважаемые читатели! Хочу поделиться с вами своим open-source проектом, над которым я работаю в своё свободное время уже достаточно давно, TeaVM [1]. TeaVM представляет собой транслятор из байткода Java в JavaScript. Существует несколько попыток создать JVM на JavaScript, одна из самых удачных — Doppio [2]. Однако, кроме академической, никакой ценности они не представляют, так как скорость интерпретации байт-кода оставляет желать лучшего. Более того, для интерпретации байткода необходимо как минимум загрузить этот байткод в браузер, а это вырождается в загрузку десятков мегабайт class
-файлов.
В отличие от них, TeaVM не интерпретирует байткод, а генерирует JavaScript, который выполняет ровно то, что делал бы байткод, будь он запущен в реальной JVM. Проще говоря, TeaVM декомпилирует байткод Java, но не обратно в Java, а в JavaScript. Разумеется, всё это верно до определённых пределов. Во-первых, в JavaScript попросту отсутствуют некоторые вещи, привычные Java-разработчикам, такие как потоки, полноценная поддержка Юникода (например, поддержка классов символов, регулярные выражения), блокирующий ввод-вывод. Во-вторых, это обусловлено требованиями, которые я предъявлял к компилятору. Например, в TeaVM очень ограничена поддержка reflection. Это следствие одного из преимуществ TeaVM — сравнительно небольшой размер генерируемого файла. Нет, TeaVM не генерирует минимально возможный JavaScript, однако и не станет генерировать огромные многомегабайтные скрипты на каждый чих. Reflection делает невозможным какой-либо статический анализ, поэтому было принято решение от него отказаться.
Прежде чем я продолжу, я хочу для начала показать, на что способен TeaVM. Во-первых, он способен в реальном времени симулировать физику [3]. Во-вторых, он ещё способен по этой физике рисовать красивые картинки [4] в Canvas. Можно увидеть, что JavaScript-файлы сравнительно небольшие. Кстати, обсчёт физики я сам не реализовывал, я всего лишь взял имеющуюся библиотеку JBox2D [5].
TeaVM задумывался как инструмент для разработчика, который был бы пригоден для разработки браузерных приложений на Java, а не как ещё один академический проект. Я считаю, что подобного рода инструмент должен обладать следующими характерными чертами:
Всё вышеперечисленное так или иначе реализовано в 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, то есть смысл установить плагин из репозитория [6].
С имеющимся проектом можно поиграться. Если есть вопросы, можно обратиться к документации [7]. А если вы не нашли ответ на свой вопрос в документации, публикуйте его в виде issue в GitHub.
Код для production генерируется системой сборки, однако при разработке каждый раз пересобирать проект не слишком удобно. Ведь для этого необходимо каждый раз запускать maven, то есть стартовать новую JVM, которой нужно время, чтобы прогреться. А значит, сборка будет осуществляться медленно. Запуская ту же сборку в уже прогретой JVM, в которой работает IDE, можно добиться существенного увеличения скорости сборки. Кроме того, в IDE возможно запускать сборку и публикацию JavaScript при изменении исходников. Таким образом можно добиться цикла, традиционного для обычного JavaScript — сохранили и обновили страницу в браузере. Собственно, эта возможность и реализована в плагине для Eclipse.
Другим моментом, который я считаю необходимым, является автоматическая настройка проекта. Например, если в проект приходит новый участник, то очень не хочется заставлять его читать длинный мануал по настройке проекта в IDE, который, к тому же, содержит ошибки, поэтому придётся ещё и потратить своё время на помощь новичку. Или, если мне захотелось поработать над проектом на даче с ноутбука, то очень не хочется повторять те шаги, которые я уже когда-то проделал в офисе. Если же проект собирается Maven, то IDE откроет и настроит его так, как нужно. Я не хотел лишать этой возможности разработчиков, которые используют TeaVM, поэтому создал так же и конфигуратор для m2e. Это позволило добиться того, что разработчик должен всего лишь импортировать проект Maven или создать проект из архетипа, после чего проект можно запускать на готовом сервере и наслаждаться разработкой, как видно из туториала [8].
Наконец, очень важной является возможность отлаживать код. В GWT есть DevMode, который запускает код в JVM и соединяется с браузером, передавая ему все нативные вызовы JavaScript. Однако, в связи с прекращением [9] поддержки NPAPI [10] в некоторых браузерах, стало невозможно дальше поддерживать плагин для браузеров, который принимал соединения и исполнял команды DevMode. Надо сказать, что это не разработчики GWT такие нехорошие, что не хотят переписывать плагин, это разработчики браузеров такие плохие, что не придумают, как же подружить JavaScript с синхронным вводом-выводом.
В качестве альтернативы команда GWT предлагает использовать SuperDevMode [11], который
основан на source maps [12]. Source maps плохи тем, что разработчик вынужден отлаживать код не в том же месте, в котором он его пишет. Более того, браузер не предоставляет всех крутых фишек, которые доступны в IDE. Наконец, source maps попросту не могут переводить такие вещи, как имена переменных, полей, методов, классов.
Как же я поступил? Если браузер понимает source maps, то пусть source maps понимает и IDE. Но только пусть это будут улучшенные source maps. В итоге, помимо стандартных source maps, TeaVM генерирует свою отладочную информацию, а так же содержит плагин, который позволяет этой отладочной информацией воспользоваться в Eclipse. Если хотите посмотреть, что получилось, можете сами попробовать [13].
Подытоживая, хочу заметить, что плагин для Eclipse является не просто инструментом, а ещё и своего рода proof of concept, показывая, что на основе имеющегося в TeaVM функционала вполне возможно создавать плагины для IDE. Реализовать плагины к другим IDE теперь уже дело техники.
На самом деле, проекту ещё развиваться и развиваться. Планов много, вот лишь некоторые из них:
Я достаточно много пишу на GWT, и я очень недоволен этим фреймворком. Идея генерировать JavaScript из исходников является крайне неудачной.
Помимо этого, у меня есть ряд претензий к тому, как реализован GWT, а именно:
При этом писать на JavaScript мне не нравится тем более из-за динамической природы языка. Поэтому из двух зол я выбираю GWT, но мне хочется чего-то получше.
На первый взгляд TeaVM очень похож на emscripten [19]. Так почему я просто не перевожу байткод Java в LLVM? Ведь LLVM уже содержит готовую реализацию SSA. Всё дело в том, что LLVM очень низкоуровневый. Это хорошо, когда программа компилируется в нативный код, но вот когда она декомплилируется в высокоуровневый язык, получается некоторый оверхед. Ведь с JavaScript уже есть такие понятия, как поля, методы, GC. А в LLVM это всё пришлось бы снова эмулировать на JavaScript. Другая причина заключается в том, что TeaVM полностью написан на Java, компилятор можно, например, заэмбеддить, что не было бы возможным в случае в LLVM и emscripten. Наконец TeaVM использует чуть более мощные алгоритмы декомпиляции, чем emscripen.
Автор: konsoletyper
Источник [20]
Сайт-источник PVSM.RU: https://www.pvsm.ru
Путь до страницы источника: https://www.pvsm.ru/java/72284
Ссылки в тексте:
[1] TeaVM: http://teavm.org/
[2] Doppio: https://github.com/plasma-umass/doppio
[3] симулировать физику: http://teavm.org/live-examples/jbox2d-benchmark/teavm.html
[4] красивые картинки: http://teavm.org/live-examples/geobot/
[5] JBox2D: https://github.com/jbox2d/jbox2d
[6] репозитория: http://teavm.org/eclipse/update-site/0.2.1
[7] документации: https://github.com/konsoletyper/teavm/wiki
[8] туториала: https://github.com/konsoletyper/teavm/wiki/Eclipse-tutorial
[9] прекращением: http://blog.chromium.org/2013/09/saying-goodbye-to-our-old-friend-npapi.html
[10] NPAPI: https://ru.wikipedia.org/wiki/%D0%9F%D1%80%D0%BE%D0%B3%D1%80%D0%B0%D0%BC%D0%BC%D0%BD%D1%8B%D0%B9_%D0%B8%D0%BD%D1%82%D0%B5%D1%80%D1%84%D0%B5%D0%B9%D1%81_%D0%BF%D0%BE%D0%B4%D0%BA%D0%BB%D1%8E%D1%87%D0%B0%D0%B5%D0%BC%D1%8B%D1%85_%D0%BC%D0%BE%D0%B4%D1%83%D0%BB%D0%B5%D0%B9_Netscape
[11] SuperDevMode: http://www.gwtproject.org/articles/superdevmode.html
[12] source maps: http://www.html5rocks.com/en/tutorials/developertools/sourcemaps/
[13] попробовать: https://github.com/konsoletyper/teavm/wiki/Debugging
[14] libGDX: http://libgdx.badlogicgames.com/
[15] DukeScript: http://dukescript.com/
[16] SSA: https://ru.wikipedia.org/wiki/SSA
[17] Scala.js: http://www.scala-js.org/
[18] Kotlin: http://kotlinlang.org/
[19] emscripten: https://github.com/kripken/emscripten
[20] Источник: http://habrahabr.ru/post/240999/
Нажмите здесь для печати.