From 64c75259088482b1bfbdab4b1590fe8d01d7a97a Mon Sep 17 00:00:00 2001 From: Paul Ferraro Date: Wed, 7 Aug 2024 17:40:23 -0400 Subject: [PATCH 1/2] WFLY-19613 Replace ProxyFactory.getInvocationHandlerStatic with field iteration - since most invocations of this predicate will throw/catch a NoSuchFieldException. --- .../StatefulSessionBeanImmutability.java | 28 +++++++++++++++---- 1 file changed, 22 insertions(+), 6 deletions(-) diff --git a/ejb3/src/main/java/org/jboss/as/ejb3/component/stateful/StatefulSessionBeanImmutability.java b/ejb3/src/main/java/org/jboss/as/ejb3/component/stateful/StatefulSessionBeanImmutability.java index 55230889db06..80696ff3f3ce 100644 --- a/ejb3/src/main/java/org/jboss/as/ejb3/component/stateful/StatefulSessionBeanImmutability.java +++ b/ejb3/src/main/java/org/jboss/as/ejb3/component/stateful/StatefulSessionBeanImmutability.java @@ -5,12 +5,15 @@ package org.jboss.as.ejb3.component.stateful; +import java.lang.reflect.Field; import java.lang.reflect.InvocationHandler; import org.jboss.as.ee.component.ProxyInvocationHandler; import org.jboss.invocation.proxy.ProxyFactory; import org.kohsuke.MetaInfServices; import org.wildfly.clustering.ee.Immutability; +import org.wildfly.security.ParametricPrivilegedAction; +import org.wildfly.security.manager.WildFlySecurityManager; /** * Immutability test for EJB proxies, whose serializable placeholders are immutable. @@ -18,14 +21,27 @@ */ @MetaInfServices(Immutability.class) public class StatefulSessionBeanImmutability implements Immutability { + private static final ParametricPrivilegedAction GET_INVOCATION_HANDLER = new ParametricPrivilegedAction<>() { + @Override + public InvocationHandler run(Object object) { + // Since there is a low probability that this object is actually a SFSB proxy, avoid Class.getDeclaredField(...) which will typically throw/catch a NoSuchFieldException + for (Field field : object.getClass().getDeclaredFields()) { + if (field.getName().equals(ProxyFactory.INVOCATION_HANDLER_FIELD)) { + field.setAccessible(true); + try { + return (InvocationHandler) field.get(object); + } catch (IllegalAccessException e) { + throw new IllegalStateException(e); + } + } + } + return null; + } + }; @Override public boolean test(Object object) { - try { - InvocationHandler handler = ProxyFactory.getInvocationHandlerStatic(object); - return handler instanceof ProxyInvocationHandler; - } catch (RuntimeException e) { - return false; - } + InvocationHandler handler = WildFlySecurityManager.doUnchecked(object, GET_INVOCATION_HANDLER); + return handler instanceof ProxyInvocationHandler; } } From fc8a193a0cc96c422b1be911d36ba6f2a947b358 Mon Sep 17 00:00:00 2001 From: Paul Ferraro Date: Wed, 7 Aug 2024 17:43:04 -0400 Subject: [PATCH 2/2] WFLY-19613 Bypass immutability check when redundant. --- .../session/attributes/coarse/CoarseSessionAttributes.java | 3 ++- .../cache/session/attributes/fine/FineSessionAttributes.java | 5 +++-- 2 files changed, 5 insertions(+), 3 deletions(-) diff --git a/clustering/web/cache/src/main/java/org/wildfly/clustering/web/cache/session/attributes/coarse/CoarseSessionAttributes.java b/clustering/web/cache/src/main/java/org/wildfly/clustering/web/cache/session/attributes/coarse/CoarseSessionAttributes.java index 46b9ac3fb4f0..7970137a06a8 100644 --- a/clustering/web/cache/src/main/java/org/wildfly/clustering/web/cache/session/attributes/coarse/CoarseSessionAttributes.java +++ b/clustering/web/cache/src/main/java/org/wildfly/clustering/web/cache/session/attributes/coarse/CoarseSessionAttributes.java @@ -67,7 +67,8 @@ public Object setAttribute(String name, Object value) { @Override public Object getAttribute(String name) { Object value = this.attributes.get(name); - if (!this.immutability.test(value)) { + // Bypass immutability check if session is already dirty + if (!this.dirty.get() && !this.immutability.test(value)) { this.dirty.set(true); } return value; diff --git a/clustering/web/cache/src/main/java/org/wildfly/clustering/web/cache/session/attributes/fine/FineSessionAttributes.java b/clustering/web/cache/src/main/java/org/wildfly/clustering/web/cache/session/attributes/fine/FineSessionAttributes.java index 5102360683b2..505d6734bd7a 100644 --- a/clustering/web/cache/src/main/java/org/wildfly/clustering/web/cache/session/attributes/fine/FineSessionAttributes.java +++ b/clustering/web/cache/src/main/java/org/wildfly/clustering/web/cache/session/attributes/fine/FineSessionAttributes.java @@ -55,8 +55,9 @@ public Object getAttribute(String name) { if (value != null) { // If the object is mutable, we need to mutate this value on close - if (!this.immutability.test(value)) { - synchronized (this.updates) { + synchronized (this.updates) { + // Bypass immutability check if we are already updating this attribute + if (!this.updates.containsKey(name) && !this.immutability.test(value)) { this.updates.put(name, value); } }