Alexey Andreev
@konsoletyper
Пользователь
Information
- Rating
- Does not participate
- Location
- München, Bayern, Германия
- Date of birth
- Registered
- Activity
Specialization
Specialist
Senior
From 6,000 €
Java
Compilers
Kotlin
Gradle
А вот и нет
Ещё причина в том, что порой хочется написать про то, что делаешь на работе, а из чисто внутреннего контекста это сложно выдрать. Вот например, делаю я сейчас UI-фреймворк для игрового движка. Игровой движок проприетарный, используется чисто внутри компании для разработки внутренних продуктов. И вот для меня персональная гордость - движок стилей а-ля CSS. Там целый ворох нетривиальных технических решений, чтобы это быстро работало на больших таблицах стилей (300+ селекторов) и на больших UI (10K+ view) и в том числе, инкрементальные апдейты - это когда вы поменяли класс где-то глубоко в иерархии view или что-то небольшое добавили в уже гигансткое дерево view, и стили пересчитались не за 100 мс, и даже не за 10 - счёт идёт на микросекунды. Ну и вот как всё это расписать для внешней публики? Для этого нужно вначале взять и написать такой же UI-фреймворк в опенсорсе, а зачем и кто за это будет за это платить? А выложить уже готовый движок в опенсорс мешает руководство.
Да, такие возможности есть, но это работает только в случае, если приложение написано целиком на Kotlin. Если же это Kotlin + Java, то спасает только native image или другие подобные AOT-компиляторы. Честно, я не в курсе, что сейчас творится на этом рынке, когда-то ещё были MOE, RoboVM и Avian, здравствуют ли они поныне - я не проверял.
Есть ещё один юзкейс для graal native image: компиляция приложений под iOS. Иногда в этом есть смысл, если хочется на Java/Kotlin ваять кроссплатформенно, но нативный look&feel вообще не нужен (например, игры).
Что касается неудобств с reflection, то тут есть одно решение: не использовать. Вы не поверите, на что способны annotation processor в умелых руках, дополненных compile time инструментацией байт-кода. Хотя полагаю, что, для spring boot это может быть невозможно.
С тестами нет вообще никаких проблем (проект в репозитории содержит несколько тестов). Наоборот, в виду специфики я для подобных байткодогенераторов стараюсь побольше тестов писать. А вот отладка - только логгированием.
Кстати, для junit 4 можно писать раннеры, которые тестовые классы загружают в кастомном лоадере, что может быть очень удобно при тестировании генераторов. Увы, в 5-м авторы перемудрили с системой расширений и такая возможность пропала.
Ну зачем же c2? Я про javac, kotlinc, scalac и иже с ними. c2 - это уже уровнем пониже и немного другие скилы.
Так AOT-компиляторы обычно берут байт-код, там перед AOT-компилятором старый-добрый javac.
Вы про java.lang.reflect.Proxy? Не поддерживают.
Вот конкретно этот пример - не уверен, не пробовал. Если взять из моего примера генерацию байт-кода класса, сохранить его в виде класса с расширением class и прилинковать к проекту - класс загрузится. Какой бы ни был внутри android формат классов, SDK умеет переводить байт-код JVM в свой собственный формат. Не вижу причин, почему бы нельзя было в ClassLoader поддержать прозрачную трансляцию из байт-кода JVM в собственный формат - это должно быть тривиально. Боюсь только, что Android такой сгенерированный на лету байт-код будет интерпретировать или если сконвертирует в нативный код, то с минимальным числом оптимизаций.
Что касается моего личного опыта, то я использую на своём текущем проекте самописные генерялки байт-кода для нужд сериализации данных, RPC и привязки данных к OT. Но работают они в compile time.
Проекты проектам рознь. Где-то понимать, как генерируют байт-код JVM - это первейший необходимый навык. В компиляторных командах, например.
Прокси, как я уже написал, плохо работают с AOT-компиляторами и proguard/r8. Постоянно приходится думать, а не придётся ли мне после написания или рефакторинга очередной пачки кода завайтлистить ещё каких классов, чтобы приложение не упало. Можно всё то же самое сделать через кодогенерацию. Обычно всё же генерируют исходники через annotation processors, но бывают нюансы.
Ну и кстати, прокси работают только с интерфейсами, а не с абстрактными классами.
Это смотря какого рода оптимизации. Если есть алгоритм, который раз и навсегда написан, то да, это кейс. Если же пользователь что-то вводит и это что-то надо максимально быстро исполнить для разных входных данных (собственно, игрушечный проект в статье - намёк на такой кейс), то я лучше сгенерю байт-код Java, чем напишу на C++ генератор нативного кода. Пример: различные пользовательские скрипты. Да, в 90% случаев проще прикрутить что-то стандартное вроде JS, но бывает всякое. Ну например, представьте, что вы пишете Excel-подобную штуку и пользователь хочет (а он 100% хочет), чтобы формулы пересчитывались максимально быстро.
Плюс JNI имеет достаточно большие накладные расходы. И нативный код не инлайнится.
У всех свой продакшен. Мы вот используем и рады. Да и потом, если не все генерируют байт-код в продакшене, мало ли что. Где-то что-то не срослось и приходится смотреть глазами вывод `javap -c`. Или где-то заглючил спринг или хибернейт и сгенерил какую-нибудь обёртку, не проходящую валидацию. Так что понимать, как устроен байт-код - очень полезный навык, а для этого хорошо поупражняться таким способом.
Кстати, а можете привести конкретные доводы, почему именно "нет ни одного повода"?
А, увидел, что они добавили поддержку, но только экспериментальную и только для хрома под флагом
Поиск по словам j2cl дал только вот эту issue, которая ещё не закрыта. Можно ссылку на новость или на документацию по поддержке WebAssembly в j2cl?
Кстати, интеропиться из Java в react - довольно сомнительная затея. Я бы мог после отпуска эту мысль развернуть. На практике лучше написать свой react на Java, я даже пилил такое, да забросил из-за нехватки ресурсов
Ну так и в TeaVM тогда несложно привнести
С каких это пор j2cl поддерживает WebAssembly?
Неправильно поняли. Это вообще не проблема. TeaVM работает в SSA. Читайте внимательно.
Я так и делаю. Но на практике всё равно остаётся весьма много ситуаций, когда ничего про значение сказать нельзя.
Это косвенный вызов, он дорогой. Кроме того, вариант с проверкой условия по месту был выбран специально, чтобы попасть в предсказатель переходов.
WebAssembly вполне себе многопоточный. Кроме того, TeaVM поддерживает потоки с помощью green threads. Так что ссылку на monitor приходится тащить. И за счёт различных ухищрений в TeaVM размер заголовка всего 8 байт. Меня совсем не устраивает, что WebAssembly добавляет ещё.
И как же это должно выглядеть? И почему это должно помочь?
TeaVM вовсе не дословно переводит. А статический анализ, если только не тратить тыщу лет (буквально) на каждую компиляцию, вовсе не всесилен
У меня нет никаких сведений об участии ядра коммитета WebAssembly в данных проектах. Я больше о другом: сам стандарт обладает лёгким душком некой функциональщины. Вот они не поддержали такие важные для рантаймов вещи, которые я описал, зато радостно бросились реализовывать хвостовую рекурсию. И вроде часть тулинга, вроде верификатора WebAssembly, они изначально писали на OCaml, вроде как частично спеку с его помощью генерируют. Да и саму спеку почитайте, часть про семантику инструкций - явно написана матёрыми функциональщиками.
Нет никакого "байт-кода V8". V8 внутри себя использует IR, и даже не один, но никакого стандартного кросс-браузерного способа его сгенерировать нет. Я про генерацию JS. Собственно, раз уж у меня получилось генерировать вполне эффективный JS из байт-кода JVM, то не вижу никаких причин, почему нельзя было бы аналогичную задачу решить для CIL. Так вот, если я правильно понимаю, blazor берёт CIL и генерирует wasm. Интересно, а в MS пробовали генерировать JS? Где-то есть в публичном доступе сравнения размера/производительности и тулинга?
Судя по всему, там тоже нет необходимых классов из java.security. И нет java.util.zip
А впрочем, нет, TeaVM не подойдёт. Я смотрю, у вас там криптография, а TeaVM криптографию не поддерживает.
Изначально да, задумывался для компиляции C++, хотя и у C++ были проблемы, например, с теми же исключениями. Забавно было смотреть, какой огород они городят для обхода данного небольшого ограничения. Забавно смотреть, как они реализуют ссылки на локальные переменные с упомянутым в статье shadow stack.
Но сейчас эта ситуация изменилась. Писать спеку наняли очень крутых учёных, которые пишут на Haskell и OCaml, они и взялись писать среду, в которой очень удобно исполнять Haskell и OCaml.