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:[EMAIL PROTECTED]]
Sent: Dienstag, 9. Juli 2002 17:36
To: [EMAIL PROTECTED]
Cc: [EMAIL PROTECTED]
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:   <mailto:[EMAIL PROTECTED]>
For additional commands, e-mail: <mailto:[EMAIL PROTECTED]>



--
To unsubscribe, e-mail:   <mailto:[EMAIL PROTECTED]>
For additional commands, e-mail: <mailto:[EMAIL PROTECTED]>

Reply via email to