You are viewing a plain text version of this content. The canonical link for it is here.
Posted to java-dev@axis.apache.org by sc...@apache.org on 2009/12/07 18:52:29 UTC
svn commit: r888050 - in
/webservices/axis2/trunk/java/modules/jaxws/src/org/apache/axis2/jaxws:
binding/BindingImpl.java handler/HandlerChainProcessor.java
Author: scheu
Date: Mon Dec 7 17:52:29 2009
New Revision: 888050
URL: http://svn.apache.org/viewvc?rev=888050&view=rev
Log:
AXIS2-4576
Contributor: Rich Scheuerle
Avoid ConcurrentModificationExcetion during Handler Chain Processing
Plus additional debug trace.
Modified:
webservices/axis2/trunk/java/modules/jaxws/src/org/apache/axis2/jaxws/binding/BindingImpl.java
webservices/axis2/trunk/java/modules/jaxws/src/org/apache/axis2/jaxws/handler/HandlerChainProcessor.java
Modified: webservices/axis2/trunk/java/modules/jaxws/src/org/apache/axis2/jaxws/binding/BindingImpl.java
URL: http://svn.apache.org/viewvc/webservices/axis2/trunk/java/modules/jaxws/src/org/apache/axis2/jaxws/binding/BindingImpl.java?rev=888050&r1=888049&r2=888050&view=diff
==============================================================================
--- webservices/axis2/trunk/java/modules/jaxws/src/org/apache/axis2/jaxws/binding/BindingImpl.java (original)
+++ webservices/axis2/trunk/java/modules/jaxws/src/org/apache/axis2/jaxws/binding/BindingImpl.java Mon Dec 7 17:52:29 2009
@@ -29,18 +29,24 @@
import org.apache.axis2.jaxws.registry.ClientConfiguratorRegistry;
import org.apache.axis2.jaxws.spi.Binding;
import org.apache.axis2.jaxws.spi.BindingProvider;
+import org.apache.axis2.jaxws.utility.JavaUtils;
import javax.xml.ws.WebServiceFeature;
import javax.xml.ws.handler.Handler;
import java.util.ArrayList;
import java.util.List;
import java.util.Set;
+import org.apache.commons.logging.Log;
+import org.apache.commons.logging.LogFactory;
/**
* Classes that would normally "implement javax.xml.ws.Binding"
* should extend this class instead.
*/
public abstract class BindingImpl implements Binding {
+
+ private static final Log log = LogFactory.getLog(BindingImpl.class);
+
// an unsorted list of handlers
private List<Handler> handlers;
@@ -79,7 +85,12 @@
if (handlers == null) {
// non-null so client apps can manipulate
handlers =
- new HandlerResolverImpl(endpointDesc.getServiceDescription()).getHandlerChain(endpointDesc.getPortInfo());
+ new HandlerResolverImpl(endpointDesc.getServiceDescription()).
+ getHandlerChain(endpointDesc.getPortInfo());
+ if (log.isDebugEnabled()) {
+ log.debug("handers list constructed from HandlerResolverImpl. The list is:" +
+ JavaUtils.getObjectIdentity(handlers));
+ }
}
return handlers;
}
@@ -89,7 +100,19 @@
if (list == null) {
handlers = new ArrayList<Handler>(); // non-null, but rather
// empty
+ if (log.isDebugEnabled()) {
+ log.debug("setHandlerChain called with a null list. " +
+ "A empty list is created:" + JavaUtils.getObjectIdentity(handlers));
+ }
} else {
+ // Use the handler list provided by the caller.
+ // The JAX-WS runtime nor user should ever modify this list or a ConcurrentModificationException
+ // may occur.
+ // @see org.apache.axis2.jaxws.handler.HandlerChainProcessor which makes a copy of
+ // the handler chain to avoid potential CMEs.
+ if (log.isDebugEnabled()) {
+ log.debug("setHandlerChain called with a list:" + JavaUtils.getObjectIdentity(list));
+ }
this.handlers = list;
}
}
Modified: webservices/axis2/trunk/java/modules/jaxws/src/org/apache/axis2/jaxws/handler/HandlerChainProcessor.java
URL: http://svn.apache.org/viewvc/webservices/axis2/trunk/java/modules/jaxws/src/org/apache/axis2/jaxws/handler/HandlerChainProcessor.java?rev=888050&r1=888049&r2=888050&view=diff
==============================================================================
--- webservices/axis2/trunk/java/modules/jaxws/src/org/apache/axis2/jaxws/handler/HandlerChainProcessor.java (original)
+++ webservices/axis2/trunk/java/modules/jaxws/src/org/apache/axis2/jaxws/handler/HandlerChainProcessor.java Mon Dec 7 17:52:29 2009
@@ -70,7 +70,9 @@
private MEPContext mepCtx;
+ // Copy of the handler chain used by HandlerChainProcessor
private List<Handler> handlers = null;
+ private static final List<Handler> EMPTY_CHAIN = new ArrayList<Handler>();
// for tracking purposes -- see trackInternalCall
private static Handler currentHandler = null;
@@ -103,28 +105,43 @@
private static boolean saaj_called = false;
/*
- * HandlerChainProcess expects null, empty list, or an already-sorted
- * list. If the chain passed into here came from our HandlerChainResolver,
- * it is sorted already. If a client app created or manipulated the list,
- * it may not be sorted. The processChain and processFault methods check
- * for this by calling verifyChain.
+ * The HandlerChainProcessor is constructed with the handler chain.
+ * The handler chain may be null, empty or already sorted.
+ * It also may be shared. For this reason a copy of chain is made
+ * so that the sort and other manipulation does not affect the original
+ * chain.
+ * @param chain Handler chain
+ * @param proto Protocol
*/
public HandlerChainProcessor(List<Handler> chain, Protocol proto) {
- if (chain == null) {
- handlers = new ArrayList<Handler>();
- }
- else
- handlers = chain;
+ if (chain != null) {
+ synchronized (chain) {
+ if (chain.size() == 0) {
+ // Use empty chain to avoid excessive garbage collection
+ this.handlers = EMPTY_CHAIN;
+ } else {
+ this.handlers = new ArrayList<Handler>();
+ this.handlers.addAll(chain);
+ }
+ }
+ } else {
+ handlers = EMPTY_CHAIN;
+ }
this.proto = proto;
}
- /*
- * sortChain will properly sort the chain, logical then protocol, since it may be
- * a chain built or modified by a client application. Also keep track of
- * start/end for each type of handler.
- */
+ /*
+ * sortChain sorts the local copy of the handlers chain.
+ * The logical handlers are first followed by the protocol handlers.
+ * sortChain also keeps track of the start/end of each type of handler.
+ */
private void sortChain() throws WebServiceException {
+ if (handlers.size() == 0) {
+ logicalLength = 0;
+ return;
+ }
+
ArrayList<Handler> logicalHandlers = new ArrayList<Handler>();
ArrayList<Handler> protocolHandlers = new ArrayList<Handler>();