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]>