27 Upgrade

Learn how to upgrade your Helidon SE application from 4.x to 27.x

Use this guide to upgrade a Helidon 4 application to Helidon 27.

Before You Start

  1. Upgrade to latest Helidon 4.5.x release.
  2. Build and test with JDK 27.
  3. Remove deprecation warnings in your Helidon 4 build.
  4. Inventory dependencies that start with io.helidon.microprofile, io.helidon.jersey, io.helidon.lra, and io.helidon.integrations.
  5. Check whether each io.helidon.integrations dependency has a replacement in the Helidon Extensions repository.

MicroProfile

MicroProfile support has been decoupled from Helidon and now releases independently from Helidon MicroProfile. MicroProfile support is not available for Helidon 27 at this time.

If your application uses Helidon MP, CDI, JAX-RS, or MicroProfile specification APIs, keep that application on Helidon 4.5.x until the independent MicroProfile release is available. Do not upgrade those workloads to Helidon 27 unless you are also replacing the MP programming model with Helidon Core APIs.

Java

Helidon 27 requires Java 27.

Update:

  • Maven and Gradle toolchains
  • CI images
  • Runtime container images
  • Native image builds
  • maven-compiler-plugin or Gradle Java language settings

Dependencies

Import the Helidon 27 BOM to update Helidon dependencies to the same version. Then remove dependencies for modules that are no longer present:

  • helidon-mp
  • helidon-microprofile*
  • helidon-jersey*
  • helidon-lra*
  • helidon-integrations*
  • helidon-tracing-providers-jaeger
  • helidon-tracing-providers-zipkin
  • helidon-tracing-providers-opentracing
  • helidon-tracing-exporter-jaeger
  • helidon-metrics-prometheus
  • helidon-cors
  • helidon-http-media-gson
  • helidon-security-abac-policy-el
  • helidon-security-providers-google-login
  • helidon-security-providers-config-vault
  • helidon-webserver-service-common

Use these replacements where applicable:

  • CORS: io.helidon.webserver:helidon-webserver-cors
  • Metrics endpoint: helidon-webserver-observe-metrics
  • Tracing: helidon-tracing-providers-opentelemetry
  • Former integrations: use the matching Helidon Extensions release when one is available

For Gson media support and the removed security providers, follow the migration steps under JSON and Security. Applications using helidon-webserver-service-common must also update their service implementations as described under WebServer. Existing SE messaging applications must migrate their API usage and connector dependencies as described under Messaging.

Extensions

Helidon 27 no longer releases the former io.helidon.integrations artifacts from the Helidon repository. Supported integrations are moving to independent releases from Helidon Extensions.

Import the extension-specific BOM and replace the old coordinates with the new extension coordinates. Each extension is versioned independently.

For most replacement artifacts, apply this rule:

  • In the group ID, replace io.helidon.integrations with io.helidon.extensions.
  • In the artifact ID, replace helidon-integrations with helidon-extensions.

For example:

<dependency>
    <groupId>io.helidon.extensions.neo4j</groupId>
    <artifactId>helidon-extensions-neo4j</artifactId>
</dependency>

The exceptions are:

IntegrationReplacement rule
Eureka discoveryUse io.helidon.extensions.eureka:helidon-extensions-eureka-discovery when you need only the Eureka discovery provider.
OCIAdd v3 to the group ID and artifact ID. For example, use io.helidon.extensions.oci.v3:helidon-extensions-oci-v3.
VaultReplace vault with hashicorp.vault in the group ID and hashicorp-vault in the artifact ID. For example, use io.helidon.extensions.hashicorp.vault:helidon-extensions-hashicorp-vault.

Extensions are released on independent schedules. All extensions might not be available initially, but they will be released over time and new extensions will be added.

Helidon Core APIs

Most Helidon Core APIs remain compatible with Helidon 4.5.x code. The most common source changes are from deprecated APIs that were removed in Helidon 27.

Make these changes before upgrading:

  • Replace Header.value() with Header.get().
  • Replace HostValidator with io.helidon.common.uri.UriValidator.
  • Replace common config bridge usage with io.helidon.config.Config.
  • Replace static metrics helper calls with injected MeterRegistry or, in imperative application code, Services.get(MeterRegistry.class).
  • Replace static metrics factory calls with injected MetricsFactory or, in imperative application code, Services.get(MetricsFactory.class).
  • Replace tracing global accessors with injected Tracer or, in imperative application code, Services.get(Tracer.class).
  • Replace direct builder constructors with static builder() or create(...) methods.

After upgrading to Helidon 27, replace old TLS reload APIs that accept Tls with TlsMaterial. TlsMaterial is new in Helidon 27 and is not available in Helidon 4.x.

Service Registry

@Service.Provider is removed. Replace it with a service scope annotation, such as @Service.Singleton or @Service.PerLookup, that preserves the intended lifetime of the service. A class with an @Service.Inject constructor is also discovered as a service; without an explicit scope it uses @Service.PerLookup. See Defining Services.

Services created by the registry must obtain dependencies through injection. Do not replace a static metrics or tracing accessor inside a registry-created service with Services.get(...). If that service needs programmatic lookup, inject ServiceRegistry and use that instance. This restriction applies during construction, lifecycle callbacks, and normal service methods.

Config

Update providers and mapping code to use io.helidon.config.Config, not io.helidon.common.config.Config.

Config.global(Config) and io.helidon.common.config.GlobalConfig are removed. For imperative application bootstrap, replace:

Config.global(config);

with:

Services.set(Config.class, config);

Register the configuration before any service resolves it. Config.global() now returns the Config from the current service registry. If the application uses a custom registry, register the configuration with that registry. Inside registry-created services, inject Config instead of using either global accessor. These registration changes can be made while still on Helidon 4.5.x.

JSON

Gson Media Support

Gson media support moves to Helidon Extensions, with a release planned after Helidon 27. Replace io.helidon.http.media:helidon-http-media-gson with io.helidon.extensions.gson:helidon-extensions-gson-media when that extension release is available. Update explicit GsonSupport imports to io.helidon.extensions.gson.media.GsonSupport. See the Gson extension documentation for the extension version, configuration, and registration details.

JWT and JWK JSON-P APIs

The deprecated JWT and JWK overloads using jakarta.json are removed. Replace them with the APIs using io.helidon.json before upgrading; the replacements are available in Helidon 4.5.x.

Helidon 4 APIReplacement
Jwt.headerClaim(name)Jwt.headerClaimValue(name)
Jwt.payloadClaim(name)Jwt.payloadClaimValue(name)
Jwt.payloadClaims()Jwt.payloadClaimsJson()
Jwt.headerJson()Jwt.headerJsonObject()
Jwt.payloadJson()Jwt.payloadJsonObject()
Jwk.create(jakarta.json.JsonObject)Jwk.create(io.helidon.json.JsonObject)

Update imports and code that reads or constructs the JSON values returned or accepted by these methods. The Helidon and Jakarta JSON types are distinct; they cannot be cast to each other. This change does not remove the separate helidon-http-media-jsonp and helidon-http-media-jsonb modules.

WebServer

If you use Unix domain sockets, move the socket path from bind-address to bindings.uds.socket.

Example:

server:
  bindings:
    tcp:
      enabled: false
    uds:
      socket: "/var/run/my-service.sock"
      required: true

Use connectionOptions() instead of removed listener connection config helpers. Use maxConnections() instead of maxTcpConnections().

The helidon-webserver-service-common module and its RestServiceSettings, FeatureSupport, and HelidonFeatureSupport APIs are removed. Implement custom services directly with HttpService and custom HTTP features with HttpFeature, preserving their route and context-path configuration. Move service-specific CORS setup to the WebServer CorsFeature or its cors configuration. See CORS.

HTTP Method Case Sensitivity

Helidon 27 preserves HTTP method text exactly and matches method selectors case-sensitively, with temporary compatibility for the security configuration listed below.

Before upgrading, enable case-sensitive wire parsing on every Helidon 4.5.x listener and test the application with its actual clients:

application.yaml
server:
  case-sensitive-methods: true

In Helidon 4.5.x this option affects only inbound HTTP/1.1 and HTTP/2 wire parsing; configured method selectors retain the 4.x compatibility normalization. At the same time, replace lowercase or mixed-case built-in method names such as get with their standard uppercase form such as GET in all configuration. This prepares those selectors for the case-sensitive behavior in Helidon 27. Update at least the following:

  • WebServer security path methods
  • security provider outbound target methods
  • HTTP signature sign-headers method entries and signing outbound targets
  • automatic metrics path methods and tracing path methods
  • WebClient metric methods
  • CORS allow-methods

To ease migration, Helidon 27 temporarily retains compatibility when loading WebServer security path methods, security provider outbound target methods, and inbound or outbound HTTP signature sign-headers method selectors from configuration. A non-uppercase known method matches both the exact configured token and its uppercase form. For example, get matches get and GET, but does not match Get; PoSt matches PoSt and POST, but does not match post. The known methods are GET, POST, QUERY, PUT, DELETE, HEAD, PATCH, OPTIONS, TRACE, and CONNECT. An already uppercase method matches only that token, and a custom method such as Follow remains exact.

For HTTP signature sign-headers, an explicit uppercase entry overrides any generated compatibility entry regardless of configuration order. Without an explicit uppercase entry, the last configured case variant supplies the signed headers for their shared uppercase entry. Security path method lists ignore duplicates; absent or empty lists continue to match all methods.

Loading a non-uppercase known method in these security settings logs a warning. This compatibility will be removed in a future major version, when all method selectors will match only their exact configured token. Use uppercase names now for standard methods.

This compatibility applies only to the security configuration listed above. Programmatic builder selectors, runtime HTTP method parsing, and selectors in other modules remain case-sensitive. A programmatic selector for get matches only the distinct lowercase method get, not GET. OpenTelemetry server metrics and spans classify only exact known method names; case variants are reported as _OTHER, and spans preserve the received token in http.request.method_original.

Method.createCaseSensitive(String) is retained as an alias for compatibility with Helidon 4 and is deprecated for removal. Use Method.create(String) on Helidon 27; both methods preserve the exact method text.

The HTTP signatures provider continues to implement the legacy draft-cavage-http-signatures-03 (request-target) canonicalization, which lowercases the method before signing. That signed component therefore does not distinguish method case. The temporary compatibility for security configuration does not change this canonicalization.

Messaging

Helidon 4 SE messaging used MicroProfile Reactive Messaging types and Reactive Streams. Helidon 27 replaces that implementation under the same io.helidon.messaging:helidon-messaging coordinates. Existing SE messaging applications require source and configuration changes; updating the dependency version alone is insufficient.

After upgrading the messaging dependency:

  • Replace Messaging.builder() and Channel topology construction with MessagingGraph.builder() and the graph's named channels. Start and close the resulting MessagingGraph as part of the application's lifecycle.
  • Replace Emitter.create(...) with an emitter obtained from the graph or injected for a named channel. Replace Emitter.send(...) with emit(...). The new call completes synchronously when the required outputs have completed; it does not return a CompletionStage. Adapt asynchronous completion callbacks and error handling accordingly.
  • Replace MicroProfile Message values with io.helidon.messaging.Message. Use Message.create(...) instead of Message.of(...), and entity() instead of getPayload(). The new message has no ack() or nack() callbacks. Handlers must finish their delivery work before returning and throw on failure; transport acknowledgement is the connector's responsibility.
  • Replace mp.messaging.* configuration with the messaging configuration model. Declare named connector instances under messaging.connector, each with a type, then reference an instance name from messaging.incoming.<channel>.connector or messaging.outgoing.<channel>.connector. This requires adapting the connector configuration, not only renaming the top-level key.
  • When loading graph configuration programmatically, pass the messaging subtree: .config(rootConfig.get("messaging")).
  • Replace old helidon-messaging-* connector artifacts with compatible connectors from Helidon Extensions. Select a connector release built for the new messaging API and follow that release's dependency and configuration documentation; the old connectors are not binary-compatible replacements.

For imperative topologies, replace .listener(...) with .payloadSink(...) and the payload-mapping .processor(...) overload with .payloadProcessor(...).

Topologies using .publisher(...), .subscriber(...), or the reactive .processor(...) overloads must also be rewritten. The graph no longer accepts Reactive Streams publishers, subscribers, or processors:

  • Rewrite publishers as java.util.stream.Stream sources registered with .payloadSource(...) or .messageSource(...), or produce messages through a graph emitter.
  • Rewrite subscribers as synchronous consumers registered with .payloadSink(...) or .messageSink(...).
  • Rewrite reactive processors as synchronous per-item mappings registered with .payloadProcessor(...) or .messageProcessor(...).

Adapt reactive operators and asynchronous completion to these synchronous contracts; these changes require more than renaming the builder methods.

Custom connectors must implement the new messaging connector and channel SPI. Review retry handling: outputs that completed before a later output failed are not rolled back, so retrying a delivery can repeat their effects.

See the Messaging API and configuration documentation for graph construction, delivery handling, and connector configuration. If a required compatible connector is not yet available, keep that application on Helidon 4.5.x until the connector migration can be completed.

Metrics

Helidon 27 uses Micrometer-backed metrics for Helidon Core. The old Prometheus Java client integration is removed.

Change code as follows:

  • Inject or look up MeterRegistry.
  • Use meter tags instead of scopes.
  • Use /observe/metrics as the canonical metrics endpoint.
  • Treat /observe/metrics/application, /observe/metrics/base, and /observe/metrics/vendor as compatibility paths only.
  • Look up gc.time as a Gauge.
  • Replace metrics.rest-request-enabled with metrics.rest-request.enabled.
  • Remove metrics.gc-time-type.

metrics.scoping no longer controls meter registration or output, and the scope query parameter is ignored. The legacy scope-specific endpoint paths return the same unscoped metrics as /observe/metrics. Applications that used scope settings to disable meters or select exported data must replace those rules and update their scrape configuration; retaining the old settings can expose meters that were previously excluded. Use ordinary meter tags for classification and implement the corresponding selection in the metrics integration. See Metrics Scopes for the customization and formatter APIs.

Tracing

Use OpenTelemetry. Remove Jaeger, Zipkin, and OpenTracing Helidon provider dependencies.

Also remove io.helidon.tracing:helidon-tracing-exporter-jaeger if the application uses the Helidon Jaeger gRPC exporter. It is removed independently of the Jaeger tracing provider. Configure an OpenTelemetry exporter and update the collector endpoint and protocol to match the selected exporter.

Prefer OTLP export. OpenTelemetry Java 1.65 no longer publishes the Zipkin exporter.

If imperative application bootstrap owns the OpenTelemetry instance, register it before any tracer lookup:

Services.set(OpenTelemetry.class, openTelemetry);

Then inject Tracer into registry-created services. Imperative application code can use:

Tracer tracer = Services.get(Tracer.class);

Security

HTTP Digest authentication is removed. Replace it with OIDC, HTTP Basic, header assertion, or HTTP signatures.

If you use JWT Provider, plan extra validation. It is retained but is no longer evolved.

The following providers are also removed. Migrate any application that depends on them before upgrading:

Removed providerRequired application change
ABAC policy EL (helidon-security-abac-policy-el)Replace EL policy evaluation with an application-supplied PolicyExecutor or equivalent authorization logic that preserves the existing rules. The policy validator API remains available, but its former EL executor does not.
Google Login (helidon-security-providers-google-login)Replace GoogleTokenProvider and its google-login provider configuration with a supported authentication provider, such as OIDC, and adapt token validation and identity mapping.
Config Vault (helidon-security-providers-config-vault)Replace the config-vault provider with the HashiCorp Vault extension's secrets and encryption providers, or an application-specific implementation. Update provider configuration and API usage as described below.

The HashiCorp Vault extension provides KV1, KV2, and Cubbyhole security providers for secrets, and a Transit security provider for encryption. See the Vault extension documentation for dependencies and setup. Migrating from ConfigVaultProvider requires moving config-backed secrets to Vault and updating secret paths and key configuration. Migrate existing encrypted data before removing the old provider; the extension uses Vault's keys and ciphertext format.

DB Client

If your application has a JPMS descriptor and uses Hikari DB client metrics, change:

requires helidon.dbclient.metrics.hikari;

to:

requires io.helidon.dbclient.metrics.hikari;

Maven coordinates and Java packages are unchanged.

Other API Changes

Review these additional changes before upgrading:

  • WebClient: deprecated compatibility methods are removed from connection, DNS, and HTTP client configuration APIs.
  • Fault Tolerance: deprecated helpers such as FaultTolerance.config(io.helidon.common.config.Config), executor(Supplier<? extends ExecutorService>), toDelayedRunnable(...), and toDelayedCallable(...) are removed.
  • Fault Tolerance: if both delay-factor and absolute jitter are configured, Helidon 27 applies the delay factor first and then jitter. Earlier releases ignored jitter in that case.
  • gRPC: deprecated helper APIs such as CollectingObserver and ResponseHelper are removed.
  • GraphQL: @GraphQl.Subscription is deprecated. Subscription execution is reserved for future use and is ignored.
  • Feature metadata: top-level Aot, Feature, Incubating, and Preview annotations are removed. Use nested annotations in io.helidon.common.features.api.Features.

Deprecated APIs

Helidon 27 still contains deprecated APIs that compile but should not be used in new code. Treat these as upgrade cleanup items:

  • Metrics scopes and scope-aware registry methods
  • Static metrics factory and lifecycle methods
  • Static meter builders and factory methods
  • Tracing global accessors and wrapper aliases
  • TLS reload methods that accept Tls
  • Security and DB client direct builder constructors
  • Old time-unit overloads in reactive, file watcher, and health APIs
  • Old config date and time mappers for Date, Calendar, TimeZone, and related types
  • SecurityContext.atzChecked()
  • HTTP/1 split receive and send logging accessors
  • BufferData.asInputStream()
  • HeaderNames.TSV_NAME and HeaderNames.TSV

Compile with deprecation warnings enabled and replace these APIs before relying on them for long-lived Helidon 27 code.

Third-Party Libraries

Review direct use of these managed libraries:

LibraryHelidon 4.5.xHelidon 27Compatibility notes
HikariCP5.0.17.1.0Validate pool behavior and metrics. HikariCP 6 changed some connection eviction and metrics behavior.
Micrometer1.15.121.17.1Prometheus duplicate meter names are stricter. Duplicate time series errors now use the Prometheus Java client exception type.
Micrometer Prometheus1.15.21.17.1Review custom Prometheus naming conventions and any direct Prometheus Java client usage.
OpenTelemetry1.62.01.65.0Zipkin exporter publishing stopped in OpenTelemetry Java 1.65. Prometheus reader constructors and some SPI property names changed in earlier 1.63 and 1.64 releases.
OpenTelemetry semantic conventions1.37.01.43.0Review code that uses semantic convention constants directly.
Protobuf4.31.14.36.0Regenerate gRPC or protobuf classes with a matching protoc version if your build pins code generation.
ASM9.89.10.1Usually build-time only. Recheck custom bytecode tooling.

Regenerate protobuf or gRPC classes if your build pins protoc or generated sources. Review custom Prometheus meter names for duplicate effective names. Review code that uses OpenTelemetry alpha, incubating, or SPI APIs directly.

GraalVM Native Image

The native-image Maven profile in example application poms has been removed. Considering using the jlink-image profile which now supports the JDK AOT Cache.

Final Checks

  1. Run with JDK 27.
  2. Run tests with deprecation warnings enabled.
  3. Check startup logs for missing service providers.
  4. Check /observe/health and /observe/metrics.
  5. Check tracing export in your collector.
  6. Check container and custom Java runtime image builds.

Copyright © 2018, 2026 Oracle and/or its affiliates.