The issue of threads as they relate to EJBís can be confusing. Actually, the specification reads: The enterprise bean must not attempt to manage threadsÖ. It would be impossible to guarantee that every 3rd party library an application utilizes does no thread management. The spirit of this restriction boils down to two issues: risks of reentrancy, and the containerís overall ability to control the runtime environment. If an EJB creates a thread, and that thread executes code that results in the creation of other EJB instances, or passes through code that the container expects to have full control over, it can (and probably will) compromise the containerís ability to manage concurrency issues and other things. This is a form of reentrancy.
Secondarily, when a thread is spawned, the container has no way of terminating the thread and/or freeing the resources held by that thread when it chooses to passivate or remove an EJB. The argument could be made that the lifecycle methods could be used to manage the thread, but there is almost always a better solution to the underlying problem that the application is trying to solve. Specifically, solutions that press the envelope on threading in this way can often be better solved using some sort of JCA approach to manage the resource they would otherwise attempt to manage using the thread.
When it comes to Log4J and other libraries that utilize threads to perform internal housekeeping, my experience has been that they pose no problems. These threads donít touch any other runtime artifacts that could introduce reentrancy, and they donít compromise the containerís ability to manage the runtime environment.