I am trying to determine the "approved" or best practices approach while in a Java EE environment for doing the following: A client is on a web page and clicks a button. This starts a thread for monitoring a process, i.e. database activity, network, etc. This process will continue to run until the user clicks a button that tells the process to end. Other clients, and/or the same client then clicks a button to listen to the status being sent from that process which will continue to listen until the user clicks a button to stop listening.
I have already done the above by using a WebSocket to communicate with a servlet which gets an injected a singleton EJB that extends WebSocketApplication. But, this EJB is spawning the process thread to do the monitoring. Although it works and should continue to work since it is a singleton, it is not the "approved" way of doing it.
Some suggestions I have reviewed discuss using JMS to spawn the thread, but, unless I am misunderstanding something, this doesn't solve anything since a Message Driven Bean isn't supposed to spawn a thread either. So, what is the approved/best practices method of doing this? How does one start and stop a background process in a Java EE environment? Again, the requirements are, only one process can be spawned, it must communicate to all WebSockets that register with the servlet, it must be able to die when told to (although that doesn't mean the server closes the sockets, since it could be started back up and would still communicate to all the previously registered clients).
Thanks.
this EJB is spawning the process thread
EJBs are not permitted to start threads. Quoth the standard:
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 enter-
prise 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.
This is by design; the specification states the following
The Enterprise JavaBeans architecture will make it easy to write applications: application
developers will not have to understand low-level transaction and state management details,
multi-threading, connection pooling, or other complex low-level APIs.
Have you considered using a stateful session bean? Clicking on the button causes the bean to enter the "started" state. Click on the second button causes the bean to enter the "stopped" state.
To create threads in an enterprise environment, you should use either ManagedThreadFactory or ManagedExecutorService.
Please see here
The answer is an asynchronous EJB 3.1 bean. Thanks for the reply.
As of Java EE 7 you can use the ManagedExecutorService to give your EJBs access to a managed thread pool.
Related
I'd like to use Publish/Subscribe in our XPages application, in Java, e.g. with Jedis. The application runs in a multi-user setting, and when one user makes some changes to a document we'd like to see those changes reflected on other users' screens. In theory that could be done using PubSub: when the change is applied, a "document modified" message is published and sent to the party or parties that subscribed to this message. The subscriber part I'd like to put in a Thread, so that the object that subscribed can react immediately when the message is received.
The scope for most objects that use subscribe is viewscope, they should be destroyed when viewscope is destroyed. But what happens when the object is abandoned and the subscriber thread is still there? For instance, how can I tell the JVM that the Thread can safely be stopped and scrapped by the garbage collector?
I have yet to try this, so I have no code that I can show, but here's the questions I have:
am I right, will the Thread continue to run even when viewscope is destroyed?
is there a way to create a garbage-collectable Thread?
or maybe: is there some API that does PubSub in the multi-threaded XPages environment?
I did something like this years ago. You can find a Pub/Sub example with Guava here: http://hasselba.ch/blog/?p=2158
I am not sure what you are planning with the subscriber thread
respectively what the benefit is for your idea.
But to answer your questions:
Yes, a thread continues to run until you stop it. You should use an ExecutorService because it helps you with management a lot. If you want to have it "automatically" removed, you just have to do a "shutdown", which then processes all jobs left and stops the ThreadPool.
If you need a server-wide Pub/Sub system, think about an OSGi Plugin which starts / stops automatically with the Domino HTTP task. All objects of this plugin can be used by any application.
I'm using Managed Executor Service to implement a service that processes background tasks. The service should be allowed to stop a running task and terminate the worker thread and return it to the threads pool for next task. Once it has been stopped, can you resume where you left off?
No, it is not possible to shutdown, terminate, or resume a ManagedExecutorService in a Java EE environment.
Per the Java EE Concurrency Utilities 1.0 spec, bullet #2
3.1.6.1 Java EE Product Provider Requirements This subsection describes additional requirements for ManagedExecutorService
providers.
All tasks, when executed from the ManagedExecutorService, will run with the Java EE component identity of the component that
submitted the task.
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().
No task submitted to an executor can run if task’s component is not started.
When a ManagedExecutorService instance is being shutdown by the Java
EE Product Provider:
All attempts to submit new tasks are rejected.
All submitted tasks are cancelled if not running.
All running task threads are interrupted.
All registered ManagedTaskListeners are invoked.
This may seem like a limitation, but the reason why this restriction is in place is because the ManagedExeuctorService is managed by the Java EE Product Provider for you.
So don't worry about starting, stopping, or resuming your ManagedExeuctorService in Java EE.
Now, if you want to wait until all of your tasks are complete, that's a perfectly reasonable requirement. This can be achieved a variety of ways:
If you submit all your tasks all at once, use ExecutorService.invokeAll(java.util.Collection) and track the List> that you get back.
If you submit your tasks one at a time, use ExecutorService.submit(Callable) or ExecutorService.submit(Runnable)
Once your tasks are submitted, you will need to manage a collection of Future<T>'s in any way you choose, and use get() (blocking) or isDone() (nonblocking) to check if they are done.
So I have some Java code that takes some time to complete (about 2 minutes). Nothing I can do about that.
But I am wondering how best to approach this in the XPages UI so that the user may still have to wait but has more control/interaction while it is running (not just a spinning wheel).
So from what I can see I can do the following.
Java class called in XPage wrapped in a thread.
Java Agent called from XPage in a thread.
Java Agent called from an XPage, but waits for a document to be updated.
Eclipse plugin (For in the client) is activated. Not sure how it would talk back to XPage though (via document?).
Any other methods?
If you created the thread in the XPage, is that going to cause any problems at the server end? Will I have to avoid using Notes objects in the Java class?
I would suggest using the OSGi Tasklet service, a.k.a. DOTS. This approach allows Java tasks to be scheduled or bound to events, just like agents, but perform significantly more efficiently than agents. Perhaps most pertinent to your need is the additional ability to trigger DOTS tasks via the console, which would allow your XPages code to start the Java code merely by issuing a remote console command via the session object.
In addition, check out the technique used in the XSP Starter Kit to provide a serverScope variable. If your code is running in a DOTS task (or even an agent), it's running in a different Java application, so it can't talk directly to the standard scope variables. The serverScope approach would theoretically allow you to store objects that can be accessed from both the XPage and the triggered task. This could aid in using Mark's technique, as mentioned above by Per, to convey progress to the user while the task is running: you'd just be storing the progress information in serverScope instead of sessionScope.
A solution would be to have an agent react on saving new documents in the database instead of kicking of the agent in your application and use threads ( because threads can be very dangerous and could easily kill your http task )
Another thing you could look into is why the code that you want to execute is taking 2 minutes to complete. What is the code for? Doing things in other databases or connect to other non notes resources?
I'm trying to execute subprocesses from within my application server (Glassfish 3.1.2)
Therefore I discovered the Apache Commons Exec library. The problem is that this library creates threads which should not be done on an application server because the server is not aware of these threads.
What could be a solution to this problem?
Would it be possible to create a message component written in Java SE who consumes messages containing information about pending jobs and register it with the application server?
The application server would then not have to deal with runtime exceptions and threads but just consume messages which contain the result or an exception.
Do you have any better ideas?
You could either use:
MDB (as pointed by duffymo),
Servlets 3.0 asynchronous processing,
Asynchronous EJB invocation.
Effectively, it should give you similar functionality as plain subprocesses.
Using Java SE component which communicates with Java EE just to overcome using threads on your own sounds a bit like an overkill. Just read about mentioned solutions and try if any of them fits your needs.
Message driven beans were designed for asynchronous processing. It could be a solution to your problem. You can create a separate listener thread pool sized to handle the traffic.
i have a webapp written with spring 3 and struts 2 that is hosted on a glassfish server. In this app i have two webservices that need to do some background work without delaying the accessed method response.
So, now i use a spring bean that uses an instance of org.springframework.core.task.TaskExecutor and from there i run my new thread.
Is this the correct/best practice approach in context of using this app on glassfish? or should find another method of doing this ?
It's discouraged to create your own threads because the app server is meant to be in charge. See the answers to Why is spawning threads in Java EE container discouraged?
However in practice, especially if it's the only application on there, you might be OK, especially if you use a fixed thread pool. Be sure all the threads are gone when you undeploy the app. (I expect Spring classes will handle disposal on undeploy / shutdown correctly, if you declare them within the Spring container).