I struggeled last week with some Corba Marshalling Exceptions. The one glassfish web app was trying to get some data from another web application on the same machine and same domain and same EAR. I found in StackOverflow the right answer. One object was not Serializable. After fixing this little problem the glassfish server got really busy doing s.t. for a while. My suspiction was that it is serializing a very large object. So my idea that only a little “pointer” is transferred from one app to the other app seems to be wrong. It copies the whole structure.
My question is now. “Is it clever to do ejb injection from one app to the other?”
I guess if i keep the objects small (“Transient” etc.) it will work fast enough. But can’t I get only access to the other object in the other app for reading some data?
Thanks for you help.
What you want to do is definitely possible. Some terminology clarifications.
What you have is Module to Module EJB Injection using a Remote interface of the bean.
What you want is Module to Module EJB Injection using Local interface of the bean.
So some clarifications on terms:
Application vs Module
When two WAR files are in the same EAR, what you have in spec terms is one Application and two Modules.
In all other situations (two EARs, WARs not in an EAR) you have Application to Application and that’s far harder to deal with.
The significance is the EAR creates one classloader which will become the parent, each WAR becomes a child classloader of the EAR. As such the WAR files cannot see each other’s classes, but they can see the shared classes in the EAR. Here’s where our solution lies — more on that in a bit.
Remote vs Local refs
Remote refs are pass-by-value (you get a copy of the data)
Local refs are pass-by-reference (“pointer” as you mention it)
Note that the same annotation
@EJBis used in either case and there’s no way to tell which you might have. It’s only the bean itself that determines which kind of references to expose via@Remoteor@Localon either the bean class or the interfaces of the bean.Solution
Because you have an EAR it is possible to move the bean (the EJB) out of the war files and into a shared jar that is placed at the root of the EAR file next to the WAR files. You must also remove the bean class and its interfaces from the WAR files for this to work.
Then you can change the
@Remoteinterface of the bean to@Local.If you do that, you will get pass-by-reference semantics and the two WAR files can share data without CORBA or anything heavy like that. They’d just be passing java objects the same way any object would be passed in java.
If you truly did have an Application to Application situation, then indeed you would need to use
@Remoteand pass-by-value semantics which is of course many times slower.If you were also exposing this EJB to other Applications (say outside the server or in other EARs), then you can still do that by adding a second interface to the bean annotated
@Remote. It’s possible and easy for a single EJB to expose@Localand@Remoteinterfaces (or views as we call them in the spec) as well as@WebServiceand REST service views.