Skip to content

Migrating from Martini Runtime v2.x to v3.0

Overview

Martini Runtime v3.0 introduces several breaking changes that require manual action when you upgrade from any Martini Runtime v2.x release. You can upgrade directly to v3.0 from any v2.x version — there's no need to be on the latest v2.8.x release first. This guide walks you through every breaking change, in the recommended order, so you can move your packages and deployments to v3.0 without hitting runtime errors.

What You Will Learn

  • Whether you need to manually upgrade your JVM to Java 21, depending on how you run Martini
  • How to find and replace javax namespace references with their jakarta equivalents
  • How to verify custom library JARs remain compatible with Martini Runtime v3.0
  • How to resolve Groovy class-version errors after upgrading
  • How to migrate expressions from $gloopOutput and undocumented workaround properties to the $output expression variable
  • How to move development workflows that relied on Swagger 2.0 to OpenAPI v3

When To Use This

Use this guide when you're planning or performing an upgrade of a Martini package, workspace, or deployment from Martini Runtime v2.x to v3.0. Follow it as a pre-upgrade and post-upgrade checklist, whether you manage Martini Runtime yourself or via Lonti Managed Hosting.

Prerequisites

  • Administrative access to the Martini Runtime deployment you're upgrading (self-managed, Docker, or Managed Hosting)
  • Martini Designer installed and connected to the workspace you're migrating
  • A backup or version-controlled copy of your Martini packages, so you can review and revert changes if needed

Suggested Migration Order

Follow these steps in order for a smooth upgrade from v2.x to v3.0. Some steps only apply to specific deployment types, as noted.

  1. Upgrade the JVM to Java 21 — only required for on-premise or other manually-managed JVM deployments. See Java 21 Requirement and Deployment-Specific Handling.
  2. Install or upgrade to Martini Runtime v3.0 — direct upgrade is supported from any v2.x release.
  3. Find and replace javax references with jakarta, for affected classes only using Martini Designer's search feature. See Updating javax Namespace References to Jakarta.
  4. Test custom or extra library JARs against Martini Runtime v3.0 running on Java 21, and update or replace any that are incompatible. See Verifying Custom Library JAR Compatibility.
  5. Update workflow expressions that rely on undocumented workaround properties (such as $context) to use $output instead; optionally migrate $gloopOutput usages in services to $output as well. See Migrating to the $output Expression Variable.
  6. Review REST APIs that relied on Swagger 2.0 for consumption or generation, and migrate them to OpenAPI v3. See Migrating from Swagger 2.0 to OpenAPI v3.
  7. If you see class-version errors after upgrading, delete .class files in your Martini packages and restart Martini Runtime. See Resolving Groovy Class-Version Errors After Upgrading.

Java 21 Requirement and Deployment-Specific Handling

Martini Runtime v3.0 requires Java 21, up from Java 11 on v2.x releases. Whether you need to take manual action depends on how you run Martini Runtime.

Deployment type Manual Java upgrade required? Details
Martini Designer v1.8+ No Designer v1.8 and later bundles both Martini Runtime v3 and Java 21 automatically.
Docker No The Martini Runtime v3.0 Docker image already includes Java 21.
On-premise / manually-managed JVM Yes You must upgrade the host JVM to Java 21 before installing or starting Martini Runtime v3.0.

Note: Martini Runtime v3.0 will not run correctly on Java 11. If you manage your own JVM, upgrade it to Java 21 before you install or start Martini Runtime v3.0. For exact specifications, see Server Runtime System Requirements.

Updating javax Namespace References to Jakarta

As part of the move to Java 21, Martini Runtime v3.0 adopts the Jakarta EE namespace for classes defined by a Jakarta EE specification. This does not mean every javax class reference needs to change. Only classes that belong to a Jakarta EE specification (servlets, mail, activation, and similar enterprise APIs) were renamed to their jakarta equivalent. Classes that belong to core Java SE — bundled with the JDK itself rather than defined by a Jakarta EE specification — keep their javax namespace permanently, since Jakarta EE doesn't own those packages. javax.crypto is a common example: it's part of the Java Cryptography Extension (JCE) in Java SE, so it has no jakarta.crypto equivalent and must stay as javax.crypto.

This mainly affects fully-qualified Java or Groovy class names wherever they appear in your package content, including:

  • Imports and code in Groovy classes
  • Scripts
  • Expressions
  • Object property class-name fields (configuration fields where you enter a class name, such as object property definitions)

The following table shows illustrative examples of classes that do move to jakarta. It isn't an exhaustive list of every affected class.

Old (v2.x) New (v3.0)
javax.servlet.http.HttpServletRequest jakarta.servlet.http.HttpServletRequest
javax.servlet.http.HttpServletResponse jakarta.servlet.http.HttpServletResponse
javax.activation.DataSource jakarta.activation.DataSource
javax.mail.Message jakarta.mail.Message
javax.mail.Address jakarta.mail.Address

Java SE Packages That Stay Under javax

The javax namespace isn't exclusive to Jakarta EE — Java SE itself has always shipped core JDK APIs under javax package names. These Java SE APIs were never part of the Jakarta EE rename, so references to them must stay as javax on Martini Runtime v3.0. Do not replace the following common examples, or any other javax class that's part of the JDK rather than a Jakarta EE specification:

Package Purpose
javax.crypto Java Cryptography Extension (JCE) — ciphers, key generators, and MAC algorithms
javax.net and javax.net.ssl Socket factories and TLS/SSL support
javax.sql Core JDBC extensions, such as DataSource
javax.naming Java Naming and Directory Interface (JNDI)
javax.management Java Management Extensions (JMX)
javax.xml.parsers, javax.xml.transform, javax.xml.xpath, javax.xml.validation, javax.xml.datatype Core JDK XML processing APIs
javax.swing Desktop GUI toolkit
javax.sound.* Audio capture and playback
javax.imageio Image reading and writing
javax.security.auth Java Authentication and Authorization Service (JAAS)
javax.script Scripting engine support (JSR 223)

Note: This list isn't exhaustive. Before changing an unlisted javax reference, confirm that its API appears in the Jakarta EE specifications and that the target jakarta package exists. Java SE packages and independent specifications such as JCache may continue to use javax.

Finding and Replacing javax References in Martini Designer

Use Martini Designer's workspace search to find every javax reference before you replace it. Replacing text blindly can touch unrelated content, such as comments or unrelated identifiers, that happens to contain javax., as well as genuine Java SE classes that must stay under javax.

  1. Open Martini Designer's text search feature.
  2. Search your workspace for all occurrences of the literal string javax..
  3. Review each match individually. Confirm it's a genuine Jakarta EE class reference — and not a Java SE class such as javax.crypto — before changing it. See Java SE Packages That Stay Under javax for common examples to leave unchanged.
  4. Replace confirmed Jakarta EE matches with jakarta..
  5. Restart Martini Runtime.

Expected result: After you replace all genuine Jakarta EE javax occurrences and restart Martini Runtime, it stops throwing classpath or class-not-found errors caused by the removed javax classes, while Java SE classes such as javax.crypto continue to resolve correctly.

Verifying Custom Library JAR Compatibility

Martini Runtime v3.0 also upgrades several internal, bundled library dependencies as part of the move to Java 21. If you added extra library JARs to your deployment that only worked on Java 11, or that depended on the specific library versions bundled with Martini Runtime v2.x, you may see breaking behavior on v3.0.

There's no exhaustive list of affected libraries, since this depends entirely on what you've added to your own deployment. Test any custom or extra JARs you rely on against Martini Runtime v3.0 running on Java 21, and update or replace any that are incompatible before you rely on them in production.

Migrating to the $output Expression Variable

Martini Runtime v3.0 introduces a consistent global expression variable, $output, exposed everywhere the invoked step or node's output data model should be accessible in expressions:

  • Services: invoke function steps, invoke service steps
  • Workflows: invoke function nodes, invoke service nodes, invoke workflow nodes, and workflow database query nodes

$output references the output data model of the invoked step or node — the same data you previously reached via $gloopOutput (services) or via undocumented workaround properties (workflows).

Backward Compatibility for Services and Workflows

  • Services: $gloopOutput continues to work everywhere it already worked, for example $gloopOutput.response.status == 200 in invoke function or invoke service step output mappings. It's now deprecated but not removed in v3.0 — there's no forced migration, but new or updated expressions should use $output.
  • Workflows: there was no officially supported equivalent before v3.0. If you relied on undocumented workaround properties — for example $context — to reach step or node output, you must update those expressions to use $output instead. The undocumented properties aren't guaranteed to keep working.

The exact set of undocumented workaround properties beyond $context isn't formally enumerated. Treat $context as a representative example, and audit your workflow expressions for any similar undocumented usage.

Migrating $output Usage Step by Step

  1. Audit your workflow and service expressions for usages of $gloopOutput and any undocumented workaround properties, such as $context.
  2. In workflows, replace any undocumented workaround property usage with $output.
  3. In services, leave $gloopOutput usages as-is if you prefer — they keep working. Migrating them to $output is optional but recommended, since $gloopOutput is deprecated.

For more on where $output is available, see Invoke Function Node, Invoke Service Node, Invoke Workflow Node, and Database Query Nodes.

Migrating from Swagger 2.0 to OpenAPI v3

Before v3.0, Martini REST APIs automatically generated a Swagger 2.0 schema for each REST API, in addition to other schema formats. You could also consume a Swagger 2.0 schema to generate a Martini REST API, or generate services that called operations from a Swagger 2.0 schema.

In v3.0, Swagger 2.0 support is removed entirely. You can no longer consume a Swagger 2.0 schema, nor generate a Swagger 2.0 schema from an existing Martini REST API.

Martini REST APIs still offer other schema formats, including OpenAPI v3 — the favored, supported format going forward — and a Postman collection. For any development workflow that previously relied on Swagger 2.0, whether for consuming or generating, use the OpenAPI v3 schema as the replacement.

Note: Martini Designer and Martini Runtime don't include a built-in conversion tool for turning an existing Swagger 2.0 schema into OpenAPI v3. If you have a Swagger 2.0 definition you still need to consume, convert it yourself first, for example with third-party Swagger-2.0-to-OpenAPI-v3 conversion tooling, and then consume the resulting OpenAPI v3 schema in Martini.

For more, see OpenAPI Schema in Martini and Consuming a REST API.

Resolving Groovy Class-Version Errors After Upgrading

Martini Runtime normally recompiles Groovy classes automatically when it detects a new Runtime version. If you encounter class-version-related errors after upgrading to v3.0, resolve them as follows:

  1. Delete all .class files under your Martini packages.
  2. Restart Martini Runtime to force a clean recompile.

Helpful Resources