Repository navigation
Fix static ObjectMapper initialization trap in JsonUtils and add native CloudEvents Jackson support #1275
Description
Activity
- addedjavaPull requests that update java codePull requests that update java code
on Mar 27, 2026 @fjtirado I remember we have some sort of support for CE already in the messaging code base, but I don't remember what we did in the models. I'll explore a bit and send a PR if necessary.
I have the fix already, I'm running more tests and will send the PR on Monday.
I mistakenly created this:
public FuncEventFilterPropertiesBuilder envelope(Predicate<CloudEvent> predicate) { this.eventProperties.setData( new EventDataPredicate().withPredicate(predicate, CloudEvent.class)); return this; } public FuncEventFilterPropertiesBuilder envelope(ContextPredicate<CloudEvent> predicate) { this.eventProperties.setData( new EventDataPredicate().withPredicate(predicate, CloudEvent.class)); return this; } public FuncEventFilterPropertiesBuilder envelope(FilterPredicate<CloudEvent> predicate) { this.eventProperties.setData( new EventDataPredicate().withPredicate(predicate, CloudEvent.class)); return this; }
The
DefaultCloudEventPredicateis not expecting aCloudEventpredicate, so it's blowing everywhere. I'll add a new type toEventPropertiesto deal with this new predicate in theadditionalPropertiesmap. So then we can have anenvelopeFilterin the predicate and test this correctly, without breaking backwards compatibility with thedatapredicates we already have.I have the fix already, I'm running more tests and will send the PR on Monday.
I mistakenly created this:
public FuncEventFilterPropertiesBuilder envelope(Predicate predicate) {
this.eventProperties.setData(
new EventDataPredicate().withPredicate(predicate, CloudEvent.class));
return this;
}public FuncEventFilterPropertiesBuilder envelope(ContextPredicate predicate) {
this.eventProperties.setData(
new EventDataPredicate().withPredicate(predicate, CloudEvent.class));
return this;
}public FuncEventFilterPropertiesBuilder envelope(FilterPredicate predicate) {
this.eventProperties.setData(
new EventDataPredicate().withPredicate(predicate, CloudEvent.class));
return this;
}
TheDefaultCloudEventPredicateis not expecting aCloudEventpredicate, so it's blowing everywhere. I'll add a new type toEventPropertiesto deal with this new predicate in theadditionalPropertiesmap. So then we can have anenvelopeFilterin the predicate and test this correctly, without breaking backwards compatibility with thedatapredicates we already have.Hmmm, withPredicate sets the object field of EventData to a Predicate, later on, when EventData is converted to a Filter, getObject is used and that should call this method, which properly handle the Predicate object , so I do not think the envelopeFilter is needed. Can I see the exact failure we are trying to fix?, I suspect JavaExpressionFactory is not getting called, maybe because the priorities are not correctly set.
- added a commit that references this issue
on Apr 1, 2026
What happened:
There are two related issues in the SDK's Jackson serialization layer that prevent proper integration with DI frameworks (like Quarkus or Spring) and cause native CloudEvent filtering/evaluation to fail.
Issue 1: Static
ObjectMapperTrap in JsonUtilsio.serverlessworkflow.impl.jackson.JsonUtilscaches theObjectMapperin a static field at class load time:If a framework attempts to inject a custom
ObjectMapperviaObjectMapperFactoryProvider.instance().setFactory(...)after theJsonUtilsclass has been loaded, the factory override is completely ignored. This forces developers to use reflection to overwrite the static field.Issue 2: Missing CloudEvent Serialization Support
The SDK natively exposes
io.cloudevents.CloudEventin its DSL (e.g.,FuncEventFilterSpec). However, the defaultObjectMapperfallback inObjectMapperFactoryProviderdoes not register the CloudEvents Jackson module. When the engine evaluates event predicates (convertingCloudEventtoJsonNodeand back), Jackson throws either:InvalidDefinitionException(Cannot construct instance of interface io.cloudevents.CloudEvent)MismatchedInputException(Missing mandatory specversion attribute due to default POJO serializers mangling the CE envelope).Proposed Solution
Remove static caching: Update JsonUtils to fetch the mapper dynamically:
Optimize fallback & register CE natively: To prevent performance drops from creating a new
ObjectMapper()on every call, updateObjectMapperFactoryProviderto provide a static, pre-configured singleton as the default fallback. This default mapper must include the official CloudEvents module:Native Converters for CloudEvent Types: Update
JsonUtilsto explicitly interceptCloudEventandCloudEventDatatypes, bypassing Jackson POJO serialization in favor of the officialEventFormatProvider.fromValue(Object value):convertValue(JsonNode jsonNode, Class<T> returnType):Anything else we need to know?:
This was something I should've tested when implementing the event filtering DSL.
Environment: