1

I have what appears to be the same question as WildFly JNDI lookup for local EJB deployed in a war, except that I can't get his solution to work.

I have an ear with EJBs deployed in the jar jaws-server-ejb3. Inside my app I want to call a method on a bean. I've tried this with and without @LocalBean on my bean.

When wildfly (8.2) starts it prints out:

java:global/jaws/jaws-server-ejb3/ForecastService!com.termalabs.common.service.ForecastServiceRemote
java:app/jaws-server-ejb3/ForecastService!com.termalabs.common.service.ForecastServiceRemote
java:module/ForecastService!com.termalabs.common.service.ForecastServiceRemote
java:jboss/exported/jaws/jaws-server-ejb3/ForecastService!com.termalabs.common.service.ForecastServiceRemote
java:global/jaws/jaws-server-ejb3/ForecastService
java:app/jaws-server-ejb3/ForecastService
java:module/ForecastService

When I add @LocalBean to my bean I see:

java:global/jaws/jaws-server-ejb3/ForecastService!com.termalabs.server.service.ForecastService
java:app/jaws-server-ejb3/ForecastService!com.termalabs.server.service.ForecastService
java:module/ForecastService!com.termalabs.server.service.ForecastService
java:global/jaws/jaws-server-ejb3/ForecastService!com.termalabs.common.service.ForecastServiceRemote
java:app/jaws-server-ejb3/ForecastService!com.termalabs.common.service.ForecastServiceRemote
java:module/ForecastService!com.termalabs.common.service.ForecastServiceRemote
java:jboss/exported/jaws/jaws-server-ejb3/ForecastService!com.termalabs.common.service.ForecastServiceRemote

So it seems clear from all I read that I should be able to lookup this bean with "java:app/jaws-server-ejb3/ForecastService" or "java:app/jaws-server-ejb3/ForecastService!com.termalabs.common.service.ForecastServiceRemote"

Here is my lookup which I have hard coded at the moment:

public static Object getBeanInternal(String beanName, Class remoteClass) throws NamingException {
    System.out.println("Getting internal bean: " + beanName + " for class "  + remoteClass.getName());
    final Hashtable jndiProperties = new Hashtable();
    jndiProperties.put(Context.URL_PKG_PREFIXES, "org.jboss.ejb.client.naming");
    InitialContext ctx = new InitialContext(jndiProperties);
    Object ejb = ctx.lookup("java:app/jaws-server-ejb3/ForecastService");
//    Object ejb = ctx.lookup("java:global/jaws-server-ejb3/ForecastService!com.termalabs.common.service.ForecastService");
    return ejb;
}

I have tried this with an empty jndiProperties table, or with the setting quoted above. No matter what I've tried I end up with a NamingException like

2015-04-07 15:50:01,836 WARN  [com.termalabs.server.system.AutosysJammerSequence] (JammerManager-2015/04/07 15:49:46.710 MDT-0) Can't lookup: javax.naming.NameNotFoundException: java:app/jaws-server-ejb3/ForecastService
    at org.jboss.as.naming.InitialContext$DefaultInitialContext.findContext(InitialContext.java:187)
    at org.jboss.as.naming.InitialContext$DefaultInitialContext.lookup(InitialContext.java:231)
    at org.jboss.as.naming.NamingContext.lookup(NamingContext.java:188)
    at org.jboss.as.naming.NamingContext.lookup(NamingContext.java:184)
    at javax.naming.InitialContext.lookup(InitialContext.java:417) [rt.jar:1.8.0_25]
    at javax.naming.InitialContext.lookup(InitialContext.java:417) [rt.jar:1.8.0_25]
    at com.termalabs.common.ejb3.EJB3Util.getBeanInternal(EJB3Util.java:55) [jaws-common-ejb3intf-1.0.jar:]
    at com.termalabs.server.system.AutosysJammerSequence.runJammerSequence(AutosysJammerSequence.java:427) [jaws-server-base-5.1dev.jar:]
    at com.termalabs.server.system.JammerSequence.run(JammerSequence.java:125) [jaws-server-base-5.1dev.jar:]
    at java.util.concurrent.Executors$RunnableAdapter.call(Executors.java:511) [rt.jar:1.8.0_25]
    at java.util.concurrent.FutureTask.run(FutureTask.java:266) [rt.jar:1.8.0_25]
    at java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1142) [rt.jar:1.8.0_25]
    at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:617) [rt.jar:1.8.0_25]
    at java.lang.Thread.run(Thread.java:745) [rt.jar:1.8.0_25]

I can get to this bean using the remote interface, but that doesn't seem right since I am running this code from the same ear. I shouldn't need to do that.

What am I missing?

Thanks,

Michael

Community
  • 1
  • 1
mdhirsch
  • 861
  • 7
  • 7
  • 1
    Is the code where you want to lookup and use the EJB deployed in the same deployable unit, eg in the same War? If so, why use JNDI to do the lookup when you could inject it with "@Inject" or "@EJB" instead? – Kevin Hooke Apr 07 '15 at 22:18
  • I just wanted to point out that in your commented-out lookup you've specified "java:global" instead of "java:app". No idea if that helps. – DavidS Apr 07 '15 at 22:20
  • @KevinHooke - In principle I should use "@EJB", but for historical reasons we are using Guice for CDI and I was hoping to not have to teach Guice about "@EJB". – mdhirsch Apr 07 '15 at 23:21

1 Answers1

3

Looking at the message I see JammerManager-2015/04/07 15:49:46.710 MDT-0 which looks like you're launching your own thread. If you're not using the new EE concurrency utilities it's likely the naming context isn't copied over to your thread. You'd need to ensure that your naming context, security context and the TCCL is set for your new thread.

James R. Perkins
  • 16,800
  • 44
  • 60
  • That makes sense. I'll look into it as soon as I'm back from vacation. Thanks! – mdhirsch Apr 08 '15 at 23:00
  • You are correct. I can access my bean from the parent thread, but not from inside my new Thread. It seems I have 2 options: 1) rewrite all my threads using the JBoss/JavaEE API. This is clearly preferable except that it is made difficult by us bypassing the standard CDI and using GUICE. And it would be pretty intrusive. 2) Do as you say and copy in my naming context, security context and the TCCL. Do you have any pointers that would show how to do this? I'm not having much luck with Google. Thanks again. – mdhirsch Apr 13 '15 at 17:38
  • Have a look at how a [batch thread](https://github.com/wildfly/wildfly/blob/master/batch/jberet/src/main/java/org/wildfly/jberet/services/BatchEnvironmentService.java#L133-L147) is launched. Have a look at the [context handle](https://github.com/wildfly/wildfly/tree/master/batch/jberet/src/main/java/org/wildfly/jberet/services). – James R. Perkins Apr 14 '15 at 03:25
  • Thanks for your help, James. It pointed me in the right direction of using a properly created Bean to create the threads I needed. Once my threads were actually managed by Wildfly I was able to call my method on the bean correctly. – mdhirsch Apr 14 '15 at 19:15
  • 1
    Following the EJB specification: **Do NOT** start any threads on your own as it "confuses" the container and it even may crash. That is what I have learned. – Roland Oct 30 '17 at 18:13
  • And one more thing (to question asker): There are 2 notations of JNDI names, one is portable (means, also works on any other container) and one is product-specific (only working on the specific container, maybe **even** major/minor version. For example `@EJB (lookup="java:global/someproject-ejb/someBean!example.test.silly.package.SomeFooRemote")` is fully portable, but `@EJB (mappedName="bla-foo-blub-something")` is product-specific and is **not** required to work on all containers, the first is always required to be supported. – Roland Oct 30 '17 at 18:17