You are viewing a plain text version of this content. The canonical link for it is here.
Posted to soap-dev@ws.apache.org by Adam Moore <mo...@ipsi.fhg.de> on 2002/07/09 17:36:26 UTC

Constructor Deadlock

I have a class that implements a SOAP service.  In the constructor of
that class, I want to make a SOAP call (using the Apache "Call" class)
to a different service that is running in the same JVM, and everything
hangs. Looking with jdb, it appears that the call is awaiting the
response from the doPost(), but the called service is never actually
invoked. Neither service can be called at this point from an external
client.

Environment:

 Sun JDK 1.3.1
 Tomcat 3.3.1
 Apache SOAP 2.3.1

Re: Constructor Deadlock

Posted by Scott Nichol <sn...@scottnichol.com>.
Adam,

If you are using Application or Session scope for your services, this
behavior is by design.  Creation of an instance of a service object is
synchronized on the app or session in those cases to ensure that only one
instance is created per application or session.

Scott Nichol

----- Original Message -----
From: "Adam Moore" <mo...@ipsi.fhg.de>
To: <so...@xml.apache.org>
Cc: <so...@xml.apache.org>
Sent: Tuesday, July 09, 2002 11:36 AM
Subject: Constructor Deadlock


>
> I have a class that implements a SOAP service.  In the constructor of
> that class, I want to make a SOAP call (using the Apache "Call" class)
> to a different service that is running in the same JVM, and everything
> hangs. Looking with jdb, it appears that the call is awaiting the
> response from the doPost(), but the called service is never actually
> invoked. Neither service can be called at this point from an external
> client.
>
> Environment:
>
>  Sun JDK 1.3.1
>  Tomcat 3.3.1
>  Apache SOAP 2.3.1
>
> --
> To unsubscribe, e-mail:   <ma...@xml.apache.org>
> For additional commands, e-mail: <ma...@xml.apache.org>
>
>


--
To unsubscribe, e-mail:   <ma...@xml.apache.org>
For additional commands, e-mail: <ma...@xml.apache.org>


Re: Constructor Deadlock

Posted by Scott Nichol <sn...@scottnichol.com>.
Adam,

If you are using Application or Session scope for your services, this
behavior is by design.  Creation of an instance of a service object is
synchronized on the app or session in those cases to ensure that only one
instance is created per application or session.

Scott Nichol

----- Original Message -----
From: "Adam Moore" <mo...@ipsi.fhg.de>
To: <so...@xml.apache.org>
Cc: <so...@xml.apache.org>
Sent: Tuesday, July 09, 2002 11:36 AM
Subject: Constructor Deadlock


>
> I have a class that implements a SOAP service.  In the constructor of
> that class, I want to make a SOAP call (using the Apache "Call" class)
> to a different service that is running in the same JVM, and everything
> hangs. Looking with jdb, it appears that the call is awaiting the
> response from the doPost(), but the called service is never actually
> invoked. Neither service can be called at this point from an external
> client.
>
> Environment:
>
>  Sun JDK 1.3.1
>  Tomcat 3.3.1
>  Apache SOAP 2.3.1
>
> --
> To unsubscribe, e-mail:   <ma...@xml.apache.org>
> For additional commands, e-mail: <ma...@xml.apache.org>
>
>


RE: Constructor Deadlock

Posted by Adam Moore <mo...@ipsi.fhg.de>.
Scenario:  We have a class that implements a SOAP service. Service scope is
set to "application". In the constructor  of that class we make a call to a
different service that is running on the same machine.  Since these are
different services with different service ids everything should run fine,
since there are no recursion. However, a deadlock occurs when trying to
invoke a call on the another service. The problem does not appear when you
call another service from any service method, it only appears during object
creation.

Reason:  The block of code that gets the target object for a service has a
synchronized block with an Object scopeLock ie: synchronized(scopeLock){}.
If the service is of type “application”, the scopeLock object is set to the
ServletContext object.  Since there is only one ServletContext per servlet
per JVM, we will be blocked if we try to call non-created service with
"application" scope from the constructor of another service with same scope.
Everything goes fine if we call a service that is on another machine. SOAP
may contain several services on a machine and the service location should
not influence the behavior of other services which depend on it.

Fix:     When retrieving the target object with application scope, do not
block on the ServletContext. Instead, block on the service providing class.
This will allow calls to be made to different services but still provide the
necessary blocking on nested service calls to the same service providing
class and only one instance of the service will be created.

Code fix: This bug was fixed by changing the value of the scopeLock when the
scope is of type “application.”  Currently the scopeLock for a type
“application” is the ServletContext object, to fix the deadlock the
scopeLock should be changed to the service provider class.

The code fix involves modifying the following code snipet:

           Class:  org.apache.soap.server.http.ServerHTTPUtils.java
           Method: getTargetObject (ServiceManager serviceManager,
                                  DeploymentDescriptor dd,
                                  String targetID,
                                  HttpServlet thisServlet,
                                  HttpSession session,
                                  SOAPContext ctxt,
                                  ServletContext context)

           1. Add an additional throw clause to the method to throw
              ClassNotFoundException.

           2. (File: org.apache.soap.server.http.ServerHTTPUtils.java, Line
#247)

              Replace:

              else if (scope == DeploymentDescriptor.SCOPE_APPLICATION) {
       	       scopeLock = context;
              }

              With:

             else if (scope == DeploymentDescriptor.SCOPE_APPLICATION) {
               scopeLock = Class.forName(className);
             }

-----Original Message-----
From: Adam Moore [mailto:moore@ipsi.fhg.de]
Sent: Dienstag, 9. Juli 2002 17:36
To: soap-dev@xml.apache.org
Cc: soap-user@xml.apache.org
Subject: Constructor Deadlock



I have a class that implements a SOAP service.  In the constructor of
that class, I want to make a SOAP call (using the Apache "Call" class)
to a different service that is running in the same JVM, and everything
hangs. Looking with jdb, it appears that the call is awaiting the
response from the doPost(), but the called service is never actually
invoked. Neither service can be called at this point from an external
client.

Environment:

 Sun JDK 1.3.1
 Tomcat 3.3.1
 Apache SOAP 2.3.1

--
To unsubscribe, e-mail:   <ma...@xml.apache.org>
For additional commands, e-mail: <ma...@xml.apache.org>



RE: Constructor Deadlock

Posted by Adam Moore <mo...@ipsi.fhg.de>.
Scott,

Thankyou for pointing out the other necessary changes.  I have new code fix
where I checked a little more carefully this time :)

Here is the new code fix:

1.      Line: 240		Class: org.apache.soap.server.http.ServerHTTPUtils.java
        Add:   Class serviceProvider = Class.forName(className);

        Note: make sure the above statement comes after className
instantiation as shown below

    if (providerType == DeploymentDescriptor.PROVIDER_JAVA ||
        providerType == DeploymentDescriptor.PROVIDER_USER_DEFINED) {
      className = dd.getProviderClass ();
    } else {
      // for scripts, we need a new BSF manager basically
      className = SCRIPT_CLASS;
    }

    Class serviceProvider = Class.forName(className);


2.  	Line:	249		Class: org.apache.soap.server.http.ServerHTTPUtils.java
	Replace:
		else if (scope == DeploymentDescriptor.SCOPE_APPLICATION) {
      		scopeLock = context;
     		}
	With:
		else if (scope == DeploymentDescriptor.SCOPE_APPLICATION) {
      		scopeLock = serviceProvider;
    		}

3.	Line:	271		Class: org.apache.soap.server.http.ServerHTTPUtils.java
	Replace:
		else if (scopeLock == context) {
          		targetObject = context.getAttribute (targetID);
        	}
	With:
		else if (scopeLock == serviceProvider) {
          		targetObject = context.getAttribute (targetID);
        	}

4.	Line:	293		Class: org.apache.soap.server.http.ServerHTTPUtils.java
	Replace:
		else if (scopeLock == context) {
              context.setAttribute (targetID, targetObject);
            }
	With:
		else if (scopeLock == serviceProvider) {
              context.setAttribute (targetID, targetObject);
            }


Adam Moore
-----Original Message-----
From: Scott Nichol [mailto:snicholnews@scottnichol.com]
Sent: Donnerstag, 11. Juli 2002 17:25
To: soap-dev@xml.apache.org
Subject: Re: Constructor Deadlock


Adam,

Thanks for the contribution.  Your technique is better than what is
currently used and will be applied to the code.  The one thing that appears
to be missing is that you do not change the code

            } else if (scopeLock == context) {
              context.setAttribute (targetID, targetObject);
            }

With your other change decribed below, scopeLock will never equal context,
so the instance will never be registered and you will create a new instance
with each invocation, effectively making the service have request scope.

Scott Nichol

----- Original Message -----
From: "Adam Moore" <mo...@ipsi.fhg.de>
To: <so...@xml.apache.org>
Sent: Thursday, July 11, 2002 10:29 AM
Subject: RE: Constructor Deadlock


> Scenario:  We have a class that implements a SOAP service. Service scope
is
> set to "application". In the constructor  of that class we make a call to
a
> different service that is running on the same machine.  Since these are
> different services with different service ids everything should run fine,
> since there are no recursion. However, a deadlock occurs when trying to
> invoke a call on the another service. The problem does not appear when you
> call another service from any service method, it only appears during
object
> creation.
>
> Reason:  The block of code that gets the target object for a service has a
> synchronized block with an Object scopeLock ie: synchronized(scopeLock){}.
> If the service is of type "application", the scopeLock object is set to
the
> ServletContext object.  Since there is only one ServletContext per servlet
> per JVM, we will be blocked if we try to call non-created service with
> "application" scope from the constructor of another service with same
scope.
> Everything goes fine if we call a service that is on another machine. SOAP
> may contain several services on a machine and the service location should
> not influence the behavior of other services which depend on it.
>
> Fix:     When retrieving the target object with application scope, do not
> block on the ServletContext. Instead, block on the service providing
class.
> This will allow calls to be made to different services but still provide
the
> necessary blocking on nested service calls to the same service providing
> class and only one instance of the service will be created.
>
> Code fix: This bug was fixed by changing the value of the scopeLock when
the
> scope is of type "application."  Currently the scopeLock for a type
> "application" is the ServletContext object, to fix the deadlock the
> scopeLock should be changed to the service provider class.
>
> The code fix involves modifying the following code snipet:
>
>            Class:  org.apache.soap.server.http.ServerHTTPUtils.java
>            Method: getTargetObject (ServiceManager serviceManager,
>                                   DeploymentDescriptor dd,
>                                   String targetID,
>                                   HttpServlet thisServlet,
>                                   HttpSession session,
>                                   SOAPContext ctxt,
>                                   ServletContext context)
>
>            1. Add an additional throw clause to the method to throw
>               ClassNotFoundException.
>
>            2. (File: org.apache.soap.server.http.ServerHTTPUtils.java,
Line
> #247)
>
>               Replace:
>
>               else if (scope == DeploymentDescriptor.SCOPE_APPLICATION) {
>               scopeLock = context;
>               }
>
>               With:
>
>              else if (scope == DeploymentDescriptor.SCOPE_APPLICATION) {
>                scopeLock = Class.forName(className);
>              }
>
> -----Original Message-----
> From: Adam Moore [mailto:moore@ipsi.fhg.de]
> Sent: Dienstag, 9. Juli 2002 17:36
> To: soap-dev@xml.apache.org
> Cc: soap-user@xml.apache.org
> Subject: Constructor Deadlock
>
>
>
> I have a class that implements a SOAP service.  In the constructor of
> that class, I want to make a SOAP call (using the Apache "Call" class)
> to a different service that is running in the same JVM, and everything
> hangs. Looking with jdb, it appears that the call is awaiting the
> response from the doPost(), but the called service is never actually
> invoked. Neither service can be called at this point from an external
> client.
>
> Environment:
>
>  Sun JDK 1.3.1
>  Tomcat 3.3.1
>  Apache SOAP 2.3.1
>
> --
> To unsubscribe, e-mail:   <ma...@xml.apache.org>
> For additional commands, e-mail: <ma...@xml.apache.org>
>
>
>
> --
> To unsubscribe, e-mail:   <ma...@xml.apache.org>
> For additional commands, e-mail: <ma...@xml.apache.org>
>
>


--
To unsubscribe, e-mail:   <ma...@xml.apache.org>
For additional commands, e-mail: <ma...@xml.apache.org>



RE: Constructor Deadlock

Posted by Adam Moore <mo...@ipsi.fhg.de>.
Scott,

Thankyou for pointing out the other necessary changes.  I have new code fix
where I checked a little more carefully this time :)

Here is the new code fix:

1.      Line: 240		Class: org.apache.soap.server.http.ServerHTTPUtils.java
        Add:   Class serviceProvider = Class.forName(className);

        Note: make sure the above statement comes after className
instantiation as shown below

    if (providerType == DeploymentDescriptor.PROVIDER_JAVA ||
        providerType == DeploymentDescriptor.PROVIDER_USER_DEFINED) {
      className = dd.getProviderClass ();
    } else {
      // for scripts, we need a new BSF manager basically
      className = SCRIPT_CLASS;
    }

    Class serviceProvider = Class.forName(className);


2.  	Line:	249		Class: org.apache.soap.server.http.ServerHTTPUtils.java
	Replace:
		else if (scope == DeploymentDescriptor.SCOPE_APPLICATION) {
      		scopeLock = context;
     		}
	With:
		else if (scope == DeploymentDescriptor.SCOPE_APPLICATION) {
      		scopeLock = serviceProvider;
    		}

3.	Line:	271		Class: org.apache.soap.server.http.ServerHTTPUtils.java
	Replace:
		else if (scopeLock == context) {
          		targetObject = context.getAttribute (targetID);
        	}
	With:
		else if (scopeLock == serviceProvider) {
          		targetObject = context.getAttribute (targetID);
        	}

4.	Line:	293		Class: org.apache.soap.server.http.ServerHTTPUtils.java
	Replace:
		else if (scopeLock == context) {
              context.setAttribute (targetID, targetObject);
            }
	With:
		else if (scopeLock == serviceProvider) {
              context.setAttribute (targetID, targetObject);
            }


Adam Moore
-----Original Message-----
From: Scott Nichol [mailto:snicholnews@scottnichol.com]
Sent: Donnerstag, 11. Juli 2002 17:25
To: soap-dev@xml.apache.org
Subject: Re: Constructor Deadlock


Adam,

Thanks for the contribution.  Your technique is better than what is
currently used and will be applied to the code.  The one thing that appears
to be missing is that you do not change the code

            } else if (scopeLock == context) {
              context.setAttribute (targetID, targetObject);
            }

With your other change decribed below, scopeLock will never equal context,
so the instance will never be registered and you will create a new instance
with each invocation, effectively making the service have request scope.

Scott Nichol

----- Original Message -----
From: "Adam Moore" <mo...@ipsi.fhg.de>
To: <so...@xml.apache.org>
Sent: Thursday, July 11, 2002 10:29 AM
Subject: RE: Constructor Deadlock


> Scenario:  We have a class that implements a SOAP service. Service scope
is
> set to "application". In the constructor  of that class we make a call to
a
> different service that is running on the same machine.  Since these are
> different services with different service ids everything should run fine,
> since there are no recursion. However, a deadlock occurs when trying to
> invoke a call on the another service. The problem does not appear when you
> call another service from any service method, it only appears during
object
> creation.
>
> Reason:  The block of code that gets the target object for a service has a
> synchronized block with an Object scopeLock ie: synchronized(scopeLock){}.
> If the service is of type "application", the scopeLock object is set to
the
> ServletContext object.  Since there is only one ServletContext per servlet
> per JVM, we will be blocked if we try to call non-created service with
> "application" scope from the constructor of another service with same
scope.
> Everything goes fine if we call a service that is on another machine. SOAP
> may contain several services on a machine and the service location should
> not influence the behavior of other services which depend on it.
>
> Fix:     When retrieving the target object with application scope, do not
> block on the ServletContext. Instead, block on the service providing
class.
> This will allow calls to be made to different services but still provide
the
> necessary blocking on nested service calls to the same service providing
> class and only one instance of the service will be created.
>
> Code fix: This bug was fixed by changing the value of the scopeLock when
the
> scope is of type "application."  Currently the scopeLock for a type
> "application" is the ServletContext object, to fix the deadlock the
> scopeLock should be changed to the service provider class.
>
> The code fix involves modifying the following code snipet:
>
>            Class:  org.apache.soap.server.http.ServerHTTPUtils.java
>            Method: getTargetObject (ServiceManager serviceManager,
>                                   DeploymentDescriptor dd,
>                                   String targetID,
>                                   HttpServlet thisServlet,
>                                   HttpSession session,
>                                   SOAPContext ctxt,
>                                   ServletContext context)
>
>            1. Add an additional throw clause to the method to throw
>               ClassNotFoundException.
>
>            2. (File: org.apache.soap.server.http.ServerHTTPUtils.java,
Line
> #247)
>
>               Replace:
>
>               else if (scope == DeploymentDescriptor.SCOPE_APPLICATION) {
>               scopeLock = context;
>               }
>
>               With:
>
>              else if (scope == DeploymentDescriptor.SCOPE_APPLICATION) {
>                scopeLock = Class.forName(className);
>              }
>
> -----Original Message-----
> From: Adam Moore [mailto:moore@ipsi.fhg.de]
> Sent: Dienstag, 9. Juli 2002 17:36
> To: soap-dev@xml.apache.org
> Cc: soap-user@xml.apache.org
> Subject: Constructor Deadlock
>
>
>
> I have a class that implements a SOAP service.  In the constructor of
> that class, I want to make a SOAP call (using the Apache "Call" class)
> to a different service that is running in the same JVM, and everything
> hangs. Looking with jdb, it appears that the call is awaiting the
> response from the doPost(), but the called service is never actually
> invoked. Neither service can be called at this point from an external
> client.
>
> Environment:
>
>  Sun JDK 1.3.1
>  Tomcat 3.3.1
>  Apache SOAP 2.3.1
>
> --
> To unsubscribe, e-mail:   <ma...@xml.apache.org>
> For additional commands, e-mail: <ma...@xml.apache.org>
>
>
>
> --
> To unsubscribe, e-mail:   <ma...@xml.apache.org>
> For additional commands, e-mail: <ma...@xml.apache.org>
>
>


--
To unsubscribe, e-mail:   <ma...@xml.apache.org>
For additional commands, e-mail: <ma...@xml.apache.org>



--
To unsubscribe, e-mail:   <ma...@xml.apache.org>
For additional commands, e-mail: <ma...@xml.apache.org>


Re: Constructor Deadlock

Posted by Scott Nichol <sn...@scottnichol.com>.
Adam,

Thanks for the contribution.  Your technique is better than what is
currently used and will be applied to the code.  The one thing that appears
to be missing is that you do not change the code

            } else if (scopeLock == context) {
              context.setAttribute (targetID, targetObject);
            }

With your other change decribed below, scopeLock will never equal context,
so the instance will never be registered and you will create a new instance
with each invocation, effectively making the service have request scope.

Scott Nichol

----- Original Message -----
From: "Adam Moore" <mo...@ipsi.fhg.de>
To: <so...@xml.apache.org>
Sent: Thursday, July 11, 2002 10:29 AM
Subject: RE: Constructor Deadlock


> Scenario:  We have a class that implements a SOAP service. Service scope
is
> set to "application". In the constructor  of that class we make a call to
a
> different service that is running on the same machine.  Since these are
> different services with different service ids everything should run fine,
> since there are no recursion. However, a deadlock occurs when trying to
> invoke a call on the another service. The problem does not appear when you
> call another service from any service method, it only appears during
object
> creation.
>
> Reason:  The block of code that gets the target object for a service has a
> synchronized block with an Object scopeLock ie: synchronized(scopeLock){}.
> If the service is of type "application", the scopeLock object is set to
the
> ServletContext object.  Since there is only one ServletContext per servlet
> per JVM, we will be blocked if we try to call non-created service with
> "application" scope from the constructor of another service with same
scope.
> Everything goes fine if we call a service that is on another machine. SOAP
> may contain several services on a machine and the service location should
> not influence the behavior of other services which depend on it.
>
> Fix:     When retrieving the target object with application scope, do not
> block on the ServletContext. Instead, block on the service providing
class.
> This will allow calls to be made to different services but still provide
the
> necessary blocking on nested service calls to the same service providing
> class and only one instance of the service will be created.
>
> Code fix: This bug was fixed by changing the value of the scopeLock when
the
> scope is of type "application."  Currently the scopeLock for a type
> "application" is the ServletContext object, to fix the deadlock the
> scopeLock should be changed to the service provider class.
>
> The code fix involves modifying the following code snipet:
>
>            Class:  org.apache.soap.server.http.ServerHTTPUtils.java
>            Method: getTargetObject (ServiceManager serviceManager,
>                                   DeploymentDescriptor dd,
>                                   String targetID,
>                                   HttpServlet thisServlet,
>                                   HttpSession session,
>                                   SOAPContext ctxt,
>                                   ServletContext context)
>
>            1. Add an additional throw clause to the method to throw
>               ClassNotFoundException.
>
>            2. (File: org.apache.soap.server.http.ServerHTTPUtils.java,
Line
> #247)
>
>               Replace:
>
>               else if (scope == DeploymentDescriptor.SCOPE_APPLICATION) {
>               scopeLock = context;
>               }
>
>               With:
>
>              else if (scope == DeploymentDescriptor.SCOPE_APPLICATION) {
>                scopeLock = Class.forName(className);
>              }
>
> -----Original Message-----
> From: Adam Moore [mailto:moore@ipsi.fhg.de]
> Sent: Dienstag, 9. Juli 2002 17:36
> To: soap-dev@xml.apache.org
> Cc: soap-user@xml.apache.org
> Subject: Constructor Deadlock
>
>
>
> I have a class that implements a SOAP service.  In the constructor of
> that class, I want to make a SOAP call (using the Apache "Call" class)
> to a different service that is running in the same JVM, and everything
> hangs. Looking with jdb, it appears that the call is awaiting the
> response from the doPost(), but the called service is never actually
> invoked. Neither service can be called at this point from an external
> client.
>
> Environment:
>
>  Sun JDK 1.3.1
>  Tomcat 3.3.1
>  Apache SOAP 2.3.1
>
> --
> To unsubscribe, e-mail:   <ma...@xml.apache.org>
> For additional commands, e-mail: <ma...@xml.apache.org>
>
>
>
> --
> To unsubscribe, e-mail:   <ma...@xml.apache.org>
> For additional commands, e-mail: <ma...@xml.apache.org>
>
>


Re: Constructor Deadlock

Posted by Scott Nichol <sn...@scottnichol.com>.
Adam,

Thanks for the contribution.  Your technique is better than what is
currently used and will be applied to the code.  The one thing that appears
to be missing is that you do not change the code

            } else if (scopeLock == context) {
              context.setAttribute (targetID, targetObject);
            }

With your other change decribed below, scopeLock will never equal context,
so the instance will never be registered and you will create a new instance
with each invocation, effectively making the service have request scope.

Scott Nichol

----- Original Message -----
From: "Adam Moore" <mo...@ipsi.fhg.de>
To: <so...@xml.apache.org>
Sent: Thursday, July 11, 2002 10:29 AM
Subject: RE: Constructor Deadlock


> Scenario:  We have a class that implements a SOAP service. Service scope
is
> set to "application". In the constructor  of that class we make a call to
a
> different service that is running on the same machine.  Since these are
> different services with different service ids everything should run fine,
> since there are no recursion. However, a deadlock occurs when trying to
> invoke a call on the another service. The problem does not appear when you
> call another service from any service method, it only appears during
object
> creation.
>
> Reason:  The block of code that gets the target object for a service has a
> synchronized block with an Object scopeLock ie: synchronized(scopeLock){}.
> If the service is of type "application", the scopeLock object is set to
the
> ServletContext object.  Since there is only one ServletContext per servlet
> per JVM, we will be blocked if we try to call non-created service with
> "application" scope from the constructor of another service with same
scope.
> Everything goes fine if we call a service that is on another machine. SOAP
> may contain several services on a machine and the service location should
> not influence the behavior of other services which depend on it.
>
> Fix:     When retrieving the target object with application scope, do not
> block on the ServletContext. Instead, block on the service providing
class.
> This will allow calls to be made to different services but still provide
the
> necessary blocking on nested service calls to the same service providing
> class and only one instance of the service will be created.
>
> Code fix: This bug was fixed by changing the value of the scopeLock when
the
> scope is of type "application."  Currently the scopeLock for a type
> "application" is the ServletContext object, to fix the deadlock the
> scopeLock should be changed to the service provider class.
>
> The code fix involves modifying the following code snipet:
>
>            Class:  org.apache.soap.server.http.ServerHTTPUtils.java
>            Method: getTargetObject (ServiceManager serviceManager,
>                                   DeploymentDescriptor dd,
>                                   String targetID,
>                                   HttpServlet thisServlet,
>                                   HttpSession session,
>                                   SOAPContext ctxt,
>                                   ServletContext context)
>
>            1. Add an additional throw clause to the method to throw
>               ClassNotFoundException.
>
>            2. (File: org.apache.soap.server.http.ServerHTTPUtils.java,
Line
> #247)
>
>               Replace:
>
>               else if (scope == DeploymentDescriptor.SCOPE_APPLICATION) {
>               scopeLock = context;
>               }
>
>               With:
>
>              else if (scope == DeploymentDescriptor.SCOPE_APPLICATION) {
>                scopeLock = Class.forName(className);
>              }
>
> -----Original Message-----
> From: Adam Moore [mailto:moore@ipsi.fhg.de]
> Sent: Dienstag, 9. Juli 2002 17:36
> To: soap-dev@xml.apache.org
> Cc: soap-user@xml.apache.org
> Subject: Constructor Deadlock
>
>
>
> I have a class that implements a SOAP service.  In the constructor of
> that class, I want to make a SOAP call (using the Apache "Call" class)
> to a different service that is running in the same JVM, and everything
> hangs. Looking with jdb, it appears that the call is awaiting the
> response from the doPost(), but the called service is never actually
> invoked. Neither service can be called at this point from an external
> client.
>
> Environment:
>
>  Sun JDK 1.3.1
>  Tomcat 3.3.1
>  Apache SOAP 2.3.1
>
> --
> To unsubscribe, e-mail:   <ma...@xml.apache.org>
> For additional commands, e-mail: <ma...@xml.apache.org>
>
>
>
> --
> To unsubscribe, e-mail:   <ma...@xml.apache.org>
> For additional commands, e-mail: <ma...@xml.apache.org>
>
>


--
To unsubscribe, e-mail:   <ma...@xml.apache.org>
For additional commands, e-mail: <ma...@xml.apache.org>


RE: Constructor Deadlock

Posted by Adam Moore <mo...@ipsi.fhg.de>.
Scenario:  We have a class that implements a SOAP service. Service scope is
set to "application". In the constructor  of that class we make a call to a
different service that is running on the same machine.  Since these are
different services with different service ids everything should run fine,
since there are no recursion. However, a deadlock occurs when trying to
invoke a call on the another service. The problem does not appear when you
call another service from any service method, it only appears during object
creation.

Reason:  The block of code that gets the target object for a service has a
synchronized block with an Object scopeLock ie: synchronized(scopeLock){}.
If the service is of type “application”, the scopeLock object is set to the
ServletContext object.  Since there is only one ServletContext per servlet
per JVM, we will be blocked if we try to call non-created service with
"application" scope from the constructor of another service with same scope.
Everything goes fine if we call a service that is on another machine. SOAP
may contain several services on a machine and the service location should
not influence the behavior of other services which depend on it.

Fix:     When retrieving the target object with application scope, do not
block on the ServletContext. Instead, block on the service providing class.
This will allow calls to be made to different services but still provide the
necessary blocking on nested service calls to the same service providing
class and only one instance of the service will be created.

Code fix: This bug was fixed by changing the value of the scopeLock when the
scope is of type “application.”  Currently the scopeLock for a type
“application” is the ServletContext object, to fix the deadlock the
scopeLock should be changed to the service provider class.

The code fix involves modifying the following code snipet:

           Class:  org.apache.soap.server.http.ServerHTTPUtils.java
           Method: getTargetObject (ServiceManager serviceManager,
                                  DeploymentDescriptor dd,
                                  String targetID,
                                  HttpServlet thisServlet,
                                  HttpSession session,
                                  SOAPContext ctxt,
                                  ServletContext context)

           1. Add an additional throw clause to the method to throw
              ClassNotFoundException.

           2. (File: org.apache.soap.server.http.ServerHTTPUtils.java, Line
#247)

              Replace:

              else if (scope == DeploymentDescriptor.SCOPE_APPLICATION) {
       	       scopeLock = context;
              }

              With:

             else if (scope == DeploymentDescriptor.SCOPE_APPLICATION) {
               scopeLock = Class.forName(className);
             }

-----Original Message-----
From: Adam Moore [mailto:moore@ipsi.fhg.de]
Sent: Dienstag, 9. Juli 2002 17:36
To: soap-dev@xml.apache.org
Cc: soap-user@xml.apache.org
Subject: Constructor Deadlock



I have a class that implements a SOAP service.  In the constructor of
that class, I want to make a SOAP call (using the Apache "Call" class)
to a different service that is running in the same JVM, and everything
hangs. Looking with jdb, it appears that the call is awaiting the
response from the doPost(), but the called service is never actually
invoked. Neither service can be called at this point from an external
client.

Environment:

 Sun JDK 1.3.1
 Tomcat 3.3.1
 Apache SOAP 2.3.1

--
To unsubscribe, e-mail:   <ma...@xml.apache.org>
For additional commands, e-mail: <ma...@xml.apache.org>



RE: Constructor Deadlock

Posted by Adam Moore <mo...@ipsi.fhg.de>.
Scenario:  We have a class that implements a SOAP service. Service scope is
set to "application". In the constructor  of that class we make a call to a
different service that is running on the same machine.  Since these are
different services with different service ids everything should run fine,
since there are no recursion. However, a deadlock occurs when trying to
invoke a call on the another service. The problem does not appear when you
call another service from any service method, it only appears during object
creation.

Reason:  The block of code that gets the target object for a service has a
synchronized block with an Object scopeLock ie: synchronized(scopeLock){}.
If the service is of type “application”, the scopeLock object is set to the
ServletContext object.  Since there is only one ServletContext per servlet
per JVM, we will be blocked if we try to call non-created service with
"application" scope from the constructor of another service with same scope.
Everything goes fine if we call a service that is on another machine. SOAP
may contain several services on a machine and the service location should
not influence the behavior of other services which depend on it.

Fix:     When retrieving the target object with application scope, do not
block on the ServletContext. Instead, block on the service providing class.
This will allow calls to be made to different services but still provide the
necessary blocking on nested service calls to the same service providing
class and only one instance of the service will be created.

Code fix: This bug was fixed by changing the value of the scopeLock when the
scope is of type “application.”  Currently the scopeLock for a type
“application” is the ServletContext object, to fix the deadlock the
scopeLock should be changed to the service provider class.

The code fix involves modifying the following code snipet:

           Class:  org.apache.soap.server.http.ServerHTTPUtils.java
           Method: getTargetObject (ServiceManager serviceManager,
                                  DeploymentDescriptor dd,
                                  String targetID,
                                  HttpServlet thisServlet,
                                  HttpSession session,
                                  SOAPContext ctxt,
                                  ServletContext context)

           1. Add an additional throw clause to the method to throw
              ClassNotFoundException.

           2. (File: org.apache.soap.server.http.ServerHTTPUtils.java, Line
#247)

              Replace:

              else if (scope == DeploymentDescriptor.SCOPE_APPLICATION) {
       	       scopeLock = context;
              }

              With:

             else if (scope == DeploymentDescriptor.SCOPE_APPLICATION) {
               scopeLock = Class.forName(className);
             }

-----Original Message-----
From: Adam Moore [mailto:moore@ipsi.fhg.de]
Sent: Dienstag, 9. Juli 2002 17:36
To: soap-dev@xml.apache.org
Cc: soap-user@xml.apache.org
Subject: Constructor Deadlock



I have a class that implements a SOAP service.  In the constructor of
that class, I want to make a SOAP call (using the Apache "Call" class)
to a different service that is running in the same JVM, and everything
hangs. Looking with jdb, it appears that the call is awaiting the
response from the doPost(), but the called service is never actually
invoked. Neither service can be called at this point from an external
client.

Environment:

 Sun JDK 1.3.1
 Tomcat 3.3.1
 Apache SOAP 2.3.1

--
To unsubscribe, e-mail:   <ma...@xml.apache.org>
For additional commands, e-mail: <ma...@xml.apache.org>



--
To unsubscribe, e-mail:   <ma...@xml.apache.org>
For additional commands, e-mail: <ma...@xml.apache.org>


RE: Constructor Deadlock

Posted by Adam Moore <mo...@ipsi.fhg.de>.
Scenario:  We have a class that implements a SOAP service. Service scope is
set to "application". In the constructor  of that class we make a call to a
different service that is running on the same machine.  Since these are
different services with different service ids everything should run fine,
since there are no recursion. However, a deadlock occurs when trying to
invoke a call on the another service. The problem does not appear when you
call another service from any service method, it only appears during object
creation.

Reason:  The block of code that gets the target object for a service has a
synchronized block with an Object scopeLock ie: synchronized(scopeLock){}.
If the service is of type “application”, the scopeLock object is set to the
ServletContext object.  Since there is only one ServletContext per servlet
per JVM, we will be blocked if we try to call non-created service with
"application" scope from the constructor of another service with same scope.
Everything goes fine if we call a service that is on another machine. SOAP
may contain several services on a machine and the service location should
not influence the behavior of other services which depend on it.

Fix:     When retrieving the target object with application scope, do not
block on the ServletContext. Instead, block on the service providing class.
This will allow calls to be made to different services but still provide the
necessary blocking on nested service calls to the same service providing
class and only one instance of the service will be created.

Code fix: This bug was fixed by changing the value of the scopeLock when the
scope is of type “application.”  Currently the scopeLock for a type
“application” is the ServletContext object, to fix the deadlock the
scopeLock should be changed to the service provider class.

The code fix involves modifying the following code snipet:

           Class:  org.apache.soap.server.http.ServerHTTPUtils.java
           Method: getTargetObject (ServiceManager serviceManager,
                                  DeploymentDescriptor dd,
                                  String targetID,
                                  HttpServlet thisServlet,
                                  HttpSession session,
                                  SOAPContext ctxt,
                                  ServletContext context)

           1. Add an additional throw clause to the method to throw
              ClassNotFoundException.

           2. (File: org.apache.soap.server.http.ServerHTTPUtils.java, Line
#247)

              Replace:

              else if (scope == DeploymentDescriptor.SCOPE_APPLICATION) {
       	       scopeLock = context;
              }

              With:

             else if (scope == DeploymentDescriptor.SCOPE_APPLICATION) {
               scopeLock = Class.forName(className);
             }

-----Original Message-----
From: Adam Moore [mailto:moore@ipsi.fhg.de]
Sent: Dienstag, 9. Juli 2002 17:36
To: soap-dev@xml.apache.org
Cc: soap-user@xml.apache.org
Subject: Constructor Deadlock



I have a class that implements a SOAP service.  In the constructor of
that class, I want to make a SOAP call (using the Apache "Call" class)
to a different service that is running in the same JVM, and everything
hangs. Looking with jdb, it appears that the call is awaiting the
response from the doPost(), but the called service is never actually
invoked. Neither service can be called at this point from an external
client.

Environment:

 Sun JDK 1.3.1
 Tomcat 3.3.1
 Apache SOAP 2.3.1

--
To unsubscribe, e-mail:   <ma...@xml.apache.org>
For additional commands, e-mail: <ma...@xml.apache.org>



--
To unsubscribe, e-mail:   <ma...@xml.apache.org>
For additional commands, e-mail: <ma...@xml.apache.org>