This is an automated email from the ASF dual-hosted git repository.
lukaszlenart pushed a commit to branch release/struts-6-8-x
in repository https://gitbox.apache.org/repos/asf/struts.git
The following commit(s) were added to refs/heads/release/struts-6-8-x by this
push:
new 94e3ffd1e WW-5622 perf(core): cache Hibernate class presence to avoid
repeated NoClassDefFoundError (#1650)
94e3ffd1e is described below
commit 94e3ffd1e79fc64dd8968477c83e74f9f3ec005e
Author: Lukasz Lenart <[email protected]>
AuthorDate: Sun Apr 5 18:30:57 2026 +0200
WW-5622 perf(core): cache Hibernate class presence to avoid repeated
NoClassDefFoundError (#1650)
Detect Hibernate availability once at class-load time via Class.forName()
and short-circuit all Hibernate-related methods immediately when absent.
This eliminates repeated NoClassDefFoundError exceptions that cause
significant performance degradation in applications without Hibernate
on the classpath.
Co-authored-by: Claude Opus 4.6 <[email protected]>
---
.../main/java/com/opensymphony/xwork2/util/ProxyUtil.java | 14 ++++++++++++++
1 file changed, 14 insertions(+)
diff --git a/core/src/main/java/com/opensymphony/xwork2/util/ProxyUtil.java
b/core/src/main/java/com/opensymphony/xwork2/util/ProxyUtil.java
index c3c4e1133..822e09fb6 100644
--- a/core/src/main/java/com/opensymphony/xwork2/util/ProxyUtil.java
+++ b/core/src/main/java/com/opensymphony/xwork2/util/ProxyUtil.java
@@ -52,6 +52,17 @@ public class ProxyUtil {
private static final int CACHE_MAX_SIZE = 10000;
private static final int CACHE_INITIAL_CAPACITY = 256;
+ private static final boolean HIBERNATE_AVAILABLE = detectHibernate();
+
+ private static boolean detectHibernate() {
+ try {
+ Class.forName("org.hibernate.proxy.HibernateProxy");
+ return true;
+ } catch (ClassNotFoundException e) {
+ return false;
+ }
+ }
+
// Holder for the cache factory (set by container)
private static volatile ProxyCacheFactory<?, ?> cacheFactory;
@@ -153,6 +164,7 @@ public class ProxyUtil {
* @param object the object to check
*/
public static boolean isHibernateProxy(Object object) {
+ if (!HIBERNATE_AVAILABLE) return false;
try {
return object != null &&
HibernateProxy.class.isAssignableFrom(object.getClass());
} catch (NoClassDefFoundError ignored) {
@@ -166,6 +178,7 @@ public class ProxyUtil {
* @param member the member to check
*/
public static boolean isHibernateProxyMember(Member member) {
+ if (!HIBERNATE_AVAILABLE) return false;
try {
Class<?> clazz =
ClassLoaderUtil.loadClass(HIBERNATE_HIBERNATEPROXY_CLASS_NAME, ProxyUtil.class);
return hasMember(clazz, member);
@@ -303,6 +316,7 @@ public class ProxyUtil {
* @return the target instance of the given object if it is a Hibernate
proxy object, otherwise the given object
*/
public static Object getHibernateProxyTarget(Object object) {
+ if (!HIBERNATE_AVAILABLE) return object;
try {
return Hibernate.unproxy(object);
} catch (NoClassDefFoundError ignored) {