Pull to refresh

Comments 11

Спасибо за труд, показали, что кодогенерация в Java — это боль. Правда, она не часто требуется. Подобный код всегда write-only, в нем не разобраться и очень сложно его развивать.

Пока нашел только один нормальный способо кодогенерации в мире JVM — создание классов из функций Clojure через gen-class. В чем-то он даже логичен — логика пишется в виде функций Clojure, потом прикручиваем поля класса, аннотации и прочюю ненужнную с т. з. функциональщика фигню.
Единственное, Clojure может поначалу испугать не видавшего обширный мир айти разработчика, но надо же расширять кругозор.
1) Зачем всё это писать на диск, когда можно компилировать из памяти ?
2) Зачем передавать удалённо код, когда можно сразу передавать удалённо байт-код? Для чего Java в общем-то и затачивалась с середины 90-х.

Да и вообще — я написал много сотен тысяч строк (наверное — не считал) на Java и C# — и копоративные, и игровые, и банковские, и просто, но мне ни разу не пришлось сталкиваться с задачей самостоятельной кодогенерации. Точнее вру — один раз пришлось (ещё джуном), но это была генерация кода PHP на C# и TSQL (совместно) — и тот проект ожидаемо утонул не дойдя до стадии даже альфы.
Что я делаю не так? Не самым странным образом выстраиваю процесс разработки и архитектуру?

Спасибо за замечание. Конечно можно компилировать из памяти, но если вы хотите все таки генерировать код, который сможете глазами посмотреть и добавить в git, то без сохранения никак. А так, да, в общем случае не важно где хранится исходник.

А вот при удаленных вычислениях довольно важно передавать исходный код или bytecode. У Java нет прямой совместимости, поэтому если на стороне клиента собирать bytecode в версии выше чем на узле, то будут проблемы. В этом случае надежнее передавать именно исходники, для исключения зависимостей в версиях Java между клиентом и узлом.

Вы говорите странное. Вы можете компилировать "новыми" инструментами код со "старым" таргетом. И вы и так знаете версию на узле, которую поддерживаете, потому что используете/не используете соответствующие языковые фичи и библиотеки.

Сколько раз сталкивался с кодо-генерацией - это всегда боль поддержки, jsp можно туда же отправить, но это хоть какой-то стандарт. Единственный сценарий я нашёл, где такое обосновано - песочница для проверки тестовых заданий, а-ля codewars.

Java Eclipse Compiler кажется справляется с этим поудобнее, даже в JRE (querydsl как пример).

Кодогенерация придумана очень давно, тем более для таких простых вещей как DTO. Тем более, когда у вас есть «стандарты». Посмотрите в сторону XSLT. Простейший DTD и шаблон в XSL решает все проблемы. Если же вам нужна версионность, и вы не хотите перезагружать JVM, то стоит посмотреть на OSGi — проверенный временем механизм. Ну или gRPC, если уж совсем нужно быстро. И да, передавать сорцы или байткод с последующей подгрузкой на сервере — огромная дыра в безопасности.

Не обязательно генерировать код в Runtime. Гораздо проще это делать во время сборки проекта. Посредством разработки плагинов для Gradle и Maven. Посмотрите в сторону библиотек для кодогенерации от Square. Лично у меня есть очень позитивный опыт их использования:

https://github.com/square/javapoet

https://square.github.io/kotlinpoet/

Спасибо за ссылки, выглядит действительно интересно. В целом проект и является gradle плагином для генерации DTO сущностей на основе документации AsyncAPI. Т.е. у нас один сервис публикует сообщения в брокер, соответственно в другом сервисе-консьюмере надо заводить DTO для получения этих сообщений. Вот и пришла мысль прикрутить нормальную документацию к сервису-источнику а в остальных сервисах генерить эти DTO по документации, избавиться от ручного копирования кода между сервисами. Особенно полезно когда сервисами занимаются разные команды.

Я для похожих целей вот такую штуку написал:

https://habr.com/ru/post/587388/

Выношу API микросервиса в виде GraphQL схемы в отдельный проект, генерирую по нему DSL, публикую jar'ник с DSL'ем в мавеновский репозиторий, и подключаю сгенерированный API во все клиентские микросервисы. Как писать DTO'шки руками мы уже давно забыли :) Ну и плюсом идет семантическое версионирование API'шек микросервисов и выявление несостыковок API во время компиляции.

Sign up to leave a comment.

Articles