1

As the title says. I have some EJBs in an EAR and I have a client jar providing remote methods to a JSF app also sitting in liberty (different server/machine). The client jar tries to access the remote EJBs via lookup.

This is breaking my heart for two days now. As the title says...

I am aware of other stackoverflow questions from the past and I am aware of the following resources: https://www.ibm.com/docs/en/was-liberty/core?topic=liberty-using-enterprise-javabeans-remote-interfaces

https://github.com/OpenLiberty/open-liberty/blob/release/dev/com.ibm.ws.ejbcontainer.remote_fat/test-applications/RemoteClientWeb.war/src/com/ibm/ws/ejbcontainer/remote/client/web/RemoteTxAttrServlet.java

I have tried every combination provided in the above but no joy.


I use (wlp-javaee8.21.0.0.8) with javaee8 feature enabled, this enables everything else I need e.g. ejb-3.2, ejbRemote-3.2, jndi-1.0 and a few others)

I have an EAR my-ear that contains a module my-module-1.0.4-SNAPSHOT.jar which contains my beans. I am using gradle/liberty plugin and IntelliJ. I am using tests from within IntelliJ in the client jar module to try to access the remote beans.

My myEAR deploys fine and starts up fine and the app shows running in admincenter. In messages.log I see my EJB bindings. Just picking one example.

[16/08/21 10:58:42:384 IST] 00000022 com.ibm.ws.ejbcontainer.osgi.internal.NameSpaceBinderImpl I CNTR0167I: The server is binding the my.org.functiona.ejb.advance.MyAdvance interface of the MyAdvanceBean enterprise bean in the my-module-1.0.4-SNAPSHOT.jar module of the my-ear application. The binding location is: ejb/my-ear/my-module-1.0.4-SNAPSHOT.jar/MyAdvanceBean#my.org.functiona.ejb.advance.MyAdvance [16/08/21 10:58:42:385 IST] 00000022 com.ibm.ws.ejbcontainer.osgi.internal.NameSpaceBinderImpl I CNTR0167I: The server is binding the my.org.functiona.ejb.advance.MyAdvance interface of the MyAdvanceBean enterprise bean in the my-module-1.0.4-SNAPSHOT.jar module of the my-ear application. The binding location is: my.org.functiona.ejb.advance.MyAdvance [16/08/21 10:58:42:385 IST] 00000022 com.ibm.ws.ejbcontainer.runtime.AbstractEJBRuntime
I CNTR0167I: The server is binding the my.org.functiona.ejb.advance.MyAdvance interface of the MyAdvanceBean enterprise bean in the my-module-1.0.4-SNAPSHOT.jar module of the my-ear application. The binding location is: java:global/my-ws-ear/my-module-1.0.4-SNAPSHOT.jar/MyAdvanceBean!my.org.functiona.ejb.advance.MyAdvance

This is my corresponding interface:

package my.org.functiona.ejb.advance;

import javax.ejb.Remote;

@Remote
public interface MyAdvance {

This is my corresponding implementation:

package my.org.functiona.ejb.advance;

import javax.ejb.EJB;
import javax.ejb.Stateless;
import javax.ejb.TransactionAttribute;

@Stateless(mappedName = "MyAdvance")
@TransactionAttribute(TransactionAttributeType.REQUIRES_NEW)
public class MyAdvanceBean implements MyAdvance {

Like I said, its breaking my heart. I tried every combination of provided in the (patchy) documentation and other sources. The most progress I made was by accessing "corbaname::localhost:2809/NameService" through a default InitialContext().lookup. So at least I was able to confirm I can gwet through to the NameService. But any subsequent bean lookup using that context with any combination of the names provided in messages.log or in the code snippets from documentation all fail with the exception below.

javax.naming.NameNotFoundException [Root exception is org.omg.CosNaming.NamingContextPackage.NotFound: IDL:omg.org/CosNaming/NamingContext/NotFound:1.0]

Same for InitialContext() lookups where I prefix the names with "corbaname::localhost:2809/NameService#".

I tried

  • ejb/my-ear/my-module-1.0.4-SNAPSHOT.jar/MyAdvanceBean#my.org.functiona.ejb.advance.MyAdvance
  • ejb/global/my-ear/my-module-1.0.4-SNAPSHOT.jar/MyAdvanceBean#my.org.functiona.ejb.advance.MyAdvance
  • ejb/my-ear/my-module-1.0.4-SNAPSHOT.jar/MyAdvance#my.org.functiona.ejb.advance.MyAdvance
  • ejb/global/my-ear/my-module-1.0.4-SNAPSHOT.jar/MyAdvance#my.org.functiona.ejb.advance.MyAdvance
  • java:global/my-ear/my-module-1.0.4-SNAPSHOT.jar/MyAdvance#my.org.functiona.ejb.advance.MyAdvance
  • java:global/my-ear/my-module-1.0.4-SNAPSHOT.jar/MyAdvanceBean#my.org.functiona.ejb.advance.MyAdvance
  • my.org.functiona.ejb.advance.MyAdvance

and probably a few others

I replaced the # sign with an exclamation mark in all of the above. And went through it again. I tried corbaloc:: and corbaloc:iiop: for context. Nothing.

I am no web dev expert but this feels very try and error and I dont feel it should be like that. I understand in websphere proper I could identify the names in the admin console but then I'm not even certain websphere proper and liberty behave the same way.

Sine accessing EJBs from remote seems bread & butter stuff I assume I am overlooking something basic and silly due to my inexperience.

Any pointers anyone? Thank you so much for your time reading this.

Carsten

Edit: server.xml

<server description="disbCoreServer">

  <featureManager>
    <feature>javaee-8.0</feature>
    <feature>adminCenter-1.0</feature>
    <feature>websocket-1.1</feature>
  </featureManager>

  <quickStartSecurity userName="admin" userPassword="carsten" />

  <!-- To access this server from a remote client add a host attribute to the following element, e.g. host="*" -->
  <httpEndpoint id="defaultHttpEndpoint"
                host="${hostname}"
                httpPort="${default.http.port}"
                httpsPort="${default.https.port}">
      <accessLogging filepath="${com.ibm.ws.logging.log.directory}/accessLog.log" logFormat='%h %i %u %t "%r" %s %b %{R}W' />
      <tcpOptions soReuseAddr="true" />
  </httpEndpoint>

  <include location="appConfXML/disb_core_jndi.xml"/>
  <include location="appConfXML/disb_core_jdbc.xml"/>
  <include location="appConfXML/disb_core_jms.xml"/>
  <include location="appConfXML/disb_core_mail.xml"/>

</server>
  • Can you please share your server config (server.xml) ? It's possible there's an issue with your configuration of the EJB container. – Scott Kurz Aug 16 '21 at 12:29
  • The `javaee-8.0` feature enables `appSecurity-3.0` which requires additional configuration to allow remote EJBs to work. Perhaps replace `javaee-8.0` with a subset of what you need, not including `appSecurity-3.0` for now, just to make sure the lookup JNDI name is correct. Based on the CNTR0167I, the correct JNDI name would be ejb/global/my-ws-ear/my-module-1.0.4-SNAPSHOT.jar/MyAdvanceBean!my.org.functiona.ejb.advance.MyAdvance – Tracy Aug 16 '21 at 13:18
  • Thanks for reading to all of you. Added server.xml and, yes, I see appsecurity-3.0 is added automatically through javaee-8.0 feature – CalleWirsch Aug 16 '21 at 13:42
  • Replaced javaee-8.0 feature package with subset not containing appsecurity but still having the same problems. – CalleWirsch Aug 16 '21 at 15:13
  • So am I understanding correctly that the "client JAR" is running out of a web app from another Liberty server? In that case, what features do you have configured from that "client server"? Do you have the ejbRemote-3.2 feature? – Scott Kurz Aug 16 '21 at 20:18
  • Hello Scott, yes, I am connecting from a second liberty server where my JSF frontend app is running from. First I started out testing the remote calls with junit tests within my backend repos executed within IntelliJ, but my understanding is now that connecting from outside a liberty context (thin client) doesnt work. So then I went straight to integration testing with the designated client app. I am unsure what features needed to be installed on the client machine. I am trying to bring this machines feature list to ejbRemote-3.2 also. See how that works. – CalleWirsch Aug 17 '21 at 08:23
  • Another thing I want to mention is that I get what seems to be a valid InitialContext from "corbaname::localhost:2809/NameService". But when I do a list("") on that context it comes back with nothing. – CalleWirsch Aug 17 '21 at 08:25

1 Answers1

1

The example provided through the FAT test (remoteLookup) works just fine. I just didnt have all my ducks in a row.

https://github.com/OpenLiberty/open-liberty/blob/release/dev/com.ibm.ws.ejbcontainer.remote_fat/test-applications/RemoteClientWeb.war/src/com/ibm/ws/ejbcontainer/remote/client/web/RemoteTxAttrServlet.java

My scenario is serverA hosting EJBs and serverB running the remote client calling serverA's EJBs.

Steps on serverB are:

  1. Get (local) InitialContext with no properties: InitialContext initialContext = new InitialContext();

  2. With the above lookup the remote Context: Context remoteContext = (Context) initialContext.lookup("corbaname::remotehost:remotePort/NameService");

  3. With the remoteContext lookup the EJB remote interfaces and 'narrow' and cast them to appropriate type

    String lookupName = "ejb/global" + "/" + "MyAppName" + "/" + "MyModuleName" + "/" + jndiName; Object remoteObj = remoteContext.lookup(lookupName); return interfaceClass.cast(PortableRemoteObject.narrow(remoteObj, interfaceClass));

    Where

    • "MyAppName" is my apps name, the name of the EAR in my case (without .jar)
    • "MyModuleName" is the name of the EJB module within my EAR (without .jar)
    • and jndiName is the bean name / fully qualified interface name separated by exclamation mark e.g. "MyBean!myorg.ejb.interfaces.MyBeanIfc"
  4. Call the interfaces to remotely execute serverA EJB code

Note: When running serverA and serverB on the same machine (e.g. localhost) ensure they are not operating on the same port for NameService.

Thanks to everyone who tried to help!