Skip to main content

Jakarta EE support

· 5 min read
Frédéric Hannes
Frédéric Hannes
R&D Engineer

We're thrilled to announce a significant milestone for our JEE platform. Support for Jakarta EE is now available! Our JEE platform expanders now target Java EE 7-8 or Jakarta EE 10.

Releases

At this time, the full support for Jakarta EE is not yet available in beam releases. For migrating expanders and testing until the time that these releases make it into the beams, we've provided developer previews that mirror the beams, but contain the latest versions of all expansion resources.

Expansion resourceVersionDescription
net.democritus.preview:minimal-jee-dev-preview1.1.0A mirror of the minimal-jee-beam.
net.democritus.preview:standard-api-dev-preview1.1.0A mirror of the standard-api-beam.
net.democritus.preview:service-api-dev-preview1.0.1A mirror of the service-api-beam.
net.democritus.preview:process-automation-dev-preview1.0.0A mirror of the process-automation-beam.
Warning

The dev previews are not intended for use in projects. While we try to do thorough automated testing of these releases to ensure stability, we do not offer the same guarantees as with the beams. The content may also be subject to change by the time the next release of a beam arrives. While these releases may contain the same elements as the corresponding beams, they are synced back up to the structure of the beams whenever a release of the beam occurs.

The goal of these previews is to provide a resource that can be used to test upcoming functionality ahead of time in case there are new features or changes that a project may want to prepare for ahead of time. One such example is the migration to Jakarta EE, where the migration path may require extra effort for some projects.

Preparing your expander project

Expander projects may require some updates if they expand code with javax imports. The first step would be to migrate those specific expanders to the new imports system.

When moving the imports to the mapping file, they should be redefined as the new jakarta imports. The imports as defined in the mapping should be considered the optional/default case:

ExpanderMapping.xml
<?xml version="1.0" encoding="UTF-8" ?>
<mapping xmlns="https://schemas.normalizedsystems.org/xsd/expanders/2025/0/0/mapping" strict="true">
<artifact this="dataElement.packageName + '.' + dataElement.name + 'ImportantBean'" importStrategy="java"/>

<uses eval="'jakarta.servlet.http.HttpServletRequest'"/>
<uses eval="'jakarta.servlet.http.HttpServletResponse'"/>
</mapping>

In addition, it will be required to add a technology lexicon to map the imports back to the old javax equivalent. This in essence allows you to define how the imports should be rewritten if a specific technology is active in the model. Note that these are defined as data resources and will be inherited from dependencies. Many imports may already remap automatically if you depend on a resource such as Expanders that had its own technology lexicon.

javaee-classes.xml
<dataResource type="expansionControl::TechnologyLexicon">
<technologyLexicon>
<technology name="JAVA_EE"/>
<coordinateRedirections>
<coordinateRedirection>
<coordinate>jakarta.servlet.http.HttpServletRequest</coordinate>
<target>javax.servlet.http.HttpServletRequest</target>
</coordinateRedirection>
<coordinateRedirection>
<coordinate>jakarta.servlet.http.HttpServletResponse</coordinate>
<target>javax.servlet.http.HttpServletResponse</target>
</coordinateRedirection>
</coordinateRedirections>
</technologyLexicon>
</dataResource>

Migrating applications

When migrating applications there are only two important steps:

  1. Updating the settings of the project to target Jakarta.
  2. Migrate custom code in harvests and ext files if needed.

Updating project settings

  1. Upgrade your expansion settings (typically in conf/expansionSettings.conf) to use versions of expansion resources that support Jakarta EE.

  2. In the technical infrastructure settings, the JEE version should be updated to 10:

    Java 21.xml
    <technicalInfrastructure name="Java 21">
    <javaVersion>jdk21</javaVersion>
    <jeeVersion>10</jeeVersion>
    </technicalInfrastructure>
  3. Add the hibernate.version option with value 6 to your Application model.

    myapplication.xml
    <application name="myapplication">
    <shortName>myapplication</shortName>
    <version>1.0.0</version>
    <components>
    <component name="account"/>
    <component name="assets"/>
    <component name="utils"/>
    <component name="validation"/>
    <component name="workflow"/>
    <component name="applicationStuff"/>
    </components>
    <options>
    <hibernate.version>6</hibernate.version>
    </options>
    </application>
  4. Update the TomEE base image for Docker to a TomEE 10 variant. The latest version can be found on the documentation page for the base image. Today, this is:

    • docker.normalizedsystems.org/nsx-tomee-base:10.1.2-3.11.1 for root-based images
    • docker.normalizedsystems.org/nsx-tomee-base:10.1.2-3.11.1-rootless for rootless images

Migrating custom code

Most custom code will be compatible with Jakarta EE already and will not require any changes. The majority of required changes will be the package names that changed from javax.* to jakarta.*. These are easy to identify once you migrate the project settings and expand, as those imports will no longer be found. This is solved by simply replacing import javax. with import jakarta..

Warning

Be careful when replacing imports. While the majority of imports in javax packages have moved to jakarta packages, this is not true for all imports!

The switch to Jakarta occurred when Oracle transferred Java EE to Eclipse Foundation. Because Oracle owns the Java trademark, the name had to change under Eclipse Foundation to Jakarta to avoid trademark conflicts. There are also classes in javax packages that are part of the standard Java platform API, which is still owned by Oracle and such they were not renamed to jakarta.

An example of classes that were not renamed is everything in javax.naming.

Java 25 Support

· 2 min read
Frédéric Hannes
Frédéric Hannes
R&D Engineer

We now offer support for Java 25 in our JEE applications. Java 25 comes with some new features and performance enhancements as listed in the official release publication.

Java 25 at runtime

TomEE 8 was not compatible with Java 25 due to the removal of the SecurityManager in Java 24 (deprecated in Java 17). A workaround for this issue was added in version 10.2.1 of TomEE. We've now also backported this change to version 8 in our fork of TomEE 8 and released it as part of our TomEE 8.0.19 update.

For now our images will still default to Java 21, but by adding the jre25 modifier to the image tags, you can already make use of the latest LTS version of Java.

Today, this is:

  • docker.normalizedsystems.org/nsx-tomee-base:8.0.19-3.11.1-jre25 for root-based images
  • docker.normalizedsystems.org/nsx-tomee-base:8.0.19-3.11.1-jre25-rootless for rootless images

For the latest version of the image, please refer to the image documentation page.

Compiling for Java 25

To compile for Java 25 and use its language features, you need to change the Java version in the technical infrastructure settings file of your JEE project. Ideally you would also make a new settings file as the name of the settings is typically the version of Java. If you make a new file with a new name, also update the technicalInfrastructure reference in your application instance.

<technicalInfrastructure name="Java 25">
<javaVersion>jdk25</javaVersion>
<jeeVersion>8</jeeVersion>
</technicalInfrastructure>
<applicationInstance name="my-application">
<shortName>my-application</shortName>
<version>1.0.0</version>
<globalOptionSettings name="3.0 Modern"/>
<presentationSettings name="3.1 Future"/>
<businessLogicSettings name="TomEE Postgres Hibernate"/>
<technicalInfrastructure name="Java 25"/>
</applicationInstance>

In addition to this change, you need at least version 9.1.0 of net.democritus:Expanders in your project to target Java 25.

Data Operations 1.1.0

· 2 min read
Jorren Hendriks
Jorren Hendriks
R&D Engineer

We've moved data-operations out of its experimental phase. This means it can now be adopted by any project which may need it. They are a successor to data-commands which means you can decide to migrate data-commands which undoubtedly have many uses throughout your application.

You can get started by adding the bundle:

<expansionResources>
<expansionResource name="net.democritus:data-operations-bundle" version="1.1.0"/>
</expansionResources>

Please note data-commands will not be deprecated and can remain to be used. Data-operations provide a more expressive model and improvements to the runtime so we do recommend switching, but this is not a requirement. If you want to migrate, the decision tree below will help you with deciding which type of Operation is the best replacement for a data-command.

Command Decision Tree

Angular Expanders 6.14.0

· 2 min read
Jan Hardy
Jan Hardy
R&D Engineer

Changes and improvements

Module-metamodel support

In this version a dependency to the module-metamodel has been added. This allows for easy declaration of dependencies between modules, which are in this case FeatureModules.

Why would you want to declare dependencies between different FeatureModules?

For example, you have a common FeatureModule that declares some DataConnectors and another FeatureModule containing DataViews that want to reuse already declared DataConnectors. When there is no possibility to declare dependencies between them, the expansion becomes unreliable. After explicitly defining the dependencies, the expansion will always make sure that the correct resources are loaded at the right time.

In order to get this to work you should add a angularAppModules.xml file to your project.

Where to place
project
├── conf
├── applications
├── angular
. ├── angularApps
. ├── space-app
. ├── model
. └── space-app.xml
.
└── angularAppModules.xml
Example declaration
<programModules xmlns="https://schemas.normalizedsystems.org/xsd/modules/1">
<modules>
<module>
<moduleId>featureModules::api</moduleId>
<moduleType>angularProjects::FeatureModule</moduleType>
</module>
<module>
<moduleId>featureModules::geo</moduleId>
<moduleType>angularProjects::FeatureModule</moduleType>
<dependencies>
<dependency>featureModules::api</dependency>
</dependencies>
</module>
<module>
<moduleId>featureModules::transport</moduleId>
<moduleType>angularProjects::FeatureModule</moduleType>
<dependencies>
<dependency>featureModules::api</dependency>
</dependencies>
</module>
</modules>
</programModules>

You are not required to add all FeatureModules here, only if you want to indicate some dependencies.

See the modules-metamodel repo for more information.

APT Certificate Expired

· One min read
Frédéric Hannes
Frédéric Hannes
R&D Engineer

If you are using our tooling with Ubuntu and your apt update command indicates that your certificate is no longer valid, you are probably using an expired copy of our signing certificate. Please update it to the current version by executing the following command:

sudo bash -c "wget -q -O - https://foundation.stars-end.net/files/rotate-keys.sh | bash <(cat) </dev/tty"

Expanders 9

· 3 min read
Frédéric Hannes
Frédéric Hannes
R&D Engineer

Version 9 of Expanders introduces support for Jakarta EE as part of an effort to support this across our entire ecosystem. This also marks the completion of the first phase of this migration, where the entire JEE base application stack is supported for both Java EE and Jakarta EE, including process automation.

Breaking change for Struts2

With this release of Expanders, we support both Struts2 6.x and 7.x to match the different versions of JEE. Since Struts2 completely removed support for the fileUpload interceptor in version 7, we've now also removed it from our application stack. The reasoning behind this decision is that this interceptor was responsible for CVE-2024-53677, which has a score of 9.5 on the CVSS 4 scale. The alternative implementation using the actionFileUpload interceptor has been implemented across all of our expanders for several months now, but custom upload actions will also have to be refactored to switch to the new system. Regrettably, the impact of this change will not be visible at compile time, so care must be taking when upgrading to version 9 of Expanders.

Migration

The migration is fairly straight-forward and is described in this migration guide from Struts2: https://struts.apache.org/core-developers/action-file-upload-interceptor

An action that handles uploads should be modified by implementing the UploadedFilesAware interface. With this interface comes a method withUploadedFiles() that should be implemented. To retain backwards compatibility with existing implementations, it is possible to set the values of existing fields in the class from this method, which were previously set dynamically by the old interceptor using reflection.

Migration example

Below you will find a small sample of how we applied this migration to the AssetUploader class.

Before
public class AssetUploader extends ActionSupport {

private File uploadData; // the actual file
private String uploadDataContentType; // the content type of the file
private String uploadDataFileName; // the uploaded file name
After
public class AssetUploader extends ActionSupport implements UploadedFilesAware {

private File uploadData; // the actual file
private String uploadDataContentType; // the content type of the file
private String uploadDataFileName; // the uploaded file name

@Override
public void withUploadedFiles(List<UploadedFile> uploadedFiles) {
if (!uploadedFiles.isEmpty()) {
final UploadedFile uploadedFile = uploadedFiles.get(0);
this.uploadData = new File(uploadedFile.getAbsolutePath());
this.uploadDataContentType = uploadedFile.getContentType();
this.uploadDataFileName = uploadedFile.getOriginalName();
}
}

Micro-Radiant 4.0.0

· 3 min read
Koen De Cock
Koen De Cock
R&D Engineer
Jorren Hendriks
Jorren Hendriks
R&D Engineer

This version introduces changes to how the javascript runtime libraries are loaded. It allows us to update the glint libraries without having to release a new micro-radiant version and removes a bottleneck that prevented us from introducing new components for the plugins.

There are also various improvements to better handle errors and reduce the number of synchronization issues.

Angular Expanders 6.1.0

· One min read
Jan Hardy
Jan Hardy
R&D Engineer

Changes and improvements

Ln0x support

Previously only Ln02 link fields were supported, this has been extended to the full range of Ln0x that is implemented by the chosen control layer (std-api or svc-api). This behaviour is locked behind a profile for backwards compatibility reasons:

  • Std API Ln0x
  • Std API yarn Ln0x
  • Svc API Ln0x
  • Svc API yarn Ln0x

New number field component

A new number field component has been introduced that handles text input in the fields more gracefully. The component also implements some fraction digits validators, adding more functionality. The component is powered by an I18N number formatter that handles fraction separators and number bounds correctly. Default this is set to the locale en-GB. For Dutch formatting use nl-BE in the app.config.ts.

Expanders-Core 8.1.1

· 2 min read
Koen De Cock
Koen De Cock
R&D Engineer

Changes and improvements

  • String interpolation
  • Strict mode to catch errors in mapping.xml
  • New list mapping syntax
  • Improved stack-traces
  • Support for extending the context of artifact paths, mapping files etc.