2

I generated a web service client using JAXWS. I notice that when using a JAXWS client, instantiating the Service and *PortType classes takes a while. As such, instantiating the Service and *PortType classes each time a request needs to be made is not a good idea.

  • Is it safe to make the Service and *PortType classes global to the whole web application? What are its pros and cons?
  • Won't there be a possibility for the request/ response to get switched to a different request/ response?
  • When you call a method in a Service, does it create a new connection? Or does it simply reuse an old connection?
  • If it's just reusing an old connection, then there could be some threading issue right?

Also given the code, port.calculate(requestParam) where port is a global variable, what will happen if many threads simultaneuosly called the calculate() method? Will each thread create a new thread for each calculate calls? Or will it wait for each calls to finish before proceeding to the next call? How will the calls be handled? I'm just afraid that I might mix some of the requests and responses.

Thanks in advanced!

Arci
  • 6,647
  • 20
  • 70
  • 98

1 Answers1

1

You are right to worry. The ports are not thread safe, however the service, which takes the longest to create, is thread safe. There is no official documentation of this but it is stated here and in this forum post an experiment is done showing multiple requests on the same port cause garbled requests. The recommended approach is to create a single service and a pool of port objects which you check out from to make requests. Another alternative is to use CXF which does make their client objects thread safe and is more explicit about how to share across threads in their documentation.

Pace
  • 41,875
  • 13
  • 113
  • 156
  • Hi Pace! Thanks for your reply! What do mean by creating a pool of port objects? Should I create, for example, 10 port objects and used which one is available? Or should I invoke `getServiceHttpSoap11Endpoint()` each time a request needs to be made? If I won't be changing the settings (e.g. address) of the port and will only be using it to call a webservice method (e.g. `calculate()`), will it still cause a problem? – Arci Feb 20 '13 at 02:32
  • Also, I've read the link you've given and I got confused. What is proxy? Or is it simply an alternative term for the Service class? Why could `port.calculate(requestParam)` cause a problem when invoke at different threads at the same time? I thought when you call it, it will create a new instance of connection to the web service method. As such it is safe since the connection is different from what other threads are using? – Arci Feb 20 '13 at 02:33
  • 1
    Yes, a pool of objects would be creating 10 port objects and then reusing them when available. This is a common approach taken with limited resources such as database connections (see c3p0) or threads (see ExecutorService). From everything I have read, even if you are just calling calculate with different parameters it can cause issues. The problem is not that the requests are all using the same connection object (those get internally pooled by Java btw) but that there is some other state that is not intended to be reused. – Pace Feb 20 '13 at 14:29
  • 1
    The proxy is an alternative term for the port. The service creates ports/proxies. Ports are considered "proxies" because they have all the same methods as the endpoint and so they are a proxy for the endpoint. – Pace Feb 20 '13 at 14:35
  • Thanks for your explanation again! :D I understand it now. Just 2 more questions though. You said earlier that services are thread-safe but the ports are not. But ports are obtained from the services. If there will only be a single service, does it mean that the service class issue a new instance of port each time `getServiceHttpSoap11Endpoint()` is called? Also, which solution will you suggest: Should I just implement pooling or use CXF instead? This considering that hundreds of thousands of users might access the site at the same time. – Arci Feb 21 '13 at 02:40
  • 1
    Yes. Each time you call the get method it will create a new port. I, personally, would recommend CXF but I have no solid evidence or facts behind that decision. However, I'm not sure if either of them are going to be extremely performance focused. Most SOAP libraries focus on server performance rather than client performance. – Pace Feb 21 '13 at 02:48
  • Thanks, Pace! Personally, I also believe that CXF would be a better choice considering the volume of the possible users. However, just like you, I don't have any experience on CXF. I will be researching about pooling and CXF. Thanks again! – Arci Feb 21 '13 at 02:57
  • 1
    No problem. Keep in mind that you may not need to implement pooling if you use CXF. – Pace Feb 21 '13 at 02:59
  • I used JMeter (with 30 users) to test JAXWS. I was able to receive all the responses properly. Can you please provide more explanation on why the JAXWS port is not thread safe? And what action will make it not thread safe so that I may try it? Just to give some background, currently, I have a global port which is being accessed by many threads at the same time. On the threads, the only action that I do with the port is to call the web service operation and get its response. I do not modify the `BindingProvider` of the port in the thread. – Arci Mar 08 '13 at 09:58
  • I understand that modifying the `BindingProvider` simultaneously is not thread safe which is the reason why I haven't done this in the first place. But based from my understanding, calling web service operations using a single port simultaneously is also not thread safe. However, I wasn't able to prove this on my testing. Could it be because the number of my users is still low? – Arci Mar 08 '13 at 10:04
  • I have no idea which pieces/operations of the port may be thread safe. Sorry. – Pace Mar 08 '13 at 21:59
  • It's okay. Thanks! :) Will be trying to run the ports with more threads. – Arci Mar 11 '13 at 01:21