Showing posts with label JNDI. Show all posts
Showing posts with label JNDI. Show all posts

Sunday, January 17, 2016

EJB and JNDI, or how to lookup a EJB from a JSP


package ejb3.bean;

import javax.ejb.LocalBean;
import javax.ejb.Stateless;

@Stateless(mappedName = "HelloEjb")
@LocalBean
public class HelloEjb implements HelloEjbRemote, HelloEjbLocal {

 public HelloEjb() {
 }

 public String printHello(String name) {
  return "Hello " + name;
 }

}



package ejb3.bean;

import javax.ejb.Remote;

@Remote
public interface HelloEjbRemote {
 String printHello(String name);
}


package ejb3.bean;

import javax.ejb.Local;

@Local
public interface HelloEjbLocal {
 String printHello(String name);
}




The LocalBean means a no-interface view .

This is what I find in JNDI tree:

Binding Name: HelloEjb#ejb3.bean.HelloEjbRemote (this is from @Remote)
Class: com.sun.proxy.$Proxy208


Binding Name: java:global.PVHelloEJBEAR.PVHelloEJB.HelloEjb!ejb3.bean.HelloEjb (this is from @LocalBean )
Class: ejb3.bean.HelloEjb_n3seu_NoIntfViewImpl


Binding Name: java:global.PVHelloEJBEAR.PVHelloEJB.HelloEjb!ejb3.bean.HelloEjbLocal (this is from @Local)
Class: ejb3.bean.HelloEjb_n3seu_HelloEjbLocalImpl


Binding Name: java:global.PVHelloEJBEAR.PVHelloEJB.HelloEjb!ejb3.bean.HelloEjbRemote (this is from @Remote again)
Class: com.sun.proxy.$Proxy208



where PVHelloEJBEAR.PVHelloEJB.HelloEjb are respectively: application name (from application.xml), ejb module name (from application.xml), ejb name (mappedName)
To lookup the EJB interface from a JSP:
HelloEjbRemote helloEjb = (HelloEjbRemote) context.lookup("HelloEjb#ejb3.bean.HelloEjbRemote");

or (it works also in a servlet) if the JSP is in a WAR the same EAR as the EJB module you can use the no-interface @LocalBean trick :
@EJB
private HelloEjb helloEjb;


If you provide a @EJB in the JSP/Servlet without having a @LocalBean annotation, you get this error:
Module named 'PVHelloEJBEAR' failed to redeploy. See Error Log view for more detail.
weblogic.management.DeploymentException: weblogic.application.naming.ReferenceResolutionException: [J2EE:160200]Error resolving ejb-ref "ejb3.bean.HelloEjb3Servlet/helloEjb" from module "PVHelloWAR.war" of application "PVHelloEJBEAR". The ejb-ref does not have an ejb-link and the JNDI name of the target bean has not been specified. Attempts to automatically link the ejb-ref to its target bean failed because no EJBs in the application were found to implement the "ejb3.bean.HelloEjb" interface. Link or map this ejb-ref to its target EJB and ensure the interfaces declared in the ejb-ref are correct.
Exception received from deployment driver. See Error Log view for more detail.



This is the documentation of @EJB : https://docs.oracle.com/javaee/6/api/javax/ejb/EJB.html

So if from your Servlet/JSP you want to access a REMOTE EJB (i.e. without LocalBean) you must change your @EJB lookup to:
@EJB(lookup="HelloEjb#ejb3.bean.HelloEjbRemote")
private HelloEjbRemote helloEjb;


or using the @Local interface:
@EJB
private HelloEjbLocal helloEjb;


Sample project available:
git clone https://github.com/vernetto/JavaMonAmour
cd JavaMonAmour\jeesamples\HelloEJB


If you wonder about Portable JNDI Syntax, have a look here.

Sunday, October 4, 2015

Digging in JNDI

JNDI is a bit of a mystery for me...whenever I get an exception like:

javax.naming.NameNotFoundException: While trying to look up comp/env/jms/CF1 in /app/webapp/rocAdmin/1482669104.; remaining name "comp/env/jms/CF1" at weblogic.jndi.internal.BasicNamingNode.newNameNotFoundException(BasicNamingNode.java:1180) at weblogic.jndi.internal.ApplicationNamingNode.lookup(ApplicationNamingNode.java:143) at weblogic.jndi.internal.WLEventContextImpl.lookup(WLEventContextImpl.java:253) at weblogic.jndi.internal.WLContextImpl.lookup(WLContextImpl.java:426) at weblogic.jndi.factories.java.ReadOnlyContextWrapper.lookup(ReadOnlyContextWrapper.java:45) at weblogic.jndi.internal.AbstractURLContext.lookup(AbstractURLContext.java:130) at javax.naming.InitialContext.lookup(InitialContext.java:411) ...

I scratch my head ... So I wrote some code to dump the content of the InitialContext (it runs in a EJB timer to avoid having to create a client:
package com.pierre;

import javax.ejb.Schedule;
import javax.ejb.Stateless;
import javax.ejb.Timer;
import javax.naming.Binding;
import javax.naming.InitialContext;
import javax.naming.NamingEnumeration;
import javax.naming.NamingException;

@Stateless
public class PVTimer {

    /**
     * Default constructor.
     */
    public PVTimer() {
 // TODO Auto-generated constructor stub
    }

    @SuppressWarnings("unused")
    @Schedule(second = "*/10", minute = "*", hour = "*", dayOfWeek = "*", dayOfMonth = "*", month = "*", year = "*", info = "MyTimer")
    private void scheduledTimeout(final Timer t) {
 System.out.println("@Schedule called at: " + new java.util.Date());
 try {
     System.out.println();
     InitialContext ic = new InitialContext();
     NamingEnumeration names = ic.listBindings("");
     printNames(names, "all");
     NamingEnumeration jms = ic.listBindings("jms");
     printNames(jms, "jms");
     System.out.println();
 } catch (Throwable t1) {
     t1.printStackTrace();
 }

    }

    private void printNames(NamingEnumeration names, String title)
     throws NamingException {
 int count = 1;
 while (names.hasMore()) {
     Binding next = names.next();
     System.out.println(title + " " + count + " ToString=" + next.toString() + " Name=" + next.getName() + " Classname=" + next.getClassName() + " getObject=" + next.getObject());
     count++;
 }
    }
}


and this is the result:

all 1 ToString=weblogic: weblogic.jndi.internal.WLEventContextImpl:EventContext (weblogic) Name=weblogic Classname=weblogic.jndi.internal.WLEventContextImpl getObject=EventContext (weblogic)
all 2 ToString=__WL_GlobalJavaApp: weblogic.jndi.internal.WLEventContextImpl:EventContext (__WL_GlobalJavaApp) Name=__WL_GlobalJavaApp Classname=weblogic.jndi.internal.WLEventContextImpl getObject=EventContext (__WL_GlobalJavaApp)
all 3 ToString=PVEarPVEjbProject_jarPVStateless_PVStatelessRemote: com.pierre.PVStateless_fcmphc_PVStatelessRemoteImpl:com.pierre.PVStateless_fcmphc_PVStatelessRemoteImpl@e964ee Name=PVEarPVEjbProject_jarPVStateless_PVStatelessRemote Classname=com.pierre.PVStateless_fcmphc_PVStatelessRemoteImpl getObject=com.pierre.PVStateless_fcmphc_PVStatelessRemoteImpl@e964ee
all 4 ToString=ejb: weblogic.jndi.internal.WLEventContextImpl:EventContext (ejb) Name=ejb Classname=weblogic.jndi.internal.WLEventContextImpl getObject=EventContext (ejb)
all 5 ToString=jms: weblogic.jndi.internal.WLEventContextImpl:EventContext (jms) Name=jms Classname=weblogic.jndi.internal.WLEventContextImpl getObject=EventContext (jms)
all 6 ToString=PVEarPVEjbProject_jarPVStateless_Home: weblogic.ejb.container.internal.StatelessEJBHomeImpl:weblogic.ejb.container.internal.StatelessEJBHomeImpl@f229af Name=PVEarPVEjbProject_jarPVStateless_Home Classname=weblogic.ejb.container.internal.StatelessEJBHomeImpl getObject=weblogic.ejb.container.internal.StatelessEJBHomeImpl@f229af
all 7 ToString=javax: weblogic.jndi.internal.WLEventContextImpl:EventContext (javax) Name=javax Classname=weblogic.jndi.internal.WLEventContextImpl getObject=EventContext (javax)
all 8 ToString=java:global: weblogic.jndi.internal.WLEventContextImpl:EventContext (java:global) Name=java:global Classname=weblogic.jndi.internal.WLEventContextImpl getObject=EventContext (java:global)
all 9 ToString=mejbmejb_jarMejb_EO: weblogic.management.j2ee.mejb.Mejb_dj5nps_EOImpl:ClusterableRemoteRef(4485985896511196818S:169.254.152.121:pvdomain:AdminServer [4485985896511196818S:169.254.152.121:pvdomain:AdminServer/294])/294 Name=mejbmejb_jarMejb_EO Classname=weblogic.management.j2ee.mejb.Mejb_dj5nps_EOImpl getObject=ClusterableRemoteRef(4485985896511196818S:169.254.152.121:pvdomain:AdminServer [4485985896511196818S:169.254.152.121:pvdomain:AdminServer/294])/294
all 10 ToString=_WL_internal_0Z7vb3dMvYJ62jEwg8odDkTCYHT0HwjvQwlqEb8FYeA1jZjPDZBGLEATyZk7rdEu: weblogic.jndi.internal.WLEventContextImpl:EventContext (_WL_internal_0Z7vb3dMvYJ62jEwg8odDkTCYHT0HwjvQwlqEb8FYeA1jZjPDZBGLEATyZk7rdEu) Name=_WL_internal_0Z7vb3dMvYJ62jEwg8odDkTCYHT0HwjvQwlqEb8FYeA1jZjPDZBGLEATyZk7rdEu Classname=weblogic.jndi.internal.WLEventContextImpl getObject=EventContext (_WL_internal_0Z7vb3dMvYJ62jEwg8odDkTCYHT0HwjvQwlqEb8FYeA1jZjPDZBGLEATyZk7rdEu)
jms 1 ToString=PVQueue: weblogic.jms.common.DestinationImpl:SystemModule-0!Queue-0 Name=PVQueue Classname=weblogic.jms.common.DestinationImpl getObject=SystemModule-0!Queue-0
jms 2 ToString=PVConnectionFactory: weblogic.jms.client.JMSXAConnectionFactory:weblogic.jms.client.JMSXAConnectionFactory@1a31048 Name=PVConnectionFactory Classname=weblogic.jms.client.JMSXAConnectionFactory getObject=weblogic.jms.client.JMSXAConnectionFactory@1a31048
jms 3 ToString=PVConnectionFactoryLocal: weblogic.jms.client.JMSXAConnectionFactory:weblogic.jms.client.JMSXAConnectionFactory@10414e6 Name=PVConnectionFactoryLocal Classname=weblogic.jms.client.JMSXAConnectionFactory getObject=weblogic.jms.client.JMSXAConnectionFactory@10414e6



(I have a stateless EJB "PVStateless" in the same module , implementing a PVStatelessRemote interface.... plus a JMS queue "PVQueue" with JNDI name "jms/PVQueue" and a JMS CF "PVConnectionFactory" with JNDI name "jms/PVConnectionFactory"....

Interesting javadoc http://docs.oracle.com/javase/7/docs/api/javax/naming/Binding.html and http://docs.oracle.com/javase/7/docs/api/javax/naming/InitialContext.html



Friday, April 27, 2012

Error untargetting and targetting again a JMSServer

We had an interesting case where WebLogic was keeping in JNDI tree a reference to a JMS Connection Factory (CF) even after untargetting the JMSServer on which the CF was deployed.
When I retarget the CF, I get this error:


An error occurred during activation of changes, please see the log for details.
Message icon - Error Error preparing connection factory GM_CommonOsbJMSModule!CommonOsbCF
Message icon - Error The proposed JNDI name "jms.jndi.cf.CommonOsb.CommonOsbCF" for connection factory "GM_CommonOsbJMSModule!CommonOsbCF" is already bound by another object of type "weblogic.jms.frontend.FEConnectionFactoryImpl_1035_WLStub"


The only solution was a server restart.

Monday, January 30, 2012

weblogic.jndi.retainenvironment

if you specify -Dweblogic.jndi.retainenvironment=true in the WLS command line,


in WLInitialContextFactoryDelegate:

if(KernelStatus.isServer())
{
String s = System.getProperty("weblogic.jndi.retainenvironment");
if(s != null)
keepEnvironmentUntilContextClose = true;
}


if (!keepEnvironmentUntilContextClose)
JNDIEnvironment.getJNDIEnvironment().popThreadEnvironment();


I am trying to understand what this - seemingly undocumented - parameter does.

If you have an idea, pleas leave a comment...

Tuesday, July 6, 2010

OSB: Changing the JNDIProvider for EJB

This is what happens if you change target to a EJB, then upgrade the JNDIProvider to point to the new target.... it looks like OSB is caching the remote reference to the EJB, and doesn't clear the cache when you change the JNDIProvider... this doesn't happen so often, but still it's an operational issue and the only workaround I could figure out is restarting the Admin and the MS!
The other solution is to disable JNDI Cache on the JNDIProvider.



 
  env:Server
  Failed to invoke end component com.bea.wli.sb.transports.ejb.Jws (POJO), operation=getLocationsByName
 -> Failed to invoke method
 -> The object identified by: '324' could not be found.  Either it was has not been exported or it has been collected by
 the distributed garbage collector.; nested exception is: java.rmi.NoSuchObjectException: The object identified by: '324
' could not be found.  Either it was has not been exported or it has been collected by the distributed garbage collector
.
  
   javax.ejb.EJBException: The object identified by: '324' could not be found.  Eit
her it was has not been exported or it has been collected by the distributed garbage collector.; nested exception is: ja
va.rmi.NoSuchObjectException: The object identified by: '324' could not be found.  Either it was has not been exported o
r it has been collected by the distributed garbage collector.
java.rmi.NoSuchObjectException: The object identified by: '324' could not be found.  Either it was has not been exported
 or it has been collected by the distributed garbage collector.