Ejb and JMS

dannysh
dannysh used Ask the Experts™
on
Hi all
I want to create connection to JMS server from EJB.
I wrote the following code:

public class PublisherSLBean implements SessionBean {
    TopicConnection topicConnection = null;
    private Topic topic = null;
   
    public void ejbCreate(String destination)
    {
          .....
          topicConnection = ....
          topic = ........
    }

    public void publish(Serializable message) throws RemoteException {
         TopicSession topicSession = topicConnection.createTopicSession(....);
         TopicPublisher topicPublisher = topicSession.createPublisher(topic);
         topicPublisher.publish(.....);
         
    }
}

I have some topics in the apllication and I want to have stateless session bean (not stateful), is it possibe?
In the ejb-jar.xml I tried  to define this bean a stateless bean, but I got the following error in the Jboss application server:
>>The home interface of a stateless session bean must have one create method that takes no arguments.

If I want the possibility to have some beans connected to a different topics, should it be stateful? If it should be stateful what cause it be stateful? What should I do?

   Thanks Danny
Comment
Watch Question

Do more with

Expert Office
EXPERT OFFICE® is a registered trademark of EXPERTS EXCHANGE®

Commented:
Hi Danny,

> In the ejb-jar.xml I tried  to define this bean a
> stateless bean, but I got the following error in the
> Jboss application server:
>>The home interface of a stateless session bean must have one create method that takes no arguments.

Of course you can have stateless beans. But since they are stateless, their create method cannot take any arguments. Your ejbCreate() takes a string argument which I presume is used to initialise your beans member variables. This is fine for stateful beans.
If you want to use stateless beans instead, passing a String in the create method and using it to initialise the bean would mean that bean has a state. But it's stateless, hence it cannot have state and I guess this is why JBoss is complaining.
Change your create method to have no arguments. If you say that's impossible, it needs to have arguments, then the answer to your next questions is yes, you need stateful beans.

> If I want the possibility to have some beans connected to a different topics, should it be stateful? If it should be stateful what cause it be stateful? What should I do?

What you should do depends on how you want to use your beans. When the client invokes a method of your bean, will that method alter the state of the bean? If yes, will the state of the bean be important to subsequent method calls the client makes to that bean?
If yes, then stateful beans are the way to go.

If this is still confusing you, let me know and I will give you a concrete example explaining the difference between stateful and stateless beans.
Alternatively, you could also check out this link:
http://octopus.cdut.edu.cn/~yf17/javaent/jenut/ch07_05.htm
It explains the difference between stateful and stateless beans.

Hope that helps!

Author

Commented:
Hi Konst
from the link:
>>A stateless session bean does not maintain state across method calls. If a client makes a series of remote method calls and/or transactions with the stateless bean, the bean is in the same state at the start of each method call or transaction

In my class TopicConnection and Topic are member class which I initialize in the create method only. Those members will not be changed between method calls, is it metter?
   Danny

Commented:
Hi Danny,

Will you be able to initialise TopicConnection and Topic without the String argument in ejbCreate()?
If not, the bean will HAVE to be stateful since you are introducing state via the string argument.
The only way you can make this bean stateless is by giving it an ejbCreate method without any arguments.

Now I don't know what the String argument is used for.
If it's a string that will never change at runtime you can make the bean stateless by removing the String argument in ejbCreate(), putting its value in a properties file and then have your server side app read the property file on startup of your app server. Now you can initialise Topic and TopicConnection by looking up the value instead of passing it as a parameter.

If the string MIGHT change at runtime you have to make it stateful. Imagine this:

bean1 = home.create("Destination1");
bean2 = home.create("Destination2");

Now suppse it was possible to declare this bean stateless, even though its create method takes an argument. We invoke:

bean1.publish(...);
bean2.publish(...);

You would think that on the server side, calls to bean1 will always get the bean which has been initialised with "Destination1". Same for bean2.
Wrong!
If you have stateless beans, you can never be sure which bean instance on the server side will be used. The app server assumes that since the bean is stateless, it doesn't matter which instance it uses.
Even if you had two consecutive method calls to the same client side instance like this

bean1.publish(...);
bean1.publish(...);

you cannot assume that they were executed on one and the same server side instance. For all you know, the app server might have created two instances of your bean and used instance one for the first call and instance two for the other.

Let me know if I am confusing you.
Angular Fundamentals

Learn the fundamentals of Angular 2, a JavaScript framework for developing dynamic single page applications.

Author

Commented:
Hi Konst
First I appreciate your help.
I have only one more question about it:

I need to connect to destination1 and to destination2 (destination1 means queue1), for this porpuse I need two beans, one that connect to destination1 and the other to destination2, lets say I will do it as you recomands me using configuration file, where should I keep the TopicConnection and Topic variables if it stateless session bean?

If one client wants to use the bean connected to destination1 and other client want to use bean connected to destination2, what should they do? should they call the same EJB?

   Thanks Danny

Author

Commented:
I forgot
Each destination have it's one TopicConnection and Topic variables.
Dose staeful mean that client A call the create() method and then he should keep the handle to this bean as member and no one else can get this instance of bean?
   Danny
Commented:
Hi Danny,

> I need to connect to destination1 and to destination2 (destination1 means queue1), for this porpuse I need two beans, one that connect to destination1 and the other to destination2,

Then you will HAVE to use stateful beans and invoke the create method with the appropriate destination. No way around it, sorry.

But how many destinations are there? If there can only be two, you could achieve statelessness by having two stateless beans. One that always connects to destination1 and one that always connects to destination2.

> lets say I will do it as you recomands me using configuration file, where should I keep the TopicConnection and Topic variables if it stateless session bean?

My suggestion with the config file only applies when
 - there is only one destination during runtime
 - that destination never changes during runtime

Having read your post, these conditions do not apply in your case, so using a config file wont help with your immediate problem.

> If one client wants to use the bean connected to destination1 and other client want to use bean connected to destination2, what should they do? should they call the same EJB?

Here are your options:

If
 - there may be many destinations which may change at runtime
then
 - use a stateful bean, like you did. No way around it.

If
 - there is a small number of destinations which do not change during runtime
 - performance is an issue
then
 - use stateless beans. For every possible destination, have a seperate bean.

Author

Commented:
Hi Konst
Thanks for your help.
Your suggestions were very helpful.
   Danny

Commented:
I just thought of another solution...
Suppose you have many destinations which may change during runtime, you could still use a stateless bean.

- Remove the initialisation of Topic and TopicConnection in the create method, making it a no argument method.
- Add an argument "destination" to your publish method
- Add a cache for Topics and TopicConnections to your bean
- Each time publish is called, check whether a topic and connection to the given destination exists in the cache. If so, get it from the cache and publish the message. If not, create appropriate instances of Topic and TopicConnection and put them in the cache

Commented:
Just saw you already accpeted my answer! Thanks. :)

> Thanks for your help.

No problem.

Author

Commented:
Hi
Konst I think I will try this solution, it seems good one.
  Thanks Danny Shaul

Commented:
Made a mistake:

> - Add a cache for Topics and TopicConnections to your bean

Silly me. Of course you don't want the cache inside the stateless bean. A chache would introduce state.
You would need the cache to be a singleton on the server side.

Commented:
Made a mistake:

> - Add a cache for Topics and TopicConnections to your bean

Silly me. Of course you don't want the cache inside the stateless bean. A chache would introduce state.
You would need the cache to be a singleton on the server side.

Author

Commented:
Hi Konst
can't singelton be a problem in application server? Once I read that if you are working with Ejb's you should avoid using threads and singeltons, am I right?
   Danny

Commented:
Hey Danny,

You are right of course. Avoid threads and in general, don't use singletons because the application server might start up more than one virtual machine.
But in your case, it doesn't really matter. You need the cache in order to minimise initialisation overhead. If all you do is cache a Topic and TopicConnection, it wouldn't matter if you lost the cache. It would just mean that initialisation is done again.

Of course I am assuming that mulitple connections to the same destination can exist and can be opened and closed at any time during runtime.
If my assumption is correct, using this method will probably boost performance quite a bit. Using stateless beans is always faster than using stateful ones.

Author

Commented:
Thanks Konst.

Do more with

Expert Office
Submit tech questions to Ask the Experts™ at any time to receive solutions, advice, and new ideas from leading industry professionals.

Start 7-Day Free Trial