Lookup an EJB Implementation by jndi name - ejb

I am new to the jndi namespace and I am trying to lookup my EJB class from a service class through below code
InitialContext ctx;
try {
ctx = new InitialContext();
ctx.lookup("?????");
} catch (NamingException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
But I really don't have any clue what to put inside lookup. I know that jndi name goes there. But from where can I get the jndi name for my ejb class. I am new to this thing and really can't devote much time in learning JNDI.

Refer server log file. When EJb beans are deployed. It looks something like this
JNDI bindings for session bean named SampleImpl in deployment unit subdeployment "sample-web-1.0.0.war" of deployment "xyz.ear" are as follows:
Sample code to lookup an EJB bean.
final Hashtable jndiProperties = new Hashtable();
jndiProperties.put(Context.URL_PKG_PREFIXES, "org.jboss.ejb.client.naming");
final Context context = new InitialContext(jndiProperties);
SampleIf sif = (SampleEJBIf) context.lookup("java:app/sample-ejb-1.0-SNAPSHOT/SampleImpl");
Other ways to define Lookup path
java:global/pms/pms-web-1.0.0/SampleClass!com.etipl.pms.x12.SampleClass
java:app/pms-web-1.0.0/SampleClass!com.etipl.pms.x12.SampleClass
java:module/SampleClass!com.etipl.pms.x12.SampleClass
java:global/pms/pms-web-1.0.0/SampleClass
java:app/pms-web-1.0.0/SampleClass
java:module/SampleClass

Related

Can't use a session ejb in my managed bean cause i get a Null Pointer Exception

First of all I want to say I'm pretty new in programming with ejb and jsf, and I'm trying to complete a project started by a friend of mine.
I'm getting a NullPointerException caused by the invoke of the method utenteSessionBean.CheckUtentebyId(username) of the session bean object called utenteSessionBean, declared inside the managed bean called Neo4jMBean.
I learned that it's not necessary creating and initializing a session bean (as you must do with a normal java object) in managed bean, but it's enough declaring it.
Here is the code of the session bean, which retrieves data from a DB
#Stateless
#LocalBean
public class UtenteSessionBean {
EntityManagerFactory emf = Persistence.createEntityManagerFactory("EnterpriseApplication2-ejbPU");
public boolean CheckUtentebyId(String username){
EntityManager em = emf.createEntityManager();
Query query = em.createNamedQuery("Utente.findByUsername");
query.setParameter("username", username);
List<Utente> Res=query.getResultList();
//completare funzione ctrl+spazio
System.out.println("pre");
System.out.println("pre"+Res.isEmpty());
em.close();
System.out.println("post");
System.out.println("post"+Res.isEmpty());
if(Res.size()>=1)
{
return true;
}
else
{
return false;
}
}
}
Here's the code of the managed bean:
#ManagedBean
#ViewScoped
public class Neo4jMBean {
#EJB
private UtenteSessionBean utenteSessionBean;
static String SERVER_ROOT_URI = "http://localhost:7474/db/data/";
public Neo4jMBean() {
}
public boolean getUser(String username) {
return utenteSessionBean.CheckUtentebyId(username);
}
}
I've searched on StackOverFlow many times a solution for fixing this problem, but I haven't found something that works for me yet.
I fixed it accessing the EJB Components using JNDI.
In few words, if i use an EJB in a managed bean method, i need to add the next lines of code:
InitialContext ic = new InitialContext();
SessionBeanName = (SessionBeanClass) ic.lookup("java:global/NameOfTheApplication/NameOfTheEJBpackage/NameOfTheSessionBean");
It must be surronded by a try-catch statement
Create empty beans.xml file in your WEB-INF folder to enable CDI

Unknown JNDI Lookup String

I am new to EJB concept. I have seen the following in different website :
Sample 1:
#Stateless
#EJB(name="audit", beanInterface=AnotherEJBLocal.class)
public class EmployeeBean implements EmployeeServiceLocal, EmployeeServiceRemote {
#PersistenceContext(unitName = "EmployeeService")
private EntityManager manager;
public void doAction(){
try {
Context ctx = new InitialContext();
AnotherEJBLocal audit = (AnotherEJBLocal) ctx.lookup("java:comp/env/audit");
audit.doAnother();
} catch (NamingException e) {
throw new EJBException(e);
}
}
}
Sample 2:
public static void main(String[] a) throws Exception {
EmployeeServiceRemote service = null;
service = (EmployeeServiceRemote) new InitialContext().lookup("EmployeeBean/remote");
service.doAction();
}
Sample 3:
obj = ctx.lookup(ejb/CBDWebAppEAR/CBDWebApp.jar/<EJB name>/<Remote Interface Class Name>);
CBDWebApp is the project name in which the bean resides.
My question is:
What is the need & MEANING of java:comp/env/audit
Why same type of string is not used in case of Sample 2. I guess as
it is a remote EJB not local.
Why is the meaning of the EJB look up string in the Sample 3.
The java:comp/env/audit string is looking up the EJB reference that was declared earlier by the #EJB(name="audit", beanInterface=AnotherEJBLocal.class). Names declared by #EJB (and #Resource and all other EE references) are implicitly declared in the java:comp/env context. With this reference, the deployer can retarget the "audit" reference to any EJB in the application that implements the AnotherEJBLocal interface, or if the deployer doesn't specify anything, the javadoc for the #EJB annotation requires it to target a single EJB within the same application that implements the interface.
This main method is (probably) declared by a standalone Java program. In that case, it (probably) is configured via system properties to connect the JNDI server of an application server, which will return the remote reference to the client. The name that is looked up is vendor-specific, and it was probably configured for the EJB during deployment.
This is very similar to #2, the only difference being the specific string being used. In this case, it is probably relying on an application server's "default" binding name if none was configured for the EJB during deployment using the pattern ejb/<app>/<module>/<bean>/<interface>.

Weblogic 10.3.5 EJB3 local seesion bean lookup from java main class

I am using Weblogic 10.3.5 and EJB 3 for session bean
but I am not able to lookup jndi for local stateless session bean even though I am able to lookup
remote bean successfully
my code are for main class is
Properties p = new Properties();
p.put(Context.INITIAL_CONTEXT_FACTORY,
"weblogic.jndi.WLInitialContextFactory");
p.put(Context.PROVIDER_URL, "t3://localhost:7001");
try {
Context ctx = new InitialContext(p);
TheBeanRemote bean = (TheBeanRemote) ctx
.lookup("MrBean#com.bdc.TheBeanRemote");
System.out.println(bean.sayHello());
TheLocalLocal bean2 = (TheLocalLocal) ctx.lookup("TheLocalLocal");
Object obj = ctx.lookup("java:comp/env/ejb/MrBean2");
System.out.println(bean2.sayHello());
} catch (Exception e) {
e.printStackTrace();
}
Remote Bean
import javax.ejb.Remote;
#Remote
public interface TheBeanRemote {
public String sayHello();
}
Local Bean
import javax.ejb.Local;
#Local(TheLocalLocal.class)
public interface TheLocalLocal {
public String sayHello();
}
If you're running as a "client", that is a remote call, if that app is running on the server itself, that is a local call. It makes sense that one works but not the other.
The properties you're using indicate a remote call:
Properties p = new Properties();
p.put(Context.INITIAL_CONTEXT_FACTORY,
"weblogic.jndi.WLInitialContextFactory");
p.put(Context.PROVIDER_URL, "t3://localhost:7001");
Context ctx = new InitialContext(p);
A local call is:
Context context = new InitialContext();
See a similar question here: How to lookup JNDI resources on WebLogic?

InitialContext.lookup(ejbMappedName) return a new instance or an old same instance

For a statful EJB, if I get its reference using InitialContext.lookup(itsMappedName), for each call of (InitialContext.lookup(itsMappedName)) it will return a new Stateful EJB or the same stateful EJB?
public class SFEJB implements EJBRemote{
//.....
}
public class Class1{
void method1{
InitialContext ctx = new InitialContext(env);
EJBRemote testEJB= (EJBRemote)ctx.lookup(mappedName#fullclassname);
//.....
}
}
I find it will return a new stateful EJB (SFEJB) for each initialcontext.lookup(mappedName#fullclassname).
At first, I think "Stateful" in "Stateful EJB" means for the same web client, I will get the same stateful EJB for each call of initialContext.lookup(mappedName#fullclassname), but now I know the "Stateful" is just means for the testEJB, each method call will call to the same SFEJB instance(so in a state).
So testEJB is the EJB Client of SFEJB? (SFEJB remember testEJB)

How to call session bean from jsp

I'm new to ejb. Actually I've created one ejb and I added reference to a web application which will call the session bean simply. How to call the session bean from the jsp file?
I could also prefer you to use the MVC model for your application. In that case there is no need to call a session bean from the jsp, you can call it from the servlets itself.
Check out this link to call a EJB from a servlet.
Click
I've tried to do that on Wildfly, but without success using #EJB annotation, probabily JSP don't have CDI. So I've implemented it on another way (not so bright):
Before the :
<%
LoginAction loginAction;
try {
Properties properties = new Properties();
properties.put("jboss.naming.client.ejb.context", true);
properties.put(Context.URL_PKG_PREFIXES,"org.jboss.ejb.client.naming");
Context ctx=new InitialContext(properties);
loginAction = (LoginAction) ctx.lookup("java:module/LoginAction");
session.setAttribute("loginAction", loginAction); //this is to be able to use loginAction on EL Expressions!
} catch (Exception e) {
e.printStackTrace();
}
%>
And all the rest stays the same!
1) the first way will be to create a direct object
use import tag to import ur class
< % # page import = packageName.Classname %>
<%
#EJB
Classname object = new Classname();
%>
and then access methods using normal jsp
<%=object.callmethod()%>
2) the other way will be to use standard actions
<jsp:useBean id="beanId' class="packagename.ClassName" />
<jsp:getStudentInfo name="beanId" property="name"/>
As you are using EJB at service layer and in MVC , I will never advice to call a session bean from your view or jsp.you can call the session beans method by injection EJB reference using #EJB annotation.
Simple..Override Jsp's jspInit method and create InitialContext object.. InitialContext object can access all the resources that have JNDI name assigned..
<%!
BeanIntefaceName instanceName;
%>
<%
public void jspInit()
{
instanceName = (BeanIntefaceName)new InitialContext().lookup("java:global/[application_name]/[module_name]/[enterprise_bean_name]/[inteface_name]");
}
instanceName.yourMethodName();
%>
You can mix and match to support multiple application servers in the best way.
The code below uses the #EJB injection for WebSphere Liberty and the InitialContext for JBoss Wildfly
<%!
#EJB
GitlabHelper gitAPI;
public void jspInit() {
if (gitAPI == null) {
try {
gitAPI = (GitlabHelper) new InitialContext().lookup("java:module/GitlabHelper");
System.out.println("<!-- initContext has been used -->");
} catch (Exception e) {
e.printStackTrace();
}
}
}
%>

Resources