Saturday, December 28, 2013

WildFly: EJB invocations from a remote client

Currently I am experimenting with Java EE7 and I have chosen WildFly as my application server. So far everything is working fine, the WebService, EJB 3.2 etc until today when I tried to access my EJB from a client application - jUnit Test.
To solve the issue initially I followed the instruction given in WildFly documentation EJB invocations from a remote client using JNDI, but it is not what I needed. After spending almost half a day at last I achieved what I wanted.

Prerequisite:

  • You need to have an Application User. Follow the instruction given in Add User Utility.
  • I am running my server with the parameter -b 0.0.0.0 --server-config standalone-full.xml
  • jboss-client.jar in your classpath, which can be found inside the /bin/client directory of the server.
Following is the piece of code which you need to access the EJB:

import java.util.Properties;

import javax.naming.Context;
import javax.naming.InitialContext;
import javax.naming.NamingException;

import org.jboss.ejb.client.EJBClient;
import org.jboss.ejb.client.EJBClientContext;
import org.jboss.ejb.client.PropertiesBasedEJBClientConfiguration;
import org.jboss.ejb.client.StatelessEJBLocator;
import org.jboss.ejb.client.remoting.ConfigBasedEJBClientContextSelector;

/**
 * Class EJBLocator is the class to connect with EJB
 * 
 * @author Tapas Bose
 * @since 1.0
 */
public class EJBLocator {

 /**
  * Method locateEJB locates an EJB for the given jndi
  * 
  * @author Tapas Bose
  * @since 1.0
  * @param jndi
  *            - the jndi to lookup
  * @return an instance of EJB
  * @throws NamingException
  */
 @SuppressWarnings("unchecked")
 public static <T> T locateEJB(String jndi) throws NamingException {
  Properties clientProperties = new Properties();
  clientProperties.put("remote.connectionprovider.create.options.org.xnio.Options.SSL_ENABLED", "false");
  clientProperties.put("remote.connections", "default");
  clientProperties.put("remote.connection.default.port", myPort);
  clientProperties.put("remote.connection.default.host", myHost);
  clientProperties.put("remote.connection.default.username", myUser);
  clientProperties.put("remote.connection.default.password", myPassword);
  clientProperties.put("remote.connection.default.connect.options.org.xnio.Options.SASL_POLICY_NOANONYMOUS", "false");

  EJBClientContext.setSelector(new ConfigBasedEJBClientContextSelector(new PropertiesBasedEJBClientConfiguration(clientProperties)));

  Properties properties = new Properties();
  properties.put(Context.URL_PKG_PREFIXES, "org.jboss.ejb.client.naming");
  Context context = new InitialContext(properties);
  return (T) context.lookup(jndi);
 }

 /**
  * Method locateEJBStateless locates an Stateless EJB for the given parameters
  * 
  * @author Tapas Bose
  * @since 1.0
  * @param viewType
  *            - the view type
  * @param appName
  *            - the application name
  * @param moduleName
  *            - the module name
  * @param beanName
  *            - the bean name
  * @param distinctName
  *            - the distinct name
  * @return an instance of EJB
  */
 public static <T> T locateEJBStateless(Class<T> viewType, String appName, String moduleName, String beanName, String distinctName) {
  Properties properties = new Properties();

  properties.put("endpoint.name", "client-endpoint");
  properties.put("remote.connectionprovider.create.options.org.xnio.Options.SSL_ENABLED", "false");
  properties.put("remote.connections", "default");
  properties.put("remote.connection.default.port", myPort);
  properties.put("remote.connection.default.host", myHost);
  properties.put("remote.connection.default.username", myUser);
  properties.put("remote.connection.default.password", myPassword);
  properties.put("remote.connection.default.connect.options.org.xnio.Options.SASL_POLICY_NOANONYMOUS", "false");

  EJBClientContext.setSelector(new ConfigBasedEJBClientContextSelector(new PropertiesBasedEJBClientConfiguration(properties)));
  StatelessEJBLocator<T> locator = new StatelessEJBLocator<T>(viewType, appName, moduleName, beanName, distinctName);
  T ejb = EJBClient.createProxy(locator);
  return ejb;
 }
}

Use this class as:
YourService service = EJBLocator.locateEJB(jndi);
//where the jndi is of the form ejb:<app-name>/<module-name>/<distinct-name>/<bean-name>!<fully-qualified-classname-of-the-remote-interface>
Or by:
YourServic service = EJBLocator.locateEJBStateless(YourServic.class, "appName", "moduleName", "YourServicImpl", "distinctName");
Hope it will help.

No comments:

Post a Comment

Note: Only a member of this blog may post a comment.