Hello. I'm trying to store a ConcurrentHashMap in JNDI for beans to read and update from, however it seems to be overwriting the ConcurrentHashMap with a new one when its referrenced by a second bean.
Firstly why am I going down this route? Well the beans may belong to different JVMs, so I ruled out using a singleton bean holding the ConcurrentHashMap. Also, since the objects that will be referenced in the ConcurrentHashMap aren't serializable (they're actually JMS queue objects), I can't write them to a database and get round the problem that way.
Okay, so I have the following test case:
In my bean package:
[b]demo/FirstBean.java[/b]:
[code]
package demo;
import java.util.concurrent.ConcurrentHashMap;
import javax.annotation.Resource;
import javax.ejb.Stateless;
@Stateless
public class FirstBean implements FirstRemote
{
@Resource(mappedName="custom/map")
private ConcurrentHashMap map;
public void first()
{
System.out.println("Call to First");
map.put("First", Integer.valueOf(1));
System.out.println("map after inserting first = " + map);
}
}
[/code]
[b]demo/FirstRemote.java[/b]:
[code]package demo;
import javax.ejb.Remote;
@Remote
public interface FirstRemote
{
void first();
}[/code]
[b]demo/SecondBean.java[/b]:
[code]package demo;
import java.util.concurrent.ConcurrentHashMap;
import javax.annotation.Resource;
import javax.ejb.Stateless;
@Stateless
public class SecondBean implements SecondRemote
{
@Resource(mappedName="custom/map")
private ConcurrentHashMap map;
public void second()
{
System.out.println("Call to Second");
System.out.println("map = " + map);
}
}[/code]
[b]demo/SecondRemote.java[/b]:
[code]package demo;
import javax.ejb.Remote;
@Remote
public interface SecondRemote
{
void second();
}[/code]
In my app package:
[b]resourcedemo/Main.java[/b]:
[code]package resourcedemo;
import demo.FirstRemote;
import demo.SecondRemote;
import java.util.Properties;
import java.util.logging.Level;
import java.util.logging.Logger;
import javax.naming.InitialContext;
import javax.naming.NamingException;
public class Main
{
private static InitialContext ctx = null;
/**
* @param args the command line arguments
*/
public static void main(String[] args)
{
try
{
FirstRemote first = (FirstRemote)getContext().lookup("ejb/FirstBean");
SecondRemote second = (SecondRemote)getContext().lookup("ejb/SecondBean");
first.first();
second.second();
}
catch (NamingException ex)
{
Logger.getLogger(Main.class.getName()).log(Level.SEVERE, null, ex);
}
}
private static InitialContext getContext()
{
if (ctx == null)
{
Properties props = new Properties();
props.setProperty("java.naming.factory.initial", "com.sun.enterprise.naming.SerialInitContextFactory");
props.setProperty("java.naming.factory.url.pkgs", "com.sun.enterprise.naming");
props.setProperty("java.naming.factory.state", "com.sun.corba.ee.impl.presentation.rmi.JNDIStateFactoryImpl");
props.setProperty("org.omg.CORBA.ORBInitialHost", "192.168.16.89");
props.setProperty("org.omg.CORBA.ORBInitialPort", "3791");
try
{
ctx = new InitialContext(props);
}
catch (NamingException ex)
{
Logger.getLogger(Main.class.getName()).log(Level.SEVERE, null, ex);
}
}
return ctx;
}
}[/code]
In my custom glassfish library:
[b]demo/ConcurrentHashMapLibrary.java[/b]:
[code]package demo;
import java.util.Hashtable;
import java.util.concurrent.ConcurrentHashMap;
import javax.naming.Context;
import javax.naming.Name;
import javax.naming.spi.ObjectFactory;
public class ConcurrentHashMapFactory implements ObjectFactory
{
public Object getObjectInstance(Object obj, Name name, Context nameCtx, Hashtable<?, ?> environment) throws Exception
{
System.out.println(">>> Creating and returning a new ConcurrentHashMap instance <<<");
return new ConcurrentHashMap();
}
}[/code]
So, when I run the app client, I see the following in the glassfish log:
[code]INFO: >>> Creating and returning a new ConcurrentHashMap instance <<<
INFO: Call to First
INFO: map after inserting first = {First=1}
INFO: >>> Creating and returning a new ConcurrentHashMap instance <<<
INFO: Call to Second
INFO: map = {}[/code]
So, the FirstBean causes Glassfish to create a ConcurrentHashMap, but when the second bean is called, instead of reusing the map, it creates a new instance.
I feel like I'm missing something fundamental, but what?
[Message sent by forum member 'antilochus']
http://forums.java.net/jive/thread.jspa?messageID=392664