Creating your own threads, a practice J2EE forbids
One mistake developers make in Java enterprise and web applications is creating their own threads for asynchronous work. Typical cases include starting long-running tasks from a browser, such as generating reports or sending large amounts of data, and scheduling work such as clearing temporary resources like caches. Application servers prohibit using threads this way, for good reasons.
- The application server is responsible for managing resources and has to guarantee their proper management. Creating or allocating resources on the side, outside its control, is a poor idea. For one thing, you lose the ability to share those resources across applications.
- The EJB specification explicitly prohibits creating threads. Some servers, such as IBM WebSphere, even throw an exception when a thread the server doesn’t manage tries to use application server resources.
- Threads are a poor fit for a cluster, for instance for failover. They’re hard to restart and won’t survive a server crash. You can solve that too by implementing your own API, though it isn’t trivial.
Every application server, including JBoss, WebLogic and WebSphere, provides official mechanisms for asynchronous processing. Some are covered by a specification and some are proprietary. The situation is worse with servlet containers such as Tomcat or Jetty.
JMS
The main way to handle asynchronous processing is JMS (Java Message Service). Every J2EE server has to provide it. JMS participates in transactions for sending and processing messages. It supports acknowledgments, persistence across a server crash, durable subscriptions, and one-to-one and one-to-many messaging. If you have JMS available, there’s little to decide.
Work Manager API
The Work Manager API gives an application a way to borrow application server threads indirectly. JSR-237 covers it, but it is not part of the J2EE specification. Both WebLogic and WebSphere support it. If you need to run something asynchronously and can’t use JMS for some reason, this should be your preferred option.
- The Work Manager API: Parallel Processing Within a J2EE Container
- The wise work manager for context-based scoping
- Timer and Work Manager for Application Servers
The Spring TaskExecutor abstraction
The Spring TaskExecutor abstraction is a layer provided by the Spring framework for asynchronous execution, with the option of configuring your own thread pool. I’d recommend this API for portability. You can easily configure it to allocate threads through the Work Manager API on WebLogic or WebSphere, or separately on Tomcat or JBoss when managed threads aren’t available.
The benefit is that in an environment where the application server manages threads, you can obtain them through the supported mechanism. Where support is missing, threads are allocated separately, but if a later version adds support you can switch to it by changing the configuration. This approach may also be preferable in deployments without JMS or where setting it up would be difficult.
A few parting tips if you’re tempted to create a thread.
- Create only as many threads as you actually need. Sometimes one really is enough.
- If you do create such a thread, try to keep it away from resources managed by the application server.
Related articles
Related CZ Podcast episodes
- #261 · Leadership
On leading people and teams. · Czech audio
- #3 · Java 6 SE, Vývoj webových aplikací
Dagi and Filemon discuss Java 6 and web application frameworks. · Czech audio
- #1 · Vývojová prostředí v Javě
The first CZ Podcast episode looks at Java development environments. · Czech audio