Skip to main content
Version: Next

Application, Functions, and plugin upgrades to Pulsar 5.0.x

This guide covers application and extension changes when upgrading from Pulsar 4.x to 5.0.x. Use it alongside the Pulsar 5.0.x upgrade checklist and Configuration default changes.

Existing v4 applications do not need to change their client dependency or API merely to upgrade brokers. Review the checks relevant to your applications and complete server-side plugin, authentication, and TLS changes before rolling the affected components.

Java requirements​

Pulsar 5.0 Java client libraries, including v4 and v5, client CLI tools, and the public Functions/IO interfaces remain compatible with Java 17. The server-side Functions implementation requires Java 21 or later; Functions compiled for Java 17 can run in a Java 21 or later Functions instance. Building broker plugins against broker-side libraries requires JDK 21 or later.

Choose Java client dependencies separately​

For new Java applications or when updating client dependencies, use org.apache.pulsar:pulsar-client-v5-all. This recommended unshaded combined dependency includes the v4 client, v5 client, and admin implementation. pulsar-client-v5-shaded is a fallback only when unshaded dependency conflicts cannot be resolved. When adopting either artifact, replace the older separate client/admin dependencies and exclude transitive copies to avoid duplicate implementations; see Java client setup.

Dependency migration is separate from v5 API adoption. An application using either combined dependency can continue using the v4 API without enabling scalable-topic services. The v5 API requires those services even for regular topics; that requirement applies to API usage, not to the artifact's name. See the v4-to-v5 API migration guide.

Align application Netty dependencies​

When adopting the unshaded pulsar-client-v5-all dependency, upgrade application dependencies from Netty 4.1.x to Netty 4.2.x. Pulsar uses 4.2.18.Final. Netty 4.2 is largely backward compatible with 4.1, but both lines cannot coexist on the same classpath. This dependency alignment is part of updating the application; it is not required merely to upgrade brokers while retaining an existing v4 client dependency.

Import io.netty:netty-bom alongside pulsar-bom, update framework-managed Netty versions, and verify that the resolved runtime graph and packaged application contain a consistent set of Netty modules without old or duplicate JARs. See the Maven and Gradle setup examples and the Netty migration guide.

Check schema dependencies​

When upgrading Java client dependencies, review Avro class trust if your clients resolve application classes from externally supplied Avro schemas. Pulsar 5.0 also uses Protobuf 4 by default; check application dependency overrides against the resolved runtime.

Check authentication, TLS, and extensions​

  • TLS hostname verification is enabled by default for the Java client and outbound TLS connections from brokers, proxies, WebSocket services, and Functions workers. Check the hostnames used by client service URLs, advertised broker addresses, proxy-to-broker connections, and geo-replication. Reissue server certificates with matching subject alternative names before the rollout so both existing and upgraded components can connect. See Hostname verification.
  • Custom TLS factories must be migrated. PIP-478 replaces the PIP-337 PulsarSslFactory SPI with PulsarTlsFactory. Replace sslFactoryPlugin / sslFactoryPluginParams with tlsFactoryClassName / tlsFactoryConfig, and replace brokerClientSslFactoryPlugin / brokerClientSslFactoryPluginParams with brokerClientTlsFactoryClassName / brokerClientTlsFactoryConfig. Non-default values for the removed keys in broker/proxy configuration or client loadConf maps are rejected. When upgrading Java client/admin dependencies to 5.0, applications using the removed builder methods must be recompiled against the replacement methods. Also audit per-cluster TLS factory settings used by geo-replication: the old ClusterData fields are retained but ignored by 5.0 brokers. Set their replacement fields with pulsar-admin clusters using --tls-factory-class-name and --tls-factory-config.
  • Proxy authentication: brokers now default to authenticateOriginalAuthData=true. For deployments using TLS client-certificate or SASL authentication through a proxy, explicitly set authenticateOriginalAuthData=false in the broker configuration before rolling the brokers. The proxy's certificate does not authenticate the original client, and a SASL handshake cannot be replayed on the proxy-to-broker connection. Retain the appropriate trusted proxyRoles and authorization settings. Test both binary client connections and proxied HTTP admin requests with your real client identities. Proxied tenant administration requires both the proxy role and original principal to be authorized as a superuser or tenant administrator; granting that permission only to the proxy is insufficient. See Proxy configuration and Authorization.
  • Pulsar Broker plugins and extensions: use JDK 21 or later to build against broker-side libraries, which now target Java 21. Update plugin build environments and CI jobs, then rebuild and test against the target Pulsar release. Update extensions that use the affected Java EE APIs from javax.* to jakarta.* at the Jakarta EE 10 level. The change does not rename every javax package. Legacy javax.servlet AdditionalServlet plugins are adapted for the new servlet environment; test their behavior along with other extensions. Adapt custom metadata-store implementations to the new overloads and Set<Option> hooks, including MetadataCache<T>.put(String path, T value, Set<Option> opts); see Custom metadata-store implementations. Custom topic-policy listeners that rely on the initial namespace-wide notification may need topicPolicyListenerReplayEnabled=true; it is disabled by default. See PIP-472 and Plugin development.
  • Custom managed-ledger integrations: remove calls to the unused ManagedLedgerConfig accessors for metadataEnsembleSize, metadataWriteQuorumSize, and metadataAckQuorumSize; those Java fields and methods have been removed. The broker settings managedLedgerDefaultEnsembleSize, managedLedgerDefaultWriteQuorum, and managedLedgerDefaultAckQuorum continue to supply default quorums, subject to persistence-policy overrides.
  • Broker interceptor ordering: hooks now run in the order listed in brokerInterceptors. Check that order when one extension depends on work performed by an earlier hook.
  • Custom diagnostics libraries: replace calls to the removed org.apache.pulsar:structured-event-log artifact and org.apache.pulsar.structuredeventlog classes. Code using the LatencyTracer API introduced in 4.2.4 must adapt: construct it with a NanoTimeSupplier without supplying a Queue<Timepoint>, and use getTracePoints() and getSnapshot(). Timepoint, getLatency(), and the previous three-argument Snapshot constructor have been replaced. See Logging.

Before rolling brokers or upgrading clients, also exercise schema lookup, schema registration, and transactions with their production roles. When authorization is enabled, binary schema reads now require topic lookup authorization, schema registration requires produce authorization, and v4 transaction participant registration checks produce or subscription-specific consume authorization. Custom authorization providers must support these checks. See Schema and transaction authorization.

Check Functions behavior and extensions​

  • Python output message properties: the Python runtime now honors forwardSourceMessageProperty. With the default worker settings, an omitted function setting enables copying input properties to the output. If downstream consumers rely on output properties without that forwarding, set forwardSourceMessageProperty: false in the Function configuration and verify output properties before upgrading the runtime. This change concerns Python; Java already applied the setting, and this change does not add it to Go. See Python and Go runtime settings.
  • Custom worker extensions: rebuild and adapt plugins that use generated org.apache.pulsar.functions.proto Java types to the LightProto API, including the top-level FunctionDetails type used by FunctionAuthProvider. See Custom worker extensions.
  • Java record implementations: KVRecord<K, V> now extends Record<V>. When rebuilding a custom implementation, ensure that getValue() returns V; an implementation that previously returned Object may need adaptation.