Skip to content

Fix lambda EventListener generic type detection via SerializedLambda - #291

Draft
mercyblitz with Copilot wants to merge 1 commit into
mainfrom
copilot/fix-event-listener-generic-type
Draft

Fix lambda EventListener generic type detection via SerializedLambda#291
mercyblitz with Copilot wants to merge 1 commit into
mainfrom
copilot/fix-event-listener-generic-type

Conversation

Copilot AI commented Aug 2, 2026

Copy link
Copy Markdown
Contributor

DirectEventDispatcher failed to identify the Event subtype when EventListener was declared as a lambda — e.g. EventListener<EchoEvent> listener = event -> {} — because constant-pool inspection is blocked by the Java 17 module system without --add-opens.

Root causes

  • ConstantPoolUtils.invoke: getConstantPool(targetClass) was called outside the try-catch, so IllegalArgumentException (from Java 17 reflective access denial) escaped uncaught and crashed addEventListener
  • ConstantPoolUtils.getSize: auto-unboxed a nullable Integer return → NPE

Changes

  • ConstantPoolUtils: move getConstantPool() inside the try-catch; null-safe unboxing in getSize() (returns 0 on null)
  • EventListener: extend Serializable so the JVM generates writeReplace() on lambda instances; update findEventType(EventListener<?>) to pass the instance (not just the class) to enable the new fallback
  • LambdaUtils: add SerializedLambda fallback in resolveLambdaMethodParameterTypes(Object, Class) — when constant-pool returns empty and the object is Serializable, invoke writeReplace() and parse the concrete instantiated method type descriptor via MethodType.fromMethodDescriptorString() to recover exact parameter types without any --add-opens
  • microsphere-java-core/pom.xml: add --add-opens java.base/java.lang=ALL-UNNAMED to jvm.argLine for tests that still exercise constant-pool inspection (e.g. LongFunction lambdas)

Example

// Previously: EchoEvent type undetectable, addEventListener silently failed
EventListener<EchoEvent> listener = event -> { System.out.println(event); };
dispatcher.addEventListener(listener); // Now correctly registers under EchoEvent

The SerializedLambda.getInstantiatedMethodType() descriptor (e.g. (Lio/microsphere/event/EchoEvent;)V) carries the concrete type argument that type erasure strips from the class hierarchy, making this approach reliable where constant-pool inspection is unavailable.

@sonarqubecloud

sonarqubecloud Bot commented Aug 2, 2026

Copy link
Copy Markdown

Copilot AI changed the title Fix lambda EventListener type detection via SerializedLambda fallback Fix lambda EventListener generic type detection via SerializedLambda Aug 2, 2026
Copilot AI requested a review from mercyblitz August 2, 2026 13:02
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants