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.