ClassCastException in InitialContext.lookup method
I need to call an EJB from my Java application. EJB is available on the same J2EE server as the application.
Below is the code snippet.
InitialContext ctx = new InitialContext();
MyEjbLocalHome objLocalHome = (MyEjbLocalHome) ctx.lookup("localejbs/my.com/abc~myearDC/MyEjbBean");
I am getting ClassCastException at the above line.
I am sure that the local home interface is correct and belongs to the same EJB.
Can you please help me with this?
Rolf Paulsen replied
this may be the same implementation problem of class loading inside SAP NetWeaver Java we stumled oger. I posted an OSS but they will not change it.
If you have to EJBs in different enterprise applications, you MUST set an application reference from one enterprise application "A" (typically the calling with the lookup) to the enterprise application "B" that contains the EJB that is looked up.
"To look up a remote object, you must have its remote interface in the clientu2019s class path (for external clients) or have a class loader reference to it (for components and applications running on the server process)."
This makes the class loader of "B" the parent class loader of "A". If you omit this reference, the object that is returned by the lookup is loaded by class loader of "B" and you try to cast it to the class of class loader "A" which of course fails.
PortableRemoteObject.narrow(obj, MyEjbLocalHome .class);
before the class cast does not help (because it does nothing to obj at all).
How do you set an application reference?
In META-INF/application-j2ee-engine.xml in enterprise applicatoin "A" enter
<?xml version="1.0" encoding="UTF-8"?>
<application-j2ee-engine xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:noNamespaceSchemaLocation="application-j2ee-engine.xsd">
<reference-target provider-name="VENDOR_NAME_OF_EAR_B" target-type="application">APP_NAME_OF_EAR_B</reference-target>
If you are working with Development Components, just add a dependency with "Runtime" and this is done automatically.
BTW if you redeploy "B", "A" will be restarted because its parent class loader changed.