Steve Cohen
Steve Cohen

Reputation: 4859

What is the difference between a Local EJB Interface and View

I believe this question is an extension of What is local/remote and no-interface view in EJB?

I am trying to port a group of EJB Jars whose EJBs are called by a Servlet in a generic fashion, from WebLogic to JBoss. This whole system is very old, the EJBs are 2.0. I have tried to update this by changing the deployment descriptor to 3.2.

That part is relatively easy.

Here's the part that isn't.

The EJBs participating in this arranbement all implement the SessionBean interface. Their local and remote interfaces are generic, they inherit from a common business interface. Here is a sample of the deployment descriptor:

<?xml version="1.0" encoding="UTF-8"?>
<ejb-jar xmlns="http://xmlns.jcp.org/xml/ns/javaee"
         version="3.2"
         xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
         xsi:schemaLocation="http://xmlns.jcp.org/xml/ns/javaee http://xmlns.jcp.org/xml/ns/javaee/ejb-jar_3_2.xsd">
<module-name>WhizBangSessionEJB</module-name>
<enterprise-beans>
   <session>
        <ejb-name>WhizBangSessionEJB</ejb-name>
        <home>com.whatever.hostinterface.ServiceLogicHome</home>
        <remote>com.whatever.hostinterface.ServiceLogic</remote>
        <local-home>com.whatever.hostinterface.ServiceLogicLocalHome</local-home>
        <local>com.whatever.hostinterface.ServiceLogicLocal</local>
        <ejb-class>com.whatever.whizbang.ejbs.WhizBangSessionBean</ejb-class>
        <session-type>Stateful</session-type>
        <transaction-type>Container</transaction-type>
    </session>
 </enterprise-beans>
</ejb-jar>

I should also mention here the signature of these interfaces:

public interface ServiceInterface
{
// business interface methods.
}

public interface ServiceLogic extends EJBObject, ServiceInterface
{}

public interface ServiceLogicLocal extends ServiceLogic, EJBLocalObject 
{}

So a ServiceLogic IS-A ServiceInterface. A ServiceLogicLocal IS-A ServiceLogic and therefore IS-A ServiceInterface

Using the remote interface, the servlet is able to instantiate a bean as follows:

Object home = ctx.lookup({JNDI of Home Interface});
EJBHome obHome = (EJBHome)PortableRemoteObject.narrow(home, EJBHome.class);
Method m = obHome.getClass().getDeclaredMethod("create", new Class[0]);
sl = (ServiceLogic) m.invoke(obHome, new Object[0]);

and I have my EJB which can be cast into a service logic.

But these EJBs and the Servlet will always be in the same container. Therefore local interfaces are indicated. Here is where I run into trouble. And Local EJBs don't require Home Interfaces in 3.x.

So I thought something like this should work.

sl = (ServiceLogicLocal)ctx.lookup({JNDI of Local Interface to Bean});

This fails with the following error.

java.lang.ClassCastException: com.whatever.hostinterface.ServiceLogicLocal$$$view60 cannot be cast to com.whatever.hostinterface.ServiceLogicLocal

And I know that the Local Home interface is not required, but I have created it. Trying to use that and calling its create() method, produces the same kind of ClassCastException where I fail because trying to cast a view (proxy) of an object into an object of the type.

What is the difference between a Local EJB Interface and a ClientView of a Local EJB Interface, and how may I instantiate this EJB through its local interface?

Thanks.

Upvotes: 1

Views: 1720

Answers (2)

user9736217
user9736217

Reputation:

This worked for me in Wildfly,

Although I had to add the dependency as provided.

 		<!-- Business Interfaces of the server EJB. -->
		<dependency>
			<groupId>com.sample.ejb</groupId>
			<artifactId>sample-engine-ejb</artifactId>
			<type>ejb</type>
			<version>1.0</version>
			<scope>provided</scope>
		</dependency>

Thank you!!

Upvotes: 0

Steve C
Steve C

Reputation: 19445

By default, Java EE deployment units (jars, ejb-jars, wars, ears-and-their-contents) are isolated from each other. In other words, classes in one deployment unit do not have access to classes in other deployment units.

This is normally a good thing.

Some Java EE implementations, such as JBossAS and WildFly, provide a mechanism for overriding this constraint.

If your EJBs and interfaces are packaged in a jar named WhizBang.jar, then you can make the classes in this jar accessible to your web application by adding a WEB-INF/jboss-deployment-structure.xml file to it with the following content:

<?xml version="1.0"?>
<jboss-deployment-structure xmlns="urn:jboss:deployment-structure:1.3">
    <deployment>
        <dependencies>
            <module name="deployment.WhizBang.jar" />
        </dependencies>
    </deployment>
</jboss-deployment-structure>

Given the above, you can then lookup your EJBs:

 InitialContext initialContext = new InitialContext();
 ServiceInterface serviceBean = (ServiceInterface)initialContext.lookup("java:global/WhizBangSessionEJB/WhizBangSessionEJB!com.whatever.hostinterface.ServiceLogicLocal");
 ServiceLogic remoteService = (ServiceLogic)initialContext.lookup("java:global/WhizBangSessionEJB/WhizBangSessionEJB!com.whatever.hostinterface.ServiceLogic");

I have this code working in WildFly 10.1.0.Final

Upvotes: 2

Related Questions