Cannot access bean when deploying ejb module and web module separately? - jboss

I was testing an EJB 2.x application. I created 2 module separately:
EJB module: contains a simple stateless session bean
Web module: contains a single servlet page to lookup EJB module.
I was using Jboss 4.2.3.
First, I deployed the EJB module and the deployment went well.
Second, I deployed the web module and the deployment went well.
Then I used the following code to look up the EJB module:
Context c = new InitialContext();
Object o = c.lookup("HelloJNDI"); // Line 1
HelloLocalHome rv = (HelloLocalHome) o; // Line 2
HelloLocal local = rv.create();
The lookup went well (Line 1), but Line 2 produced a class cast exception.
Then I test the above code in 2 scenarios:
I packaged the EJB and the Web module into a single EAR module. Then, deployed this EAR module in JBoss 4.2.3, and the lookup code above worked like a charm.
I tried to use JBoss 5, and even deployed the EJB module and the Web module separately, the lookup code above worked great.
So, why when I deployed the 2 modules separately in JBoss 4, things did not work out? I use local JNDI lookup only because the 2 modules were deployed in the same container.
Was I missing something or this is a flaw in JBoss 4?

Try using the following code instead of your cast:
HelloLocalHome rv = (HelloLocalHome)javax.rmi.PortableRemoteObject.narrow(o, HelloLocalHome.class);
If that does now work, then you have the infamous classloading problem. (One of the reasons JBoss 5's default server uses a different classloading mechanism). Easiest is to indeed place them in a single EAR (so the Home and remote classes are loaded once). The Home interface class in your web application is loaded by a different classloader than the one being returned by JNDI.
You can also remove the interfaces from your WAR file's classes or lib dirrectory

Related

How to solve ClassCastException for same class in Jboss EAP 6.5

I have created and deployed one war for my application.
I wanted to use derby for integration testing so I created one module in Jboss.
At run time I am getting ClassCastException for same class, since the class is getting loaded twice: first from war, then from my module's jar.
To elaborate, my war, say application.war contains myderby.jar and under my module i have added myderby.jar .My class, say Custom.java, is present in myderby.jar.
If you want a jar to be accessible to multiple WARs, JARs, or an EAR and a WAR/JAR - or in fact any such combination, you can include it as a global module. Here's how it can be done.
This might also help.
As Suggested I followed the following link
https://access.redhat.com/documentation/en-US/JBoss_Enterprise_Application_Platform/6/html/Administration_and_Configuration_Guide/Add_a_module_to_all_deployments.html and it worked for me.

How to deploy two cross-dependent EARs in JBoss 7 in order to prevent ClassCastExceptions?

I have a problem when deploying two ear files in Jboss 7 and would be thankful for your help.
Following scenario:
EAR 1 contains EJBs which are looked up by EAR 2 (also) at server startup. Thus, EAR 1 has to be deployed before EAR 2 (via jboss-deployment-structure.xml dependency settings).
Right after being deployed, EAR 1 also needs access to classes contained in EAR 2 because of Hibernate and JNDI related class loading (among others).
But as EAR 2 isn't deployed at that time, there's a need for EAR 1 to contain a client-jar file of EAR 2.
Now, the problem is that in the course of EAR 1 and EAR 2 configuration (at server startup) ClassCastExceptions occur because...
(non-EJB) Java object obj1, whose class C was loaded by the classloader of EAR 1, is bound in JNDI
and after being looked up, supposed to be cast to object obj2 whose class C was loaded by the classloader of EAR 2
Now I wonder, if there's a possibility that these common classes of EAR 1 and EAR 2 are being loaded with the same classloader in JBoss 7. I already tried to put them in a server module, which didn't work out.
Thanks a lot for your help in advance!
PS: I'm aware of the poor design declared above. But due to restrictions, I have to follow up on it.
To avoid class cast exceptions, the common libraries need to be put in a classloader that is common to all applications in the two EARs, and no other copies of those libraries should exist in each application.
If it's an option to use only one EAR instead of two, put all the WARs inside a single EAR, remove the common classes from the WARs and put them on the EAR library folder.
This will associate the common classes to the EAR classloader, which is common to all the applications running inside a EAR, so that would solve the problem.
If you must use two EARS, then the common classes need to be put in a classloader at the level of the server shared by all applications.
JBoss 7 is an OSGI based container that allows to create an isolated module with a few jars and link it to an application. So if you try this:
create a module with the common library AND it's dependencies, see instructions here
link the module to all applications
remove the copies of those libraries from all applications and leave them only at the module
It will work fine, but don't forget to put the dependencies of the common library in the module as well otherwise it will not work, the dependencies need to be visible at the level of the module, and there can be no duplicate jars between module and applications (otherwise class cast exceptions might happen).
Another way far less recommendable but it would also work, is to put the common classes at the level of the common classloader, see this diagram. The common classloader folder is located at $CATALINA_HOME/lib (Jboss is based internally on Tomcat).
Specially if there are other applications running in that server don't try the second option. It could help to have a look at a tool I built for these type of issues, JHades.

Glassfish V3.1 Invalid ejb jar it contains zero ejb

I'm just about migrating from JBoss 6.1 to Glassfish 3.1 (don't ask why). The following occurs:
Invalid ejb jar [mmsUserMgmtAct-0.0.1-SNAPSHOT.jar]: it contains zero ejb
...
Note:
1. A valid ejb jar requires at least one session, entity (1.x/2.x style), or message-
driven bean.
2. EJB3+ entity beans (#Entity) are POJOs and please package them as library jar.
3. If the jar file contains valid EJBs which are annotated with EJB component level
annotations (#Stateless, #Stateful, #MessageDriven, #Singleton), please check server.log
to see whether the annotations were processed properly.
As everything was running perfectly with Jboss I can swear there are EJBs within the jars. The only thing which might cause the error is the fact, that I splitted the interfaces (#Remote and #Local) plus the entities (#Entity) into a package xyzService.jar and the stateless bean (#Stateless, #Remote(XyzService.class)) into another archive named xyzServiceImpl.jar.
All packaging was generated by maven, so no issues with this. Maybe I should mention that I simply copied the things into autodeploy folder.
Any glues?
Thx in advance
El Subcomandante

Separate JSF and EJB apps

How do I use a deployed EJB app from a separate JSF application?
I'm attempting to separate the two applications and access the EJB through the remote interface. To do this I have two eclipse projects - one contains the EJB and persistence logic, tested independently and works. I then created a JSF project that references the EJB project (so I gain access to the remote interface), however this fails when attempting to either inject the EJB instance or lookup the JNDI name (I've tried several variants to no avail). This is what my JSF backing bean contains:
#EJB(lookup="java:global/LocEJB/LocalityEJB!com.ame.business.LocalityEJBRemote")
private LocalityEJBRemote locality;
This is on Glassfish, and I am only referencing the EJB project and not packaging it with the JSF project. When I do the latter, I receive error initializing EJB container problems on the JSF project. So, how do I access the remote EJB and does the way I'm approaching this make any sense?
Thanks in advance!
Your JSF application has to know about the EJB interfaces (at least they did on EJB 2.0). You're using the Proxy pattern to hide the fact that this is a remote component from your JSF client.
First of all you can not use Local interface if trying to access outside the container. You must use Remote Interface.
You can define your Remote interface in the sun-web.xml or EJB injection in the bean.
sun-web.xml code:
<ejb-ref>
<ejb-ref-name>com.xxx.session.UserRemote</ejb-ref-name>
<jndi-name>corbaname:iiop:127.0.0.xxx:3700#com.xxx.session.UserRemote</jndi-name>
</ejb-ref>
Another thing you must have Remote interfaces in your classpath.

jndi.properties in JBoss and GlassFish deployment

Currently an EJB / Web Application project uses a JBoss-specific JNDI configuration file, placed either in the conf directory or in the Jar file (both works fine).
How can I make this project portable between JBoss (4.2.3 or 5) and GlassFish 3? Is there a recommended way to set different JNDI configuration parameters depending on the container?
According to their EJB FAQ, Glassfish developers have put a jndi.properties file within appserv-rt.jar. The JNDI machinery in Java SE automatically detects this file when used in conjunction with no-arg InitialContext() and bootstraps the correct naming provider.
My understanding is that this should work in Glassfish also. Did you try do deploy your application without the jndi.properties file specific to JBoss (and to place it into the conf directory when deploying on JBoss)?