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

dkulp pushed a commit to branch main
in repository https://gitbox.apache.org/repos/asf/cxf.git


The following commit(s) were added to refs/heads/main by this push:
     new 728edf1b58 CXF-8885: Eliminate hard refs to `HttpClient` via 
`HTTPClientPolicy`
728edf1b58 is described below

commit 728edf1b589c87715220e753208a5b1ff2a3f0cb
Author: Leonard Wörteler <leonard.woerte...@knime.com>
AuthorDate: Sat Aug 12 17:22:26 2023 +0200

    CXF-8885: Eliminate hard refs to `HttpClient` via `HTTPClientPolicy`
    
    There are additional potential references to the `HttpClientFacade`
    hidden in the property change listeners of `HTTPClientPolicy`.
    To prevent those from keeping the SelectorManager thread alive, the
    `HTTPConduit` now registers itself as a listener only via a
    `WeakReference`, so the conduit can be garbage collected even if the
    client policy is still referenced inside the SelectorManager thread.
---
 .../org/apache/cxf/transport/http/HTTPConduit.java | 32 ++++++++++++++++++----
 1 file changed, 27 insertions(+), 5 deletions(-)

diff --git 
a/rt/transports/http/src/main/java/org/apache/cxf/transport/http/HTTPConduit.java
 
b/rt/transports/http/src/main/java/org/apache/cxf/transport/http/HTTPConduit.java
index 33b6157559..801eac24e4 100644
--- 
a/rt/transports/http/src/main/java/org/apache/cxf/transport/http/HTTPConduit.java
+++ 
b/rt/transports/http/src/main/java/org/apache/cxf/transport/http/HTTPConduit.java
@@ -26,6 +26,7 @@ import java.io.InputStream;
 import java.io.OutputStream;
 import java.io.PrintWriter;
 import java.io.StringWriter;
+import java.lang.ref.WeakReference;
 import java.net.HttpRetryException;
 import java.net.HttpURLConnection;
 import java.net.MalformedURLException;
@@ -298,6 +299,27 @@ public abstract class HTTPConduit
 
     private volatile boolean clientSidePolicyCalced;
 
+    private final PropertyChangeListener weakRefListener = new 
WeakPropertyChangeListenerAdapter(this);
+
+    /**
+     * Change listener that propagates events to this conduit as long as it is 
alive without holding a hard reference.
+     */
+    private static final class WeakPropertyChangeListenerAdapter implements 
PropertyChangeListener {
+        /** Weak reference so the listener can be garbage collected even if it 
is still registered somewhere. */
+        private final WeakReference<PropertyChangeListener> reference;
+
+        WeakPropertyChangeListenerAdapter(PropertyChangeListener inner) {
+            reference = new WeakReference<>(inner);
+        }
+
+        @Override
+        public void propertyChange(PropertyChangeEvent evt) {
+            PropertyChangeListener inner = reference.get();
+            if (inner != null) {
+                inner.propertyChange(evt);
+            }
+        }
+    }
 
     /**
      * Constructor
@@ -352,8 +374,8 @@ public abstract class HTTPConduit
                                                                         this,
                                                                         new 
ClientPolicyCalculator());
                 if (clientSidePolicy != null) {
-                    clientSidePolicy.removePropertyChangeListener(this); 
//make sure we aren't added twice
-                    clientSidePolicy.addPropertyChangeListener(this);
+                    
clientSidePolicy.removePropertyChangeListener(weakRefListener); //make sure we 
aren't added twice
+                    
clientSidePolicy.addPropertyChangeListener(weakRefListener);
                 }
             }
         }
@@ -749,7 +771,7 @@ public abstract class HTTPConduit
      */
     public void close() {
         if (clientSidePolicy != null) {
-            clientSidePolicy.removePropertyChangeListener(this);
+            clientSidePolicy.removePropertyChangeListener(weakRefListener);
         }
     }
 
@@ -927,8 +949,8 @@ public abstract class HTTPConduit
         }
         this.clientSidePolicyCalced = true;
         this.clientSidePolicy = client;
-        clientSidePolicy.removePropertyChangeListener(this); //make sure we 
aren't added twice
-        clientSidePolicy.addPropertyChangeListener(this);
+        clientSidePolicy.removePropertyChangeListener(weakRefListener); //make 
sure we aren't added twice
+        clientSidePolicy.addPropertyChangeListener(weakRefListener);
         endpointInfo.setProperty("org.apache.cxf.ws.addressing.replyto", 
client.getDecoupledEndpoint());
     }
 

Reply via email to