I have read through all the suggestions that I could find regarding scoped EARs but am still having an issue as I migrate to scoped ears. I would appreciate your advice.
I have a deployment with 5 EARs. This gives you an idea of the setup.
Each jboss-app.xml specifies a classloader and I can see invidual ones being created as I would expect via the JBoss console.
I receive the following error when I try to lookup an ejb. The deployment descriptors work for a non-scoped deployment, but as I have moved to scoped ears I receive this error.
javax.ejb.EJBException: Invalid invocation, check your deployment packaging, method=public blah, blah, blah
The exception is thrown when the home.create() is invoked. I have checked its type and it is cast correctly. It just dies on the create.
In my deployment the *-client.jars contain the homes, remotes, vos, exceptions. The *-ejb.jars contain everything for that systems, ie homes, remotes, EJB, vos, exceptions, defined MANIFEST.MF.
This deployment only contains stateless session beans, no entity.
I tried the using <!-- EAR deployer, remove if you are not using Web layers -->
<!-- Isolate all ears in their own classloader space -->
<!-- Enforce call by value to all remote interfaces -->
for the conf/jboss-service.xml, but was unable to get the server to restart.
call by value is going to kill your performance. have you read this wiki page?
is there any reason you need to be running scoped ears? for example, if each ear is sharing the same version of "common.jar" you'd be better off extracting that jar from all the ears and deploying it seperately.
The "commons" jar contains a singleton that I wanted scoped at the ear level, not server level. It also contains, general utility type classes that will not hurt if they are thrown in and redeployed out across the system.
I am aware of the pass by value aspect of using remote stateless session beans and am willing to accept all that comes with that.
For business reasons, we need to run scoped ears.
Any ideas on what the problem is?
just to clarify - are you trying to invoke ejbs across ears? ie: App.ear calls ejbs in Core.ear
The App.ear would use the home and remote interface in the core-client.jar to invoke services that will execute within the Core.ear where the actual core-ejb.jar resides.
*-client.jars contain the homes, remotes, vos, exceptions.
*-ejb.jars contain everything for that system, homes, remotes, stateless EJB, DAOs, vos, exceptions, defined MANIFEST.MF.
hrm - i'm not really sure how to correct your issue. i was in somewhat of the same situation as you are, using scoped ears w/ the need to communicate and did not have much luck, even w/ setting the pass-by-value attribute to true.
hence the reason i did away w/ scoped ears and packaged my code as described in that wiki page. thinking out loud, i believe the issue is b/c the ears are scoped, so App.ear can not find the implementation class in Core.ear.
umm - do you have the ability to package the ejb implementation classes outside of the ear, but package the deployment descriptors inside the ear?
ie: you'd have one jar w/ all the java classes inside, and then another that contains only deployment descriptors packaged inside the ear.
you could also turn on classloading debugging (there is a wiki page that states how) to see if that helps produce any useful information. also, if you have access to the jboss book, chapter 2 talks about how the classloader works so it may be useful to read and digest that information and then re-approach the problem.
I think you might be right, but that seems kinda crazy to me.
The unified classloader is ok, but it seems to depart from the encapsulation concept.
The main reason I want to do this is so I can produce a client jar for my client that will not include DAO/JDBC code, etc, etc. I want to be strict with enforcing what the clients can invoke and thus want to encapsulate all of the business code and objects behind a Facade implemented using a remote stateless session bean. This facade then resides in it's own ear out on the system, but is accessible only through the remote interface. With unified classloader, it seems everything is out on the system for anybody to access as they please.
It seems like the client-jar and ejb-jar is not a concept that is often used with JBoss? Any ideas? Examples? on how to use the scoped ears in the manner described above would be appreciated.
i'm confused about how this is going to be deployed. are you going to "host" the server side of things and then have a client connect over some type of vpn, etc? if they were to "host" both sides, there's nothing that would prevent them from unpackaging the ears, and decompiling your classes - although i guess you could ship code using one of those tools that obscures some of that.
either way, using scoping is not a solution to locking down the system. for that you'd want to use jaas. an
i do client-jar/ejb-jar packaging all the time.
he's a brief example of how i do it (and this is some what modelled after how nukes is packaged, and i find it to be quite flexible).
1) create "api" (client) jar - inside here will go any Home/Remote interfaces, helper classes, etc. this is basically the jar you would give to the client so they could access the app.
2) create a "lib" jar - inside here will go any server side classes - ejb implementations, etc. no deployment descriptors are packaged here.
3) create "ejb" jar which contains all the deployment descriptor files, and no other classes. this allows you to do things like deploying all your entity bean classes once, but still deploy "read only" and "read/write" versions.
4) create an ear that contains the "lib" and "ejb" jars (and any sars you may have, wsrs, etc).
5) if you have any "third party" libraries, package them inside a sar (this will guarentee they get deployed first) or put them in the "lib" directory.
when you do your deployments to jboss, you deploy both the "api" jar that you gave to your client, plus the ear file. in addition to getting rid of those nasty ClassCastExceptions, you have the ability to hot deploy the ear if you make backend changes (not that you'd want to do this for production, but it is a great advantage in development).
imo, scoped ears are best if you have apps that don't need to communicate together and share different versions of a common library. if you're really concerned about who can access what, as i said before, jaas is the route you want to go.
The desire to limit access to the DAOs, etc is more from a design perspective, not a security one. Your approach is essentially the same, except that I have always bundled my "lib" classes in with the "ejb" jar descriptors. This approach has always worked in weblogic and I assumed it would work in JBoss. The whole portable application thing. :-)
I will try your "lib" approach, although I am not sure why bundling the ejb implementations into a "lib" directory as opposed to the ejb.jar itself would work since they will reside in the same ear.
Do you know if this works with scoped ears on JBoss?
are the DAOs behing the stateless session beans? or are they standalone POJOs?
the reason to seperate the ejb impl classes to avoid deploying the classes twice (i believe jboss will complain about this) - this makes lots of sense if you have entity beans and are planning to have a read-only and a read-write set. if you're not using entity beans, you can package them together. it's just my preference to keep all the classes together in one jar.
this still isn't going to work w/ the scoped ears. if you're really looking to do this type of thing, is there any reason you can't bundle the 5 deperate ears together into one big ear that is scoped? jboss allows for the russian-doll type packaging, so there's no reason that shouldn't work for you.
if you could give me some more details on how the app is hosted and more of what is in the individual ears and what gets given to the clients, i can try and offer some more suggestions.
I appreciate your suggestions, but I've decided to abandon scoped ears for now. To answer your question regarding structure. The DAOs are behind POJOs which are wrapped by stateless session beans or message beans. All business logic resides in POJOs and the EJBs are just a wrapper/pass through to provide transactions, remoteness, asynchronous (MDBs), etc... The DAOs provide all data access and return simple data objects.
I considered the BAE (Big Ass Ear) approach, but have decided to just go with the unified class loader.
Thanks for your thoughts.
same problem here: two ear's, one calls into the other. salted with the need for ear scooping.
jboss 3.2.5 siletly ignores the callbyvalue parameter, you need to add it to org\jboss\metadata\BeanMetaData.java
callByValue = callByValueElt.equalsIgnoreCase ("True");
in importJbossXml() at an obvious place or wait for a new release.
damn, i wasted an entire day... but that's just open source. but i could at least fix it... :)