Executor service shutdown is not supported - java

I am using the executor service provided by IBM Websphere 8.5.5
ExecutorService es = (ExecutorService ) new InitialContext().lookup("wm/default")
when I call es.shutdown()method, I get the error:
java.lang.IllegalStateException: ASYN0093E: The operation shutdown is not supported.
Why Websphere does not support the shutdown method? Should not I call that method?

WebSphere Application Server rejects the shutdown method in order to comply with the following requirement of the Concurrency Utilities for Java EE Specification, Section 3.1.6: Lifecycle , which states:
The lifecycle of ManagedExecutorService instances are centrally managed by the application server and cannot be changed by an application.
And more explicitly, Section 3.1.6.1 Java EE Product Provider Requirements , which explicitly states:
The lifecycle of a ManagedExecutorService is managed by an application server. All lifecycle operations on the ManagedExecutorService interface will throw a java.lang.IllegalStateException exception. This includes the following methods that are defined in the java.util.concurrent.ExecutorService interface: awaitTermination(), isShutdown(), isTerminated(), shutdown(), and shutdownNow().
It seems likely this requirement exists to prevent applications from interfering with each other when both use the same executor.

Related

What is the difference between ManagedExecutorService and ExecutorService in java

I have a requirement of submitting task to executor service in my wildfly java ee application.
The current code is as below,
ExecutorService jobExecutorService = Executors.newSingleThreadExecutor();
jobExecutorService.submit(new Task(request));
On each request, the same piece of code will run and submit the task for single-threaded executor.
But I am not sure whether the newly constructed thread is managed or is it a correct way of submitting tasks in my java ee application for any async flow.
If I need to start a thread which should be managed by the container, do I need to use ManagedExecutorService or is there any other implementation.
Need some knowledge on this.
To answer the question out of the title:
ManagedExecutorService is part of the Java EE specification while ExecutorService is part of the Java SE specification.
The main difference between these two interfaces is that the ManagedExecutorService is just a
manageable version of a ExecutorService.
Since you should not spawn any unmanaged Thread in an Java EE environment, you should only use the managed stuff there, while the unmanaged is perfectly fine for Java SE applications.
The proper way to get a ManagedExecutorService in a Java EE application is to inject the ManagedExecutorService with the #Resource annotation
#Resource
ManagedExecutorService managedExecutorService;
ExecutorService does n't need any web container, where as ManagedExecutorService is used in the context of application deployed to a webserver, where threadpools are created and their life cycles are maintained by the container.

EJB #Schedule is synchronous or asynchronous?

As #Balus has explained in Spawning threads in a JSF managed bean for scheduled tasks using a timer
EJB available? Use #Schedule
If you target Java EE 6 or newer (e.g. JBoss AS, GlassFish, TomEE, etc and thus not a barebones JSP/Servlet container such as Tomcat), then use a #Singleton EJB with a #Schedule method instead. This way the container will worry itself about pooling and destroying threads via ScheduledExecutorService.
So i am curious to know by using #Schedule, the background process will run asynchronously by container managed threads (magically) or it is like a java.util.timer which creates single thread and all process run within this threads??
if #Schedule creates only single thread just to manage the scheduler then would it be safe to use further ScheduledExecutorService within #Schedule? and this ScheduledExecutorService contains further runnable tasks based on multiple threads.
I have a long running process including file manipulation, data processing and email generating, but really should i rely only on this single #Schedule annotation without using any executorservices/creating further threadpool?? BTW i am using Glassfish.

Propagate Java EE context Websphere

I am working on Jersey based JAX-RS2 app running on Websphere 8.5. I am using async feature to spawn a new thread. The issue is that the new thread is not getting the Java EE context required for jndi lookups. The error that I get is:
A JNDI operation on a java:comp/env name cannot be completed because
the current thread is not associated with a Java Enterprise Edition
application component. This condition can occur when the JNDI client
using the java:comp/env name does not occur on the thread of a server
application request. Make sure that a Java EE application does not run
JNDI operations on java:comp/env names within static code blocks or in
threads created by that application. Such code does not necessarily
run on the thread of a server application request and therefore is not
supported by JNDI operations on java:comp/env names.
There is feature in Java EE 7 for ManagedExecutorService that can be configured in websphere. I am not able to use that as Websphere 8.5 supports Java EE 6 only. I am not able to do the lookups in advance as there are third party jars included that need the Java EE context to work.
I want to propagate Java EE context to the newly spawnned thread. Please suggest if that is possible.
It is possible to submit the task to a new thread having J2EE context by creating a Work Manager in WebSphere Application Server. For WAS 8 and above the WorkManager that is available in the full profile is now also an ExecutorService. The steps for this are:
On WAS admin console goto Resources -->Asynchronous Beans--> Work manager and created a new work manager with jndi name wm/myWM.
In java code do a jndi lookup for the work manager.
ExecutorService execService = (ExecutorService) initialContext.lookup("wm/myWM");
Submit the task to Executor Service.
execService.submit(new AsyncJob(inputData, asyncResponse));
On Websphere Liberty profile, this can be configured as managedExecutorService. Following additions are required in server.xml
<feature>concurrent-1.0</feature>
<managedExecutorService jndiName="wm/myWM">
<contextService>
<jeeMetadataContext/>
<classloaderContext/>
<securityContext/>
</contextService>
</managedExecutorService>
More details are in the pdf at this link: ManagedService WAS 8.5

Custom thread in JAX-WS web method

I have a problem with web service via JAX-WS. If I start thread in web method, it will be ended while connection with client ended.
Example:
#WebMethod(operationName="test")
public boolean test()
{
Thread th = new MyThread();
th.start();
// Thread is running
...
return true;
// Now thread th ends;
}
Is there any solution to keep thread th running?
The problem is that you are trying to start a Thread on a Java EE app server. Manual threading is in violation of the Java EE specs, which is why you are running into problems. on some app servers you can't even start a separate thread at all. From the spec:
The enterprise bean must not attempt to manage threads. The enterprise bean must not attempt to start, stop, suspend, or resume a thread, or to change a thread’s priority or name. The enterprise bean must not attempt to manage thread groups.These functions are reserved for the EJB container. Allowing the enterprise bean to manage threads would decrease the container’s ability to properly manage the runtime environment.
If you need to do the work on a separate thread, you need to use the facilities provided by the app server for asynchronous work. some options are queueing the data to a JMS queue for processing by an MDB or possibly using an asynchronous ejb request (think that's in Java EE 6).
If you just want to be sure before returning that the thread has finished - easiest way is th.join(). This method waits for the thread to die.

Javax.xml.ws.Endpoint how does it deal with multiple connections?

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)

Categories

Resources