Camel Quarkus 3.33.3 Migration Guide
The following guide outlines how to adapt your code to changes that were made in Camel Quarkus 3.33.3.
LDAP extension changes
security-authentication is no longer defaulted to none
quarkus.camel.ldap.dir-contexts."name".security-authentication previously defaulted to none, which was put into the JNDI environment for every directory context whether or not it had been configured. Its documentation has always said that the behaviour is determined by the service provider when the property is unspecified, and it is now the only option in that configuration group without a default, matching initial-context-factory, provider-url, security-protocol and socket-factory.
The property is now only placed into the JNDI environment when it is configured, so the service provider decides otherwise.
This matters where credentials are supplied through additional-options, which is the only way to pass them. Previously none was already in the environment, and supplying only a principal and credentials left the bind anonymous with the credentials ignored. They now take effect.
To keep the previous behaviour for a context that relied on the default, set it explicitly.
quarkus.camel.ldap.dir-contexts."my-context".security-authentication=none JTA extension changes
Rollback and resume failures are no longer swallowed
TransactionalJtaTransactionPolicy, the base class of all six PROPAGATION_* policies, logged a warning and carried on when rollback(), setRollbackOnly() or resume() failed. A route that handled the original exception could therefore continue as though the transaction had been marked for rollback when it had not, and work after a failed resume ran outside the transaction the policy was expected to restore.
These failures are now raised:
-
A failure to roll back, or to mark an outer transaction for rollback, is attached to the exception that made the rollback necessary as a suppressed exception. That exception still propagates unchanged, so the failure is visible without hiding its cause.
-
A failure to resume a suspended transaction, in
PROPAGATION_REQUIRES_NEWandPROPAGATION_NOT_SUPPORTED, is attached to the in-flight failure in the same way, or raised on its own when the body succeeded.
An application that inspected only the top-level exception sees no difference. One that handles exceptions and continues may now see a failure it previously never learned about. Check Throwable.getSuppressed() when diagnosing.
No method signatures changed. resumeTransaction(Transaction) is unchanged and now wraps a resume failure in a RuntimeCamelException; a new resumeTransaction(Transaction, Throwable) overload is what the policies use so that a resume failure cannot replace a failure already on its way out.
Core extension changes
serialization-enabled can now veto extension serialization registrations
quarkus.camel.native.reflection.serialization-enabled previously defaulted to false, but a false value carried no meaning of its own. Extensions that require Java serialization to work, such as camel-quarkus-jms, camel-quarkus-jolt, camel-quarkus-management, camel-quarkus-netty, camel-quarkus-sjms, camel-quarkus-sjms2 and camel-quarkus-sql, registered the base set of classes for serialization on being present on the classpath, and there was no way to prevent it.
The option is now unset by default and has three states:
-
When it is not set, classes are registered for serialization only if an extension on the classpath requires it. This matches the previous behaviour.
-
When it is
true, the base set of classes is always registered. This is unchanged. -
When it is
false, nothing is registered for serialization, even if extensions on the classpath require it. This is new.
Setting the option to false therefore now bounds what the native image is able to deserialize, at the cost of breaking any component that depends on Java serialization. A build that requests the veto while extensions ask for serialization logs a warning.
Applications that set the option to false while relying on one of the extensions above must remove the setting to keep working. Applications that set it to true, or that never set it, are unaffected.
XSLT extension changes
The camel-quarkus-xslt extension transforms with Xalan-J rather than the XSLT implementation built into the JDK, because translets have to be compiled ahead of time to work in native mode. Xalan-J 2.7.x predates JAXP 1.5 and cannot honour javax.xml.XMLConstants.ACCESS_EXTERNAL_DTD or ACCESS_EXTERNAL_STYLESHEET, and its secure processing feature restricts extension functions only, without implying the external access restrictions the JDK applies under the same feature. Those restrictions are now applied by the extension instead, so that an application gets the same protection it would get from plain Camel on the JDK.
This affects more than the xslt: endpoints. The extension registers its factory as the JAXP default, so any code in the application that obtains a TransformerFactory through TransformerFactory.newInstance() is transforming with it, including code reached through camel-quarkus-tika and camel-quarkus-xmlsecurity, which depend on the same support extension without using XSLT themselves. Refer to the XSLT extension documentation for the steady state behaviour.
External entities in input documents are no longer resolved
Documents being transformed are now parsed with an XMLReader that does not resolve external entities or load external DTDs, so a SYSTEM entity in a DOCTYPE declaration no longer expands into the transformation result, and an external DTD or parameter entity is skipped.
Most routes see no change, because camel-xslt already converts String, byte[] and InputStream bodies through Camel’s own hardened parser before the transformer sees them. The change matters where the body reaches the transformer already shaped as a Source, for example after convertBodyTo(Source.class) or from a component that produces one, and for code calling the factory directly.
A SAXSource carrying an XMLReader the caller configured is passed through untouched, so an application that needs different parsing rules can supply its own reader.
SAXParserFactory parserFactory = SAXParserFactory.newInstance();
parserFactory.setNamespaceAware(true);
// Configure the parser as required, then hand the transformer a reader of your own
Source source = new SAXSource(parserFactory.newSAXParser().getXMLReader(), inputSource); DOMSource and StAXSource bodies are parsed before they reach the transformer and are unaffected.
document() is denied unless a URIResolver resolves it
Resources fetched at transform time by the XSLT document() function are now denied unless the application’s own javax.xml.transform.URIResolver resolves them, which is what the JDK does when secure processing is enabled.
Routes are unaffected. camel-xslt installs a URIResolver on every transformer it uses, so document() continues to resolve exactly as it did, and as it does on plain Camel. The change affects code that uses the JAXP default factory directly and relies on document() without setting a resolver.
The restriction applies to every entry point that hands out something to transform with, so code driving the SAX push API through newTransformerHandler() or newXMLFilter() is restricted in the same way, including the Transformer reached through TransformerHandler.getTransformer().
Because the restriction is carried by a URIResolver rather than by a factory attribute Xalan cannot honour, it survives the two things that would otherwise remove it: Transformer.reset() keeps it, and setURIResolver(null) falls back to it rather than lifting it. An application that needs document() to resolve sets a resolver of its own, as before.
Transformer transformer = TransformerFactory.newInstance().newTransformer(stylesheet);
transformer.setURIResolver(myResolver); xsl:import and xsl:include are unchanged. Xalan dereferences those hrefs itself while compiling a stylesheet, ignoring the resolver it consulted first, so they cannot be restricted here. Stylesheets are deployment owned rather than attacker controlled, and camel-xslt resolves includes through its own unrestricted resolver in any case.
quarkus.camel.xslt.features applies to every template
quarkus.camel.xslt.features was only applied to templates that were compiled to a translet at build time, which is classpath: templates. It was silently ignored for templates loaded at runtime, which is the remaining schemes in JVM mode. It is now applied to every template the component transforms with.
A feature that previously had no effect on those endpoints now takes effect, and one the TransformerFactory does not support now fails endpoint creation rather than passing unnoticed. Review the property if it is set for an application that transforms with templates loaded at runtime.
Disabling secure processing also now logs a warning on startup, since it permits templates to call Xalan extension functions.
quarkus.camel.xslt.features."http\://javax.xml.XMLConstants/feature/secure-processing"=false | Only disable it where every template the application transforms with is trusted. |
Jolokia extension changes
Jolokia is now locked down by default. In prod mode the agent binds to localhost, accepts requests only from the local machine, and denies cross-origin requests. Previously it bound to all interfaces and accepted every client.
Jolokia now honours Sec-Fetch-* headers, rejecting browser requests marked as anything other than an explicit top-level navigation, which affects neither command line clients such as curl nor the calls Hawtio makes.
Refer to the Jolokia extension documentation for details of the options below.
Remote clients are refused
To allow clients from other hosts again.
quarkus.camel.jolokia.server.host=0.0.0.0
quarkus.camel.jolokia.remote-access-allowed=true This exposes an agent that authenticates nobody. Confine it to a trusted network, or configure authentication, which the extension has always been able to do through additional-properties and which is now documented. |
Where SSL client authentication is configured, which is the default on OpenShift, the agent still binds 0.0.0.0 and still accepts remote clients. Plain Kubernetes has no service CA certificate, so client authentication cannot be configured there and the agent binds localhost. Binding it elsewhere now fails startup rather than warning, unless you acknowledge that nothing authenticates the agent. Switching client authentication off through additional-properties does the same, since the agent still binds 0.0.0.0 there.
quarkus.camel.jolokia.server.host=0.0.0.0
quarkus.camel.jolokia.kubernetes.client-authentication-enabled=false Cross-origin requests are denied
Requests with no Origin header and those from a loopback origin are still accepted. List any other origin.
quarkus.camel.jolokia.allowed-origins=https://hawtio.example.com is a wildcard, so ://.example.com covers a domain and accepts any origin. remote-access-allowed no longer affects origins.
On OpenShift, setting a client principal restricts access to one service identity and also accepts the cross-origin requests that identity forwards, so allowed-origins does not have to list the console.
quarkus.camel.jolokia.kubernetes.client-principal=cn=hawtio-online.hawtio.svc jolokia-access.xml is now applied
A policy file was previously ignored whenever the Camel restrictor was registered, which is the default. Review yours before upgrading.
-
A
<remote>section decides client addresses outright, so one that does not list127.0.0.1refuses local clients too. A policy without that section says nothing about addresses and leaves the loopback default andquarkus.camel.jolokia.remote-access-allowedto decide them. -
The
<cors>section is not used at all. Move<allow-origin>values toquarkus.camel.jolokia.allowed-origins, which takes the same wildcard syntax, and replace<ignore-scheme/>withquarkus.camel.jolokia.ignore-origin-scheme=true. -
A
policyLocationpointing at nothing now fails startup. A policy that cannot be parsed denies all access.
Proxy headers are part of the client address chain
Jolokia now adds any Forwarded, X-Forwarded-For and X-Real-IP values to the chain of client addresses passed to the restrictor, whatever trustProxyHeaders is set to, and every address in the chain has to be allowed. A request claiming to be forwarded on behalf of a remote client is therefore now refused even when it arrives over loopback.
This affects a reverse proxy in front of the agent. The real client is now visible and subject to the same rules as any other, so allow it.
quarkus.camel.jolokia.remote-access-allowed=true Every address in the chain must also satisfy a <remote> section in an access policy. Hawtio adds the browser’s address as X-Forwarded-For by default, so a policy restricting addresses to a cluster subnet rejects its requests unless the browser’s address is allowed too. |
Native mode now refuses an HTTPS origin over a plain HTTP agent
Jolokia refuses a request whose Origin uses https when the agent itself serves plain http, responding with a status of 403, whatever quarkus.camel.jolokia.allowed-origins lists. That rule has always applied in JVM mode and now applies in native mode too, so a native application whose agent serves plain HTTP behind an HTTPS console starts returning 403 after upgrading. Either serve the agent over HTTPS, or turn the check off.
quarkus.camel.jolokia.ignore-origin-scheme=true | Only do this where something in front of the agent terminates TLS. Otherwise, a page loaded over HTTPS ends up driving an agent that is not. |
This does not arise on Kubernetes or OpenShift where SSL client authentication is configured, since the agent then serves HTTPS.