When you use javax.xml.ws.Endpoint.publish to handle incoming restful/soap requests, will it generate a thread for each request? or will I have handle threads myself?
I've been trying to work this out for a couple of days now. The documentation hints on threads, but there is nothing specific about this.
Doc says:
An Executor may be set on the endpoint in order to gain better control
over the threads used to dispatch incoming requests. For instance,
thread pooling with certain parameters can be enabled by creating a
ThreadPoolExecutor and registering it with the endpoint.
For me that looks like it handles threads, but you will have no control over them, so adding a ThreadPoolExecutor to execute the threads, you will have a pool of threads you can work with. Is this right?
Examining section 5.2.7 of the JavaTM API for XML-Based Web Services specification (JAX-WS) seems to indicate so, although it looks like there is some room for implementation specific behavior. To really know what is going on you'd have to investigate the JAX-WS implementation you are using and the particular deployment environment. I'd imagine the behavior might be different depending upon whether the service is deployed within a Servlet container or in a standalone process. The control that you do have over the threads is limited to providing a specific ThreadPoolExecutor implementation. Section 5.2.7 states:
5.2.7 Executor
Endpoint instances can be configured with a java.util.concurrent.Executor. The executor will then be used to dispatch any incoming requests to the application. The setExecutor and getExecutor methods of Endpoint can be used to modify and retrieve the executor configured for a service.
<> Conformance (Use of Executor): If an executor object is successfully set on an Endpoint via the setExecutor method, then an implementation MUST use it to dispatch incoming requests upon publication of the Endpoint by means of the publish(String address) method. If publishing is carried out using the publish(Object serverContext)) method, an implementation MAY use the specified executor or another one specific to the server context being used.
<> Conformance (Default Executor): If an executor has not been set on an Endpoint, an implementation MUST use its own executor, a java.util.concurrent.ThreadPoolExecutor or analogous mechanism, to dispatch incoming requests.
Also, section 5.2.2 references 5.2.7 near the end of the section:
5.2.2 Publishing
...
An Endpoint will be typically invoked to serve concurrent requests, so its implementor should be written so as to support multiple threads. The synchronized keyword may be used as usual to control access to critical sections of code. For finer control over the threads used to dispatch incoming requests, an application can directly set the executor to be used, as described in section 5.2.7.
I realize this probably doesn't answer your question exactly, but hopefully it points you in a direction that you can get the answer you are looking for.
An Executor needs to be set in order to make an Endpoint multi-threaded. A simple multi-threaded Executor would be the fixed thread pool Executor.
endpoint.setExecutor(Executors.newFixedThreadPool(4));
This will allow your WebService to accept 4 connections simultaneously. But make sure your Service is thread safe.
I could not find and answer to this in the official doco, but after playing around with it and reading 'Java Web Services: Up and Running', it seems like it does not generate threads for each connections. So the service is blocked until it's done with one request, then a new request is handled.
Endpoint.publish(Url, ServiceImplObj) publishes a webservice at a given url. The no. of threads assigned for request handling truly is under control of the jvm because this is a light weight deployment which is handled by jvm itself.
For better clarification you can print the current thread name at service side and you can see that the service threads are being assigned from a thread pool which is managed by jvm.
[pool-1-thread-1]: Response[57]:
[pool-1-thread-5]: Response[58]:
[pool-1-thread-4]: Response[59]:
[pool-1-thread-3]: Response[60]:
[pool-1-thread-6]: Response[61]:
[pool-1-thread-6]: Response[62]:
I have used jdk1.6.0_35
xjc -version
xjc version "JAXB 2.1.10 in JDK 6"
JavaTM Architecture for XML Binding(JAXB) Reference Implementation, (build JAXB
2.1.10 in JDK 6)
Related
I am in the process of developing an EJB that makes 10+ calls to other components (EJBs, Web services, etc.) as part of it's business logic. In my case, performance is a huge concern. This EJB will be servicing a few million requests a day.
My question is: For each of those 10+ calls, how can I enforce a timeout?
I cannot wait more than 'n' seconds for any one of the calls to return. If a call takes longer than 'n' seconds, I will use a default response for processing.
I would normally use a Executor to solve this problem but, from what I understand, one shouldn't spawn threads from within an EJB as it may potentially interfere with the EJB's lifecycle.
how can I enforce a timeout?
The ejb3.1 specification provides the possibility to set a timeout using #AccessTimeout annotation that applies for serialized client calls that have to wait when an Session Bean instance
is busy executing a previous request.
Clearly (and explicity described in the specification) this applies to StateFul and Singleton session bean, although it could be implemented for Stateless in the case the bean pool run out of available instances.
Notice, once the client-invoked business method is in progress this timeout no applies.
Other possibility that is not part of the specification but, is supported by several servers (see JBoss example) is to define a timeout at the remote client side. If the client invocation
takes longer than the configured timeout, the client will be informed, however, the server execution will not be interrupted which it is not good enough.
Set a transaction timeout neither is a good option because there is no guarantee the thread that executes the business logic will be interrupted when the transaction timeout expires.
I would normally use a Executor to solve this problem but, from what I understand, one shouldn't spawn threads from within an EJB..
Instead you could use ManagedExecutorService class that is an Executor extension suitable to use within a EJB Container.
Aditionally, to implement asynchronous call within an EJB, take a look at #Asynchronous annotation, which provides a high level abstraction to solve the multithreding issue you are facing.
Cancel() method from Future class, allows you to interrup a thread's execution if you consider that the process has taken too long.
since you are not providing much detail of your environment:
use bean managed transactions and set the transaction timeout
EE7: provides an managed executor service
EE6: custom executor service as a JCA connector
in our project we have a need for distributed synchronization where a given thread's lock state has to be synchronized on multiple nodes in a cluster so that the threads running on other nodes can wait on this locked object. I know Java does not do this across JVMs. I don't have the leverage to introduce a new 3rd party product (like Terracotta) at this stage in our project. I was wondering if Weblogic (11g) has some inbuilt facility that allows me to achieve this...
You can use SingletonService. It is a cluster-wide singleton in WebLogic. You should bind it to a JNDI name in activate method and then make lookup and call from other beans. Remember to implement your singleton service object as a plain RMI object not EJB, so make an interface extending Remote and add RemoteExceptions to methods.
For this to work you must configure WebLogic cluster service migration and migration basis.
Here is a complete guide for implementing and configuring the service.
On most of applications servers, J2EE Ejb specification forbids creating threads "by hand", since these resources should be managed by the server.
But is there any way to get threads from Tomcat, Glassfish, Jboss etc.; thus access their ThreadPool?
You can use the commonj WorkManager. It was a proposal by IBM and BEA to provide a standard means to accomplish this task (access to container managed threads).
Although it was not included in the actual specification, there are implementations available for most containers.
Use in Weblogic
Use in WebSphere
Implementation for Tomcat, JBOSS and maybe others
Spring integration
The legal way to get threads from container is using JCA (Java Connector Architecture). The component you implement using this technology is called "resource adapter" and is packaged as rar file.
The implementation is pretty verbose but not too complicated in simple cases. So, good luck.
I've seen at least one utility class for getting ahold of Tomcat's threadpool, but it's not wise to go this route. Those threads are created to service your EJB or Servlet's requests, not for you to support the EJB or Servlet. Each one you take up is just another thread that won't be available to service requests to the container.
You could probably just throw in a static ThreadPool and use a static initializer to get around the EJB spec on this one, but you'd obviously have to make sure the thread code works well otherwise it could really bork your EJB.
We recently changed our system to keep the latest data in the memory instead of writing to the database. (it will be written to the database when the I/O is relatively free)
However, now we are stuck if in the event of Shutdown is required, there might be some data that have not written to the Database yet.
Is there anyway in Tomcat to trigger a call either a servlet method or some sort to perform action when a "shutdown" is issue to tomcat? We are using the following setup:
OS: Windows Server 2008
Tomcat: 5.5.30
Any idea how to perform the above?
Note: at the moment, we shutdown the tomcat from the windows services.
Like everyone else has pointed out, looks like Servlet.destroy() may be what you want.
public void destroy()
Called by the servlet container to indicate to a servlet that the servlet
is being taken out of service. This
method is only called once all threads
within the servlet's service method
have exited or after a timeout period
has passed. After the servlet
container calls this method, it will
not call the service method again on
this servlet.
This method gives the servlet an opportunity to clean up any resources
that are being held (for example,
memory, file handles, threads) and
make sure that any persistent state is
synchronized with the servlet's
current state in memory.
Does this meet your requirements? You can also implement a context listener:
Handling Servlet Life-Cycle Events
You can monitor and react to events in
a servlet's life cycle by defining
listener objects whose methods get
invoked when life cycle events occur.
To use these listener objects, you
must define the listener class and
specify the listener class.
There's examples there too.
ServletContextListener is what should do the trick
http://download.oracle.com/javaee/1.3/api/javax/servlet/ServletContextListener.html
sample code from PetStore Demo
http://java.sun.com/j2ee/tutorial/1_3-fcs/examples/src/web/bookstore1/listeners/ContextListener.java
I have a Web application using spring and hibernate and struts (it runs on Tomcat)
The call sequence is something like this...
Struts action calls spring service bean which in turn calls Spring DAO bean. The DAO implementation is a Hibernate implementation.
The question is
Would all my spring beans be running in the same thread ?
Can I store something in the ThreadLocal and get it in another bean?
I am quite sure this would not work in Stateless Session Bean.
The EJB container can (or will) spawn a new thread for every call to the session bean
Will the spring container do the same? i.e. run all beans in the same thread ?
When I tried a JUnit test - I got the same id via Thread.currentThread().getId() in the Test Case and the two beans- which leads me to believe there was only one thread in action
Or is the behavior unpredictable?
Or will it change when running on Tomcat server ?
Clarification
I do not wish to exchange data between two threads. I want to put data in the ThreadLocal and be able to retrieve it from all beans in the call stack. This will work only if all beans are in the same thread
Spring doesn't spawn the threads. Tomcat does. Spring is just creating and wiring up the objects for you.
Each request from the browser is processed in one request. It is Tomcat that handles the request. It is Tomcat that creates the thread to process the request.
Assuming you have just created a singleton bean in Spring called "X". Then the same instance of X is used by all requests.
The Spring beans don't live in a thread. They are just allocated on the heap.
Would all my spring beans be running
in the same thread ? Can I store
something in the ThreadLocal and get
it in another bean?
AFAIK for the components you mentioned (service bean, DAO bean - i guess they are plain spring beans), Spring does not spawn a new thread. I do not understand your use case (ie, exchanging data between two threads).
For most webapps, a new thread is spawned for each new request, and if you want to share data between two requests you normally:
- use the get/post parameters to pass the data
- use the session to share data
To answer your question, I'm pretty sure the spring container does not spawn threads for most components.
Yes, you can do this. The same thread will be used to execute your action so the ThreadLocal will work. Typically, the same thread is used for the stateless session bean as well, assuming it is running in the same app server instance. I would not depend on this though, as it is probably vendor dependent.
We use this technique to access the callers identity anywhere in the code. We use session beans and jms as well, but explicitly pass the information between containers and set the ThreadLocal at each entry point. This way it doesn't matter if the bean (session or mdb) are local or not.
In addition to all the other answers, I will just add the following:
Normally the only reason to switch threads is because of some requirement for parallellity. Since this normally does not come for free in terms of complexity, you will usually be clearly informed when this happens.
Switching threads within what appears to be a single-threaded processing of a request is actually extremely complex. This will normally only happen at one place in a container, and this is usually handled by tcp/ip socket readers that receive the request from the external clients. These reader threads usually determine which thread(pool) should process the request and forward the request to that thread. After that the request stays with that thread.
So normally the only thing that will/can happen is that additional threads get created for parallelity or asynchronous processing (like JMS).