This is an automated email from the ASF dual-hosted git repository.

lukaszlenart pushed a commit to branch 
fix/WW-5622-hibernate-proxy-detection-perf
in repository https://gitbox.apache.org/repos/asf/struts.git

commit 2eede240920cd942ed071aecae41723fdd0de4d2
Author: Lukasz Lenart <[email protected]>
AuthorDate: Sat Apr 4 15:22:14 2026 +0200

    WW-5622 perf(core): cache Hibernate class presence to avoid repeated 
NoClassDefFoundError
    
    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) {

Reply via email to