You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@struts.apache.org by lu...@apache.org on 2026/04/04 09:47:57 UTC
(struts) 01/01: WW-5622 perf(core): optimize Hibernate proxy detection when Hibernate is absent
This is an automated email from the ASF dual-hosted git repository.
lukaszlenart pushed a commit to branch fix/WW-5622-hibernate-proxy-detection
in repository https://gitbox.apache.org/repos/asf/struts.git
commit 496ad4eeb86149ab5695601a3439022cf0e10055
Author: Lukasz Lenart <lu...@apache.org>
AuthorDate: Sat Apr 4 11:47:41 2026 +0200
WW-5622 perf(core): optimize Hibernate proxy detection when Hibernate is absent
Detect Hibernate availability once at class-load time via Class.forName()
and short-circuit all Hibernate-related methods immediately when absent.
This eliminates repeated LinkageError/NoClassDefFoundError exceptions
that cause significant performance degradation in applications without
Hibernate on the classpath.
Fixes https://issues.apache.org/jira/browse/WW-5622
Co-Authored-By: Claude Opus 4.6 <no...@anthropic.com>
---
.../java/org/apache/struts2/util/ProxyUtil.java | 16 +++++++++++++++-
.../apache/struts2/util/StrutsProxyService.java | 22 +++++++++++++++++++++-
2 files changed, 36 insertions(+), 2 deletions(-)
diff --git a/core/src/main/java/org/apache/struts2/util/ProxyUtil.java b/core/src/main/java/org/apache/struts2/util/ProxyUtil.java
index 8117807d4..6ec3679ce 100644
--- a/core/src/main/java/org/apache/struts2/util/ProxyUtil.java
+++ b/core/src/main/java/org/apache/struts2/util/ProxyUtil.java
@@ -57,6 +57,17 @@ public class ProxyUtil {
private static final OgnlCache<Member, Boolean> isProxyMemberCache = new DefaultOgnlCacheFactory<Member, Boolean>(
CACHE_MAX_SIZE, OgnlCacheFactory.CacheType.BASIC, CACHE_INITIAL_CAPACITY).buildOgnlCache();
+ private static final boolean HIBERNATE_AVAILABLE = isHibernateAvailable();
+
+ private static boolean isHibernateAvailable() {
+ try {
+ Class.forName("org.hibernate.proxy.HibernateProxy");
+ return true;
+ } catch (ClassNotFoundException e) {
+ return false;
+ }
+ }
+
/**
* Determine the ultimate target class of the given instance, traversing
* not only a top-level proxy but any number of nested proxies as well —
@@ -121,8 +132,9 @@ public class ProxyUtil {
*/
@Deprecated(since = "7.2")
public static boolean isHibernateProxy(Object object) {
+ if (!HIBERNATE_AVAILABLE || object == null) return false;
try {
- return object != null && HibernateProxy.class.isAssignableFrom(object.getClass());
+ return HibernateProxy.class.isAssignableFrom(object.getClass());
} catch (LinkageError ignored) {
return false;
}
@@ -137,6 +149,7 @@ public class ProxyUtil {
*/
@Deprecated(since = "7.2")
public static boolean isHibernateProxyMember(Member member) {
+ if (!HIBERNATE_AVAILABLE) return false;
try {
return hasMember(HibernateProxy.class, member);
} catch (LinkageError ignored) {
@@ -220,6 +233,7 @@ public class ProxyUtil {
*/
@Deprecated(since = "7.2")
public static Object getHibernateProxyTarget(Object object) {
+ if (!HIBERNATE_AVAILABLE) return object;
try {
return Hibernate.unproxy(object);
} catch (LinkageError ignored) {
diff --git a/core/src/main/java/org/apache/struts2/util/StrutsProxyService.java b/core/src/main/java/org/apache/struts2/util/StrutsProxyService.java
index 76c06f469..ee2a3ca70 100644
--- a/core/src/main/java/org/apache/struts2/util/StrutsProxyService.java
+++ b/core/src/main/java/org/apache/struts2/util/StrutsProxyService.java
@@ -48,6 +48,17 @@ import static java.lang.reflect.Modifier.isStatic;
*/
public class StrutsProxyService implements ProxyService {
+ private static final boolean HIBERNATE_AVAILABLE = isHibernateAvailable();
+
+ private static boolean isHibernateAvailable() {
+ try {
+ Class.forName("org.hibernate.proxy.HibernateProxy");
+ return true;
+ } catch (ClassNotFoundException e) {
+ return false;
+ }
+ }
+
private final OgnlCache<Class<?>, Boolean> isProxyCache;
private final OgnlCache<Member, Boolean> isProxyMemberCache;
@@ -90,8 +101,11 @@ public class StrutsProxyService implements ProxyService {
@Override
public boolean isHibernateProxy(Object object) {
+ if (!HIBERNATE_AVAILABLE || object == null) {
+ return false;
+ }
try {
- return object != null && HibernateProxy.class.isAssignableFrom(object.getClass());
+ return HibernateProxy.class.isAssignableFrom(object.getClass());
} catch (LinkageError ignored) {
return false;
}
@@ -99,6 +113,9 @@ public class StrutsProxyService implements ProxyService {
@Override
public boolean isHibernateProxyMember(Member member) {
+ if (!HIBERNATE_AVAILABLE) {
+ return false;
+ }
try {
return hasMember(HibernateProxy.class, member);
} catch (LinkageError ignored) {
@@ -108,6 +125,9 @@ public class StrutsProxyService implements ProxyService {
@Override
public Object getHibernateProxyTarget(Object object) {
+ if (!HIBERNATE_AVAILABLE) {
+ return object;
+ }
try {
return Hibernate.unproxy(object);
} catch (LinkageError ignored) {