5 Replies Latest reply on Aug 10, 2018 8:41 PM by mevans7

    EJB call from one EAR to another EAR, local or remote?

    mevans7

      We deploy multiple EAR and WAR files in WildFly 10 (and soon upgrading to WildFly 12).

       

      Should I be able to make local EJB calls from one EAR/WAR to another EAR, or do these calls have to be remote?

       

      My experience is that I can make remote calls, but if I'm in two way SSL/TLS mode, then I need to define my client certificates (e.g., modify standalone.sh to include -Djavax.net.ssl.keyStore parameters) which is not great.

       

      Also, if I make local calls, I get class cast exceptions unless I move my interface to a separate jar (during which I CAN make local calls).

       

      For example:

       

      Bean:

      @Stateless

      @Local ({TestLocal.class})

      @Remote ({TestRemote.class})

      public class TestBean implements TestLocal, TestRemote {

      ...

      }

       

      Local:

      @Local

      public interface TestLocal extends Test {

      }

       

      Remote:

      @Remote

      public interface TestRemote extends Test {

      }

       

      Interface:

      public interface Test {

          public String getRandomString();

      }

       

      If I put the Test interface in the same jar as the local and remote interfaces, I get class cast exception trying to cast the returned interface to Test.  If I put the Test interface in a separate JAR, then I'm able to make local EJB calls from one EAR/WAR to another EAR.

       

          InitialContext ic = new InitialContext();

          Test test = (Test) ic.lookup("java:global/MorphoBIS/TestEJB/TestBean!com.printrak.test.ejb.TestLocal"); // Exception if Test is in same jar as TestLocal and TestRemote.  No exception if in a different jar.

        • 1. Re: EJB call from one EAR to another EAR, local or remote?
          dmlloyd

          As you've discovered, you'll be facing ClassCastExceptions if you try to make local invocations between two application modules which have different copies of the classes in question.  You should probably use remote invocation for this unless you're ready to restructure things.  The good news though is that in-VM remote EJB invocation is very optimized so that no network connection should be necessary.  This means you don't have to worry about TLS or network latency.

          • 2. Re: EJB call from one EAR to another EAR, local or remote?
            mevans7

            I can use remote interface calls.  But I'm left with the problem that in a two way SSL/TLS configuration, WildFly 12 requires the client certificate in order to access the "remove" (yet local) EJB.  This behavior is different than from WildFly 10.  I was hoping that these calls would be considered "local" internally and not require the client keys.

             

            How can I make remote EJB calls from one EE application to another (deployed in the same server) without having to supply a client private key certificate to WildFly 12?

            • 3. Re: EJB call from one EAR to another EAR, local or remote?
              dmlloyd

              That sounds very odd, like either there is some configuration problem or a bug.  Or both.  You should not need a client certificate in order to call an EJB on the same JVM.

              • 4. Re: EJB call from one EAR to another EAR, local or remote?
                mevans7

                I re-tested two way SSL/TLS in WildFly 12 to be sure of the failure.  If I don't have client certificates defined in standalone.sh, and I have one EJB call another via remote interface, I get the following exception:

                 

                2018-05-23 16:48:28,628 ERROR [org.jboss.as.ejb3.invocation] (default task-5) WFLYEJB0034: EJB Invocation failed on component MyFirstBean for method ... java.rmi.RemoteException: org.jboss.ejb.client.RequestSendFailedException: EJBCLIENT000409: No more destinations are available

                        at org.jboss.ejb.client.EJBClientInvocationContext.getResult(EJBClientInvocationContext.java:567) [jboss-ejb-client-4.0.9.Final.jar:4.0.9.Final]

                        at org.jboss.ejb.client.EJBClientInvocationContext.getResult(EJBClientInvocationContext.java:503) [jboss-ejb-client-4.0.9.Final.jar:4.0.9.Final]

                        at org.jboss.ejb.protocol.remote.RemotingEJBClientInterceptor.handleInvocationResult(RemotingEJBClientInterceptor.java:56) [jboss-ejb-client-4.0.9.Final.jar:4.0.9.Final]

                        at org.jboss.ejb.client.EJBClientInvocationContext.getResult(EJBClientInvocationContext.java:569) [jboss-ejb-client-4.0.9.Final.jar:4.0.9.Final]

                        at org.jboss.ejb.client.EJBClientInvocationContext.getResult(EJBClientInvocationContext.java:503) [jboss-ejb-client-4.0.9.Final.jar:4.0.9.Final]

                        at org.jboss.ejb.client.TransactionPostDiscoveryInterceptor.handleInvocationResult(TransactionPostDiscoveryInterceptor.java:133) [jboss-ejb-client-4.0.9.Final.jar:4.0.9.Final]

                        at org.jboss.ejb.client.EJBClientInvocationContext.getResult(EJBClientInvocationContext.java:569) [jboss-ejb-client-4.0.9.Final.jar:4.0.9.Final]

                        at org.jboss.ejb.client.EJBClientInvocationContext.getResult(EJBClientInvocationContext.java:503) [jboss-ejb-client-4.0.9.Final.jar:4.0.9.Final]

                        at org.jboss.ejb.client.DiscoveryEJBClientInterceptor.handleInvocationResult(DiscoveryEJBClientInterceptor.java:108) [jboss-ejb-client-4.0.9.Final.jar:4.0.9.Final]

                        at org.jboss.ejb.client.EJBClientInvocationContext.getResult(EJBClientInvocationContext.java:569) [jboss-ejb-client-4.0.9.Final.jar:4.0.9.Final]

                        at org.jboss.ejb.client.EJBClientInvocationContext.getResult(EJBClientInvocationContext.java:503) [jboss-ejb-client-4.0.9.Final.jar:4.0.9.Final]

                        at org.jboss.ejb.client.NamingEJBClientInterceptor.handleInvocationResult(NamingEJBClientInterceptor.java:78) [jboss-ejb-client-4.0.9.Final.jar:4.0.9.Final]

                        at org.jboss.ejb.client.EJBClientInvocationContext.getResult(EJBClientInvocationContext.java:569) [jboss-ejb-client-4.0.9.Final.jar:4.0.9.Final]

                        at org.jboss.ejb.client.EJBClientInvocationContext.getResult(EJBClientInvocationContext.java:503) [jboss-ejb-client-4.0.9.Final.jar:4.0.9.Final]

                        at org.jboss.ejb.client.TransactionInterceptor.handleInvocationResult(TransactionInterceptor.java:172) [jboss-ejb-client-4.0.9.Final.jar:4.0.9.Final]

                        at org.jboss.ejb.client.EJBClientInvocationContext.getResult(EJBClientInvocationContext.java:569) [jboss-ejb-client-4.0.9.Final.jar:4.0.9.Final]

                        at org.jboss.ejb.client.EJBClientInvocationContext.getResult(EJBClientInvocationContext.java:503) [jboss-ejb-client-4.0.9.Final.jar:4.0.9.Final]

                        at org.jboss.ejb.client.EJBClientInvocationContext.awaitResponse(EJBClientInvocationContext.java:913) [jboss-ejb-client-4.0.9.Final.jar:4.0.9.Final]

                        at org.jboss.ejb.client.EJBInvocationHandler.invoke(EJBInvocationHandler.java:177) [jboss-ejb-client-4.0.9.Final.jar:4.0.9.Final]

                        at org.jboss.ejb.client.EJBInvocationHandler.invoke(EJBInvocationHandler.java:112) [jboss-ejb-client-4.0.9.Final.jar:4.0.9.Final]

                        at com.sun.proxy.$Proxy128.amethod(Unknown Source)

                        at com.mycompany.mymethod(MyFile.java:197) [MyJar.jar:]

                 

                If I add -Djavax.net.ssl.keystore=/my-client.keystore, and -Djavax.net.ssl.keyStorePassword=my-password to the standalone.sh file (on the lines where the eval \"$JAVA\"... are, then the remote EJB methods get executed just fine.

                 

                (For both tests) I configure two way SSL/TLS by adding the following in my equivalent of standalone-full.xml:

                 

                            <security-realm name="MYRealm">

                                <server-identities>

                                    <ssl>

                                        <keystore path="server.keystore" relative-to="jboss.server.config.dir" keystore-password="my-password" alias="my-alias" key-password="my-password"/>

                                    </ssl>

                                </server-identities>

                                <authentication>

                                    <truststore path="server.truststore" relative-to="jboss.server.config.dir" keystore-password="my-password"/>

                                    <jaas name="my-security-domain"/>

                                </authentication>

                            </security-realm>

                ...

                                <https-listener name="https" disallowed-methods="TRACE DUMMY" max-post-size="104857600" enabled-protocols="TLSv1.2" verify-client="REQUIRED" security-realm="MYRealm" socket-binding="https"/>

                 

                The remote EJB calls work on WildFly 10 without having to add the keystores to the standalone.sh file.

                 

                Am I configuring something incorrectly?

                • 5. Re: EJB call from one EAR to another EAR, local or remote?
                  mevans7

                  Does anyone have any comments with respect to using two way SSL/TLS with application to application EJB calls?

                   

                  My scenario is above.  I have in ejb3:

                   

                  <remote connector-ref="http-remoting-connector" thread-pool-name="default"/>

                   

                  In remoting:

                   

                  <http-connector name="http-remoting-connector" connector-ref="https"/>

                   

                  In undertow:

                   

                  <https-listener name="https" socket-binding="https" max-post-size="104857600" disallowed-methods="TRACE" ssl-context="https-two-way-server-ssl-context"/>

                   

                  And the ssl-context is configured with a key-manager and a trust-manager.

                   

                  This results in an error when calling an EJB from and in-WildFly deployed application (remote because calling application is deployed in a different war/ear).

                   

                  If I add the -Djavax.net.ssl.* values to standalone.sh, then the error goes away.

                   

                  How can I secure my server with SSL yet not have to secure in-server cross-deployment EJB calls?  Or, can I have two separate connections (EJB receivers?  listeners? other?), one for internal and one for external?