Replace serialization-based type inference with reified varargs type token#1524
Open
mdproctor wants to merge 1 commit into
Open
Replace serialization-based type inference with reified varargs type token#1524mdproctor wants to merge 1 commit into
mdproctor wants to merge 1 commit into
Conversation
…token The fluent DSL previously used SerializableFunction/Predicate/Consumer interfaces and ReflectionUtils.inferInputType() to recover generic type information at runtime. This relied on JVM serialization internals (writeReplace → SerializedLambda) which are fragile, heavyweight, and force all lambdas to implement Serializable. Replace with the reified varargs type token pattern: declaring a trailing T... parameter causes Java to create a reified array at the call site, making the erased-but-concrete class recoverable via getClass().getComponentType(). This gives the same runtime Class<T> with zero reflection, zero serialization, zero allocation, and works with any lambda or method reference regardless of serializability. Changes: - Replace ~40 call sites across FuncDSL, Step, CommonFuncOps, FuncEmitSpec, FuncEmitEventPropertiesBuilder, and FuncEventFilterSpec - Delete ReflectionUtils, SerializableFunction, SerializablePredicate, SerializableConsumer (no longer needed) - Drop Serializable from InstanceIdFunction and UniqueIdBiFunction (was only needed for the inference hack; ContextFunction and FilterFunction keep it as they are stored in serializable CallJava objects) - Add test demonstrating nested generic type safety (Map<String, List<Integer>>) Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
Contributor
There was a problem hiding this comment.
Pull request overview
This PR removes the previous serialization/SerializedLambda-based runtime type inference utilities and migrates the fluent function DSL to a “reified varargs type token” approach for recovering the raw input Class<T> at call sites, eliminating the need for Serializable* functional interfaces and ReflectionUtils.
Changes:
- Deleted
ReflectionUtilsand theSerializableFunction/SerializablePredicate/SerializableConsumerhelper interfaces; removedSerializablefromInstanceIdFunctionandUniqueIdBiFunction. - Updated fluent DSL entrypoints (
FuncDSL,Step,CommonFuncOps, and related specs/builders) to accept standard JDK functional interfaces plus an optional varargs type token for input class inference. - Added a test intended to demonstrate nested generic lambda type safety.
Reviewed changes
Copilot reviewed 13 out of 13 changed files in this pull request and generated 1 comment.
Show a summary per file
| File | Description |
|---|---|
| experimental/types/src/main/java/io/serverlessworkflow/api/reflection/func/UniqueIdBiFunction.java | Drops Serializable from the functional interface now that serialization inference is removed. |
| experimental/types/src/main/java/io/serverlessworkflow/api/reflection/func/SerializablePredicate.java | Removed obsolete serializable predicate shim. |
| experimental/types/src/main/java/io/serverlessworkflow/api/reflection/func/SerializableFunction.java | Removed obsolete serializable function shim. |
| experimental/types/src/main/java/io/serverlessworkflow/api/reflection/func/SerializableConsumer.java | Removed obsolete serializable consumer shim. |
| experimental/types/src/main/java/io/serverlessworkflow/api/reflection/func/ReflectionUtils.java | Deleted serialization/reflection-based lambda type inference utility. |
| experimental/types/src/main/java/io/serverlessworkflow/api/reflection/func/InstanceIdFunction.java | Drops Serializable from the functional interface now that serialization inference is removed. |
| experimental/fluent/func/src/test/java/io/serverlessworkflow/fluent/func/FuncDSLTest.java | Adds a nested-generics-focused test for the updated DSL typing behavior. |
| experimental/fluent/func/src/main/java/io/serverlessworkflow/fluent/func/FuncEmitEventPropertiesBuilder.java | Accepts Function directly instead of a serializable wrapper. |
| experimental/fluent/func/src/main/java/io/serverlessworkflow/fluent/func/dsl/Step.java | Replaces reflection-based inference with varargs type token input-class derivation for chained operations. |
| experimental/fluent/func/src/main/java/io/serverlessworkflow/fluent/func/dsl/FuncEventFilterSpec.java | Switches envelope/data filter overloads from serializable predicates to standard Predicate. |
| experimental/fluent/func/src/main/java/io/serverlessworkflow/fluent/func/dsl/FuncEmitSpec.java | Adds varargs type-token overload for JSON event data emission. |
| experimental/fluent/func/src/main/java/io/serverlessworkflow/fluent/func/dsl/FuncDSL.java | Updates core DSL helpers to use varargs type tokens for input class inference and removes reflection-based return-type inference wiring. |
| experimental/fluent/func/src/main/java/io/serverlessworkflow/fluent/func/dsl/CommonFuncOps.java | Updates shared DSL ops to accept standard Function/Predicate with type-token inference. |
💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.
Comment on lines
+687
to
+690
| List<TaskItem> items = wf.getDo(); | ||
| assertEquals(1, items.size()); | ||
| assertNotNull(items.get(0).getTask().getCallTask(), "CallTask expected"); | ||
| } |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Summary
SerializableFunction/SerializablePredicate/SerializableConsumer+ReflectionUtils.inferInputType()with the reified varargs type token pattern across ~40 call sitesReflectionUtils,SerializableFunction,SerializablePredicate,SerializableConsumer— no longer neededSerializablefromInstanceIdFunctionandUniqueIdBiFunction(was only needed for the inference hack)Map<String, List<Integer>>)Motivation
The previous approach used JVM serialization internals (
writeReplace→SerializedLambda→getInstantiatedMethodType) to recover erased type parameters at runtime. This is:SerializableThe reified varargs type token pattern achieves the same result (recovering the raw
Class<T>at runtime) with zero reflection, zero serialization, and works with any lambda or method reference regardless of serializability. Java reifies array creation at the call site even for generic varargs parameters, soT... typeTokenwith zero arguments creates anew T[0]whose component type is recoverable viagetClass().getComponentType().Test plan
function_with_nested_generics_preserves_type_safety— verifiesMap<String, List<Integer>>flows through with compile-time type safety🤖 Generated with Claude Code