Access EJB on JBoss from outside

How to acces an enterprise java bean (EJB) running on JBoss from a standalone application running outside JBoss?



  1. In the code you must, among others:



    1. Set properties for a naming context and create one to be able to look the EJB up


  2. Authenticate by JBoss by means of JAAS
  3. To run the application:



    1. Set the classpath (-cp ...): it must contain jbosssx.jar (ClientLoginModule), jboss-common.jar and jnpserver.jar (naming stuff) from <jboss home>/server/default/lib


    2. Create the JAAS configuration file sample_jaas.config containing:
      jboss_jaas { org.jboss.security.ClientLoginModule required; };
      


      If you ever wanted to run the application from JBoss, replace the JAAS config file by the following entry in <JBoss home>/server/default/conf/login-config.ml (application-policy name must be the same name as the one passed to the constructor of a LoginContext):
      <application-policy name = "tap_experiments">
             <authentication>
                <login-module code = "org.jboss.security.ClientLoginModule"  flag = "required"></login-module>
             </authentication>
          </application-policy>
      


    3. Pass the file to the JVM: -Djava.security.auth.login.config=sample_jaas.config


    4. Set a security manager by passing the following options to the JVM: -Djava.security.manager -Djava.security.policy="<jboss home>\server\default\conf\server.policy"
    5. import java.rmi.RemoteException;
      import java.util.Properties;

      import javax.ejb.CreateException; import javax.naming.Context; import javax.naming.InitialContext; import javax.naming.NamingException; import javax.rmi.PortableRemoteObject; import javax.security.auth.callback.Callback; import javax.security.auth.callback.CallbackHandler; import javax.security.auth.callback.NameCallback; import javax.security.auth.callback.PasswordCallback; import javax.security.auth.callback.UnsupportedCallbackException; import javax.security.auth.login.LoginContext; import javax.security.auth.login.LoginException;

      import com.teradata.tap.system.query.ejb.QueryEngineRemote; import com.teradata.tap.system.query.ejb.QueryEngineRemoteHome;

      /** * Call a business method of an EJB running on JBoss */public class ExternalCallEjbSample {

      public static void main(String[] args) {// 1: Get the naming Context// Required JARs (in jboss/server/default/lib): jboss-common.jar, jnpserver.jar Properties props = new Properties(); // Matches the java.naming.factory.initial property in jndi.properties props.put(Context.INITIAL_CONTEXT_FACTORY, "org.jnp.interfaces.NamingContextFactory"); // Matches the java.naming.provider.url property in jndi.properties props.put(Context.PROVIDER_URL, "jnp://localhost:1099"); props.put(Context.URL_PKG_PREFIXES, "org.jboss.naming:org.jnp.interfaces"); QueryEngineRemoteHome queryEngineHome = null;

      try {

      Context ctx = new InitialContext(props);

      /*/ Print all entries in the JNDI NamingEnumeration ne = ctx.list("java:"); while (ne.hasMore()) { System.out.println("A: " + ne.next().toString()); } //*/

      // Look up and instantiate the home interface of the EJB// IMPORTANT: It fails if no SecurityManager specified for RMI class loader will be disabled// -> add these options to the JVM:// -Djava.security.manager -Djava.security.policy=" home>\server\default\conf\server.policy" String beanName = QueryEngineRemoteHome.JNDI_NAME; System.out.println("Looking up '" + beanName + "'"); Object lookup = ctx.lookup(beanName);

      queryEngineHome = (QueryEngineRemoteHome) PortableRemoteObject .narrow(lookup, QueryEngineRemoteHome.class);

      } catch (NamingException e) { System.out.println("new InitialContext failed:" + e); }

      // 2. Instantiate the (remote) EJB and call its business method(s)// 2.1 I have to authenticate unless security allows anybody to call create on the EJB// Otherwise an EJBException: checkSecurityAssociation will be thrown.// TODO: JVM option -Djava.security.auth.login.config==sample_jaas.config - use org.jboss.security.ClientLoginModule// and have home>\server\default\lib\jbosssx.jar on the path (class ClientLoginModule)// Listing of sample_jaas.config:// jboss_jaas { org.jboss.security.ClientLoginModule required debug=true; }; LoginContext loginContext = null; boolean loggedIn = false; try { CallbackHandler handler = new MyPresetCallbackHandler("tapdev","tapdev"); // jboss_jaas - name of a configuration in the jaas config file loginContext = new LoginContext("jboss_jaas", handler); System.out.println("Created LoginContext"); loginContext.login(); // throws LoginException System.out.println("Logged in."); loggedIn = true; } catch (LoginException le) { System.out.println("Login failed"); le.printStackTrace(); }

      // Create & use the EJB:if (loggedIn && queryEngineHome != null) {try { QueryEngineRemote queryEngine = queryEngineHome.create(); System.out.println("queryEngine remote created."); // TODO: call business method(s)} catch (RemoteException e1) { e1.printStackTrace(); } catch (CreateException e1) { e1.printStackTrace(); }}

      // Log outif (loggedIn && loginContext != null) {try { loginContext.logout(); } catch (LoginException e) { System.out.println("Logout failed:" + e); }}

      System.out.println("## DONE! ##"); } // main

      /** Authentication CallbackHandler with preset username/password. */static class MyPresetCallbackHandler implements CallbackHandler { String username;

      char[] password;

      public MyPresetCallbackHandler(String username, String password) {this.username = username; this.password = password.toCharArray(); }

      public void handle(Callback[] callbacks) throws java.io.IOException, UnsupportedCallbackException {for (int i = 0; i < callbacks.length; i++) { Callback callback = callbacks[i]; if (callback instanceof NameCallback) { ((NameCallback) callback).setName(username); } else if (callback instanceof PasswordCallback) { ((PasswordCallback) callback).setPassword(password); } else {throw new UnsupportedCallbackException(callback, "Unrecognized Callback"); }}}// handle }// MyPresetCallbackHandler}

      See EjbLocator.java and EjbLocatorException.java. With them, you can replace all above with QueryEngineRemote queryEngine = (QueryEngineRemote) EjbLocator.getInstance().locate( QueryEngineRemoteHome.JNDI_NAME );


      Tags: java


      Copyright © 2024 Jakub Holý
      Powered by Cryogen
      Theme by KingMob