Remote lookup to another Glassfish from a Servlet - java

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.

Related

JCA Connector Classloading

in my Scenario, i try to use JCA Adapters to connect to an external storage - just to try this feature of J2EE.
I use JBoss EAP 7 and its packed implementation ironjacamar.
i deploy an adapter.rar, which contains an adapter.jar (this contains the Connection and ConnectionFactory Interfaces and all implementations) and META-INF/ironjacamar.xml.
I then deploy a app.war file, containing a Bean with an annotated field:
#RequestScoped
public class Bean {
...
#Resource(lookup = "java:/eis/StorageConnectionFactory")
private StorageConnectionFactory connectionFactory;
}
The war also contains the adapter.jar as library - as it needs to know of all the classes at runtime (NoClassDefFound etc.)
To my amazement, the Connector itself seems to work - as is get the Exception:
java.lang.IllegalArgumentException: Can not set conn.StorageConnectionFactoryImpl field Bean.connectionFactory to conn.HsmConnectionFactoryImp
and on ommitting the interfaces even:
#Resource(lookup = "java:/eis/StorageConnectionFactory")
private StorageConnectionFactoryImpl connectionFactory;
still
java.lang.IllegalArgumentException: Can not set conn.StorageConnectionFactoryImpl field Bean.connectionFactory to conn.HsmConnectionFactoryImp
I see that the Problem is, that the adapter.rar does nto share the same classloader as the app.war and both contain the corresponding classes, leading to a sort of ClassCastException - how do i solve this issue correctly?
It seems you haven't configure resource adapter properly.
See the below guide, it will help you to configure:
https://access.redhat.com/documentation/en/red-hat-jboss-enterprise-application-platform/version-7.0/configuration-guide/#configuring_jca_subsystem

How does the JNDI InitialContext null constructor behave ?

I saw a stackoverflow answer to a question on JNDI.
The answer showed a few lines of code using InitialContext to retrieve a DataSource.
However, the instance of InitialContext was not created with any properties to use any sort of service such as LDAP or the file system.
Where does the entry go when you bind it to an InitialContext with the null constructor ?
Will the entry only visible within the application ?
Will it not persist when you shutdown the application ?
Where does the entry go when you bind it to an InitialContext with the null constructor?
If there is a resource file named /jndi.properties it uses whatever environment is defined in there. Servlet containers typically use this to define an extra object factory for the java: namespace.
Will the entry only [be] visible within the application?
Yes.
Will it not persist when you shutdown the application?
It will not persist unless the container implements that.

Trouble using #Resource and JNDI lookup

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!

comp/env/pool not found in context "java:"?

I have a web application trying to access a JNDI declared in WebSphere Application Server.
The JNDI is declared under Object pool managers. However, I'm receiving an error when I access the pool. The error says that comp/env/pool is not found in context "java:".
My code is written as follows:
InitialContext initialContext = new InitialContext();
ObjectPoolManager opm = (ObjectPoolManager)initialContext.lookup("java:comp/env/pool");
Accessing the pool via the code below works:
ObjectPoolManager opm = (ObjectPoolManager)initialContext.lookup("pool");
I'm confused because according to what I've found on the internet, java:comp/env/ is a default prefix for JNDI. So why does it cause an error in my case?
Thank you!
you can only use java:comp/env if you have declared a reference to the Object Pool in your web.xml under the resource-ref section.
See What is resource-ref in web.xml used for? for further explanation.

Accesing an remote enterprise bean within a simple Java class

Here's my Java class
import endpoint.NewSessionRemote;
import javax.naming.Context;
import javax.naming.InitialContext;
public class HelloClient {
public static void main(String[] args) {
try {
Context ctx = new InitialContext();
NewSessionRemote hello = (NewSessionRemote) ctx.lookup("endpoint.NewSessionRemote");
System.out.println(hello.stringChange(4));
} catch (Exception ex) {
ex.printStackTrace();
}
}
}
When I run this class I'm getting an exception.
javax.naming.NameNotFoundException: endpoint.NewSessionRemote not found
at com.sun.enterprise.naming.TransientContext.doLookup(TransientContext.java:216)
at com.sun.enterprise.naming.TransientContext.lookup(TransientContext.java:188)
at com.sun.enterprise.naming.SerialContextProviderImpl.lookup(SerialContextProviderImpl.java:74)
at com.sun.enterprise.naming.RemoteSerialContextProviderImpl.lookup(RemoteSerialContextProviderImpl.java:129)
at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:39)
at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:25)
at java.lang.reflect.Method.invoke(Method.java:597)
at com.sun.corba.ee.impl.presentation.rmi.ReflectiveTie._invoke(ReflectiveTie.java:154)
at com.sun.corba.ee.impl.protocol.CorbaServerRequestDispatcherImpl.dispatchToServant(CorbaServerRequestDispatcherImpl.java:687)
at com.sun.corba.ee.impl.protocol.CorbaServerRequestDispatcherImpl.dispatch(CorbaServerRequestDispatcherImpl.java:227)
at com.sun.corba.ee.impl.protocol.CorbaMessageMediatorImpl.handleRequestRequest(CorbaMessageMediatorImpl.java:1846)
at com.sun.corba.ee.impl.protocol.CorbaMessageMediatorImpl.handleRequest(CorbaMessageMediatorImpl.java:1706)
at com.sun.corba.ee.impl.protocol.CorbaMessageMediatorImpl.handleInput(CorbaMessageMediatorImpl.java:1088)
at com.sun.corba.ee.impl.protocol.giopmsgheaders.RequestMessage_1_2.callback(RequestMessage_1_2.java:223)
at com.sun.corba.ee.impl.protocol.CorbaMessageMediatorImpl.handleRequest(CorbaMessageMediatorImpl.java:806)
at com.sun.corba.ee.impl.protocol.CorbaMessageMediatorImpl.dispatch(CorbaMessageMediatorImpl.java:563)
at com.sun.corba.ee.impl.protocol.CorbaMessageMediatorImpl.doWork(CorbaMessageMediatorImpl.java:2567)
at com.sun.corba.ee.impl.orbutil.threadpool.ThreadPoolImpl$WorkerThread.run(ThreadPoolImpl.java:555)
java.lang.NullPointerException
All the other enterprise bean classes are written according to the EJB 3.0 standard.
Your valuable contribution is expected.
Solution
The exception was
javax.naming.NameNotFoundException: endpoint.NewSessionRemote not found
It occurs because the JNDI name that was given by the application side didn't match the servser's (Glassfish) actual JNDI name, so I did was check the JNDI tree in Glassish through its admin console (vendor specific) and I did notice that the JNDI for the NewSessionRemote interface (which is the business interface of the session bean NewSessionBean) is different from the name which I have given in the application side. So how did this happen then suddenly something came in to my mind that's the ejb-jar.xml there is another name JNDI name assigned to the same NewSessionRemote using tag. So I simply remove it and redeploy EJB module. That's it.
Looks like you have no RMI registry (i.e. active server) you are lookingUp() against.
You supplied no Context.INITIAL_CONTEXT_FACTORY variable, so the lookup should be a valid URL, which it is not.
Hence, you should put something like this on your env (on the iCtx):
env.put(Context.INITIAL_CONTEXT_FACTORY, "com.sun.jndi.rmi.registry.RegistryContextFactory");
I suggest you read the the simple examples over at http://java.sun.com/j2se/1.5.0/docs/guide/jndi/jndi-rmi.html
When using JNDI, you're using an API that requires a specific configuration underlying it in order to connect to the server (see the Javadoc for details on what that configuration is). For example, java.naming.factory.initial is the property which indicates which implementation of JNDI you want to use.
Now, when running code inside a JavaEE server, this configuration is available implicitly, and all you need to do is what you have done in your code - instantiate InitialContext, and perform a lookup. However, when running outside the server, this implicit configuration is not present, and so you need to configure your InitialContext explicitly.
Your sample code uses a main() method, which suggests that you're running outside the container. The config you need will depend on your specific application server, you'll need to look up that documentation to see what config to supply.

Categories