Skip to main content

51 posts tagged with "migration-guide"

View All Tags

Modular beams

· 11 min read
Dries Ryckbosch
Dries Ryckbosch
Engineer
Sven Torfs
Sven Torfs
Engineer

This blog post introduces a fresh set of beam releases. The following new releases are now available.

  • minimal-jee-beam:2.2.0
  • standard-api-beam:2.0.0
  • service-api-beam:1.3.0
  • jee-backend-beam:1.0.0 (new)
  • struts-api-beam:1.0.0 (new)
  • knockout-frontend-beam:1.0.0 (new)

These releases mark a milestone in the modularization of the JEE-stack. For the first time it is possible to offer modular beams for frontend and control layer. Hence the introduction of jee-backend-beam, struts-api-beam and knockout-frontend-beam.

When upgrading please read the changelog and migration guide for each individual beam. You can find them in their respective GitHub repositories.

caution

The new beams require expanders-maven-plugin version 2026.1.0 or higher.

Splitting beams

For a long time, our primary JEE beam, the minimal-jee-beam, was a comprehensive package that included everything from the backend logic to the Struts 2 API and Knockout.js frontend. This made it easy to get started with a full-stack application, but with the arrival of API and frontend alternatives, it often forced developers to include technologies they didn't necessarily need.

By making the beams and underlying expansion resources more modular you have the option to leave some of these legacy technologies behind. This has benefits such as having fewer vulnerabilities, smaller artifacts and cleaner models.

The purpose of expander beams has always been to provide functional units to developers. Ideally these functional units are small so that they can be more easily maintained and updated. However, as functionality keeps getting added, eventually expanders beams become large enough that they can be split into smaller functional units. On the other hand some beams have always been a bit too large, encompassing a few too many concerns, such as the minimal-jee-beam, but it was not technically possible to split them yet. In both cases, at some point large beams will inevitably be split into smaller beams. In this case the minimal-jee-beam has been split into three distinct beams:

  • jee-backend-beam: This is the core of your application: Maven skeleton, JPA data layer, EJB logic layer and JNDI proxy layer.
  • struts-api-beam: Provides a full control layer implemented in Struts2. Including actions, interceptors, and the legacy web-based API.
  • knockout-frontend-beam: Contains a full view layer implemented in Knockout.js UI.

When combined, these three beams will expand exactly the same application as the minimal-jee-beam. However it does not contain net.democritus:Expanders anymore which will have an impact if you include other expansion resources in your expansion.

Modularizing net.democritus::Expanders

Splitting the minimal-jee-beam was no trivial feat. Many expansion resources needed to be updated (and many other still need to be updated), including the infamous net.democritus:Expanders. That has historically been an expansion resource which contained many expanders spanning over various technologies and concerns. Over the past years and months large efforts have been made to modularize the net.democritus:Expanders expansion resource. Modularizing the net.democritus:Expanders means that knockout and struts related expanders are isolated and split into different modules. Also the different layers in the JEE backend are split into modules. Each module results in an expansion resource that can be used independently.

Below is a simplified overview of how net.democritus:Expanders has changed in preparation for the new beam releases.

net.democritus.Expanders:9.3.0:

net.democritus.Expanders:9.4.0:

end-of-life

The net.democritus:Expanders expansion resource will not receive new updates and will stay at 9.4.0. Expansion resources should move away from using net.democritus:Expanders and use the new modules instead.

net.democritus:Expanders::9.4.0 solely exists to make the migration away from net.democritus:Expanders easier and is intended to be used for backwards compatibility while expansion resources migrate to the submodules.

Problems with splitting beams

This section shows common issues you are likely to encounter. It will be explained why they happen and how to best fix them. Note that you should not encounter any of these issues if you stay with the minimal-jee-beam.

Duplication of expanders

When you split an expansion resource, the expanders within now exist in multiple expansion resources (in the old expansion resource, and the newly split off expansion resource). This means that if both the old expansion resource and the newly split expansion resource are present, some expanders will be duplicated. This can lead to expander features being injected twice. A similar thing happens when you rename an expansion resource. In the case of renaming an expansion resource the replace configuration can be used. The replace however is not sufficient when splitting an expansion resource. For example, the jee-proxy-logic-expanders replace the net.democritus:Expanders. This means that only the expanders from the jee-proxy-logic-expanders will be present. So expansion resources that depend on expanders from net.democritus:Expanders that are not in the jee-proxy-logic-expanders will throw an error on expansion.

To help solve the issues encountered while splitting beams and modularizing expansion resources, new guardrails were added. These new guardrails require expanders-maven-plugin:2026.1.0.

New guardrails:

  • Resource version constraints
  • Added modelVersion field to expansionSettings and expansionResource to provide better feedback when the configuration causes a mismatch.
  • Added resolution tree information to ResolveResourcesResult. Use mvn expanders:dependency-tree to view this information.

Resource version constraint on Expanders:9.4.0

When replacing the minimal-jee-beam with the new smaller beams, no beam is depending on net.democritus:Expanders anymore. This causes version conflicts when other expansion resources still require an older version of it.

[ERROR] Failed to execute goal net.democritus.maven.plugins:expanders-maven-plugin:2026.1.0:expand (default-cli) on project
project-factory: Execution default-cli of goal net.democritus.maven.plugins:expanders-maven-plugin:2026.1.0:expand failed:
ExpansionResource dependency resolution failed: 'net.democritus:jee-ear-packaging-expanders::9.5.0' requires
at least 'net.democritus:Expanders::9.4.0', but resolved version was '9.2.0'
[ERROR] Either upgrade 'net.democritus:Expanders' or remove it from the (transitive) dependencies.
[ERROR] Dependency Resolution Chains:
[ERROR] - org.normalizedsystems.beam:jee-backend-beam::1.0.0
[ERROR] '-> net.democritus:jee-ear-packaging-expanders::9.5.0
[ERROR] - org.normalizedsystems:project-factory-expanders::1.10.0
[ERROR] '-> net.democritus:Expanders::9.2.0

The easiest way, but not the preferred/recommended way to solve this issue is to add a dependency on Expanders:9.4.0. Either by updating the Expanders dependency in the project-factory-expanders or by adding Expanders:9.4.0 explicitly in the expansionSettings. Expanders:9.4.0 has been created as a backwards compatibility measure and so can be used this way. However as Expanders:9.4.0 still contains all submodules it is still monolithic preventing full modularization. So while this does solve the issue it is only a temporary solution and should ideally be avoided in favor of the better solution.

Instead of including Expanders:9.4.0 in some way, it is best to replace the dependency on Expanders completely. In the case of this example the project-factory-expanders need to remove the dependency on Expanders and replace it by one or more of the submodules (e.g. jee-proxy-logic-expanders, jee-ear-packaging-expanders, ...). Only the submodules that are actually necessary should be used.

info

The minimal-jee-beam will be discontinued once most expansion resources have removed their dependency on net.democritus.Expanders. After that only the three newly created beams (jee-backend-beam, struts-api-beam and knockout-frontend-beam) will receive updates.

Leaving out Struts or Knockout

The new beams allow developers to leave out the knockout-frontend-beam and the struts-api-beam. Doing this on an existing application is in practice quite difficult.

This is because while the beams have been updated to be modular and make use of the symbiotic dependencies. Many other expansion resources do not. They often still depend on net.democritus:Expanders or don't make it possible to leave out some knockout related expanders. This makes it impossible to fully remove the struts and knockout technologies until these expansion resources have been updated.

If you do try to leave out a technology or refactor an expansion resource you might encounter the following error.

Exception in thread "main" net.democritus.elements.ElementNotFoundException: Cannot find Expander(ListHtmlExpander::net.democritus.expander.knockout.projection)

at ExpanderFeatureTreeToComposite.fetchExpander (expander=<Expander ListHtmlExpander::net.democritus.expander.knockout.projection>)
at ExpanderFeatureTreeToComposite.mapTree (tree=<ExpanderFeature >)
at FeatureTreeToComposite.mapExpanderFeatures ()


at net.democritus.expansion.ExpanderFeatureTreeToComposite.fetchExpander(ExpanderFeatureTreeToComposite.java:168)
at net.democritus.expansion.ExpanderFeatureTreeToComposite.mapTree(ExpanderFeatureTreeToComposite.java:131)
at net.democritus.expansion.FeatureTreeToComposite.mapExpanderFeatures(FeatureTreeToComposite.java:259)
at net.democritus.expansion.FeatureTreeToComposite.mapTree(FeatureTreeToComposite.java:139)
at net.democritus.expansion.ExpansionResourceTreeToComposite.mapFeatures(ExpansionResourceTreeToComposite.java:336)
at net.democritus.expansion.ExpansionResourceTreeToComposite.mapTree(ExpansionResourceTreeToComposite.java:152)
at net.democritus.model.resources.ExtractResourcesStep.convertExpansionResources(ExtractResourcesStep.java:162)
at net.democritus.model.resources.ExtractResourcesStep.performStep(ExtractResourcesStep.java:40)
at net.democritus.model.resources.ExtractResourcesStep.performStep(ExtractResourcesStep.java:27)
at net.democritus.model.common.ModelLoader.performStep(ModelLoader.java:151)
at net.democritus.model.common.ModelLoader.loadModel(ModelLoader.java:90)
at net.democritus.model.common.ModelLoader.loadModel(ModelLoader.java:54)
at net.democritus.tasks.ExpandTask.execute(ExpandTask.java:43)
at net.democritus.runner.NsxPrimeRunner.executeLocalTask(NsxPrimeRunner.java:70)
at net.democritus.runner.NsxPrimeRunner.main(NsxPrimeRunner.java:21)

In this case the knockout-frontend-beam was omitted from the expansionSettings. This means that ListHtmlExpander is not present so the expander feature cannot be injected into it which leads to this error. To solve this, expanders and expander features that depend on knockout (web-styles) should be isolated into a separate module (expansion resource) with a dependency on web-styles. This new expansion resource should then be included as a symbiotic dependency on the expansion resource it was isolated from. This will ensure that the new expansion resource will only be included if web-styles (knockout) is present in the expansion settings.

In this example web-styles is used, but the same can happen with other technologies and expansion resources, hence why it is important to make small modular expansion resources instead of monolithic expansion resources which combine different technologies and dependencies.

How to modularize an expansion resource

Note: This modularization step is optional. It is only required for expansion resource maintainers that seek a truly modular application.

Typically, expansion resources provide an extension to the NSX JEE-stack. They contain expanders and expander features targeting various technologies that are present in the JEE-stack. In order to do this, they depend on net.democritus:Expanders, which covered most of the stack. As explained above, net.democritus:Expanders has now been modularized into distinct expansion resources that group expanders per technology.

To make use of this modularization in an application, all included expansion resources must be modularized as well. Below is a step-by-step guide on how to achieve this, based on an example scenario.

Example Scenario: CSV Expanders

Suppose you have an expansion resource adding CSV download functionality. It is called csv-expanders, and it contains an integration with the Knockout frontend, the standard-api, and the Angular frontend.

Step 1: Create modular expansion resources

The first step in creating a modular expansion resource is to create a sub-module for each technology you want to split off, and then move all relevant expanders into them.

Rename your root maven resource from csv-expanders to csv-expanders-project and create a submodule csv-expanders. This module will act as the entry point for your users (as it did before because we kept the name). Next, create a submodule for your core expanders and one for each technology you want to split off. Finally, move all the expanders, features and data resources to the correct module.

You might need to add a dependency from technology specific modules to the core module to inject features or use shared data resources.

After this step, your bundle module should not contains anything more then a pom.xml.

Step 2: Add symbiotic dependencies

In this step, we will add the dynamic behavior. We only want to include technology-specific resources if the underlying technology is actually included in the application. This can be done using symbiotic dependencies.

Configure a symbiotic dependency in the bundle module (csv-expanders) for each of the modularized sub-modules. Base modules, such as csv-core-expanders, should always be present; therefore, their dependencies should not be symbiotic.

With this second step, we have now created an expansion resource that provides a feature with a set of core expanders that will always be present and optional support for a set of technologies. Using this architecture, expander maintainers can easily add support for more technologies while giving application builders the choice of what to include in their application.

Angular Beam 0.2.0 (angular-expanders 7.0.0)

· 17 min read
Jan Hardy
Jan Hardy
R&D Engineer
Dries Ryckbosch
Dries Ryckbosch
Engineer

Changes and improvements

Upgrade to Angular 21 and Angular Material 21

For this release we updated all the code to Angular 21, in order to stay up to date with the releases and best practices.

Added DataProjection support

A mechanism has been implemented to facilitate fetching of different DataProjections if the used control layer allows this (std-api). The defaults are set to details for getSingle calls and info for getList calls. This implementation also allows the use of calculated fields with the info projection now.

tip

Double check in your application if the same table columns are still shown. The option cruds.table.hide is now also taken into account.

For the moment, the possible projections are set by a ModelLoadingListener that defaults to the info ($DataConnector$-table.model.ts) and details ($DataConnector$.model.ts) projections. In the future it will be possible to manually define other projections as well.

Added Finder support

We have added a FinderConnector and QueryConnector that implements the new abstract FilterConnector. This allows to support finders as well as querysearch at the same time (depending on what control layer you are using).

The option hasSearchBar has also been ported. Like in KO this will expand a searchbar in the header of the list page connected to a finder defined by the specified value of the option.

Related to the addition of a universal Filter feature, previously only one querysearch was supported to be used as a filter. This has been changed to any amount of querysearches and finders.

Added Authorization support

We have added AuthorizationRights to make certain parts of the application not accessible (used in guards, directives, services). These rights can be accessed through the ACTION_AUTHORIZATION_SOURCE InjectionToken, the interface can be provided by a control layer specific implementation, or you can provide your own. Some directives have been added to handle authorization on the most common used components

  • ButtonAuthorizationDirective
  • TableRowActionMenuAuthorizationDirective

These directives handle disabling components as well as showing tooltips on why it is disabled. You can look at these as examples when wanting to use the authorization feature somewhere else.

Added support for swapping out default add/edit with DataOperations

Using the following tags you can now conditionally turn of some expanders:

  • #angular.data-view.action.add.custom: disable default add page.
  • #angular.data-view.action.edit.custom: disable default edit page.
  • #angular.data-view.action.delete.custom: disable default delete dialog.
  • #angular.data-view.routing.add.disable: disable the add route.
  • #angular.data-view.routing.edit.disable: disable the edit route.
  • Added feature anchors to remaining DataView actions (add, edit, delete, details, list).

Refactored use of HttpClient

We have added an API specific HttpClient. This allows for easy changing of authentication headers, error handling etc. per different API implemented. The implicit behavior of the http interceptors is also now removed. To facilitate the removal of the use of interceptors a lot of operator functions that handled the logic of the interceptors have been created.

  • handleDataAccessError
  • handleAlertError
  • handleDataAccessFormError
  • notifyDataConnectorSuccessEvent
  • notifyDataConnectorFailureEvent
Important

The new client is still based on the angular HttpClient and all functionality of this client can still be used.

Metamodel changes and additions

Metamodel additions of abstract Connector and View. This allows for easier extension of different types of views (e.g. ListView, InstanceView, FilterView) or connectors (e.g. DataProjectionConnector, DataOperationConnector, ...).

datamodeldatamodel
For more added features check out the changelog
  • Allowed file type validation
  • Dynamic sidebar support
  • New functions folder in structure
  • Resolved filename encoding issues
  • Added error handling for std-api

Data Operations 2.0.0

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

Changes and improvements

note

The new version is still able to read models from version 1.x.x. This means migration should be straight-forward for most cases. For a step-by-step upgrade follow the migration guide.

Model schema adjustments

DataOperations were originally designed as an abstract type to support extending the schema. After implementing many different types already, we have seen this was never really needed. Abstract types impose some restrictions in our tooling which led to the decision to implement types as a field instead. This gives us three clear advantages:

  • It is easy to switch between different types throughout our tooling.
  • It is easier to migrate from DataCommands to a Custom operation first, before switching to a more appropriate type later.
  • It is much easier to define new types in an expansionResource, without the need for your own Metamodel.
Before
<dataOperation type="operations::CreateOperation">
<name>register</name>
<parameterGroups>
...
</parameterGroups>
</dataOperation>
After
<dataOperation>
<type>Create</type>
<name>register</name>
<parameterGroups>
...
</parameterGroups>
</dataOperation>

Simplified parameter types

Previously we had ValueFieldParameter to refer to valueFields and AssociationParameter to refer to linkFields. This would sometimes be confusing from the perspective of the model. To simplify this a bit the new situation is as follows:

  • FieldParameter with a field reference for both value and linkFields.
  • AssociationParameter with a dataElement reference for references without corresponding field. (New)
  • Deprecated ValueFieldParameter.
  • Deprecated field reference on AssociationParameter.

Angular Expanders upgrade

In version angular-expanders 7.0.0 the ui model has enabled abstract compositions for both the DataView and DataConnector. Previously data-operation connectors, forms and actions were modeled as extensions. These have also been changed to implement these abstract types instead.

As a result they will show up differently in the model files. Instead of a separate file for each connector or view, they will now be inlined in the file of their parent.

Before
<!-- featureModules/country/model/dataViews/City.xml -->
<dataView xmlns="https://schemas.normalizedsystems.org/xsd/angularProjects/6/0/0">
<name>City</name>
<dataConnector>country::City</dataConnector>
</dataView>
<!-- featureModules/country/model/dataViews/City/DataOperationForms/Add.xml -->
<dataOperationForm xmlns="https://schemas.normalizedsystems.org/xsd/operationsAngular/2">
<name>Add</name>
<connector>country::City::register</connector>
</dataOperationForm>
<!-- featureModules/country/model/dataViews/City/DataOperationActions/Add.xml -->
<dataOperationAction xmlns="https://schemas.normalizedsystems.org/xsd/operationsAngular/2">
<name>Add</name>
<connector>country::City::register</connector>
<dialog>form-page</dialog>
<form>country::City::Add</form>
<roles>
<role>add-action-button</role>
</roles>
</dataOperationAction>
After
<!-- featureModules/country/model/dataViews/City.xml -->
<dataView
xmlns="https://schemas.normalizedsystems.org/xsd/angularProjects/7/0/0"
xmlns:oa="https://schemas.normalizedsystems.org/xsd/operationsAngular/3"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance">
<name>City</name>
<dataConnector>country::City</dataConnector>
<views>
<view type="operationsAngular::DataOperationForm" xsi:type="oa:dataOperationForm">
<oa:name>Add</oa:name>
<oa:connector>country::City::register</oa:connector>
</view>
<view type="operationsAngular::DataOperationAction" xsi:type="oa:dataOperationAction">
<oa:name>Add</oa:name>
<oa:connector>country::City::register</oa:connector>
<oa:dialog>form-page</oa:dialog>
<oa:form>country::City::Add</oa:form>
<oa:roles>
<oa:role>add-action-button</oa:role>
</oa:roles>
</view>
</views>
</dataView>

SQL Expanders 5.0.0

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

Version 5.0.0 of SQL Expanders introduces support for multiple data scripts. The data has now been more closely integrated with the NS model, allowing us to work with multiple scripts per application.

The new file format simply adds a name attribute to the root element. This attribute indicates the name that will be used for the file of the generated SQL script. The name should also equal the filename.

001-app-init-data.xml
<dataInstances
xmlns="https://schemas.normalizedsystems.org/xsd/sql-expanders/5/0/0/dataInstances"
name="001-app-init-data">
<!-- data instances here -->
</dataInstances>

Migration

Once you upgrade the version of sql-expanders to 5.0.0 or above, the next time you export the application model from micro-radiant, it will move the existing init data file and update the file to the latest format. This is now possible because the model is aware of the init data file, represented as an ApplicationData meta element.

Do note that at this time it is not possible to modify the data in the micro-radiant, as it is not represented by a full NS model.

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.

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.

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();
}
}

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.