Skip to main content

Expanders 5.28.0

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

Efforts to reimagine and improve the way workflows are modeled and implemented within our applications have started a while ago. This release marks the first impact of those efforts on Expanders.


The expansion resources below provide Expanders 5.28.0.


Changes and improvements

Task perform and delegation

Modeling your application should be as simple as possible. This includes providing developers with sensible defaults. Best practices shouln't be hidden behind an option. For this reason the following options have become deprecated and are now the default behavior:

  • includePerform Every task should be able to be performed. The expanded perform method has the advantage that its contract aligns with the TaskElement model.
  • includeDelegation In the JEE application stack a task is accessed as an EJB. Delegation allows us to implement the task independently of this technology. It will also improve the ability to test this implementation. To opt-out of delegate implementation(s) you can use the new noDelegation option.

Additionally, adding the includeRemoteAccess option is no longer recommended. This option exposes a task directly to a Struts api, which doesn't have the best interface and implementation.

Non-dynamic task implementation

Available task implementations must be known at compile-time, which is why we replaced the dynamic lookup using Class.forName(..) with a switch-statement. This explicitly lists all available implementations and allows for better code navigation.

Multiple task implementations for the same task are infrequently used. However, when applicable it should at least be clear what each implementation does. For this reason we chose to retire the <Task> artifact, custom implementations with meaningful names should be used instead.

Additionally, getting rid of the dynamic lookup allows us to use named implementations instead of fully qualified class names as well. You could for example have a task implemented with and without encryption of some data. These implementations can now be named default and secure, which would then resolve to their respective implementation. Since the implementation name is just a string, you can still use fully qualified names as well.

Migration guide

Task implementations

  1. Check if your application has any (useful) <Task>Impl2 or custom task implementations.
    • The Impl2 class must be moved from gen to ext. Preferably rename it to something more meaningful.
  2. For each of these, add a switch case to the <Task> as illustrated below:
     // @anchor:prePerform:start
    final Calculate implementation;
    String implementationName = targetParameter.getContext().find(ProcessingContext.class)
    switch (implementationName) {
    // anchor:custom-implementations:start
    case "my.custom.impl.CalculateInParallel":
    implementation = new CalculateInParallel();
    case "net.demo.CalculateImpl2":
    implementation = new CalculateImpl2();
    // anchor:custom-implementations:end
    case "net.demo.CalculateImpl":
    case "default":
    implementation = new CalculateImpl();
    logger.error("No Calculate implementation found for " + implementationName);
    return TaskResult.error();
    // @anchor:prePerform:end

Task options

  1. Make sure prime-transmutations is on version 2.1.2 or above.
    • Included in nsx-default-stack version 2023.12.0.
  2. Run the 'Upgrade' transmutation on your applicaton.
    • Either in the microradiant or from commandline using:
    mvn expanders:transmute-model -Dtransmutation=Upgrade
  3. The 'Upgrade' will remove the includeRemoteAccess option from all tasks as it is not needed for most applications. If your UI depends on executing tasks directly (e.g. it calls nsxActions.performTask from webStyles) you can still use this option. We do however recommend not using it and plan on providing a better alternative in the future.