Hello everyone, I am the originator of the thread. Here is the problem that I encountered and the solution to it.
Problem: =========== 1) The issue is NOT in the Locator: I used a cached instance of the Locator (thanks to a suggestion from this list). It made the performance much better. 2) The lock is caused by the generated Stub client: The method createCall() causes it. The moment I use more than one thread I get the lock. I agree with Pratik Parikh, the problem is not in HashMap, but in the way it is used in axis, therefore it is a bug in axis. Neil Fergusson pointed us to https://issues.apache.org/jira/browse/AXIS-2284, where this axis bug and a fix to it is mentioned. My Solution: ============== Until axis is fixed I have a work around for this lock. I created a class which extends the generated Stub client and overwrites the method createCall() to make it synchronized. I tested it and it works. Here is the class that I created: import gov.nih.nlm.ncbi.www.soap.eutils.EUtilsServiceSoapStub; import javax.xml.namespace.QName; public class eRaStub extends EUtilsServiceSoapStub{ public eRaStub(java.net.URL endpointURL, javax.xml.rpc.Service service, QName cachedPortName) throws Exception{ stub._getService()); super(endpointURL, service); setPortName(cachedPortName); } // End Constructor // Overwrite createCall to resolve the thread Lock public org.apache.axis.client.Call createCall() throws java.rmi.RemoteException { // ObjectLock is a singleton ObjectLock obj = ObjectLock.getInstance(); synchronized(obj) { return super.createCall(); } // End Synch } // End createCall() }// End eRaStub Laheeb Alsarraf -----Original Message----- From: Cyrille Le Clerc [mailto:[EMAIL PROTECTED] Sent: Friday, February 03, 2006 6:58 AM To: [email protected] Subject: Re: Generated code not Thread safe Hello Ever, I am confused. I replayed many stress tests and I never reproduced such a multi threading lock. My environment is Sun JDK-1.5.0_06, Tomcat 5.5.9 and Axis 1.3 (same versions on client and server) and I used pretty complex WSDLs (5 to 7 complex types involved each call). Can somebody send me its configuration (wsdl + jdk ... version) ? I would try to reproduce this multi threading lock. Cyrille -- Cyrille Le Clerc [EMAIL PROTECTED] [EMAIL PROTECTED] On 2/1/06, Olano, Ever <[EMAIL PROTECTED]> wrote: > Hello. I just need someone to confirm if my understanding of this > thread (pun not intended) is correct. I take it, as it stands right > now, even in 1.3, it is not actually safe to use just a single instance > of the Locator class due to its use of HashMap (unless we synchronize > the call to its getport*() method, i.e. the one that returns a stub > object). Is that right? If not, please summarize what exactly it is > that we have to look out for. > > Thanks, > Ever > > -----Original Message----- > From: Parikh,Pratik [mailto:[EMAIL PROTECTED] > Sent: Wednesday, February 01, 2006 9:31 AM > To: [email protected] > Subject: RE: Generated code not Thread safe > > > Well you can used synchronized block to make sure that access to the > map is thread safe. I would not blame HashMap for it, this would be > considered as bug. > > Thanks, > Parikh, Pratik | Software Engineer | Cerner Corporation | > (1)-816-201-1298 | [EMAIL PROTECTED] | www.cerner.com > > > -----Original Message----- > From: Alsarraf, Laheeb (NIH/OD) [C] [mailto:[EMAIL PROTECTED] > > Sent: Wednesday, February 01, 2006 9:24 AM > To: [email protected] > Subject: RE: Generated code not Thread safe > > You are right. It is the same issue as the one discussed in the link > below. It is the get/put method in HashMap.java. > > However I found that the problem is not limited to > org.apache.axis.utils.JavaUtils.isEnumClass. When I cached the Locator > the code locked in another place: > > org.apache.axis.encoding.TypeMappingImpl.internalRegister > > The reason is the same HashMap. So it looks like the usage of HashMap in > axis should be reviewed. > > Thread Dump: > > "Thread-0" prio=5 tid=0x00a58ba0 nid=0xbac runnable [2cff000..2cffd8c] > at java.util.HashMap.put(HashMap.java:382) > at > org.apache.axis.encoding.TypeMappingImpl.internalRegister(TypeMapping > Impl.java:263) > at > org.apache.axis.encoding.TypeMappingImpl.register(TypeMappingImpl.jav > a:221) > at > org.apache.axis.encoding.TypeMappingDelegate.register(TypeMappingDele > gate.java:73) > at > org.apache.axis.client.Call.registerTypeMapping(Call.java:2285) > at > org.apache.axis.client.Call.registerTypeMapping(Call.java:2322) > at > gov.nih.nlm.ncbi.www.soap.eutils.EUtilsServiceSoapStub.createCall(EUt > ilsServiceSoapStub.java:10286) > - locked <0x10585758> (a > gov.nih.nlm.ncbi.www.soap.eutils.EUtilsServiceS > oapStub) > at > gov.nih.nlm.ncbi.www.soap.eutils.EUtilsServiceSoapStub.run_eSummary(E > UtilsServiceSoapStub.java:10513) > at > gov.nih.nihms.www.soap.nihmssrv1_cgi.NIHMSClient.run(NIHMSClient.java > :79) > > Laheeb Alsarraf > Contractor, AC Technologies > E-mail: [EMAIL PROTECTED] > Office: 301.451.1783 > > -----Original Message----- > From: Ferguson, Neil, VF-NZ [mailto:[EMAIL PROTECTED] > Sent: Tuesday, January 31, 2006 5:09 PM > To: [email protected] > Subject: RE: Generated code not Thread safe > > Hi Laheeb. > > Good find. This looks like this issue: > https://issues.apache.org/jira/browse/AXIS-2284. Seems like it's been > fixed, but after the 1.3 release, and there doesn't seem to be a fix > version specified. > > Neil. > > -----Original Message----- > From: Alsarraf, Laheeb (NIH/OD) [C] [mailto:[EMAIL PROTECTED] > Sent: Wednesday, 1 February 2006 8:36 a.m. > To: [email protected] > Subject: RE: Generated code not Thread safe > > > I tested that the web service is Not causing the lock. I opened multiple > JVMs and ran the same code as simultaneously as I could press the enter > button. > > Below is the thread dump on Windows. The lock happens in > org.apache.axis.utils.JavaUtils.java method isEnumClass(): > > Attribute enumMap is not Thread safe. Maybe Axis should replace HashMap > with Hashtable: > > > private static HashMap enumMap = new HashMap(); > > public static boolean isEnumClass(Class cls) > { > Boolean b = (Boolean)enumMap.get(cls); > if(b == null) > { > b = isEnumClassSub(cls) ? Boolean.TRUE : Boolean.FALSE; > enumMap.put(cls, b); > } > return b.booleanValue(); > } > > ======================================================================= > Full thread dump Java HotSpot(TM) Client VM (1.4.2_08-b03 mixed mode): > ======================================================================= > "Thread-5" prio=5 tid=0x00a620f8 nid=0xb5c runnable [304f000..304fd8c] > at java.util.HashMap.get(HashMap.java:325) > at > org.apache.axis.utils.JavaUtils.isEnumClass(JavaUtils.java:1060) > at > org.apache.axis.encoding.ser.BeanSerializerFactory.init(BeanSerialize > rFactory.java:49) > at > org.apache.axis.encoding.ser.BeanSerializerFactory.<init>(BeanSeriali > zerFactory.java:42) > at > org.apache.axis.encoding.ser.BaseSerializerFactory.createFactory(Base > SerializerFactory.java:235) > at > org.apache.axis.client.Call.registerTypeMapping(Call.java:2315) > at > gov.nih.nlm.ncbi.www.soap.eutils.EUtilsServiceSoapStub.createCall(EUt > ilsServiceSoapStub.java:10286) > - locked <0x10589da0> (a > gov.nih.nlm.ncbi.www.soap.eutils.EUtilsServiceS > oapStub) > at > gov.nih.nlm.ncbi.www.soap.eutils.EUtilsServiceSoapStub.run_eSummary(E > UtilsServiceSoapStub.java:10513) > at > gov.nih.nihms.www.soap.nihmssrv1_cgi.NIHMSClient.run(NIHMSClient.java > :77) > > "Thread-4" prio=5 tid=0x00a61f78 nid=0x848 runnable [300f000..300fd8c] > at java.util.HashMap.get(HashMap.java:325) > at > org.apache.axis.utils.JavaUtils.isEnumClass(JavaUtils.java:1060) > at > org.apache.axis.encoding.ser.BeanSerializerFactory.init(BeanSerialize > rFactory.java:49) > at > org.apache.axis.encoding.ser.BeanSerializerFactory.<init>(BeanSeriali > zerFactory.java:42) > at > org.apache.axis.encoding.ser.BaseSerializerFactory.createFactory(Base > SerializerFactory.java:235) > at > org.apache.axis.client.Call.registerTypeMapping(Call.java:2315) > at > gov.nih.nlm.ncbi.www.soap.eutils.EUtilsServiceSoapStub.createCall(EUt > ilsServiceSoapStub.java:10286) > - locked <0x10589de8> (a > gov.nih.nlm.ncbi.www.soap.eutils.EUtilsServiceS > oapStub) > at > gov.nih.nlm.ncbi.www.soap.eutils.EUtilsServiceSoapStub.run_eSummary(E > UtilsServiceSoapStub.java:10513) > at > gov.nih.nihms.www.soap.nihmssrv1_cgi.NIHMSClient.run(NIHMSClient.java > :77) > > "Thread-3" prio=5 tid=0x00a84be8 nid=0x148 runnable [2fcf000..2fcfd8c] > at java.util.HashMap.get(HashMap.java:325) > at > org.apache.axis.utils.JavaUtils.isEnumClass(JavaUtils.java:1060) > at > org.apache.axis.encoding.ser.BeanSerializerFactory.init(BeanSerialize > rFactory.java:49) > at > org.apache.axis.encoding.ser.BeanSerializerFactory.<init>(BeanSeriali > zerFactory.java:42) > at > org.apache.axis.encoding.ser.BaseSerializerFactory.createFactory(Base > SerializerFactory.java:235) > at > org.apache.axis.client.Call.registerTypeMapping(Call.java:2315) > at > gov.nih.nlm.ncbi.www.soap.eutils.EUtilsServiceSoapStub.createCall(EUt > ilsServiceSoapStub.java:10286) > - locked <0x10589e30> (a > gov.nih.nlm.ncbi.www.soap.eutils.EUtilsServiceS > oapStub) > at > gov.nih.nlm.ncbi.www.soap.eutils.EUtilsServiceSoapStub.run_eSummary(E > UtilsServiceSoapStub.java:10513) > at > gov.nih.nihms.www.soap.nihmssrv1_cgi.NIHMSClient.run(NIHMSClient.java > :77) > > "Thread-2" prio=5 tid=0x00a84a88 nid=0x8ac runnable [2d7f000..2d7fd8c] > at java.util.HashMap.get(HashMap.java:325) > at > org.apache.axis.utils.JavaUtils.isEnumClass(JavaUtils.java:1060) > at > org.apache.axis.encoding.ser.BeanSerializerFactory.init(BeanSerialize > rFactory.java:49) > at > org.apache.axis.encoding.ser.BeanSerializerFactory.<init>(BeanSeriali > zerFactory.java:42) > at > org.apache.axis.encoding.ser.BaseSerializerFactory.createFactory(Base > SerializerFactory.java:235) > at > org.apache.axis.client.Call.registerTypeMapping(Call.java:2315) > at > gov.nih.nlm.ncbi.www.soap.eutils.EUtilsServiceSoapStub.createCall(EUt > ilsServiceSoapStub.java:10286) > - locked <0x10589e78> (a > gov.nih.nlm.ncbi.www.soap.eutils.EUtilsServiceS > oapStub) > at > gov.nih.nlm.ncbi.www.soap.eutils.EUtilsServiceSoapStub.run_eSummary(E > UtilsServiceSoapStub.java:10513) > at > gov.nih.nihms.www.soap.nihmssrv1_cgi.NIHMSClient.run(NIHMSClient.java > :77) > > "Thread-1" prio=5 tid=0x00a58d00 nid=0x914 runnable [2d3f000..2d3fd8c] > at java.util.HashMap.get(HashMap.java:325) > at > org.apache.axis.utils.JavaUtils.isEnumClass(JavaUtils.java:1060) > at > org.apache.axis.encoding.ser.BeanSerializerFactory.init(BeanSerialize > rFactory.java:49) > at > org.apache.axis.encoding.ser.BeanSerializerFactory.<init>(BeanSeriali > zerFactory.java:42) > at > org.apache.axis.encoding.ser.BaseSerializerFactory.createFactory(Base > SerializerFactory.java:235) > at > org.apache.axis.client.Call.registerTypeMapping(Call.java:2315) > at > gov.nih.nlm.ncbi.www.soap.eutils.EUtilsServiceSoapStub.createCall(EUt > ilsServiceSoapStub.java:10286) > - locked <0x10589ec0> (a > gov.nih.nlm.ncbi.www.soap.eutils.EUtilsServiceS > oapStub) > at > gov.nih.nlm.ncbi.www.soap.eutils.EUtilsServiceSoapStub.run_eSummary(E > UtilsServiceSoapStub.java:10513) > at > gov.nih.nihms.www.soap.nihmssrv1_cgi.NIHMSClient.run(NIHMSClient.java > :77) > > "Thread-0" prio=5 tid=0x00a58ba0 nid=0xbb8 runnable [2cff000..2cffd8c] > at java.util.HashMap.get(HashMap.java:325) > at > org.apache.axis.utils.JavaUtils.isEnumClass(JavaUtils.java:1060) > at > org.apache.axis.encoding.ser.BeanSerializerFactory.init(BeanSerialize > rFactory.java:49) > at > org.apache.axis.encoding.ser.BeanSerializerFactory.<init>(BeanSeriali > zerFactory.java:42) > at > org.apache.axis.encoding.ser.BaseSerializerFactory.createFactory(Base > SerializerFactory.java:235) > at > org.apache.axis.client.Call.registerTypeMapping(Call.java:2315) > at > gov.nih.nlm.ncbi.www.soap.eutils.EUtilsServiceSoapStub.createCall(EUt > ilsServiceSoapStub.java:10286) > - locked <0x10589f08> (a > gov.nih.nlm.ncbi.www.soap.eutils.EUtilsServiceS > oapStub) > at > gov.nih.nlm.ncbi.www.soap.eutils.EUtilsServiceSoapStub.run_eSummary(E > UtilsServiceSoapStub.java:10513) > at > gov.nih.nihms.www.soap.nihmssrv1_cgi.NIHMSClient.run(NIHMSClient.java > :77) > > "Signal Dispatcher" daemon prio=10 tid=0x009fefe8 nid=0x81c waiting on > condition [0..0] > > "Finalizer" daemon prio=9 tid=0x009fc640 nid=0xafc in Object.wait() > [2bbf000..2b bfd8c] > at java.lang.Object.wait(Native Method) > - waiting on <0x104fa938> (a java.lang.ref.ReferenceQueue$Lock) > at java.lang.ref.ReferenceQueue.remove(ReferenceQueue.java:111) > - locked <0x104fa938> (a java.lang.ref.ReferenceQueue$Lock) > at java.lang.ref.ReferenceQueue.remove(ReferenceQueue.java:127) > at > java.lang.ref.Finalizer$FinalizerThread.run(Finalizer.java:159) > > "Reference Handler" daemon prio=10 tid=0x009fb2c0 nid=0xe00 in > Object.wait() [2b > 7f000..2b7fd8c] > at java.lang.Object.wait(Native Method) > - waiting on <0x104fa748> (a java.lang.ref.Reference$Lock) > at java.lang.Object.wait(Object.java:429) > at > java.lang.ref.Reference$ReferenceHandler.run(Reference.java:115) > - locked <0x104fa748> (a java.lang.ref.Reference$Lock) > > "main" prio=5 tid=0x00036108 nid=0xd34 in Object.wait() [7f000..7fc38] > at java.lang.Object.wait(Native Method) > - waiting on <0x104fa750> (a > gov.nih.nihms.www.soap.nihmssrv1_cgi.NIHMSC > lient) > at java.lang.Thread.join(Thread.java:1001) > - locked <0x104fa750> (a > gov.nih.nihms.www.soap.nihmssrv1_cgi.NIHMSClien > t) > at java.lang.Thread.join(Thread.java:1054) > at > gov.nih.nihms.www.soap.nihmssrv1_cgi.ThreadsTest.main(ThreadsTest.jav > a:33) > > "VM Thread" prio=5 tid=0x00a3b6e8 nid=0x280 runnable > > "VM Periodic Task Thread" prio=10 tid=0x00a55fe8 nid=0x8dc waiting on > condition > > "Suspend Checker Thread" prio=10 tid=0x009fe6a0 nid=0xc88 runnable > > > > Laheeb Alsarraf > > -----Original Message----- > From: Ferguson, Neil, VF-NZ [mailto:[EMAIL PROTECTED] > > Sent: Monday, January 30, 2006 4:59 PM > To: [email protected] > Subject: RE: Generated code not Thread safe > > Hi. > > You've probably considered this already, but it's worth noting that it > may not necessarily be the Axis client that's hanging, but could be the > remote service. Have you checked to see whether the call is getting as > far as the remote service? (the org.apache.axis.utils.tcpmon tool may be > useful for this). Anyway, like Cyrille says, you should try and generate > a thread dump (hit CTRL-Break in the JVM in Windows). > > Neil. > > -----Original Message----- > From: Alsarraf, Laheeb (NIH/OD) [C] [mailto:[EMAIL PROTECTED] > > Sent: Tuesday, 31 January 2006 6:02 a.m. > To: [email protected] > Subject: RE: Generated code not Thread safe > > > Neil, > > I checked out the discussion thread and I do use a new Stub object but > the generated code still hangs unless I use Synchronize around my call. > Here is the run() method I use in my test class which extends Thread. > > > public void run(){ > System.out.println("Starting Thread:" + threadName); > try{ > EUtilsServiceLocator eUtilService = new > EUtilsServiceLocator(); > EUtilsServiceSoap utils = > eUtilService.geteUtilsServiceSoap(); > > ESummaryRequest params = new ESummaryRequest(); > params.setDb("pubmed"); > params.setId(pubMedId); > Date startTimeEsum_ = new Date(); > System.out.println("Thread:" + threadName + ". " > + "Calling utils.run_eSummary > ===================="); > > // When I use this line as is then the code hangs. > ESummaryResult eSummaryRes = utils.run_eSummary(params); > > > /* When I replace the above code line with this commented code then the > client returns successfully. > > ObjectLock obj = ObjectLock.getInstance(); > synchronized(obj) { > ESummaryResult eSummaryRes = utils.run_eSummary(params); > } > */ > > }catch(Exception e){ > System.out.println("Exception in Thread:" + threadName + > "\n" + e); > stop(); > } > }// End run() > > > > Thanks > Laheeb Alsarraf > > > -----Original Message----- > From: Ferguson, Neil, VF-NZ [mailto:[EMAIL PROTECTED] > > Sent: Sunday, January 29, 2006 7:17 PM > To: [email protected] > Subject: RE: Generated code not Thread safe > > Hi. > > You might find this recent discussion on this mailing helpful: > http://marc.theaimsgroup.com/?l=axis-user&m=113771126214607&w=2 > > Basically, the generated stub doesn't seem to be thread-safe, but it > doesn't seem to be very expensive to create a new stub each time you > want one. The service locator does seem to be thread-safe (and is > relatively expensive to create), so you can cache this. > > Hope this helps. > > Neil. > > > -----Original Message----- > From: Alsarraf, Laheeb (NIH/OD) [C] [mailto:[EMAIL PROTECTED] > > Sent: Saturday, 28 January 2006 8:51 a.m. > To: [email protected] > Subject: Generated code not Thread safe > > > Hello, > > > I have used axis 1.1.2 and axis 1.1.3 to generate client code for a web > service. I tested the generated code for multithreading and the program > deadlocks. I added "Synchronized" keyword in the method createCall() of > the generated code and that solved the problem. > > > Has anyone had thread safety problems with web service client code > generated using axis. > > > Here is the command I use to generate the code: > > > java -cp %AXISCP% org.apache.axis.wsdl.WSDL2Java --timeout -1 %* > > > > > Thanks > > > Laheeb Alsarraf > > > ------------------------------------------------------------------------ > ----------------------- > > Have you seen our website?.... http://www.vodafone.co.nz > > Manage Your Account, check your Vodafone Mail and send web2TXT online: > http://www.vodafone.co.nz/myvodafone > > CAUTION: This correspondence is confidential and intended for the named > recipient(s) only. > If you are not the named recipient and receive this correspondence in > error, you must not copy, distribute or take any action in reliance on > it and you should delete it from your system and notify the sender > immediately. Thank you. > > Unless otherwise stated, any views or opinions expressed are solely > those of the author and do not represent those of Vodafone New Zealand > Limited. > > Vodafone New Zealand Limited > 20 Viaduct Harbour Avenue, Private Bag 92161, Auckland 1030 Telephone + > 64 9 355 2000 Facsimile + 64 9 355 2001 > ------------------------------------------------------------------------ > ----------------------- > > Have you seen our website?.... http://www.vodafone.co.nz > > Manage Your Account, check your Vodafone Mail and send web2TXT online: > http://www.vodafone.co.nz/myvodafone > > CAUTION: This correspondence is confidential and intended for the named > recipient(s) only. > If you are not the named recipient and receive this correspondence in > error, you must not copy, distribute or take any action in reliance on > it and you should delete it from your system and notify the sender > immediately. Thank you. > > Unless otherwise stated, any views or opinions expressed are solely > those of the author and do not represent those of Vodafone New Zealand > Limited. > > Vodafone New Zealand Limited > 20 Viaduct Harbour Avenue, Private Bag 92161, Auckland 1030 Telephone + > 64 9 355 2000 Facsimile + 64 9 355 2001 >
