Search code examples
jakarta-eeejbwildflyejb-3.1wildfly-8

EJB: @Local invocation to another EAR


I'm using EJB 3.1 and Wildfly 8.2.Final

Ear 1 :

jar-impl with Bean1 (where I execute the lookup of Interface2)

lib /
    jar with Interface2

Ear 2 :

jar-impl with Bean2

lib / 
    jar with Interface2 and META-INF/ejb-jar.xml

I would like to execute the lookup in the Bean1 of Interface2 annotated with @Local.

"Look up" code:

Properties jndiProp = new Properties();
InitialContext ctx = new InitialContext(jndiProp);
Object bean = ctx.lookup(JNDI);
Interface2 interface = (Interface2) bean;

If I annotate Interface2 with @Remote, the wildfly at startup writes:

    java:global/c4c.commons.backend/c4c.commons.backend-impl/Bean2!eu.dedalus.c4c.commons.service.Interface2
    java:app/c4c.commons.backend-impl/Bean2!eu.dedalus.c4c.commons.service.Interface2
    java:module/Bean2!eu.dedalus.c4c.commons.service.Interface2
    java:jboss/exported/c4c.commons.backend/c4c.commons.backend-impl/CMSRemoteServiceBean!eu.dedalus.c4c.commons.service.Interface2
    java:global/c4c.commons.backend/c4c.commons.backend-impl/Bean2
    java:app/c4c.commons.backend-impl/Bean2
    java:module/Bean2

Having

JNDI = "ejb:c4c.commons.backend/c4c.commons.backend-impl/Bean2!eu.dedalus.c4c.commons.service.Interface2"

Everything goes well.. but when I annotate Interface2 with @Local witch is the thing i want to do, the wildfly at startup writes:

java:global/c4c.commons.backend/c4c.commons.backend-impl/Bean2!eu.dedalus.c4c.commons.service.Interface2
    java:app/c4c.commons.backend-impl/Bean2!eu.dedalus.c4c.commons.service.Interface2
    java:module/Bean2!eu.dedalus.c4c.commons.service.Interface2
    java:global/c4c.commons.backend/c4c.commons.backend-impl/Bean2
    java:app/c4c.commons.backend-impl/Bean2
    java:module/Bean2
  • If i execute the lookup with "ejb:" prefix goes well, but when i try to invoke any of the methods of the bean, it throws: “JBAS014151: Could not find view ”
  • If i execute the lookup with "java:global/" prefix goes well, but when i try to assing to the interface i get a java.lang.ClassCastException: HelloWorldRemote$$$view4 cannot be cast to HelloWorldRemote

    This may be because i have two interfaces "Interface2" in two different ears ? But why with the remote the error does not occur?

    It's useful to use the @Local invocation instead of the @Remote, for local invocation? I've read several things, the better one is this: https://coderanch.com/t/79249/application-servers/Local-EJB-calls-separate-ear

    But still i have confused ideas. Please in the answer provide documentation links to official docs.


Solution

  • See EJB 3.x specification for clarification, e.g. EJB 3.2 spec section 3.2.2:

    Access to an enterprise bean through the local client view is only required to be supported for local clients packaged within the same application as the enterprise bean that provides the local client view. Compliant implementations of this specification may optionally support access to the local client view of an enterprise bean from a local client packaged in a different application. The configuration requirements for inter-application access to the local client view are vendor-specific and are outside the scope of this specification. Applications relying on inter-application access to the local client view are non-portable.

    Using the remote interface will usually need marshalling and unmarshalling of the method parameters and the returning object along with a clear classloader separation.

    Use remote EJBs if you need access from another JVM (e.g. remote client) or another application scope within the same application server. Use local EJBs if you want to provide access to an EJB within your application scope, only.