Hot questions for Using Enterprise JavaBeans in multithreading

Question:

I can't understand how the EJB container manage thread-safety for @Stateless beans with instance variables. So I will give a simple example before explaining my concerns:

@Stateless
public class BeanTest{

@Inject
private String var;

private Connection connection;

@Resource(name = "jdbc/TestDB")
private DataSource dataSource;

public void modify() {
    var = "TestName";
}

@PostConstruct
public void initialize() {
    try {
        connection = dataSource.getConnection();
    } catch (SQLException sqle) {
        sqle.printStackTrace();
    }
}

@PreDestroy
public void cleanup() {
    try {
        connection.close();
        connection = null;
    } catch (SQLException sqle) {
        sqle.printStackTrace();
    }
}
}

Here is my questions, assuming that our container supports pooling:

1. Pooling vs Thread-safe:

User 1 used an instance of BeanTest and modified the var using the modify method, then he finished and the container put the instance of BeanTest in the managed pool. When User 2 tries to use the same bean for a request, he might get the same instance of BeanTest intially modified by User 1 (I understand that might get another instance too). So which state of the instance variable var he will find (default value which is null or "TestName")? if its the new modified one, do that mean that even @Stateless beans are not 100% thread-safe? So finnaly there is no container added -value regarding thread safety, as not using instance variable makes a bean thread safe even if it's not a @Stateless bean

2. Pooling vs @PreDestroy

If the bean is returned to the managed pool and not destroyed, do that mean that the @Predestroy method will not be called and in that case the connection will stay opened ? So, if we have 30 inctance of that bean in the pool, we may have 30 open connection that is not used, isn't that a performance issue? or this not how @Predestroy is working conbined with pooling? (using Connection is just an example, we may have other kind of ressource that we need to close in @Predestroy)

NB: This is not a real life example, so I'am not looking for an alternative solution, my concern is to understand the whole concept and how things are managed in the Application Server, what is happening under the hood


Answer:

I think the Thread-Safety you are referring to is the non-reenterant clause

The Responsibilities of the Container Provider Enterprise JavaBeans 3.2, Final Release Session Bean Component Contract April 10, 2013 2:59 pm Oracle

4.10.13 Non-reentrant Instances The container must ensure that on ly one thread can be executing a st ateless or stateful session bean instance at any time. Therefore, statef ul and stateless session beans do not have to be coded as reentrant. One implication of this rule is that an application ca nnot make loopback calls to a stateless or stateful session bean instance

You could in a stateless session bean, ignore the EJB programming restrictions, create a bunch of threads and do something non-Thread safe. the container won't stop you. This may cause all sorts of errors due to thread management conflicts.

The container only promises that it will only allow 1 thread access to the stateless ejb at a time. (there are some different rules around singletons)

you are right, that if the instances are returned to a pool that the connections in your example could build up. because of course the been instance still exists.

If you dig in to app server docs, ie Glassfish EJB pool tuning chapter, you will find that the default is to destroy the object instances rather than return them to the pool. same with the JDBC connections, which would get closed and cleaned up. Re-use is an option, in which case you could consume some extra memory if you attempt to create state in SSBs. I don't think there is much performance impact if the instance is sitting idle in a pool.

the exact pooling implementation is up to the application server vendor, so long as they obey the spec. I think you will find the default behavior is to destroy the instance after use. Which causes managed resources to get cleaned up.

But all this is kind of mute, in your example you are trying to store a state, the connection field, in the class. There is no need to create state in a stateless component, that is not what this type of component is for. Other parts of the Java EE architecture handle state. (entities, statefulbeans, JCA)

Question:

I am hitting a webservice from my code twice. The first hit gives me a product_ID using which as a path parameter I make the second get call which gives me the response.

The problem is that the second(GET) call should be hit after 2 seconds from the first(POST) call. I am using EJB in my project and the simplest solution is using Thread.sleep(2000). But EJB does not recommend the programmer to manage threads on it's own.

In my research I have found a probable solution, but due to my lack of EJB skills I am not able to understand it much. could someone guide me to solve this issue.

The URL to the probable solution is: Using the EJB3 timer service instead of Thread.sleep()


Answer:

In your method of the first call, you should create a programmatic single action timer with a 2 second delay after the first call.

Timer timer = timerService.createSingleActionTimer(2000, new TimerConfig(product_ID, true));

When a programmatic timer expires (goes off), the container calls the method annotated @Timeout in the bean’s implementation class. The @Timeout method contains the business logic that handles the timed event.

@Timeout
public void handleTimerEvent(Timer timer) {
   String productId = timer.getInfo();
   someMethodWithDoSecondCallLogic(productInfo)
}

refs:

Question:

I have list of invoices which has pdfs in it. Users can select n number of invoices and click download button. Immediately we will show the new window showing status as pending but in background all the pdf should be merged and if the merging is over, the status should be changed to Available.

How to achieve background process in web application after sending response and send again response after background process completes


Answer:

Your Web UI could send the request to the WebServer which immediately spawns an internal Thread and returns status pending. While the WebServer's thread is processing, your UI could be usable (unlocked) again.

Alternative 1: The Web UI could poll every 5 seconds or so (see HTML5 web worker) to check on the status of this processing by a request/replay and retrieve the final result when done.

Alternative 2: You could establish some form of 'push notification' from WebServer to WebUI to make it known to the UI once the processing is done. There are a couple of Push APIs out there (choose it depending on your backend/frontend language). Some simply implement a polling status check as described above for you.. Other's like WebSocket are more generic. Unfortunately there's no standard yet, but it's coming, I hope: https://www.w3.org/TR/push-api/

Question:

Application Overview :

In my application we use to receive 60000 messages every day. It is using 11 MDB and MessageListener to subscribe the messages from different OMB queues and process it. Using weblogic server and JAP. We have total 32 instance for each MDB, because we have 8 different node each node's max-beans-in-free-pool is 4.

Current Problem :

When DB down, catch it in exception and rollback the transaction context so message will put back to queue. We checking if JMSXDeliveryCount is less then 100 it will retry else it will drop the message and send the email with message reference.

Problem : Message is getting lose, 100 time retry reach with in few secs. but DB may up after 2 hours.

Proposed approach :

Check database connectivity prior to processing a message, if DB connectivity isssue – sleep the thread for 5mins after repoll to check the connection. In this case each MDB can hold 32 message (Tread) in application level remaining message will be in queue. We have 11 MDB so possible of (11*32) thread will be sleep in application level.

I felt its bad to check DB connection for all message at initial level and holding 352 message (controlling 352 thread, possible of weblogic crash) in application level till DB up.

Any better approach to handle this issue in MDB level or weblogic level ?


Answer:

I am not familiar with Web Logic but responding with my knowledge on IBM MQ.

Have you looked at setting up Redelivery Limit and Error Destination properties for the queue from where your application is receiving messages? If the JMSXDeliveryCount property of a message exceeds Redelivery Limit, then that message will be routed to Error Destination, basically a queue or a topic. You could also setting up Redelivery Delay Override property for messages.

You can write separate logic for moving messages from Error Destination to the queue from which your application receives messages. This way messages are not lost.

More details here.

Hope this helped.

Question:

Is it allowed to use libraries inside an EJB which are spawning and manage threads?

I wrote a JavaSE library with a class like this:

public class LibraryClass {
    public void longRunningMethod() {
        ExecutorService service = Executors.newFixedThreadPool(10);
        //schedule tasks
        service.shutdown();
        try {
            service.awaitTermination(Long.MAX_VALUE, TimeUnit.DAYS);
        } catch (InterruptedException e) {
            e.printStackTrace();
        }
    }
}

Example EJB:

@Stateless
class Bean {
    public void beanMethod() {
        LibraryClass libraryClass = new LibraryClass();
        libraryClass.longRunningMethod();
    }
}

Would it be ok to use something like this inside an EJB?

The specification states that "The enterprise bean must not attempt to manage threads", would this still apply if the threads are managed outside of the EJB, maybe even out of control of the developer (for example when using 3rd party libraries)?


Answer:

Hi in general the suggestion is true. It is a bad practice, since you are already running on a 'contained' environment that already does the heavy lifting of thread handling /hread pooling (allocation) for you. In case that you really want to span threads you should, make sure that the container is aware of them or provide him the constructs so that it can handle and monitor it. This is materialized with the use of the Executor Service in Java.See here and here