Jakarta EE 10. Надія на відродження
Всім привіт. Я Сергій Моренець, розробник, викладач, спікер та технічний письменник, хочу поділитися з вами досвідом роботи з такою цікавою темою як Enterprise Java поточної версії (Jakarta EE 10). У 1998 році була випущена її перша версія (тоді вона називалася Java EE) і до появи Spring у 2002 році це була єдина платформа для розробки великих корпоративних додатків на Java. Втім, і зараз Spring/Spring Boot не намагається її повністю витіснити з ринку, а навпаки, підтримує багато її специфікацій, наприклад, Spring Data JPA базується на JPA (зараз Jakarta Persistence), а Spring Framework підтримує анотації з Jakarta Inject.
З середини
Трохи пізніше Java EE перейшла під крило Eclipse Foundation, пішов ребрендинг, і в результаті Jakarta EE 8 і 9 не містили жодних змін у специфікаціях, а лише болісне перейменування javax.* -> jakarta.*. Все це зайняло майже 4 роки. Java EE Guardians стали Jakarta EE Ambassadors, але продовжували займатися розвитком та підтримкою Enterprise Java. І ось настав час для виходу вже Jakarta EE 10, яка і мала відповісти на питання, в якому напрямку рухається ця технологія і наскільки вона відповідає сучасним вимогам.
Зміни в Jakarta EE 10
Jakarta EE 10 була випущена у вересні 2022 року. Якщо попередня версія в основному була присвячена переходу на пакет jakarta.*, то нова версія містить важливі зміни (понад 20 оновлених специфікацій), про які ми зараз поговоримо.
Перша важлива зміна — це перехід на JDK 11, як мінімально підтримувана версія і підготовка до поступового переходу на JDK 17. Але при цьому якщо ви вже використовуєте JDK 17 та її фічі (наприклад, Java records), то можете успішно використовувати в тому ж REST API для класів DTO. Інша важлива зміна — створення так званого Core Profile. Профілі (Web profile) з’явилися в Java EE 6 як спроба мінімізувати кількість технологій для створення вебзастосунків. З того часу Web Profile є частиною повної специфікації (Jakarta EE Platform). І ось в
Єдина нова специфікація тут — CDI Lite 4.0. Що це та чим відрізняється від звичайного CDI? Context and Dependency Injection (CDI) з’явився в Java EE 6 на противагу важким EJB. У версії 3.0 він був розділений на три частини: Core CDI, CDI для Java SE і CDI для Jakarta EE. І ось у версії 4.0 Core CDI підлягало подальшому поділу на CDI Lite та CDI Full.
У CDI Lite вперше в історії enterprise Java зробили спробу реалізувати Ahead-of-time (AOT) компіляцію для того, щоб можна було генерувати GraalVM native images. Для цього необхідно використовувати так звані Build Compatible extensions. Ця фіча дозволяє знайти та визначити всі біни на етапі компіляції програми, а не запуску:
public class CustomBeanExtension implements BuildCompatibleExtension {
@Discovery
public void addBeans(ScannedClasses classes) {
classes.add("demo.MyBean");
}
}
По суті, у CDI Lite немає тільки опціональних речей — наприклад, таких scopes як session та conversation. Така фіча виглядає дещо запізнілою. Наприклад, мікровеб-фреймворки Micro-naut/Quarkus спочатку проєктувалися як повністю сумісні з GraalVM native images. Spring Framework з 2019 року адаптував себе до AOT компіляції і навіть створив окремий проєкт Spring Native для підтримки native images. Недавно вийшов Spring 6, ця інтеграція була завершена. У той же час Jakarta EE не виявила жодну активність у цьому напрямку. І ось перша спроба.
З інших новацій Core Profile:
- У Jakarta RESTful Web Services 3.1 додали підтримку multipart для медіа-даних. Крім того, тепер ви можете використовувати REST API за межами Jakarta EE контейнера. Це довгоочікувана зміна для написання автоматизованих тестів для REST API. Ось як виглядає код для старту REST програми в Java SE за допомогою так званого Bootstrap API:
SeBootstrap.Configuration configuration = SeBootstrap.Configuration.builder()
.port(9000)
.build();
SeBootstrap.start(RestApplication.class,configuration);
- У Jakarta JSON-P 2.1 додали можливість використовувати дублікатні ключі в JSON
На цей момент Core Profile реалізують три application сервери — Open Liberty 22, Payara 6 і WildFly 27. Web Profile/Platform також підтримують GlassFish 7 і новий проєкт Fujisu Software Enterprise Application Platform.
Які зміни нас порадують у Web Profile?
- Випущено специфікацію Jakarta Concurrency 3.0 зі значними змінами:
- Асинхронні методи (з підтримкою CompletionStage/CompletableFuture).
- Поліпшення в тригерах та підтримка Cron-планувальників.
- Підтримка 3rd party context providers.
- Анотації для context propagation.
Тепер написати асинхронний метод досить просто:
@Singleton
public class AccountsBean {
@Asynchronous(executor = "java:module/concurrent/MainExecutor")
CompletableFuture<List<Account>> findOverdue(int minDaysLate) {
List<Account> overdueAccounts = new ArrayList<Account>();
Тішить, що її розробники мають великі плани. Вони вже замислюються про повну підтримку віртуальних потоків та Structured Concurrency. До того ж, ця специфікація має відразу дві реалізації — Eclipse Concurro для GlassFish і OpenLiberty Runtime. Якщо раніше для написання тригерів та асинхронних jobs використовували несумісні між собою рішення, такі як Quartz, Cron4j або Jobrunr, то нарешті в цій ніші з’явився стандарт.
- Jakarta Expression Language 5.0 — підтримка масивів та generic types.
- Jakarta Security 3.0 — підтримка OpenID Connect.
- Jakarta Server Faces 4.0 — можливість програмного створення facelets, mapping для розширень, нові атрибути/теги та багато іншого.
- Jakarta Persistence 3.1 — підтримка типів UUID для первинних ключів та нових арифметичних/тимчасових функцій у JPQL/JPA Criteria (наприклад, округлення або зведення в ступінь).
Тепер для того, щоб отримати поточний рік, достатньо виконати такий запит:
SELECT EXTRACT (YEAR FROM LOCAL DATE);
Ну і Jakarta EE Platform — найповніший набір специфікацій:
Менш приємна зміна — втрата backward compatibility. Багато речей, оголошених deprecated, були видалені в
- Підтримка JAXM (Java API for XML Messaging) та JAXB 1.0.
- Entity beans та Embeddable EJB контейнер (специфікація Jakarta Enterprise Beans).
Загалом це позитивний процес, тому що видаляються застарілі фічі, що мало використовуються, які були додані ще в
Що чекає на нас в Jakarta EE 11:
- Jakarta Config — універсальний API для роботи з розподіленою конфігурацією.
- Jakarta RPC — підтримка gRPC для enterprise-застосунків.
- Jakarta Data — використання патерну Repository для доступу до даних (за аналогією зі Spring Data, DeltaSpike Data та Micronaut Data).
Цікаво, що розмови про третю специфікацію ведуться вже три роки, але є речі, які уповільнюють її написання:
- Бажання об’єднати тут доступ і до реляційних баз даних та NoSQL (проект Jakarta NoSQL).
- Відсутність чіткого розуміння на початку, чи повинна Jakarta Data бути окремою специфікацією або частиною JPA (Jakarta Persistence). В останньому випадку всі JPA провайдери (Hibernate, EclipseLink) повинні були б реалізувати її і, по суті, ми отримали б дублювання цієї функціональності в Hibernate і Spring Data. Але все ж таки здоровий глузд переважав, і це буде окремою реалізацією.
- Бажання додати підтримку реактивних технологій.
Використання буде дуже схоже на Spring Data:
@Repository
public interface CarRepository extends CrudRepository<Car, Long> {
List<Car> findByType(CarType type);
Optional<Car> findByName(String name);
}
Різниця лише в анотації @Repository і в тому, що інтерфейс Repository із Spring Data тут називається DataRepository.
Крім того, плануються 5 нових проєктів, які були відокремлені від відповідних специфікацій.:
- Eclipse Exousia — реалізує Jakarta Authorization.
- Eclipse Parsson — реалізує Jakarta JSON Processing.
- Eclipse Angus — реалізує Jakarta Activation.
- Eclipse Open-DI — реалізує специфікацію Jakarta
CDI-lite на базі Micronaut. - Eclipse ExpresLy — реалізує Jakarta Expression Language.
Міграція на Jakarta EE 10
Наскільки легко мігрувати на Jakarta EE 10 з
Ще одна зміна, яка виявилася лише в run-time — нова залежність Jakarta RESTful Web Services. І третя зміна, нам так і не вдалося подолати — помилка, яка виникає після успішної аутентифікації. З нею виявилося найскладніше, тому що у нас в проєкті використовується Tomcat, який начебто неофіційно і підтримується, але не входить до списку серверів, сумісних з Jakarta EE. На жаль, у Soteria дуже мізерна документація, а розробники дуже повільно реагують на tickets, тому довелося назад відкотитися на версію 2.0 (яка з Jakarta EE 9).
На жаль, але у Soteria практично немає альтернатив. Є проєкт Eleos, але він взагалі не містить документації і використовувати його поки не хочеться. Є перспективніший проєкт Eclipse Exousia, але він реалізує Jakarta Authorization.
Ще одна breaking change була пов’язана із проєктом Jersey (REST API). Після переходу з версії 3.0.x на 3.1 впали всі тести, пов’язані із REST-сервісами. Причому впали помилково 404 (not found). Джерело — це ось такий коміт, який з одного боку поламав тести, з іншого боку додав шлях з анотації @ApplicationPath (у нашому випадку «api») при старті Grizzly вебсервера в тестах:
@ApplicationPath("api")
public class JerseyConfig extends ResourceConfig {
public JerseyConfig() {
super(ComponentFeature.class);
}
}
На жаль, про це немає жодної інформації в посібнику з міграції на версію 3.1.x. Я створив ticket на цю проблему, де її підтвердили, але пообіцяли зафіксувати цей use-case у документації. Виправити її було нескладно.
Висновки
Загалом зміни до Jakarta EE 10 залишили позитивні емоції не тільки у мене. За опитуванням Jakarta EE Developer Survey
Головний мінус викликали breaking changes, необробленість документації та слабкий фідбек від авторів на знайдені помилки. Сподіватимемося на те, що це буде виправлено незабаром, а якість проектів буде підвищена.
6 коментарів
Додати коментар Підписатись на коментаріВідписатись від коментарів