EJB #Schedule is synchronous or asynchronous? - java

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.

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.

How to run a bean as a background service?

I need to be able to initiate a bean at startup and have it run constantly in the background using some kind of internal event/time loop (looking for data records to process). I was wondering what the correct Java EE 7/ JBoss EAP 6.2 method of doing this would be.
Any ideas?
Use the Quartz Scheduler framework and have the job fire up as configured.
It depends what you want to achieve. There are various ways you can achieve the stated goal. Some i can think of are :-
1)Use spring which automatically instantiate singleton beans on startup and call init method while start up
2)In terms of web app , you can use loadOnstartUp servlet configuration
3)Use quarts Job to run the background jobs
EJBs should work fine in this case (standard Java EE - no external framework needed)
I am assuming you need a 'pull' mode for the data rather than having a component to 'listen' to data events
Spin up a Singleton EJB
Write your business logic which would query the data repository
#Singleton
#Startup //container initializes the bean when it starts or when the application is deployed
public class MySingletonEJB{
#Schedule //configure this annotation as per required schedule e.g. via a Cron like syntax
public void executeJob(){
//.... search data records
}
}

How do I timeout a blocking call inside an EJB?

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

How to reliably kill #Scheduled threads across servers?

I'm building a plugin that is implemented as a Spring MVC application. This plugin is deployed on 3 - 6 tomcat servers via a gui on one of the servers. Each of the instances of the plugin has an #Scheduled method to collect information on the server and store it in a central database.
My issue is that the gui interface for uninstalling the plugin leaves some of the #Scheduled threads running.
For example, I have an environment that has servers 1 - 3. I install and enable the plugin via the gui on server 1. There are now 3 instances of the application running #Scheduled threads on servers 1 - 3. If I go back to server 1 and uninstall the plugin, the thread is reliably killed on server 1 but not servers 2 or 3.
I've implemented the following but the behavior persists:
#Component
public class ContextClosedListener implements ApplicationListener<ContextClosedEvent> {
#Autowired
ThreadPoolTaskExecutor executor;
#Autowired
ThreadPoolTaskScheduler scheduler;
public void onApplicationEvent(ContextClosedEvent event) {
scheduler.shutdown();
executor.shutdown();
}
}
Additionally, I've thought of implementing this as a context listener rather than an #Scheduled method but I'd rather stick to Spring for maintenance and extensibility reasons.
How can I reliably kill threads in an environment like this?
A couple thoughts I have. ThreadPoolTaskExecutor has a method setThreadNamePrefix, which allows you to set the prefix of the thread. You could set the prefix to something unique, then find and kill those threads at runtime. You can also set the thread group using the setThreadGroup method on the same object, then just stop the threads in the threadgroup.
The better, and safer, solution would be to create a break-out method in your scheduled jobs. This is the prefered method to stopping a Thread instead of the old "shot it in the head" method of calling Thread.stop(). You could get reference to those Runnables either by setting a common prefix or by using the thread group as described above.
The next question is: how do you stop the threads easily? For that, it would depend on how your appliation is implemented. Since I deal mainly with Spring MVC apps, my first solution would be to write a Controller to handle admin tasks. If this was JBoss, or some other large app server that had JMX (Tomcat can be configured to provide JMX I believe, but I don't think its configured out of the box that way), I might write a JMX-enabled bean to allow me to stop the threads via the app servers console. Basically, give your self a method to trigger the stopping of the threads.

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.

Categories

Resources