2 Replies Latest reply on Feb 2, 2016 11:56 AM by quadrone

    Is it possible to selectively access EJBs on multiple EAP6 servers from a remote EAP6 client server?

    quadrone

      I have EJBs deployed in an ear that is deployed on multiple EAP 6.4 servers. Using the setup provided by EJB invocations from a Remote Server I am able to access EJBs, but the server upon which access is granted is random (I've since read that this is the default behavior). I tried to implement a scoped context following the example given at CustomScopedEJBContextSelector, but I'm getting an Error that says: EJB client context selector may not be changed. Is it possible to invoke an EJB on a server of my choosing in EAP 6.4? If so, is there configuration not mentioned in the article and example that I need to include? Or in the code below, is there an error I'm making?

       

      Method that gets the remote Interface

      public Object retrieveObjectJbossWay(Class<RemoteInterface> interfaceClazz,
                  Class<RemoteBean> beanClazz, String hostIp, String hostPort)
          {
      
              final String beanName = beanClazz.getSimpleName();
              final String viewClassName = interfaceClazz.getName();
              Object ourInterface = null;
              try
              {
                  ourInterface = ContextRegistrar.getContext()
                          .lookup("ejb:" + appName + "/" + moduleName + "/" + beanName + "!" + viewClassName);
                  ContextRegistrar.registerScope(hostIp, hostPort);
                  ContextRegistrar.getSelector().setScope(hostIp + hostPort);
              } catch (NamingException e)
              {
                  log.error("While trying to get context..." + e.toString() + StringUtil.loggableStackTrace(e));
              }
              return ourInterface;
          }
      
      

       

      Class for setting up custom selector and registering scoped context

      public class ContextRegistrar
      {
          private static final Context context;
          private static final CustomScopeEJBClientContextSelector selector = new CustomScopeEJBClientContextSelector();
      
          static
          {
              System.out.println("Inside ContextRegistrator static block...");
              Hashtable<String, String> p = new Hashtable<String, String>();
              p.put(InitialContext.URL_PKG_PREFIXES, "org.jboss.ejb.client.naming");
              try
              {
                  context = new InitialContext(p);
              } catch (NamingException e)
              {
                  throw new RuntimeException("Could not create InitialContext!", e);
              }
              EJBClientContext.setSelector(selector);
             
              System.out.println("The Custom selector was set");
          }
      
          public static void registerScope(String host, String port)
          {
              Properties p = new Properties();
              p.put("remote.connectionprovider.create.options.org.xnio.Options.SSL_ENABLED", "false");
              p.put("remote.connections", "default");
              p.put("remote.connection.default.port", port);
              p.put("remote.connection.default.host", host);
      
              p.put("remote.connection.default.username", "ejbuser");
              p.put("remote.connection.default.password", "ejbP@ssw0rd");
      
              selector.registerEJBClientContext(host+port, p);
          }
      
          public static Context getContext()
          {
              return context;
          }
      
         public static CustomScopeEJBClientContextSelector getSelector()
          {      
              return selector;
          }
      }
      
      

       

      The following exception is thrown at line 18 in the ContextRegistrar above:

      2016-01-22 16:34:20,310 SEVERE [com.vaadin.server.DefaultErrorHandler] (http-127.0.0.1/127.0.0.1:40000-2) : java.lang.ExceptionInInitializerError

          at com.csg.mpgconsole.utils.RemoteObjectRetriever.retrieveObjectJbossWay(RemoteObjectRetriever.java:135) [classes:]

          at com.csg.mpgconsole.remote.callers.RefreshApplication.refreshProperties(RefreshApplication.java:45) [classes:]

          at com.csg.mpgconsole.view.listeners.AppServerRefreshButtonClickListener.buttonClick(AppServerRefreshButtonClickListener.java:56) [classes:]

          at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method) [rt.jar:1.7.0_80]

          at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:57) [rt.jar:1.7.0_80]

          at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43) [rt.jar:1.7.0_80]

          at java.lang.reflect.Method.invoke(Method.java:606) [rt.jar:1.7.0_80]

          at com.vaadin.event.ListenerMethod.receiveEvent(ListenerMethod.java:508) [vaadin-server-7.5.3.jar:7.5.3]

          at com.vaadin.event.EventRouter.fireEvent(EventRouter.java:198) [vaadin-server-7.5.3.jar:7.5.3]

          at com.vaadin.event.EventRouter.fireEvent(EventRouter.java:161) [vaadin-server-7.5.3.jar:7.5.3]

          at com.vaadin.server.AbstractClientConnector.fireEvent(AbstractClientConnector.java:1003) [vaadin-server-7.5.3.jar:7.5.3]

          at com.vaadin.ui.Button.fireClick(Button.java:393) [vaadin-server-7.5.3.jar:7.5.3]

          at com.vaadin.ui.Button$1.click(Button.java:61) [vaadin-server-7.5.3.jar:7.5.3]

          at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method) [rt.jar:1.7.0_80]

          at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:57) [rt.jar:1.7.0_80]

          at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43) [rt.jar:1.7.0_80]

          at java.lang.reflect.Method.invoke(Method.java:606) [rt.jar:1.7.0_80]

          at com.vaadin.server.ServerRpcManager.applyInvocation(ServerRpcManager.java:158) [vaadin-server-7.5.3.jar:7.5.3]

          at com.vaadin.server.ServerRpcManager.applyInvocation(ServerRpcManager.java:118) [vaadin-server-7.5.3.jar:7.5.3]

          at com.vaadin.server.communication.ServerRpcHandler.handleInvocations(ServerRpcHandler.java:313) [vaadin-server-7.5.3.jar:7.5.3]

          at com.vaadin.server.communication.ServerRpcHandler.handleRpc(ServerRpcHandler.java:202) [vaadin-server-7.5.3.jar:7.5.3]

          at com.vaadin.server.communication.UidlRequestHandler.synchronizedHandleRequest(UidlRequestHandler.java:95) [vaadin-server-7.5.3.jar:7.5.3]

          at com.vaadin.server.SynchronizedRequestHandler.handleRequest(SynchronizedRequestHandler.java:41) [vaadin-server-7.5.3.jar:7.5.3]

          at com.vaadin.server.VaadinService.handleRequest(VaadinService.java:1408) [vaadin-server-7.5.3.jar:7.5.3]

          at com.vaadin.server.VaadinServlet.service(VaadinServlet.java:350) [vaadin-server-7.5.3.jar:7.5.3]

          at javax.servlet.http.HttpServlet.service(HttpServlet.java:847) [jboss-servlet-api_3.0_spec-1.0.2.Final-redhat-2.jar:1.0.2.Final-redhat-2]

          at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:295) [jbossweb-7.5.7.Final-redhat-1.jar:7.5.7.Final-redhat-1]

          at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:214) [jbossweb-7.5.7.Final-redhat-1.jar:7.5.7.Final-redhat-1]

          at org.apache.catalina.core.StandardWrapperValve.invoke(StandardWrapperValve.java:231) [jbossweb-7.5.7.Final-redhat-1.jar:7.5.7.Final-redhat-1]

          at org.apache.catalina.core.StandardContextValve.invoke(StandardContextValve.java:149) [jbossweb-7.5.7.Final-redhat-1.jar:7.5.7.Final-redhat-1]

          at org.jboss.as.web.security.SecurityContextAssociationValve.invoke(SecurityContextAssociationValve.java:169) [jboss-as-web-7.5.0.Final-redhat-21.jar:7.5.0.Final-redhat-21]

          at org.apache.catalina.core.StandardHostValve.invoke(StandardHostValve.java:150) [jbossweb-7.5.7.Final-redhat-1.jar:7.5.7.Final-redhat-1]

          at org.apache.catalina.valves.ErrorReportValve.invoke(ErrorReportValve.java:97) [jbossweb-7.5.7.Final-redhat-1.jar:7.5.7.Final-redhat-1]

          at org.apache.catalina.core.StandardEngineValve.invoke(StandardEngineValve.java:102) [jbossweb-7.5.7.Final-redhat-1.jar:7.5.7.Final-redhat-1]

          at org.apache.catalina.connector.CoyoteAdapter.service(CoyoteAdapter.java:344) [jbossweb-7.5.7.Final-redhat-1.jar:7.5.7.Final-redhat-1]

          at org.apache.coyote.http11.Http11Processor.process(Http11Processor.java:854) [jbossweb-7.5.7.Final-redhat-1.jar:7.5.7.Final-redhat-1]

          at org.apache.coyote.http11.Http11Protocol$Http11ConnectionHandler.process(Http11Protocol.java:653) [jbossweb-7.5.7.Final-redhat-1.jar:7.5.7.Final-redhat-1]

          at org.apache.tomcat.util.net.JIoEndpoint$Worker.run(JIoEndpoint.java:926) [jbossweb-7.5.7.Final-redhat-1.jar:7.5.7.Final-redhat-1]

          at java.lang.Thread.run(Thread.java:745) [rt.jar:1.7.0_80]

      Caused by: java.lang.SecurityException: EJBCLIENT000021: EJB client context selector may not be changed

          at org.jboss.ejb.client.EJBClientContext.setSelector(EJBClientContext.java:218) [jboss-ejb-client-1.0.30.Final-redhat-1.jar:1.0.30.Final-redhat-1]

          at com.csg.mpgconsole.utils.ContextRegistrar.<clinit>(ContextRegistrar.java:38) [classes:]

          ... 39 more

        • 1. Re: Is it possible to selectively access EJBs on multiple EAP6 servers from a remote EAP6 client server?
          wdfink

          It is not possible to change the EJBClientContext and its selector if you run inside of EAP.

          Also the ScopedSelector is special and will not work inside of EAP as the container will create that for you.

           

          So what you can do is to use a ScopedContext approach shown here jboss-eap-quickstarts/MainAppSContextBean.java at 6.3.x-develop · wfink/jboss-eap-quickstarts · GitHub

          The drawback here is that it will consume a lot of resources.

          Another option is to use the so called distinct name. the lookup will change like this:

                                     "ejb:" + appName + "/" + moduleName + "/" + distinctName + "/" + beanName + "!" + viewClassName);

          So you have all connections in parallel but the distinction between the different EJB applications.

          1 of 1 people found this helpful
          • 2. Re: Is it possible to selectively access EJBs on multiple EAP6 servers from a remote EAP6 client server?
            quadrone

            Thanks. I've tried the ScopedContext approach (code below) and I'm getting the dreaded "No EJB reciever available... " error even though I see the successful handshake take place. Any ideas on where I went wrong?

             

            BTW, I didn't try the distinct name approach because we have 72 instances running and, as I understand the documentation, I'd have to add a distinct jboss-ejb3.xml to the ejb jar of every deployed ear - a logistical nightmare. If my understanding isn't correct, please correct me.

             

            Method for Interface lookup

            private ContextRegistrar scope = new  ContextRegistrar();
            
            public Object retrieveObjectJbossWay2(Class<RemoteInterface> interfaceClazz, Class<RemoteBean> beanClazz, String hostIp, String hostPort)
            {
                    String remoteName = hostIp.replace(".", "-") + hostPort;
                    final String beanName = beanClazz.getSimpleName();
                    final String viewClassName = interfaceClazz.getName();
                    Object ourInterface = null;
                    try
                    {
                        InitialContext ic = null;
                        if(!scope.isContextRegistered(remoteName))
                        {
                            Properties ejbClientContextProps = new Properties();          
                            ejbClientContextProps.put("endpoint.name", remoteName);
                            ejbClientContextProps.put(Context.URL_PKG_PREFIXES, "org.jboss.ejb.client.naming");
                            ejbClientContextProps.put("org.jboss.ejb.client.scoped.context", "true");
                            ejbClientContextProps.put("remote.connectionprovider.create.options.org.xnio.Options.SSL_ENABLED", "false");
                            ejbClientContextProps.put("remote.connections",remoteName);
                            ejbClientContextProps.put("remote.connection." + remoteName + ".host",hostIp);
                            ejbClientContextProps.put("remote.connection." + remoteName + ".port",hostPort);
                            ejbClientContextProps.put("remote.connection." + remoteName + ".username", "ejbuser");
                            ejbClientContextProps.put("remote.connection." + remoteName + ".password", "ejbP@ssw0rd");
            
                            ic = new InitialContext(ejbClientContextProps);
                            scope.registerContext(remoteName, ic);
                        }else
                        {
                            ic = (InitialContext)scope.getContextMap().get(remoteName);
                        }
                        ourInterface = ic.lookup("ejb:" + appName + "/" + moduleName + "/" + beanName + "!" + viewClassName);
                    } catch (NamingException e)
                    {
                        log.error("While trying to get context..." + e.toString() + StringUtil.loggableStackTrace(e));
                    }
                    return ourInterface;
            }
            
            
            

             

            Class for holding onto context initializations

            public class ContextRegistrar
            {  
                //map for various looked up contexts
                private HashMap<String, Context> contextMap = new HashMap<String, Context>();
              
                /**
                 * Maps the context name to the context.
                 * @param name - name of the context
                 * @param ct - an initialized context
                 */
                public void registerContext(String name, Context ct)
                {
                    contextMap.put(name, ct);
                }
              
                public boolean isContextRegistered(String name)
                {
                    return contextMap.containsKey(name);
                }
            
                public HashMap<String, Context> getContextMap()
                {
                    return contextMap;
                }
            }
            
            
            

             

            Error

            2016-02-02 08:23:51,112 DEBUG [com.csg.mpgconsole.remote.callers.RefreshApplication] (http-127.0.0.1/127.0.0.1:40000-2) Remoting to 127.0.0.1 44452

            2016-02-02 08:23:51,202 INFO  [org.jboss.ejb.client.remoting] (Remoting "127-0-0-144452" task-5) EJBCLIENT000017: Received server version 2 and marshalling strategies [river]

            2016-02-02 08:23:51,210 INFO  [org.jboss.ejb.client.remoting] (http-127.0.0.1/127.0.0.1:40000-2) EJBCLIENT000013: Successful version handshake completed for receiver context EJBReceiverContext{clientContext=org.jboss.ejb.client.EJBClientContext@1d37aee, receiver=Remoting connection EJB receiver [connection=org.jboss.ejb.client.remoting.ConnectionPool$PooledConnection@12bb9d7,channel=jboss.ejb,nodename=master:MPG1]} on channel Channel ID 925515e0 (outbound) of Remoting connection 0060d956 to /127.0.0.1:44452

            2016-02-02 08:23:51,218 INFO  [org.jboss.ejb.client] (http-127.0.0.1/127.0.0.1:40000-2) JBoss EJB Client version 1.0.30.Final-redhat-1

            2016-02-02 08:23:51,222 DEBUG [com.csg.mpgconsole.remote.callers.RefreshApplication] (http-127.0.0.1/127.0.0.1:40000-2) Retrieved Remote Object

            2016-02-02 08:23:51,226 ERROR [com.csg.mpgconsole.view.listeners.AppServerRefreshButtonClickListener] (http-127.0.0.1/127.0.0.1:40000-2) java.lang.IllegalStateException: EJBCLIENT000025: No EJB receiver available for handling [appName:mpg-ear, moduleName:mpg-ejbs, distinctName:] combination for invocation context org.jboss.ejb.client.EJBClientInvocationContext@437803

            Details:EJBCLIENT000025: No EJB receiver available for handling [appName:mpg-ear, moduleName:mpg-ejbs, distinctName:] combination for invocation context org.jboss.ejb.client.EJBClientInvocationContext@437803

             

            Stack Trace:

              -->org.jboss.ejb.client.EJBClientContext.requireEJBReceiver(EJBClientContext.java:747)

              -->org.jboss.ejb.client.ReceiverInterceptor.handleInvocation(ReceiverInterceptor.java:116)

              -->org.jboss.ejb.client.EJBClientInvocationContext.sendRequest(EJBClientInvocationContext.java:186)

              -->org.jboss.ejb.client.EJBInvocationHandler.sendRequestWithPossibleRetries(EJBInvocationHandler.java:255)

              -->org.jboss.ejb.client.EJBInvocationHandler.doInvoke(EJBInvocationHandler.java:200)

              -->org.jboss.ejb.client.EJBInvocationHandler.doInvoke(EJBInvocationHandler.java:183)

              -->org.jboss.ejb.client.EJBInvocationHandler.invoke(EJBInvocationHandler.java:146)

              -->com.sun.proxy.$Proxy21.refreshAppProperties(Unknown Source)

              -->com.csg.mpgconsole.remote.callers.RefreshApplication.refreshProperties(RefreshApplication.java:53)

              -->com.csg.mpgconsole.view.listeners.AppServerRefreshButtonClickListener.buttonClick(AppServerRefreshButtonClickListener.java:56)

              -->sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)

              -->sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:57)

              -->sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)

              -->java.lang.reflect.Method.invoke(Method.java:606)

              -->com.vaadin.event.ListenerMethod.receiveEvent(ListenerMethod.java:508)

              -->com.vaadin.event.EventRouter.fireEvent(EventRouter.java:198)

              -->com.vaadin.event.EventRouter.fireEvent(EventRouter.java:161)

              -->com.vaadin.server.AbstractClientConnector.fireEvent(AbstractClientConnector.java:1003)

              -->com.vaadin.ui.Button.fireClick(Button.java:393)

              -->com.vaadin.ui.Button$1.click(Button.java:61)

              -->sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)

              -->sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:57)

              -->sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)

              -->java.lang.reflect.Method.invoke(Method.java:606)

              -->com.vaadin.server.ServerRpcManager.applyInvocation(ServerRpcManager.java:158)

              -->com.vaadin.server.ServerRpcManager.applyInvocation(ServerRpcManager.java:118)

              -->com.vaadin.server.communication.ServerRpcHandler.handleInvocations(ServerRpcHandler.java:313)

              -->com.vaadin.server.communication.ServerRpcHandler.handleRpc(ServerRpcHandler.java:202)

              -->com.vaadin.server.communication.UidlRequestHandler.synchronizedHandleRequest(UidlRequestHandler.java:95)

              -->com.vaadin.server.SynchronizedRequestHandler.handleRequest(SynchronizedRequestHandler.java:41)

              -->com.vaadin.server.VaadinService.handleRequest(VaadinService.java:1408)

              -->com.vaadin.server.VaadinServlet.service(VaadinServlet.java:350)

              -->javax.servlet.http.HttpServlet.service(HttpServlet.java:847)

              -->org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:295)

              -->org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:214)

              -->org.apache.catalina.core.StandardWrapperValve.invoke(StandardWrapperValve.java:231)

              -->org.apache.catalina.core.StandardContextValve.invoke(StandardContextValve.java:149)

              -->org.jboss.as.web.security.SecurityContextAssociationValve.invoke(SecurityContextAssociationValve.java:169)

              -->org.apache.catalina.core.StandardHostValve.invoke(StandardHostValve.java:150)

              -->org.apache.catalina.valves.ErrorReportValve.invoke(ErrorReportValve.java:97)

              -->org.apache.catalina.core.StandardEngineValve.invoke(StandardEngineValve.java:102)

              -->org.apache.catalina.connector.CoyoteAdapter.service(CoyoteAdapter.java:344)

              -->org.apache.coyote.http11.Http11Processor.process(Http11Processor.java:854)

              -->org.apache.coyote.http11.Http11Protocol$Http11ConnectionHandler.process(Http11Protocol.java:653)

              -->org.apache.tomcat.util.net.JIoEndpoint$Worker.run(JIoEndpoint.java:926)

              -->java.lang.Thread.run(Thread.java:745)