Search code examples
javajakarta-eewildflywildfly-8

Java EE containers don't allow using Java SE conccurency API


In the book of Arun Gupta "Java EE 7 Essentials" I found this:

Java EE containers such as the EJB or web container do not allow using common Java SE concurrency APIs such as java.util.concurrent.ThreadPoolExecutor, java.lang.Thread, or java.util.Timer directly.

What does mean "do not allow"? I don't understand how container can forbid me create new thread or use standard ExecutorService. What will happen with my standard threads? Can anybody explain these?

Some remark. I understand why use ManagedExecutorService instead of ExecutorService for example can be mor efficient, I don't understand what problems can occur if I'll use SE


Solution

  • I think the answer is explained fairly clearly if you continue reading. Later in the paragraph:

    ... This is because all application code is run on a thread managed by the container, and each container typically expects all access to container-supplied objects to occur on the same thread. This allows the container to manage the resources and provide centralized administration. Further, using resources in a nonmanaged way is discouraged, because it can potentially undermine the enterprise features that the platform is designed to provide, such as availability, security, reliability, and scalability.

    I can see why you raised your initial question though, the wording on the initial statement is a bit confusing.

    To answer your question:
    Java EE containers don't have to explicitly prevent you from calling these APIs in the way you might expect (such as throwing an exception if you try to use them). Some Java EE containers might use a SecurityManager or something to prevent access to certain classes, but doing so it not required by the spec.

    However, the Java EE container will not be able to manage anything you do with these "unmanaged" JavaSE APIs, and it's considered bad practice to use them when there are managed equivalents available to you (such as ManagedExecutorService vs ExecutorService)

    To illustrate, the following code will work just fine in a Servlet:

    Runnable printSomething = new Runnable() {
        @Override
        public void run() {
            System.out.println("Hello");
        }
    };
    
    new java.lang.Thread(printSomething, "JavaSE-Thread").start();
    

    (tested using WebSphere Liberty)

    However, doing this is considered bad practice because:

    Using resources in a nonmanaged way is discouraged, because it can potentially undermine the enterprise features that the platform is designed to provide, such as availability, security, reliability, and scalability.