I'm using WildFly 8.1.0 Final release.
My application is a JavaEE web app deployed in a WAR (there is no EJB module .ear).
I want to programmatically invoke local EJB with his name using JNDI.
The EJB are just annotated with @Stateless (there is no Local or Remote interfaces)
I try below function:
private <E extends DomainObject> CrudService<E> lookUp(Class<E> cl) {
try {
final Hashtable jndiProperties = new Hashtable();
jndiProperties.put(Context.URL_PKG_PREFIXES, "org.jboss.ejb.client.naming");
final Context context = new InitialContext(jndiProperties);
// The app name is the application name of the deployed EJBs. This is typically the ear name
// without the .ear suffix. However, the application name could be overridden in the application.xml of the
// EJB deployment on the server.
// Since we haven't deployed the application as a .ear, the app name for us will be an empty string
final String appName = "";
// This is the module name of the deployed EJBs on the server. This is typically the jar name of the
// EJB deployment, without the .jar suffix, but can be overridden via the ejb-jar.xml
// In this example, we have deployed the EJBs in a jboss-as-ejb-remote-app.jar, so the module name is
// jboss-as-ejb-remote-app
final String moduleName = "jboss-as-ejb-remote-app";
// AS7 allows each deployment to have an (optional) distinct name. We haven't specified a distinct name for
// our EJB deployment, so this is an empty string
final String distinctName = "";
// The EJB name which by default is the simple class name of the bean implementation class
final String serviceName = cl.getSimpleName() + "Service";
// let's do the lookup
return (CrudService<E>) context.lookup("ejb:" + appName + "/" + moduleName + "/" + distinctName + "/" + serviceName );
//return (CrudService<E>) context.lookup(serviceName);
} catch (NamingException e) {
log.error("NamingException {}",e) ;
throw new RuntimeException(e) ;
}
}
but it doesn't work (obviusly it's for remote EJB)
But I don't find any example for local EJB in a WAR with WildFly and I have no idea how to do, I don't use JNDI often...
I found a work arround annotating EJB with @Named(value="EjbClassName") and invoke them using JSF.
FacesContext context = FacesContext.getCurrentInstance() ;
return context.getApplication().evaluateExpressionGet(context, "#{"+cl.getSimpleName()+"Service}", CrudService.class) ;
And it's working,
but I'd prefer not using JSF as it's not related to the view layer.
Thank you Yamada the JNDI names appear in the server logs at startup
this solution works:
private <E extends DomainObject> CrudService<E> lookUp(@NonNull Class<E> entityClass) throws NamingException {
try {
final Hashtable jndiProperties = new Hashtable();
jndiProperties.put(Context.URL_PKG_PREFIXES, "org.jboss.ejb.client.naming");
final Context context = new InitialContext(jndiProperties);
return (CrudService<E>) context.lookup("java:module/"+entityClass.getSimpleName()+"Service");
} catch (NamingException e) {
log.error("lookUp({}) throws NamingException {}",entityClass.getSimpleName(),e.getMessage()) ;
throw e ;
}
}
without annotate EJB with @LocalBean