I am trying to write a simple stateless sesssion bean but I have problem with narrow reference I give in lookup time.
I got
class cast exeption
I use
eclipse IDE
my bean class
package codes;
import java.rmi.RemoteException;
import javax.ejb.EJBException;
import javax.ejb.SessionBean;
import javax.ejb.SessionContext;
public class SinaBean implements SessionBean {
/**
*
*/
private static final long serialVersionUID = 1L;
public String getHello()
{
return "hello";
}
public void ejbCreate(){
}
#Override
public void ejbActivate() throws EJBException, RemoteException {
// TODO Auto-generated method stub
}
#Override
public void ejbPassivate() throws EJBException, RemoteException {
// TODO Auto-generated method stub
}
#Override
public void ejbRemove() throws EJBException, RemoteException {
// TODO Auto-generated method stub
}
#Override
public void setSessionContext(SessionContext arg0) throws EJBException,
RemoteException {
// TODO Auto-generated method stub
}
}
my home interface
package codes;
import java.rmi.RemoteException;
import javax.ejb.CreateException;
import javax.ejb.EJBHome;
public interface SinaHome extends EJBHome {
public SinaObject create() throws RemoteException,CreateException;
}
my component
package codes;
import java.rmi.RemoteException;
import javax.ejb.EJBObject;
public interface SinaObject extends EJBObject {
String getHello() throws RemoteException;
}
my client
package codes;
import java.util.Properties;
import javax.naming.Context;
import javax.naming.InitialContext;
import javax.naming.NamingException;
import javax.rmi.PortableRemoteObject;
public class Client {
/**
* #param args
*/
public static void main(String[] args) {
Context con=null;
try {
Properties p=new Properties();
p.setProperty(Context.INITIAL_CONTEXT_FACTORY,
"org.jnp.interfaces.NamingContextFactory");
p.setProperty(Context.PROVIDER_URL, "localhost:1099");
p.setProperty(Context.URL_PKG_PREFIXES,
"org.jboss.namingrg.jnp.interfaces");
con = new InitialContext(p);
Object o=con.lookup("SinaBean");
System.out.println(o);/***/untill know it works.it sysout :
//org.jnp.interfaces.NamingContext#e83912***
#SuppressWarnings("unused")
SinaHome sh=(SinaHome)PortableRemoteObject.narrow(o, SinaHome.class);//***exeption is here!!***
} catch (Exception e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
}
my xml file
<?xml version="1.0" encoding="UTF-8"?>
<ejb-jar version="3.0" xmlns="http://java.sun.com/xml/ns/javaee" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://java.sun.com/xml/ns/javaee http://java.sun.com/xml/ns/javaee/ejb-jar_3_0.xsd">
<display-name>Ejb </display-name>
<enterprise-beans>
<session>
<display-name>SinaBean</display-name>
<ejb-name>SinaBean</ejb-name>
<home>codes.SinaHome</home>
<remote>codes.SinaObject</remote>
<ejb-class>codes.SinaBean</ejb-class>
<session-type>Stateless</session-type>
<transaction-type>Bean</transaction-type>
<security-identity>
<description></description>
<use-caller-identity></use-caller-identity>
</security-identity>
</session>
</enterprise-beans>
</ejb-jar>
the exception I receive
java.lang.ClassCastException
at com.sun.corba.se.impl.javax.rmi.PortableRemoteObject.narrow(PortableRemoteObject.java:229)
at javax.rmi.PortableRemoteObject.narrow(PortableRemoteObject.java:137)
at codes.Client.main(Client.java:27)
Caused by: java.lang.ClassCastException: org.jnp.interfaces.NamingContext cannot be cast to org.omg.CORBA.Object
at com.sun.corba.se.impl.javax.rmi.PortableRemoteObject.narrow(PortableRemoteObject.java:212)
... 2 more
I will be extremely grateful for your advices.
First of all, your xml file indicates you are using EJB3 (which is actually the only version even worth considering), but your bean is an EJB2 bean.
If your server indeed runs EJB3, remove the XML file and remove the needless EJB home and component implementations. Add the #Stateless annotation and a remote interface. Make sure it looks something like this:
#Remote
public interface SinaRemote {
String getHello();
}
#Stateless
public class SinaBean implements SinaRemote {
public String getHello() {
return "hello";
}
}
Then correct your JNDI properties. The following is wrong:
p.setProperty(Context.URL_PKG_PREFIXES, "org.jboss.namingrg.jnp.interfaces");
it should be:
p.setProperty(Context.URL_PKG_PREFIXES, "org.jboss.naming:org.jnp.interfaces");
(the variants people use here are almost endless and it basically always works anyway, but just to be sure use the correct variant)
Furthermore, and most likely the main culprit, you're using the ejb-name as-if it was a global JNDI name but this is not the case. The ejb-name is a somewhat confusing logical name that's used as an extra kind of qualifier when referring to a specific bean when injecting or creating an ejb-ref.
In your case you're setting it to the same as the unqualified bean name, which is already the default. Since SinaBean exists, I'm guessing you're not deploying via an EAR, but deploy a standalone EJB jar, right?
If you are using JBoss AS 6 (EJB3.1) you can use the global portable JNDI names, otherwise the old JBoss specific JNDI naming can be used: [ear name]/[simple bean name]/remote. Note that [simple bean name] is not the ejb-name, but again in your case they happened to be the same. Since [ear name]/ is removed when you're deploying only an EJB jar, this explains the exception you're getting: SinaBean is a directory (context in JNDI terms), which can contain the actual entries local, remote and no-interface. What you're doing is trying to cast this intermediate directory node to the proxy to your bean, which of course doesn't work.
Anyway, finally, remove the usage of PortableRemoteObject, this is no longer needed. The client code will then look like this:
Properties properties = new Properties();
properties.setProperty(Context.INITIAL_CONTEXT_FACTORY, "org.jnp.interfaces.NamingContextFactory");
properties.setProperty(Context.URL_PKG_PREFIXES, "org.jboss.naming:org.jnp.interfaces");
properties.setProperty(Context.PROVIDER_URL, "localhost:1099");
context = new InitialContext(properties);
SinaRemote sina = (SinaRemote) context.lookup("SinaBean/remote");
Here If you are using EJB 2.0 along with Jboss 5.0 and trying to type cast Object obj to your Home Object from Client as below then it might throw java.lang.ClassCastException com.sun.proxy.$Proxy104 cannot be cast to org.omg.CORBA.Object .
Code to lookup JNDI :
java.lang.Object obj = ctx.lookup("java:comp/env/ATSessionBean");
ATHome home = (ATHome) PortableRemoteObject.narrow(obj, ATHome.class);
Solution : Here u need to add additional jars in classpath of Client app those are available in Higher version of JBOSS.
So better to download latest version **jboss-7.1.1.Final server and deploy your application and it will run successfully. :)**
download JBOSS server (Download EAP 6.4.0) from below link : http://jbossas.jboss.org/downloads/
Related
I am trying to learn how to use Felix iPOJO API to create components dynamically.
I have a simple bundle with the following files:
1- HelloService.java (Contains a Service Interface).
/*
* #author zaid almahmoud
*
*/
package helloipojo.service;
public interface HelloService
{
public void sayHello();
}
2- Its implementation HelloServiceImpl.java:
package helloipojo;
import helloipojo.service.HelloService;
public class HelloServiceImpl implements HelloService{
#Override
public void sayHello() {
System.out.println("Hello iPojo!");
}
}
3- Activator.java :
package helloipojo;
import org.osgi.framework.BundleActivator;
import org.osgi.framework.BundleContext;
public class Activator implements BundleActivator {
public void start(BundleContext context) throws Exception {
System.out.println("Bundle Started!");
}
public void stop(BundleContext context) throws Exception {
context = null;
System.out.println("Bundle Stopped!");
}
}
4- MANIFEST.MF :
Manifest-Version: 1.0
Bundle-ManifestVersion: 2
Bundle-Name: HelloIPojo
Bundle-SymbolicName: HelloIPojo
Bundle-Version: 1.0.0.qualifier
Bundle-Activator: helloipojo.Activator
Bundle-RequiredExecutionEnvironment: JavaSE-1.6
Import-Package: org.osgi.framework
In my application, I start Felix framework and deploy the following bundles:
iPOJO (core)
iPOJO Composite
iPOJO API
According to this source.
Next, I install my bundle, and instantiate the component. Below is my class:
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import org.apache.felix.framework.Felix;
import org.apache.felix.framework.util.FelixConstants;
import org.osgi.framework.Bundle;
import org.osgi.framework.BundleContext;
import org.osgi.framework.BundleException;
import org.osgi.framework.Constants;
import org.osgi.framework.ServiceRegistration;
import org.apache.felix.ipojo.ComponentInstance;
import org.apache.felix.ipojo.ConfigurationException;
import org.apache.felix.ipojo.MissingHandlerException;
import org.apache.felix.ipojo.UnacceptableConfiguration;
import org.apache.felix.ipojo.api.ComponentType;
import org.apache.felix.ipojo.api.PrimitiveComponentType;
import org.apache.felix.ipojo.api.Service;
public class HostApplication
{
private HostActivator m_activator = null;
private Felix m_felix = null;
public HostApplication()
{
// Create a configuration property map.
Map config = new HashMap();
config.put(Constants.FRAMEWORK_STORAGE_CLEAN, Constants.FRAMEWORK_STORAGE_CLEAN_ONFIRSTINIT);
// Create host activator;
m_activator = new HostActivator();
List list = new ArrayList();
list.add(m_activator);
config.put(FelixConstants.SYSTEMBUNDLE_ACTIVATORS_PROP, list);
try
{
// Now create an instance of the framework with
// our configuration properties.
m_felix = new Felix(config);
// Now start Felix instance.
m_felix.start();
}
catch (Exception ex)
{
System.err.println("Could not create framework: " + ex);
ex.printStackTrace();
}
// Register the application's context as an OSGi service!
BundleContext bundleContext1 = m_felix.getBundleContext();
System.out.println("6");
try {
//starting ipojo required bundles
Bundle coreBundle = bundleContext1.installBundle("file:C:\\Users\\zaid.almahmoud\\Dropbox\\EBTIC\\ADERE\\feasibility-codes\\ipojo\\ipojo-distribution-1.11.0\\bundle\\org.apache.felix.ipojo-1.6.2.jar");
coreBundle.start();
if(coreBundle.getState()== coreBundle.ACTIVE)
System.out.println("Core Bundle is Active!");
Bundle apiBundle = bundleContext1.installBundle("file:C:\\Users\\zaid.almahmoud\\Dropbox\\EBTIC\\ADERE\\feasibility-codes\\ipojo\\ipojo-distribution-1.11.0\\bundle\\org.apache.felix.ipojo.api-1.6.0.jar");
apiBundle.start();
if(apiBundle.getState()== apiBundle.ACTIVE)
System.out.println("API Bundle is Active!");
Bundle compositeBundle = bundleContext1.installBundle("file:C:\\Users\\zaid.almahmoud\\Dropbox\\EBTIC\\ADERE\\feasibility-codes\\ipojo\\ipojo-distribution-1.11.0\\bundle\\org.apache.felix.ipojo.composite-1.6.0.jar");
compositeBundle.start();
if(compositeBundle.getState()== compositeBundle.ACTIVE)
System.out.println("Composite Bundle is Active!");
//HERE INSTALLING AND STARTING MY BUNDLE!!
Bundle b = bundleContext1.installBundle("file:C:\\Users\\zaid.almahmoud\\Desktop\\plugins\\HelloIPojo_1.0.0.201401211340.jar");
b.start();
try {
ComponentType type = new PrimitiveComponentType()
.setBundleContext(b.getBundleContext())
.setComponentTypeName("hello.type")
.setClassName("helloipojo.HelloServiceImpl")
.setImmediate(true);
type.start();
ComponentInstance instance = type.createInstance();
}
catch (UnacceptableConfiguration
| MissingHandlerException | ConfigurationException e) {
// TODO Auto-generated catch block
e.printStackTrace();
} // Create the instance
System.out.println("done starting bundles!");
} catch (BundleException e) {
e.printStackTrace();
System.out.println("Not done!");
}
//shutdownApplication();
}
public Bundle[] getInstalledBundles()
{
// Use the system bundle activator to gain external
// access to the set of installed bundles.
return m_activator.getBundles();
}
public void shutdownApplication()
{
// Shut down the felix framework when stopping the
// host application.
try {
m_felix.stop();
} catch (BundleException e1) {
// TODO Auto-generated catch block
e1.printStackTrace();
}
try {
m_felix.waitForStop(0);
} catch (InterruptedException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
}
When I run my application, it shows the following output (with the error at the end):
6
Core Bundle is Active!
API Bundle is Active!
Composite Bundle is Active!
Bundle Started!
Exception in thread "main" java.lang.IllegalStateException: The factory associated with the component type is invalid (not started or missing handlers)
at org.apache.felix.ipojo.api.ComponentType.ensureFactory(ComponentType.java:189)
at org.apache.felix.ipojo.api.ComponentType.ensureAndGetFactory(ComponentType.java:177)
at org.apache.felix.ipojo.api.ComponentType.createInstance(ComponentType.java:79)
at HostApplication.<init>(HostApplication.java:109)
at Embedder.main(Embedder.java:11)
Where did I go wrong? Thanks.
Update 1
I could see that I am missing 2 handlers. I knew that by adding the following two lines:
System.out.println(type.getFactory().getRequiredHandlers());
System.out.println(type.getFactory().getMissingHandlers());
The output of the above two lines is:
[org.apache.felix.ipojo:architecture, org.apache.felix.ipojo:callback]
[org.apache.felix.ipojo:architecture, org.apache.felix.ipojo:callback]
I also tried:
type.getFactory().createComponentInstance(new Properties());
then I got:
org.apache.felix.ipojo.MissingHandlerException: Missing handlers : org.apache.felix.ipojo:architecture org.apache.felix.ipojo:callback
I don't know why these handlers are missing. I tried to add them, but could not figure out the right syntax. Any help? Thanks.
Update 2
According to Clement in his answer, my bundle should import: org.apache.felix.ipojo and org.apache.felix.ipojo.architecture
I did that, and now I am getting the following error:
java.lang.ClassCastException: org.apache.felix.ipojo.HandlerManagerFactory cannot be cast to org.apache.felix.ipojo.HandlerFactory
I am getting the error at this line: type.start();
Please help. Thanks!
The issue comes from the asynchronous start of iPOJO. When you create your instance, not everything is available.
I’ve several question: Why are you using the iPOJO API to declare your type and instance ? Can’t you just use the annotations ? In that case it will just create everything smoothly.
If you really need / want to use the API, don’t create the instance like you do, but expose an instance declaration: http://felix.apache.org/documentation/subprojects/apache-felix-ipojo/apache-felix-ipojo-userguide/ipojo-advanced-topics/ipojo-factory-service.html#deleting-instances. The declaration waits until the factory is valid to create the instance.
Here in webcenter-driven ADF application we have a standard library called generic-site-resources-model.jar which contains file META-INF/service-definition.xml, which i wish to alter at one line, to add view resource' security permission, as in:
## -1189,7 +1189,7 ##
<resource-permission>
<resource-permission-impl>oracle.webcenter.security.auth.WebCenterResourcePermission</resource-permission-impl>
<resource-permission-target-id>resource_oracle_webcenter_siteresource_#scope#_navigation_#resource#</resource-permission-target-id>
- <resource-permission-action-list>manage,update</resource-permission-action-list>
+ <resource-permission-action-list>view,manage,update</resource-permission-action-list>
</resource-permission>
</permission-metadata>
</security-definition>
How this is can be possibly done without alterning weblogic domain containing this library itself, somehow configuring our application? Maybe some way to override the whole generic-site-resources-model.jar with application-shipped clone? Or (ideally) some way to replace the targeted resource permission? Or some custom way of taking control over resource loading in application?
It is possible to implement appending custom actions to specific resource type using initialization phase listener and a little bit code, without any overriding at all.
Here is how:
ViewControllerProject/src/META-INF/adf-settings.xml
<?xml version="1.0" encoding="UTF-8" ?>
<adf-settings xmlns="http://xmlns.oracle.com/adf/settings">
<adfc-controller-config xmlns="http://xmlns.oracle.com/adf/controller/config">
<lifecycle>
<phase-listener>
<listener-id>PortalInitializer</listener-id>
<class>com.otr.portal.initializer.PortalInitializer</class>
</phase-listener>
</lifecycle>
</adfc-controller-config>
</adf-settings>
com.otr.portal.initializer.PortalInitializer
package com.otr.portal.initializer;
import oracle.adf.controller.v2.lifecycle.Lifecycle;
import oracle.adf.controller.v2.lifecycle.PagePhaseEvent;
import oracle.adf.controller.v2.lifecycle.PagePhaseListener;
import oracle.webcenter.security.internal.common.SecurityUtil;
import oracle.webcenter.security.model.exception.SecExtensionNotFoundException;
import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;
public class PortalInitializer implements PagePhaseListener {
private static final Log log = LogFactory.getLog(PortalInitializer.class);
private boolean firstCall = true;
#Override
public void afterPhase(PagePhaseEvent pagePhaseEvent) {
if (pagePhaseEvent.getPhaseId() == Lifecycle.INIT_CONTEXT_ID) {
if (firstCall) {
setupViewNavigationResourcePermssion();
firstCall = false;
}
}
}
private void setupViewNavigationResourcePermssion() {
try {
SecurityUtil.getSecurityExtension("oracle.webcenter.siteresources.navigation").getExtensionPermMetadata().getResourcePermMetadata().getResourcePermActionsList().add("view");
} catch (SecExtensionNotFoundException e) {
log.error("Error adding view resource permission to navigation resource type", e);
}
}
#Override
public void beforePhase(PagePhaseEvent pagePhaseEvent) {
}
}
I need to programmatically add and remove a servlet on a Jetty 6 server.
While it is almost straighforward to add I cannot find an effective way to remove.
For my purposes it is important to add and remove a servlet because it is associated to a dynamic compontent architecture. I need to add a new service when I add a component and I need to remove the service when I remove the component.
To add a servlet I used this pattern:
Server server = new Server(8080);
class MyServlet extends HttpServlet
{
#Override
protected void doGet(HttpServletRequest req, HttpServletResponse resp)
throws ServletException, IOException
{
resp.getOutputStream().write("Hello World!".getBytes());
}
}
...
public void addServlet(HttpServlet s, String path)
{
Context root = new Context(server,"/",Context.SESSIONS);
root.addServlet(new ServletHolder(new MyServlet()), "/test/*");
root.getServletHandler().
}
public void removeServlet(HttpServlet s, String path)
{
//What I have to put here ? There is no removeServlet like methods in server/Context/ServletHolder
}
Why removing a servlet is not so obvious? Can you explain me the motivations ?
first off I would recommend updating to jetty 7 or 8 if its possible, jetty 6 is quite old at this point and is lacking the last couple years of development that are present in 7 and 8. heck, jetty 9 is being actively worked on now.
second I wouldn't look at this on the servlet level but the handler level, working with the server to add and remove handlers, which can be either static resource type handlers or full fledged servlet context handlers, or even webapp context handlers.
as to why the servlet context handlers do not have remove servlet type operations, its really not a part of the servlet spec to remove active servlets at that level, fits more at the war deploy/undeploy level. feel free to open an issue on it though, I did experiment with adding and removing at servlet context handler level and you can remove them but it seems to be problematic then adding more afterwards, so I suspect removing the context itself and adding a new one would be your best bet at this point.
Here's instructions for doing it on Jetty 7.
Jetty : Dynamically removing the registered servlet
It should be pretty straight forward to port that code to Jetty 6.
This solution seems to be working:
import javax.servlet.ServletException;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import org.mortbay.jetty.Server;
import org.mortbay.jetty.handler.ContextHandler;
import org.mortbay.jetty.handler.ContextHandlerCollection;
import org.mortbay.jetty.handler.ResourceHandler;
import org.mortbay.jetty.servlet.Context;
import org.mortbay.jetty.servlet.ServletHandler;
import org.mortbay.jetty.servlet.ServletHolder;
import org.mortbay.jetty.servlet.ServletMapping;
public class MyServer extends Server
{
ServletHandler sh = new ServletHandler();
public MyServer()
{
super(9090);
setHandler(sh);
test();
}
class MyServlet extends HttpServlet
{
/**
*
*/
private static final long serialVersionUID = 1L;
#Override
protected void doGet(HttpServletRequest req, HttpServletResponse resp)
throws ServletException, IOException
{
resp.getWriter().println("CIAO!");
}
}
void test()
{
MyServlet ms = new MyServlet();
addServlet(ms, "/ciao/*");
//removeServlet(ms);//uncomment this ilne in order to remove the servlet right after the deploy
}
public void addServlet(HttpServlet s, String path)
{
sh.addServletWithMapping(new ServletHolder(s), path);
for (ServletHolder so : sh.getServlets())
try
{
System.out.println((so.getServlet() == s));
} catch (ServletException e)
{
// TODO Auto-generated catch block
e.printStackTrace();
}
}
public void removeServlet(HttpServlet s)
{
try
{
HashSet<String> names = new HashSet<String>();
for (ServletHolder so : sh.getServlets())
if (so.getServlet() == s)
names.add(so.getName());
HashSet<ServletMapping> sms = new HashSet<ServletMapping>();
for (ServletMapping sm : sh.getServletMappings())
{
if (!names.contains(sm.getServletName()))
sms.add(sm);
}
sh.setServletMappings(sms.toArray(new ServletMapping[] {}));
} catch (ServletException e)
{
// TODO Auto-generated catch block
e.printStackTrace();
}
}
}
I am trying to develop a Basic EJB3 application on JBOSS 4.2 in Eclipse
I have created an EJB project in eclipse.
The following are my remote and local interfaces.
package com.test;
import javax.ejb.Local;
#Local
public interface HelloWorldLocal
{
public String getGreeting();
}
package com.test;
import javax.ejb.Remote;
#Remote
public interface HelloWorldRemote
{
public String getGreeting();
}
and my ejb implementation is
package com.test;
import javax.ejb.Stateless;
#Stateless
public class HelloWorld implements HelloWorldRemote, HelloWorldLocal {
public HelloWorld() {
// TODO Auto-generated constructor stub
}
public String getGreeting() {
// TODO Auto-generated method stub
return "First EJB People";
}
}
I have deployed this as an exploded JAR in JBoss and it runs fine.
My first question is:
What else do I have to add to this exploded jar ?
Secondly I created a stand alone client and added the above jar to its classpath
The client code is as follows
package com.testejb;
import java.io.FileInputStream;
import java.util.Properties;
import javax.naming.InitialContext;
public class TestBean {
/**
* #param args
*/
public static void main(String[] args)
{
// TODO Auto-generated method stub
HelloWorldRemote getMess = null;
try {
Properties props = new Properties();
Properties props = new Properties();
props.setProperty("java.naming.factory.initial","org.jnp.interfaces.NamingContextFactory");
props.setProperty("java.naming.factory.url.pkgs", "org.jboss.naming");
props.setProperty("java.naming.provider.url", "localhost:1099");
InitialContext ic = new InitialContext(props);
//
getMess = (HelloWorldRemote) ic.lookup("HelloWorldRemote/remote");
System.out.println(getMess.getGreeting());
} catch (Exception e)
{
// TODO: handle exception
e.printStackTrace();
}
}
}
The name of the jar is FirstEJB.
I have tried the look up as FirstEJB/HelloWorldRemote/remote.
But when I run the program I get the error
javax.naming.NameNotFoundException: HelloWorldRemote not bound
If I type the lookup as HelloWorld/remote i get the error
Caused by: java.io.InvalidClassException: org.jboss.ejb3.remoting.BaseRemoteProxy; local class incompatible: stream classdesc serialVersionUID = 1126421850898582900, local class serialVersionUID = -2711693270411201590
What else do I have to add to this exploded jar ?
Nothing, it's usable.
I have tried the look up as FirstEJB/HelloWorldRemote/remote
With JBoss, the JNDI name will be:
<myEarName>/<EJB-Name>/remote
Where the EJB-Name defaults to the Bean name if not specified. So in your case, without using an EAR packaging, the JNDI name should be:
HelloWorld/remote
This should be logged in the server logs at deployment time by the way.
If I type the lookup as HelloWorld/remote I get the error (...)
The JNDI name used for the lookup is correct, this error is another problem that looks very similar to EJBTHREE-1118. Could you try with JBoss 4.2.3.GA?
The second JNDI lookup in the code below fails with an exception when running as a standalone application against Glassfish (which has been configured to expose a QueueConnectionFactory and a DataSource via JNDI). However, the code works fine when the line jndiContext.close() is removed.
In the real code, the call to close() is being made by Spring in a JndiObjectFactoryBean, so I can't easily remove it.
Is this a bug in Glassfish, or am I doing something wrong (e.g. misconfiguration or incorrect coding)?
import javax.naming.Context;
import javax.naming.InitialContext;
public class TestInitCtx {
private final static String QUEUE_CONNECTION_FACTORY_JNDI_NAME = "QCF";
private final static String DATA_SOURCE_JNDI_NAME = "DS";
public static void main(String[] args) throws Exception {
Context jndiContext = new InitialContext();
jndiContext.lookup(QUEUE_CONNECTION_FACTORY_JNDI_NAME);
// In Glassfish, this line causes the second lookup
// to throw a com.sun.enterprise.connectors.ConnectorRuntimeException
// (wrapping a NullPointerException)
jndiContext.close();
jndiContext = new InitialContext();
jndiContext.lookup(DATA_SOURCE_JNDI_NAME);
}
}
Your JNDI implementation may only support a single static implementation of the InitialContext object. You can use the documentation at sun to determine how to find out what the actual concrete type of the JNDI context factory is and then find the implementation docs that detail what close does.