Wildfly to Wildfly EJB client without remote-outbo

2019-02-20 14:42发布

问题:

I'd like to be able to have two Wildfly (or JBoss 7) instances where one of the servers talks to EJBs on the other server. The tricky part is that according to documentation, remote-outbound-connections with outbound-socket-bindings need to be created. This is a big hassle for our Operations team, especially when we want to scale out.

Is there any way for a Wildfly instance to call EJB's on another Wildfly instance by programmatically specifying the remote host?

I've been able to have Tomcat 7 invoke Wildfly EJB's. I added a Maven dependency on org.jboss.as:jboss-as-ejb-client-bom:7.5.0.Final-redhat-21 and set up connection settings according to this documentation.

Thanks!

EDIT

When I try the same code that worked in Tomcat 7 (which uses the jboss-ejb-client library), I get the error EJBCLIENT000021: EJB client context selector may not be changed when my code tries to do EJBClientContext.setSelector( selector ). I am setting the remote connection host and port programmatically instead of using jboss-ejb-client.properties.

回答1:

jgitter's answer got me most of the way there. Here's what I ended up with:

  /**
   * @return a reference to the EJB
   * @throws EjbLookupException
   */
  @NotNull
  public T lookup ()
     throws EjbLookupException
  {
     String path = createJndiPath();
     Context initialContext = null;
     try
     {
        initialContext = createInitialContext();

        //noinspection unchecked
        final T ejb = (T)initialContext.lookup( path );

        if( m_apiVersion != null )
        {
           ( (RemoteAPI)ejb ).validateClientCompatibility( m_apiVersion );
        }

        return ejb;
     }
     catch( NamingException | RuntimeException e )
     {
        throw new EjbLookupException( "Unable to find the JBoss EJB at " + path, e );
     }
     finally
     {
        if( initialContext != null )
        {
           //noinspection ThrowableResultOfMethodCallIgnored
           Closer.close( initialContext );
        }
     }
  }

  /**
   * There are a lot of ways to do JBoss 7 / Wildfly EJB lookups.  Using this method, we don't have to create
   * outbound socket bindings whenever we want to use a remote EJB.
   *
   * @throws NamingException
   */
  @NotNull
  private Context createInitialContext ()
     throws NamingException
  {
     Properties properties = new Properties();

     properties.put( Context.URL_PKG_PREFIXES, "org.jboss.ejb.client.naming" );
     properties.put( "org.jboss.ejb.client.scoped.context", "true" );
     properties.put( "remote.connectionprovider.create.options.org.xnio.Options.SSL_ENABLED", "false" );
     properties.put( "remote.connection.default.connect.options.org.xnio.Options.SASL_POLICY_NOANONYMOUS", "false" );
     properties.put( "remote.connections", "default" );

     properties.put( "remote.connection.default.host", m_host );
     properties.put( "remote.connection.default.port", String.valueOf( m_port ) );

     if( m_username != null )
     {
        properties.put( "remote.connection.default.username", m_username );
     }
     if( m_password != null )
     {
        properties.put( "remote.connection.default.password", m_password );
     }

     return new InitialContext( properties );
  }

  public static class EjbLookupException
     extends Exception
  {
     EjbLookupException (
        @NotNull String message,
        @NotNull Throwable cause )
     {
        super( message, cause );
     }
  }

I'm not sure if I need a scoped context, and I may not be closing the connection properly. I'll update this answer based on what I find out.



回答2:

You don't have to use the remote-outbound-connection. You can just write the code as though you were any external client. See: https://docs.jboss.org/author/display/WFLY9/EJB+invocations+from+a+remote+client+using+JNDI.