I have created a EJB2.0 using Eclipse 3.7 IDE, and deployed it in JBoss 5 application server (my bean name is product). I am doing normal context lookup (and other stuff to call ejb), and I am able to call EJB successfully. Now my question is what is JNDI name exactly, and where did it get used in all this. Is my bean name the JNDI name, or is this my JNDI name -> org.jnp.interfaces.NamingContextFactory. Where is the JNDI name in this?????
my code:-
// initial code.............
Context ctx = getContext();
Object obj=ctx.lookup("Product");
ProductHome home =(ProductHome) javax.rmi.PortableRemoteObject.narrow(obj,ProductHome.class);
ProductRemote remote=home.create();
Product prd = new rohit.Product("PRDCamera",001,50.50) ;
remote.addProduct(prd);
remote.updateProduct(prd);
remote.removeProduct(001);
remote.findProduct(001);
remote.findAllProduct();
// getContext Method
public static InitialContext getContext() throws Exception{
Properties pro = new Properties();
pro.put(javax.naming.InitialContext.INITIAL_CONTEXT_FACTORY,"org.jnp.interfaces.NamingContextFactory");
pro.put(javax.naming.InitialContext.PROVIDER_URL,"localhost:1099");
return new InitialContext(pro);
}
There is no JNDI name in your code.
This is how you look up EJBs in EJB 2.0:
Object ejbHome = initialContext.lookup("java:comp/env/com/mycorp/MyEJB");
MyHome myHome = (MyHome)javax.rmi.PortableRemoteObject.narrow(
(org.omg.CORBA.Object)ejbHome, MyHome.class);
The JNDI name is java:comp/env/com/mycorp/MyEJB in this case.
In the much saner EJB 3.0, you just do
MyEJB myEJB = initialContext.lookup("java:comp/env/com/mycorp/MyEJB")
and do away with the terrible home interface idea.
Related
I'm trying to run a remote lookup to another Glassfish from a Servlet. So, I was following the link documentation (http://docs.oracle.com/cd/E19798-01/821-1752/beanv/index.html). First I created a Sateless Session Ben called CalculatorBean, packaged in an EJB JAR of the same name (CalculatorBean), the JNDI name was java:global/CalculatorBean/CalculatorBean.
According to the documentation, I created a Web project and declared my EJB in sub-web.xml the following file:
<ejb-ref>
<ejb-ref-name>ejb/CalculatorBean</ejb-ref-name>
<jndi-name>corbaname:iiop:127.0.0.1:3700#CalculatorBean/CalculatorBean</jndi-name>
</ejb-ref>
where 127.0.0.1 is the host of the machine (local!), 3700 is the default port for querying and, CalculatorBean/CalculatorBean is the global JNDI name. First question, theoretically the JNDI name passes into an interoperable String "CalculatorBean/CalculatorBean" instead of "java: global/CalculatorBean/CalculatorBean", right?
After that, I created a Servlet and put the following code snippet:
ctx = new InitialContext ();
bean = (CalculatorRemote) ctx.lookup ("java:comp/env/ejb/CalculatorBean");
Where, CalculatorRemote is the name of the remote interface that we included in the java project:comp/env/ is the directory section to access Java EE components and ejb/CalculatorBean is the name of my bean in the configuration of the sun-web.xml file
When put to run my Servlet I'm getting the exception:
Caused by: javax.naming.NameNotFoundException: No object bound to name java:comp/env/ejb/CalculatorBean
Obviously, it's not finding the name, however, do not really know what name I should use to set the lookup.
I had the same problem, and I solved it.
By default, your EJB is not visilbe into java:comp/env/ and you can not lookup for an EJB into InitialContext instance. But, you can successful lookup for an EJB after when at least one EJB instance is injected using #EJB annotation, like, for your example:
#EJB(name = "ejb/CalculatorBean")
private CalculatorRemote calc;
After that, CalculatorRemote EJB is visible in InitialContext instance.
I'm having trouble applying the concept of injection and also JNDI with EJBs and I'd like your help. I am learning this and I really want to understand and apply the techniques of #Resource and/or JNDI lookups with XML configuration. I can't seem to find any of the initial parameters in my JNDI lookups. Now, before I continue, if I manually enter the JNDI name of my datasource, everything works great. What I'm trying to do (again as an exercise) is use #Resource or JNDI to get the JNDI datasource name itself and then do a JNDI lookup on the datasource. I know that you can directly inject a DataSource object but if I can't inject a String, I gotta start with this.
First, here's the important part of my ejb-jar.xml:
<env-entry>
<description>DataSource JNDI lookup name</description>
<env-entry-name>datasourceName</env-entry-name>
<env-entry-type>java.lang.String</env-entry-type>
<env-entry-value>myDataSource</env-entry-value>
</env-entry>
In terms of injection using #Resource I've tried I've tried the following field in the EJB
#Resource(name = "datasourceName")
String dsName;
I've also tried with mappedName and lookup (using JNDI lookup) nothing is coming in. Then I've tried JNDI lookup as follows:
// get JNDI name from environment entry in EJB Context and use to lookup DataSource
Context context = new InitialContext();
String dsName = (String) context.lookup("java:comp/env/SRS/datasourceName");
(The name of the application is SRS) - This comes up with a NamingException that the JNDI lookup did not find anything. I've tried the following lookups:
String datasourceName = (String) context.lookup("java:comp/env/SRS/Status/datasourceName"); // name of EJB is Status
String datasourceName = (String) context.lookup("datasourceName");
String datasourceName = (String) context.lookup("SRS/datasourceName");
String datasourceName = (String) context.lookup("SRS/Status/datasourceName");
String datasourceName = (String) context.lookup("java:global/SRS/datasourceName");
String datasourceName = (String) context.lookup("java:global/SRS/Status/datasourceName");
My first post here so I hope I asked properly. Thanks for the help!
Ok. Two days later I saw that my mistake was nowhere in the code of the EJB itself but in a configuration of the JSP which invoked the EJB!! My mistake is that I had somehow invoked the methods of the EJB class as a POJO and NOT through the container. I had assumed since the EJB methods were being called that the container had correctly injected the EJB to the JSP. But it didn't. I put in a JNDI lookup in the JSP and everything resolved itself. Thanks everyone for your responses!
I use ProgrammaticLogin in Glassfish 3.1.2 with username,password and realm and it works good. Anyway when I call context.getCallerPrincipal() I get org.glassfish.security.common.PrincipalImpl with context.getCallerPrincipal().getName() which returns the username.
Is there any way that I can pass Principle via ProgrammaticLogin
so it is passed in my ejb and available from SessionContext - context.getCallerPrincipal()?
I guess you are in a context where resource-injection is not possible via annotations.
You can try to get an instance of the desired EJB via a manual JNDI lookup.
Example:
InitialContext init = new InitialContext();
YourBean bean = (YourBean) init.lookup(JNDI_NAME_OF_YOUR_BEAN);
Now you should be able to pass the Principal to your bean.
I want to check if same schema registered with two different DS name in JBoss, So
How to get list of all registered DS names (Object) in JBoss programmatically?
You can list all Objects bound to the JBoss (JNDI) via following method:
Context initCtx = new InitialContext();
NamingEnumeration<NameClassPair> namedEnum = initCtx.list("java:comp/env");
Then afterwards you may filter by className in NameClassPair
See API
By using JNDI, something like this.
Context context = new InitialContext();
context.listBindings("java:comp/env");
I'm trying to use the EJB timer service, I have a class named TimerBean which carries the methods to schedule a timer and handle the timeout, this implements TimerBeanRemote an interface class.
In another session bean I have the following:
TimerBeanRemote service = (TimerBeanRemote) new InitialContext().lookup("TimerBean/remote");
When I try to run it on the server I get the error:
javax.naming.NamingException: Lookup failed for 'TimerBean/remote' in SerialContext [Root exception is javax.naming.NameNotFoundException: TimerBean]
Any ideas as to why it can't find it? Thanks!
Following from your comments -if you are trying to access TimerBeanRemote within the same container then you can inject the #Remote ejb in your servlet or JSF Backing Bean else you can locate your EJB through a JNDI lookup.
Suppose your TimerBean is: com.mypackage.timer.TimerBeanRemote
then as per explanation above you can either inject or lookup:
Injection
public class MyServlet ...{
#EJB
com.mypackage.timer.TimerBeanRemote timerBean;
}
JNDI lookup:
Properties props = new Properties();
props.setProperty(Context.INITIAL_CONTEXT_FACTORY, "com.sun.enterprise.naming.SerialInitContextFactory");
String[] serverDetails = server.split(":");
props.setProperty("org.omg.CORBA.ORBInitialHost", MyHost);
props.setProperty("org.omg.CORBA.ORBInitialPort", MyPort);
InitialContext ic = new InitialContext(props);<br>
TimerBeanRemote timerBean = (TimerBeanRemote)ic.lookup("com.mypackage.timer.TimerBeanRemote");
You can read the following articles for further details:
http://download.oracle.com/javaee/1.4/tutorial/doc/Session5.html
http://www.javabeat.net/articles/3-ejb-30-timer-services-an-overview-1.html