4 Replies Latest reply on Dec 14, 2007 12:32 PM by hmccartney

    New EJB causes JNDI failure on existing EJB?

    hmccartney

      Hi,

      We have an existing JEE application with components on 2 JBoss servers (machine 1 and machine 2). The application on machine 1 uses JNDI to access the application on machine 2. This has been working with no problems for about a year now.

      Recently we tried to add a second application to the same 2 JBoss servers. This time machine 2 uses JNDI to access machine 1.

      When we tried to deploy the second application, it worked fine, but it caused JNDI in the first application to stop working with javax.naming.NameNotFoundException (stack trace below). However the session bean in question was logged as bound on startup and appeared in the list in the JMX console.

      The names of the ears in the second application come before those in the first application alphabetically, so I guess the classes in the second application are loaded first and this might be confusing the first application somehow? We are using org.jboss.deployment.scanner.PrefixDeploymentSorter and have not yet attempted to isolate the ears from each other in any way.

      The problem went away when we removed the second application on machine 2. However I don't understand why there was a problem in the first place, because the 2 applications on machine 2 do not share any of the same classes. Application 2 on machine 2 does have a jndi.properties referencing machine 1. Is there any way that this could be interfering with the code that makes the first application available to JNDI?

      We are using jboss-4.0.4.GA on Red Hat.

      The code in application 1 on machine 1 to do the JNDI lookup is:

      Hashtable<String,String> env=new Hashtable<String,String>();
      env.put(InitialContext.INITIAL_CONTEXT_FACTORY, "org.jnp.interfaces.NamingContextFactory");
      env.put(InitialContext.PROVIDER_URL,"jnp://machine2.mycompany.com:1099");
      env.put(InitialContext.URL_PKG_PREFIXES,"org.jboss.naming:org.jnp.interfaces");
      
      InitialContext context = new InitialContext(env);
      MyWorker myWorker = (MyWorker) context.lookup("MyWorkerBean/remote");


      Stack trace is:
      javax.naming.NameNotFoundException: MyWorkerBean not bound
       at org.jnp.server.NamingServer.getBinding(NamingServer.java:529)
       at org.jnp.server.NamingServer.getBinding(NamingServer.java:537)
       at org.jnp.server.NamingServer.getObject(NamingServer.java:543)
       at org.jnp.server.NamingServer.lookup(NamingServer.java:267)
       at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
       at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:39)
       at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:25)
       at java.lang.reflect.Method.invoke(Method.java:585)
       at sun.rmi.server.UnicastServerRef.dispatch(UnicastServerRef.java:294)
       at sun.rmi.transport.Transport$1.run(Transport.java:153)
       at java.security.AccessController.doPrivileged(Native Method)
       at sun.rmi.transport.Transport.serviceCall(Transport.java:149)
       at sun.rmi.transport.tcp.TCPTransport.handleMessages(TCPTransport.java:460)
       at sun.rmi.transport.tcp.TCPTransport$ConnectionHandler.run(TCPTransport.java:701)
       at java.lang.Thread.run(Thread.java:595)
       at sun.rmi.transport.StreamRemoteCall.exceptionReceivedFromServer(StreamRemoteCall.java:247)
       at sun.rmi.transport.StreamRemoteCall.executeCall(StreamRemoteCall.java:223)
       at sun.rmi.server.UnicastRef.invoke(UnicastRef.java:126)
       at org.jnp.server.NamingServer_Stub.lookup(Unknown Source)
       at org.jnp.interfaces.NamingContext.lookup(NamingContext.java:625)
       at org.jnp.interfaces.NamingContext.lookup(NamingContext.java:587)
       at javax.naming.InitialContext.lookup(InitialContext.java:351)
       at com.mycompany.client.MyWorkerBeanDelegate.<init>(MyWorkerBeanDelegate.java:43)
       at com.mycompany.client.Controller.doMyWorkerAction(Controller.java:289)
       at com.mycompany.client.Controller.doWorkPackage(Controller.java:167)
       at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
       at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:39)
       at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:25)
       at java.lang.reflect.Method.invoke(Method.java:585)
       at org.jboss.aop.joinpoint.MethodInvocation.invokeNext(MethodInvocation.java:112)
       at org.jboss.ejb3.interceptor.InvocationContextImpl.proceed(InvocationContextImpl.java:166)
       at org.jboss.ejb3.interceptor.EJB3InterceptorsInterceptor.invoke(EJB3InterceptorsInterceptor.java:63)
       at org.jboss.aop.joinpoint.MethodInvocation.invokeNext(MethodInvocation.java:101)
       at org.jboss.ejb3.entity.TransactionScopedEntityManagerInterceptor.invoke(TransactionScopedEntityManagerInterceptor.java:54)
       at org.jboss.aop.joinpoint.MethodInvocation.invokeNext(MethodInvocation.java:101)
       at org.jboss.ejb3.AllowedOperationsInterceptor.invoke(AllowedOperationsInterceptor.java:47)
       at org.jboss.aop.joinpoint.MethodInvocation.invokeNext(MethodInvocation.java:101)
       at org.jboss.aspects.tx.TxPolicy.invokeInCallerTx(TxPolicy.java:126)
       at org.jboss.aspects.tx.TxInterceptor$Required.invoke(TxInterceptor.java:201)
       at org.jboss.aop.joinpoint.MethodInvocation.invokeNext(MethodInvocation.java:101)
       at org.jboss.ejb3.stateless.StatelessInstanceInterceptor.invoke(StatelessInstanceInterceptor.java:62)
       at org.jboss.aop.joinpoint.MethodInvocation.invokeNext(MethodInvocation.java:101)
       at org.jboss.ejb3.mdb.ConsumerContainer.dynamicInvoke(ConsumerContainer.java:885)
       at org.jboss.ejb3.mdb.ConsumerContainer$MessageListenerImpl.onMessage(ConsumerContainer.java:1091)
       at org.jboss.jms.asf.StdServerSession.onMessage(StdServerSession.java:266)
       at org.jboss.mq.SpyMessageConsumer.sessionConsumerProcessMessage(SpyMessageConsumer.java:902)
       at org.jboss.mq.SpyMessageConsumer.addMessage(SpyMessageConsumer.java:170)
       at org.jboss.mq.SpySession.run(SpySession.java:323)
       at org.jboss.jms.asf.StdServerSession.run(StdServerSession.java:194)
       at EDU.oswego.cs.dl.util.concurrent.PooledExecutor$Worker.run(PooledExecutor.java:743)
       at java.lang.Thread.run(Thread.java:595)


      Many thanks in advance for your help.

      Heather

        • 1. Re: New EJB causes JNDI failure on existing EJB?
          jaikiran

          When is the lookup being done? Is it done when the server is starting up? Or is it after the deployment of your application has been done successfully?

          javax.naming.NameNotFoundException: MyWorkerBean not bound


          How are you packaging the application? Is it just a jar file or an ear? If it's an ear then you will have to prefix the name of the ear file to the JNDI name. For example, if your application is MyApp.ear and the bean implementation classname is MyWorkerBean and your are looking up the remote interface, then the default lookup string will be:
          MyWorker myWorker = (MyWorker) context.lookup("MyApp/MyWorkerBean/remote");


          And the most important thing to do when you run into a NameNotFoundException is to look at the JNDI tree through the jmx-console of JBoss. That will show you the exact lookup string you have to use. For more details, you can refer http://jaitechwriteups.blogspot.com/2007/10/why-do-i-get-namenotfoundexception.html

          • 2. Re: New EJB causes JNDI failure on existing EJB?
            hmccartney

            Thanks very much for your reply.

            The lookup is being done after the deployment of the application.

            Both applications on both machines are packaged as ears containing several ejb3 and jar files. So on machine 2 we have MyApp1.ear and MyApp2.ear. MyWorkerBean is in Worker.ejb3 inside MyApp1.ear.

            I should have said that in MyWorkerBean I have specified the JNDI name with:

            public @Stateless
            @TransactionAttribute(value = TransactionAttributeType.REQUIRES_NEW)
            @RemoteBinding(jndiBinding = "MyWorkerBean/remote")
            class MyWorkerBean implements MyWorker {


            Does the rule about prefixing the JNDI name with the name of the ear still apply in this case?

            I don't have access to the test system at the minute but I'll try using
            MyWorker myWorker = (MyWorker) context.lookup("MyApp1/MyWorkerBean/remote");

            instead as soon as I get the chance. I'll also double-check the JNDI tree in the JMX console.

            Thanks again for your suggestions.

            Heather





            • 3. Re: New EJB causes JNDI failure on existing EJB?
              jaikiran

               

              "hmccartney" wrote:

              I should have said that in MyWorkerBean I have specified the JNDI name with:
              public @Stateless
              @TransactionAttribute(value = TransactionAttributeType.REQUIRES_NEW)
              @RemoteBinding(jndiBinding = "MyWorkerBean/remote")
              class MyWorkerBean implements MyWorker {


              Does the rule about prefixing the JNDI name with the name of the ear still apply in this case?



              Well in that case, the prefix will not be added. So you should have been able to lookup using MyWorkerBean/remote jndi-name. I would check the jndi listing through the jmx-console to make sure the jndi-name of the bean.

              • 4. Re: New EJB causes JNDI failure on existing EJB?
                hmccartney

                I've managed to fix it, but I don't understand how!

                I mentioned before that application 2 on machine 2 contained a jndi.properties (to allow it to talk to machine 1). When I renamed this to application2.properties, the problem was solved.

                I can only assume that this jndi.properties in application 2 was preventing the ejbs in application 1 from making themselves available to JNDI.

                I don't quite understand why this should be. I could understand if application 1 wanted to do an outward JNDI lookup and read the jndi.properties in application 2 by mistake. But I don't understand why it should affect inward JNDI.

                If anyone is able to explain why a jndi.properties should have this kind of effect, I'd be interested to find out - but I'm just grateful it's fixed.

                Thanks Jaikiran for your help.

                Heather