On Thu, Oct 9, 2008 at 10:36 AM, André Warnier <[EMAIL PROTECTED]> wrote: > Leon Rosenberg wrote: >> >> On Thu, Oct 9, 2008 at 9:59 AM, André Warnier <[EMAIL PROTECTED]> wrote: >>> >>> I realise that this can be done via e.g. an external DB. >>> It could also probably be done, most portably, by creating an entirely >>> separate application accessed via HTTP calls e.g. (à la "Amazon DB" ?). >>> But it looks as if "within the same container", it would be much more >>> efficient if kept in local memory, and avoiding overhead like TCP/IP or >>> JDBC >>> or RMI. >>> >>> Not being an expert in any of the underlying matters, I would just like >>> to >>> know from the eperts here, but preferably without too many difficult >>> words >>> like "classloader" and "dispatchers", if this is in theory >>> possible/allowed, >>> if it could be done in such a way as to be portable to a different >>> container >>> etc.. >> >> Well, it is possible by placing stuff in shared/lib and access it from >> different contextes, but it will make your life extremely complicated, >> especially if you start to reload applications on the fly, probably >> causing an outofmemory exception at some point. >> On the other side an rmi connection on the local machine is extremely >> cheap (same applies to corba), if you make one call to rmi (or corba) >> in one request to the application you won't even be able to measure >> the transport overhead (far below 1 ms), and taking in account that >> transport from browser to server is much much slower, you can ignore >> the overhead. The overhead of http or soap is much higher due to >> larger footprint of the call, parsing, connection issues (you have to >> reconnect or handle keep alives yourself) and so on. >> Behind your rmi service you can have an external db or just a hashmap >> (concurrent one) or whatever serves best. >> To sum it up, the TOC (total cost of ownership) of an RMI service are >> much much lower as of most other solutions. >> > Many thanks. > So, assuming that I am now convinced by RMI (Remote Method Invocation ?), > how would such a scheme be implemented ? > Are you talking about a separate daemon, running on the same host, which > would "offer RMI services" to all these webapps ?
That would be the standard way of doing it. However, it is well possible that the RMI Service is running in one of the webapps or a special 'dummy' webapp if you want to bundle startup/shutdown. You would also need to start the rmiregistry which is just a programm supplied with the jdk/jre and started by nohup rmiregistry & (on *nix/mac) > Or would this "thing" be living inside Tomcat ? If so, what kind of "thing" > would this be ? It would, I guess, have to start before the webapps do, load > its original data, then remain there waiting for client webapp RMI calls, > yes ? Yes, that would be probably the best :-) It could look like following: public interface CentralDataService extends Remote { void setData(String key, Object value) throws CentralDataServiceException, RemoteException; Object getData(String key)throws CentralDataServiceException, RemoteException; } impl public class CentralDataServiceImpl implements CentralDataService{ private Map<String,Object> data = new ConcurrentHashMap<String,Object>(); public void setData(String key, Object value){ data.put(key,value); } public Object getData(String key){ return data.get(key); } } server, the class you start from command line if run separately. public class CentralDataServer{ private static Logger log = Logger.getLogger(CentralDataServer.class); private static final String REG_HOST = "localhost"; private static final int REG_PORT = Registry.REGISTRY_PORT; //default public static void main(String a[]){ DOMConfigurator.configureAndWatch("/log4j.xml"); Registry rmiRegistry = null; // lookup rmi registry try{ rmiRegistry = LocateRegistry.getRegistry(REG_HOST, REG_PORT); }catch(Exception e){ log.fatal("Coulnd't obtain rmi registry", e); System.err.println("Coulnd't obtain rmi registry"); System.exit(-1); } try{ startService(rmiRegistry); }catch(Exception e){ log.fatal("Couldn't start service", e); System.err.println("Couldn't start service"); System.exit(-2); } } public static final String getServiceId(){ //use your own well known string, might be class name return "net_anotheria_xxx_CentralDataService"; } public static void startService(Registry registry) throws Exception{ CentralDataService myServant = new CentralDataService(); CentralDataService rmiServant = (CentralDataService) UnicastRemoteObject.exportObject(myServant, 0);; // //register service. String serviceId = getServiceId(); registry.rebind(serviceId, rmiServant); log.info("UserServer for service " + serviceId + " is up and running."); } } --------- client: private CentralDataService myDataService; private static Registry rmiRegistry; static{ // lookup rmi registry try{ rmiRegistry = LocateRegistry.getRegistry(REG_HOST, REG_PORT); }catch(Exception e){ log.fatal("Coulnd't obtain rmi registry", e); } } init(){ myDataService = rmiRegistry.lookup(CentralDataServer.getServiceId()); } somewhere in the code: myDataService.setData(.....) myDataService.putData(....)... I haven't actually compiled or tested the code but copied parts from existing (working) code and altered it, so i don't guarantee it will compile ;-) but it should give you the basic idea. regards Leon --------------------------------------------------------------------- To start a new topic, e-mail: users@tomcat.apache.org To unsubscribe, e-mail: [EMAIL PROTECTED] For additional commands, e-mail: [EMAIL PROTECTED]