This week's book giveaway is in the OCAJP 8 forum. We're giving away four copies of OCA Java SE 8 Programmer I Study Guide and have Edward Finegan & Robert Liguori on-line! See this thread for details.
I have a servlet which spawns a number of threads which perform database queries. The main thread acts as a kind of watchdog and cuts-off long running queries after a certain time. Note I am using JDBC and there are no EJBs.
We are in the process of migrating from Websphere 4 to Websphere 5 and I am now getting warnings which basically say that threads in servlets are not J2EE conform and that support for threads may be withdrawn completely in the future.
Does anyone have any opinons on this? Was it a bad idea to use threads in the first place? Are there better ways to ignore long-running queries?
Well the question is always about what is your purpose for the threads. to speed the time to return the results, or to get a few records in one thread, and some in another thread, then combine the data later. Or can you even make it asynchronous?
Yes, it's not a good idea to use threads in a servlet. A servlet is akin to an interrupt service routine in that the object is to get in, do what you need, and get out again as quickly as possible. Otherwise the user will see a sgtalled browser and the browser request may even timeout. HTTP is not a client/server platform, so the rules are not the same.
Servlets should also not attempt to maintain state. For one thing, in a clustered environment, the next user hit may be to a different instance of the same servlet in a different JVM or even on a different machine.
If a process is too long-running to execute directly, you should pass the request to a background processor of some sort. My ususal choice is what I call a "null servlet", which is a servlet that has no get/post processors, but starts up the engine as a background thread from its init() method and then stands by to recieve requests. Although that might conceivably break too, depending whether a new system bans all threading or just request/response threading. Two other ways of handling this situation are to use (vendor-specific) startup classes (which is not portable) or use a system such as JMS.
An IDE is no substitute for an Intelligent Developer.
...getting warnings which basically say that threads in servlets are not J2EE conform and that support for threads may be withdrawn completely in the future.
I'm confused about what is meant by "support for threads". How can they possibly prevent you from running threads in a servlet? I believe it is common for servlets to call other objects that start mutiple threads themselves. This is good object oriented programming but I don't see how it's fundamentally different than the servlet starting multiple threads itself.
Threading inside EJB's is a compliance issue...But I dont think threading as such is...I dont see any reason why you shouldnt use multiple-threads : I'm not suggesting to spawn multiple-threads in the dopost method of the servlet. Instead it could be a helper object to which you delegate a method call. The helper instead of doing the work with one worker could do the work simultaneously with XXX workers....
LXI Technologies P Ltd
Joined: Sep 22, 2000
To be a bit more specific...
The application is a front-end to a wide range of legacy data. It allows the user to search for information from this pool and the results of n different queries are presented in the browser. Because the input criteria are quite loose it is possible that some queries will run too long. The idea behind using threads was to set all queries running in parallel and to use the parent thread to cut-off after a certain time.
The warning which I am getting from Websphere seems to be EJB specific but we don't use EJBs. Here is the text:
J2CA0075W: An active transaction should be present while processing method allocateMCWrapper. J2CA0075W: An active transaction should be present while processing method initializeForUOW
Problem Application gets the following warning messages in the SystemOut.log:
[4/11/03 11:53:41:711 PDT] 891a0 ConnectionMan W J2CA0075W: An active transaction should be present while processing method allocateMCWrapper. [4/11/03 11:53:41:815 PDT] 891a0 ConnectionMan W J2CA0075W: An active transaction should be present while processing method initializeForUOW.
Cause These messages are being produced due to an "unsupported" environment. When application has spun its own threads from an EJB, accessing a database is not supported (per the J2EE specification). If a Servlet is spinning its own threads and accessing a database, the J2EE specification is not clear on this, so WebSphere Application Server 5.0 will allow it at this time. IBM is working with Sun to clarify this in the specification, so eventually (i.e. J2EE 1.4) spun threads from a Servlet accessing a database outside of a transaction will not be supported either. Since we don't want to promote the usage of these "naked" threads accessing databases, we are producing the warning messages. Although they may be filling up the logs, we feel that these are necessary to warn the user that they are doing something not in-line with the intended usage. Customers should consider changing their application to comply with the J2EE specification.
Joined: Aug 08, 2003
Your message is complaining that your doing stuff outside a transaction. Is it possible for you to change your code so that it runs within a transaction? I don't know how to do that with Websphere.
On a side note, I understand that transactions are used to enable a rollback of multiple tasks but I don't understand why it should matter whether those task are run in separate threads or sequentially. Can anyone out there answer that?