finalize method in MessageDrivenBean - java

Message-Driven Bean Class
the requirements of a message-driven bean class:
It must not define the finalize method.
What is the reason for above requirement ?

If you look in the EJB spec, you will see that it is a requirement for all types of EJB.
http://download.oracle.com/otndocs/jcp/ejb-3.1-pfd-oth-JSpec/
I can't find a definitive answer but looking on various Java forums over the last 13 years, you can see answers consistently saying that, because the container will decide the life-cycle of the EJB, the finalize may never be called (or called when you don't expect) and it would there be dangerous to use it.
https://community.oracle.com/thread/1582366

The reason is that the bean lifecycle is managed by a container (either EJB, CDI or different one) so you should use methods annotated with #PreDestroy to do your cleanup when the bean is going to be disposed. Remember that calling of finalize during object disposal is not guaranteed by JVM so you should never use it even in Java SE environment (Java doesn't have concept of destructors like in C++).

An MDB is not garbage collected unless it fails by number of times configured in the server. And so, this method may never be called at all since MDBs are pooled in the MDB pool and just reused as needed. Since finalize method is called by the GC, then it's rational that you should not define it in your MDB since all it's life cycle is managed by the EJB container. You won't get any exception if you overridden the method since it's already inherited from the Object class, but it's unpredictable when will the code inside it be called. Also, it will be too late to access any resources in the MDB, since the EJB container would have already done it's cleaning job of closing connections and so forth

Related

Is it allowed (aka a "good idea") to pass a CDI "Instance<>"-instance to a ManagedExecutorService Runnable?

I have a stateless session bean and the only reason i use an EJB is because i want to utilize the #Schedule annotation, so the container can frequently trigger my code.
The code itself uses an Instance<> to dynamically inject CDI beans (think of them as "workers")
#Inject #Any
private Instance<OutboundMessageProcessor> outboundMessageProcessorFactory;
those OutboundMessageProcessor beans implement the Runnable interface and will be submitted to a ManagedExecutorService for parallel execution:
// create a processor
OutboundMessageProcessor outboundMessageProcessor = outboundMessageProcessorFactory.get();
// and run it
Future<?> future = managedExecutorService.submit( outboundMessageProcessor );
Unfortunately this leads to a memory leak. My understanding is that this happens because the OutboundMessageProcessor beans have a #Dependent scope and so they live as long as the object that injected them lives, which is the EJB in this case, and the EJB is pooled by the container, so it "never" dies and the OutboundMessageProcessor instances never get removed by the garbage collector.
The solution is to call outboundMessageProcessorFactory.destroy() with the injected bean as parameter after you're done with it. But the problem is that I can't wait in the EJB for the Future to finish. That would defeat the purpose of running it in a new Thread in the first place.
So my idea was, what if i pass the outboundMessageProcessorFactory instance to the outboundMessageProcessor? After getting the outboundMessageProcessor instance with outboundMessageProcessorFactory.get() I could just call a .setFactory() method and pass it along. Then whenever the Runnable is done it could destroy itself at the end of its run() method, using the passed along factory and itself as a parameter to the destroy method.
So my question is, if this is a "good idea"? Will it work at all or will i run into problems because the outboundMessageProcessorFactory instance doesn't really "belong" into the "scope" of the other Thread?
And if this is a bad idea, how could i approach this memory leak otherwise?
EDIT: while i really liked the idea provided by Nikos in the comments, by the time i read it, i already went with another solution. Which is to cache/pool the processor instances and reuse them. Apart from avoiding the memory leak this has the added benefit of giving a slight performance gain. and in my case the number of distinct processors that needed to be cached/pooled was small, so the memory overhead was insignificant.

What is a real use-case for #Stateless over #Singleton in EJB

if I understand EJB correctly, #Singleton is actually the same as Singleton in plain Java and also singleton in spring -> one instance, every call goes through the same instance concurrently.
#Stateless declares a bean, that could (but must not) have multiple instance, with the limitation that only one call can be in an instance at the same time. Right sofar?
This remains me on the servlet programming model: in theory servlet containers are allowed to make multiple copies of the servlet, in practice I haven't seen any servlet container to do so.
So assuming I do not have REALLY LIMITED resources like doors, windows or printers in my code (and if I did I could still solve it with queues and stuff), what is the REAL example, where usage of #Stateless is advantageous over usage of #Singleton.
regards
Leon
You can have multiple instances of a stateless bean to increase throughput.
On the other hand there is only one instance of a singleton. The reason for this is normally to share state in application scope, serializes access to resources etc., and this implies locking or synchronization.
So if you are not really having a singleton, then use a stateless bean.
If you have a "stateless singleton", there is no difference. But if you read "singleton", it has a special meaning by convention (= there must be a reason for using the singleton pattern).
Stateless implies that the bean is thread safe. This is because there is no code in the bean that relies on state. This means that running any of its methods will not affect future running of said methods.
An example of a stateless class would a class that does addition and subtraction. All the necessary parameters are passed into the method. Doing an addition or subtraction does not alter the way these methods work at a later call. This implies that you do not need to worry about concurrency with the class.
A singleton is usually used for a class that is very expensive to create such as a Database connection. You do not want every class creating a new Database connection every time they need to use the database so you have it instantiated once at program start up. Being a singleton does not necessarily mean that the class is thread safe (although it absolutely should be).
So Stateless means the class is threadsafe.
Singleton refers to the fact that the class is only created once. While this heavily implies that the class is (AND IT SHOULD BE) thread safe, it does not directly imply it like stateless does.

JavaEE: Perform task at the end of a request/transaction

we have a situation where we want to perform some tasks at the end of a request or transaction. More specifically, we need to collect some data during that request and at the end we use that data to do some automatic database updates.
This process should be as transparent as possible, i.e. users of the EJBs that require this should not have to worry about that.
In addition we can't control the exact call stack since there are multiple entry points to the process.
To achieve our goal, we're currently considering the following concept:
certain low level operations (that are always called) fire a CDI event
a stateless EJB listens for those events and upon receiving one it collects the data and stores it into a scoped CDI bean (either request scope or conversation scope would be fine)
at the end of the request another event is fired which causes the data in the scoped CDI bean to be processed
So far, we managed to get steps 1 and 2 up and running.
However, the problem is step 3:
As I already said, there are multiple entry points to the process (originating from web requests, scheduled jobs or remote calls) and thus we thought of the following approach:
3a. A CDI extension scans all beans and adds an annotation to every EJB.
3b. An interceptor is registered for the added annotation and thus on every call to an EJB method the interceptor is invoked.
3c. The first invocation of that interceptor will fire an event after the invoked method has returned.
And here's the problem (again in the 3rd step :) ):
How would the interceptor know whether it was the first invocation or not?
We thought of the following, but neither worked so far:
get a request/conversation scoped bean
fails because no context is active
get the request/conversation context and activate it (which then should mark the first invocation since in subsequent ones the context should be active)
the system created another request context and thus WELD ends up with at least two active request contexts and complained about this
the conversion context stayed active or was deactivated prematurely (we couldn't yet figure out why)
start a long running conversation and end it after the invocation
failed because there was no active request context :(
Another option we didn't try yet but which seems to be discouraged:
use a ThreadLocal to either store some context data or at least to use invocation context propagatation as described here: http://blog.dblevins.com/2009/08/pattern-invocationcontext-propagation.html
However, AFAIK there's no guarantee that the request will be handled entirely by the same thread and thus wouldn't even invocation context propagation break when the container decides to switch to another thread?
So, thanks to all who endured with me and read through all that lengthy description.
Any ideas of how to solve this are welcome.
Btw, here are some of the software components/standards we're using (and which we can't switch):
JBoss 7.1.0.Final (along with WELD and thus CDI 1.0)
EJB 3.1
Hibernate 3.6.9 (can't switch to 4.0.0 yet)
UPDATE:
With the suggestions you gave so far, we came up with the following solution:
use a request scoped object to store the data in
the first time an object is stored in that object an event is fired
a listener is invoked before the end of the transaction (using #Observes(during=BEFORE_COMPLETION) - thanks, #bkail)
This works so far but there's still one problem:
We also have MBeans that are managed by CDI and automatically registered to the MBean server. Thus those MBeans can get EJB references injected.
However, when we try and call an MBean method which in turn calls an EJB and thus causes the above process to start we get a ContextNotActiveException. This indicates that within JBoss the request context is not started when executing an MBean method.
This also doesn't work when using JNDI lookups to get the service instead of DI.
Any ideas on this as well?
Update 2:
Well, seems like we got it running now.
Basically we did what I described in the previous update and solved the problem with the context not being active by creating our own scope and context (which activated the first time an EJB method is called and deactivated when the corresponding interceptor finishes).
Normally we should have been able to do the same with request scope (at least if we didn't miss anything in the spec) but since there is a bug in JBoss 7.1 there is not always an active request context when calling EJBs from MBeans or scheduled jobs (which do a JNDI lookup).
In the interceptor we could try to get an active context and on failure activate one of those present in the bean manager (most likely EjbRequestContext in that case) but despite our tests we'd rather not count on that working in every case.
A custom scope, however, should be independent from any JBoss scope and thus should not interfere here.
Thanks to all who answered/commented.
So there's a last problem though: whose answer should I accept as you all helped us get into the right direction? - I'll try to solve that myself and attribute those points to jan - he's got the fewest :)
Do the job in a method which is annotated with #PreDestroy.
#Named
#RequestScoped
public class Foo {
#PreDestroy
public void requestDestroyed() {
// Here.
}
}
It's invoked right before the bean instance is destroyed by the container.
What you're looking for is SessionSynchronization. This lets an EJB tie in to the transaction lifecycle and be notified when transactions are being completed.
Note, I am being specific about Transactions, you mention "requests and transactions" and I don't know if you specifically mean EJB Transactions or something tied to your application.
But I'm talking about EJB Transactions.
The downside is that it is only invoked when the specific EJB is invoked, not to "all" transactions in general. But that may well be appropriate anyway.
Finally, be careful in these interim call back areas -- I've had weird things happen with transactional at these lifecycle methods. In the end, ended up putting stuff in to a local, memory based queue that another thread reaped for committing to JMS or whatever. Downside is that they were tied to the transaction at hand, upside was that they actually worked.
Phew, that's a complex scenario :)
From how I understand what you've tried so far you are pretty advanced with the CDI techniques - there is nothing big you are missing.
I would say that you should be able to activate a conversation context at the entry point (you've probably seen the relevant documentaton?) and work with it for the whole processing. It might actually be worthwhile considering implementing an own scope. I did that once in a distantly related scenario where we could not tell whether we've been invoked by HTTP-request or EJB-remoting.
But to be honest, all this feels far too complex. It's a rather fragile construct of interceptors notifying each other with events which all in all seems just too easy to break.
Can it be that there is another approach which better fits your needs? E.g. you might try to hook on the transaction management itself and execute your data accumulation from there?

EJB3 how to make sure things happen before a bean get deleted

Suppose I let my customer reserve seats on a plane using Stateful Session Bean. If the client explicitly calls my Remove method, all of his reservations will be cancelled and the bean is removed afterward.
However, in case the client is idle for some time and the Bean get passivated, if the Bean times out while being passivated, it would be deleted without calling any of my functions. Hence, I'd be very grateful if someone could show me how I can make sure that the reservations would be cancelled if the bean get deleted. If I use the #PreDestroy annotation, will it solve this problem?
Best regards,
James Tran
It is quite possible for the #PreDestroy method to not be invoked. The EJB 3.1 specification, explicitly states this:
4.6.3 Missed PreDestroy Calls
The Bean Provider cannot assume that the container will always invoke
the PreDestroy lifecycle callback interceptor method(s) (or ejbRemove
method) for a session bean instance. The following scenarios result in
the PreDestroy lifecycle callback interceptor method(s) not being
called for an instance:
• A crash of the EJB container.
• A system exception thrown from the instance’s method to the container.
• A timeout of client inactivity while the instance is in the passive state. The timeout is specified by the Deployer in an EJB container implementation-specific way.
The specification also details how resources may be removed if the #PreDestroy method is not invoked in such scenarios:
For example, if a shopping cart component is implemented as a session
bean, and the session bean stores the shopping cart content in a
database, the application should provide a program that runs
periodically and removes “abandoned” shopping carts from the database.
In your case, it would depend on how you are storing the state of your reservations. If they are persisted in the database, then I would suggest employing the same approach as mandated in the specification. You could use the EJB Timer service, to perform this activity periodically, or use a scheduler like Quartz. Note, that it is imperative to distinguish between the contents of passivated session bean instances that no longer exist, and those that will be made ready once again.
A passivated bean will get destroyed on timeout and hence any method annotated with #PreDestroy will do what you are looking for.
While A is active, A's instance of the Stateful bean will not be shared with B until A's instance is destroyed. See the diagram on this article for further reading
Yes it should. The method annotated with #PreDestroy will be called prior to bean removal (even if i times-out in the passivated state)

Why pool Stateless session beans?

Stateless beans in Java do not keep their state between two calls from the client. So in a nutshell we might consider them as objects with business methods. Each method takes parameters and return results. When the method is invoked some local variables are being created in execution stack. When the method returns the locals are removed from the stack and if some temporary objects were allocated they are garbage collected anyway.
From my perspective that doesn’t differ from calling method of the same single instance by separate threads. So why cannot a container use one instance of a bean instead of pooling a number of them?
Pooling does several things.
One, by having one bean per instance, you're guaranteed to be threads safe (Servlets, for example, are not thread safe).
Two, you reduce any potential startup time that a bean might have. While Session Beans are "stateless", they only need to be stateless with regards to the client. For example, in EJB, you can inject several server resources in to a Session Bean. That state is private to the bean, but there's no reason you can't keep it from invocation to invocation. So, by pooling beans you reduce these lookups to only happening when the bean is created.
Three, you can use bean pool as a means to throttle traffic. If you only have 10 Beans in a pool, you're only going to get at most 10 requests working simultaneously, the rest will be queued up.
Pooling enhances performance.
A single instance handling all requests/threads would lead to a lot of contention and blocking.
Since you don't know which instance will be used (and several threads could use a single instance concurrently), the beans must be threadsafe.
The container can manage pool size based on actual activity.
The transactionality of the Java EE model uses the thread context to manage the transaction lifecycle.
This simplification exists so that it is not necessary to implement any specific interface to interact with the UserTransaction object directly; when the transaction is retrieved from the InitialContext (or injected into the session bean) it is bound to a thread-local variable for reuse (for example if a method in your stateless session bean calls another stateless session bean that also uses an injected transaction.)
Life cycle of the Statelesss session beans are Doesnot exist, Passive and MethodReady(Passive or Inactive) state.To optimize on perormance, instead of traversing the bean all through from create to method ready state, container manages the bean between active and passive states through the container callbacks - ejbActivate() and ejbPassivate() there by managing the bean pool.
sreenut
Methods by nature ARE THREAD SAFE (including static). Why? Simple, because every variable inside the method is created in the stack memory, i.e. every variable used inside the method is created per call (it's not shared). However, parameters aren't part of the stack.
However, a method is unsafe if it uses an unsafe variable:
a) calling a static field or variable. However, it happens in every single case.
b) calling a resource that it's shared. Such as the EntityManager.
c) passing a parameter that is not safe.

Categories

Resources