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 di...@apache.org on 2005/04/22 15:59:30 UTC

cvs commit: ws-axis/java/src/org/apache/axis/client Service.java Stub.java

dims        2005/04/22 06:59:29

  Modified:    java/src/org/apache/axis/i18n resource.properties
               java/src/org/apache/axis/client Service.java Stub.java
  Log:
  Fix for AXIS-935 - Using ThreadLocal Call objects in a servlet memory leak both on client and server side
  
  After reading tom's comment...moved the _getCall to stub, which ensures that Service is threadsafe. Added a deprecated flag and an exception in Service's getCall to point people in the right direction.
  
  Revision  Changes    Path
  1.117     +1 -0      ws-axis/java/src/org/apache/axis/i18n/resource.properties
  
  Index: resource.properties
  ===================================================================
  RCS file: /home/cvs/ws-axis/java/src/org/apache/axis/i18n/resource.properties,v
  retrieving revision 1.116
  retrieving revision 1.117
  diff -u -r1.116 -r1.117
  --- resource.properties	13 Apr 2005 16:22:52 -0000	1.116
  +++ resource.properties	22 Apr 2005 13:59:29 -0000	1.117
  @@ -1072,6 +1072,7 @@
   cannotFindObjectForClass00=No object was found for class type {0}
   NullDelegate=Null delegate passed to TypeMappingDelegate constructor
   optionWrapArrays=Prefers building beans to straight arrays for wrapped XML array types (defaults to off).
  +useStubsGetCallMethod=Please use Stub's _getCall method 
   
   #                                                                    #
   # In-use keys                                                        #
  
  
  
  1.108     +14 -18    ws-axis/java/src/org/apache/axis/client/Service.java
  
  Index: Service.java
  ===================================================================
  RCS file: /home/cvs/ws-axis/java/src/org/apache/axis/client/Service.java,v
  retrieving revision 1.107
  retrieving revision 1.108
  diff -u -r1.107 -r1.108
  --- Service.java	20 Apr 2005 23:55:18 -0000	1.107
  +++ Service.java	22 Apr 2005 13:59:29 -0000	1.108
  @@ -79,10 +79,6 @@
       private HandlerRegistryImpl registry = new HandlerRegistryImpl();
       private Parser wsdlParser = null;
   
  -    /**
  -     * Thread local storage used for storing the last call object
  -     */
  -    private static Call previousCall = null;
       private static HashMap cachedWSDL = new HashMap();
       private static boolean cachingWSDL = true;
   
  @@ -160,7 +156,7 @@
        *
        * @param parser          Parser for this service
        * @param serviceName      Qualified name of the desired service
  -     * @throws ServiceException If there's an error 
  +     * @throws ServiceException If there's an error
        */
       public Service(Parser parser, QName serviceName) throws ServiceException {
           this.serviceName = serviceName;
  @@ -266,7 +262,7 @@
   
       /**
        *  Code for building up the Service from a Parser
  -     * 
  +     *
        * @param parser            Parser for this service
        * @param serviceName       Qualified name of the desired service
        * @throws ServiceException If there's an error finding or parsing the WSDL
  @@ -376,7 +372,7 @@
               // If not found, just pick the first port.
               port = (Port) ports.values().iterator().next();
           }
  -        
  +
           // First, try to find a generated stub.  If that
           // returns null, then find a dynamic stub.
           Remote stub = getGeneratedStub(new QName(port.getName()), proxyInterface);
  @@ -416,16 +412,16 @@
               Port port = wsdlService.getPort(portName.getLocalPart());
               if (port == null)
                   throw new ServiceException(Messages.getMessage("noPort00", "" + proxyInterface.getName()));
  -    
  +
               Binding binding = port.getBinding();
               SymbolTable symbolTable = wsdlParser.getSymbolTable();
               BindingEntry bEntry = symbolTable.getBindingEntry(binding.getQName());
               if(bEntry.getParameters().size() !=  proxyInterface.getMethods().length) {
                   throw new ServiceException(Messages.getMessage("incompatibleSEI00", "" + proxyInterface.getName()));
  -            }  
  +            }
               // TODO: Check the methods and the parameters as well.
           }
  -        
  +
           try {
               Call call = null;
               if (portName == null) {
  @@ -546,7 +542,6 @@
        */
       public javax.xml.rpc.Call createCall() throws ServiceException {
           Call call = new org.apache.axis.client.Call(this);
  -        previousCall = call;
           return call;
       }
   
  @@ -586,7 +581,7 @@
               javax.xml.rpc.Call call = createCall(QName.valueOf(port.getName()),
                                      QName.valueOf(operation.getName()));
               calls.add(call);
  -        }        
  +        }
           javax.xml.rpc.Call[] array = new javax.xml.rpc.Call[calls.size()];
           calls.toArray(array);
           return array;
  @@ -766,10 +761,10 @@
        * lazy engine instantiation work, and not have to duplicate every single
        * Service constructor with a EngineConfiguration argument.
        * <p>
  -     * If you need to use a non-default <code>EngineConfiguration</code>, do 
  +     * If you need to use a non-default <code>EngineConfiguration</code>, do
        * the following before calling the Service constructor:<p><code>
  -     * 
  -     *   AxisProperties.setProperty(EngineConfigurationFactory.SYSTEM_PROPERTY_NAME, 
  +     *
  +     *   AxisProperties.setProperty(EngineConfigurationFactory.SYSTEM_PROPERTY_NAME,
        *                              "classname.of.new.EngineConfigurationFactory");
        * </code><p>
        * Where the second parameter is the name of your new class that implements
  @@ -786,7 +781,7 @@
        * the getClientEngineConfig() of your own EngineConfigurationFactory will be
        * called, and your configuration will be used in the constructed Service object.<p>
        *
  -     * Another way is to use the "discovery" method of 
  +     * Another way is to use the "discovery" method of
        * <code>EngineConfigurationFactoryFinder</code>.
        *
        * @param config the EngineConfiguration we want to use.
  @@ -828,11 +823,12 @@
       }
   
       /**
  -     * Returns last Call object associated with 
  +     * Returns last Call object associated with
        * this service.
  +     * @deprecated please use Stub._getCall
        */
       public Call getCall() throws ServiceException {
  -        return previousCall;
  +        throw new ServiceException(Messages.getMessage("useStubsGetCallMethod"));
       }
   
       /**
  
  
  
  1.41      +23 -9     ws-axis/java/src/org/apache/axis/client/Stub.java
  
  Index: Stub.java
  ===================================================================
  RCS file: /home/cvs/ws-axis/java/src/org/apache/axis/client/Stub.java,v
  retrieving revision 1.40
  retrieving revision 1.41
  diff -u -r1.40 -r1.41
  --- Stub.java	8 Oct 2004 18:11:42 -0000	1.40
  +++ Stub.java	22 Apr 2005 13:59:29 -0000	1.41
  @@ -64,6 +64,9 @@
       // a synchronized block in the generated stub code.
       private boolean firstCall = true;
   
  +    // The last call object
  +    private Call _call = null;
  +
       /**
        * Is this the first time the type mappings are being registered?
        */
  @@ -325,10 +328,9 @@
       public SOAPHeaderElement getResponseHeader(String namespace, String partName) {
           try
           {
  -            Call lastCall = ((org.apache.axis.client.Service)service).getCall();
  -            if (lastCall == null)
  +            if (_call == null)
                   return null;
  -            return lastCall.getResponseMessage().getSOAPEnvelope().getHeaderByName(namespace, partName);
  +            return _call.getResponseMessage().getSOAPEnvelope().getHeaderByName(namespace, partName);
           }
           catch (Exception e)
           {
  @@ -352,10 +354,9 @@
           SOAPHeaderElement[] array = new SOAPHeaderElement[0];
           try
           {
  -            Call lastCall = ((org.apache.axis.client.Service)service).getCall();
  -            if (lastCall == null)
  +            if (_call == null)
                   return array;
  -            Vector h = lastCall.getResponseMessage().getSOAPEnvelope().getHeaders();
  +            Vector h = _call.getResponseMessage().getSOAPEnvelope().getHeaders();
               array = new SOAPHeaderElement[h.size()];
               h.copyInto(array);
               return array;
  @@ -394,6 +395,10 @@
       }
   
       protected void setRequestHeaders(org.apache.axis.client.Call call) throws AxisFault {        
  +        // HACK: store the _call object.
  +        _call = call;
  +
  +        // Set the call headers.
           SOAPHeaderElement[] headers = getHeaders();
           for(int i=0;i<headers.length;i++){
               call.addHeader(headers[i]);
  @@ -407,6 +412,7 @@
        * @throws AxisFault
        */
       protected void setAttachments(org.apache.axis.client.Call call) throws AxisFault {
  +        // Set the attachments.
           Object[] attachments = getAttachments();
           for(int i=0;i<attachments.length;i++){
               call.addAttachmentPart(attachments[i]);
  @@ -415,14 +421,22 @@
       }
   
       /**
  -     * Provide access to the service object, through which you can get the Call
  -     * that is used to process the operations.
  -     * Not part of JAX-RPC
  +     * Provide access to the service object. Not part of JAX-RPC
  +     *
        * @return the service object for this stub
        */
       public Service _getService() {
           return service;
       }
  +
  +    /**
  +     * Returns last Call object associated with
  +     * this stub.
  +     */
  +    public Call _getCall() {
  +        return _call;
  +    }
  +
       /**
        * Helper method for updating headers from the response.
        *