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
  2. 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 { 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/ (application-policy name must be the same name as the one passed to the constructor of a LoginContext):

      <application-policy name = "tap_experiments">
                <login-module code = ""  flag = "required"></login-module>
    3. Pass the file to the JVM:
    4. Set a security manager by passing the following options to the JVM:"<jboss home>\server\default\conf\server.policy"
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 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
                //      Matches the java.naming.provider.url property in
                props.put(Context.PROVIDER_URL, "jnp://localhost:1099");
                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: " +;
                         } //*/

                        // 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:
                        //" 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 - use
                // and have  home>\server\default\lib\jbosssx.jar on the path (class ClientLoginModule)
                // Listing of sample_jaas.config:
                //      jboss_jaas { 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");

                // 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) {
                        } catch (CreateException e1) {

                // Log out
                if (loggedIn && loginContext != null) {
                        try {
                        } 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,
                                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

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

Published by Jakub Holý

I’m a JVM-based developer since 2005, consultant, and occasionally a project manager, working currently with Iterate AS in Norway.