001    /*
002      Copyright (C) 2001 Lionel Seinturier
003    
004      This program is free software; you can redistribute it and/or modify
005      it under the terms of the GNU Lesser General Public License as
006      published by the Free Software Foundation; either version 2 of the
007      License, or (at your option) any later version.
008    
009      This program is distributed in the hope that it will be useful,
010      but WITHOUT ANY WARRANTY; without even the implied warranty of
011      MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
012      GNU Lesser General Public License for more details.
013    
014      You should have received a copy of the GNU Lesser Generaly Public License
015      along with this program; if not, write to the Free Software
016      Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA */
017    
018    package org.objectweb.jac.core.dist.rmi;
019    
020    import java.io.File;
021    import java.io.IOException;
022    import java.lang.Runtime;
023    import java.rmi.Naming;
024    import java.rmi.RMISecurityManager;
025    import java.rmi.RemoteException;
026    import org.apache.log4j.Logger;
027    import org.objectweb.jac.core.dist.Distd;
028    import org.objectweb.jac.core.dist.RemoteContainer;
029    
030    /**
031     * RMIDistd is a jac daemon that supports the RMI communication protocol.
032     *
033     * Daemons hold containers (only one for the moment) which themselves hold
034     * remote objects.
035     *
036     * @author <a href="http://www-src.lip6.fr/homepages/Lionel.Seinturier/index-eng.html">Lionel Seinturier</a>
037     */
038     
039    public class RMIDistd extends Distd {
040        static final Logger logger = Logger.getLogger("dist.rmi");
041    
042        /**
043         * This method initializes the RMI communication protocol.
044         */   
045        public void init() {
046    
047            /** Create and install a security manager */
048           
049            if (System.getSecurityManager() == null)
050                System.setSecurityManager(new RMISecurityManager());
051    
052            try {
053                File path;
054                File jar = new File(org.objectweb.jac.core.Jac.getJacRoot()+"jac.jar");
055                logger.debug("$JAC_ROOT/jac.jar = "+jar.getPath());
056                if (jar.exists()) {
057                    path = jar;
058                } else {
059                    path = new File(org.objectweb.jac.core.Jac.getJacRoot()+"classes");
060                }
061                logger.debug("Launching rmiregistry with CLASSPATH="+path.getPath());
062                rmiProcess = Runtime.getRuntime().exec(
063                    new String[] { "rmiregistry", 
064                                   "-J-classpath", 
065                                   "-J"+path.getPath()});
066            } catch (IOException e) {
067                logger.error("Could not start rmiregistry",e);
068            }
069        }
070    
071        static Process rmiProcess = null;
072    
073        static {
074            Runtime.getRuntime().addShutdownHook(
075                new Thread() {
076                        public void run() {
077                            if (rmiProcess!=null) {
078                                logger.info("Stopping rmiregistry...");
079                                rmiProcess.destroy();
080                            }
081                        }
082                    }
083            );
084        }
085    
086        /**
087         * This method creates a new container and returns it.
088         *
089         * @param name  the container name
090         * @return      the container reference
091         */   
092        protected RemoteContainer newContainer(String name) throws Exception {
093    
094            RMIRemoteContainer remCont = null;
095          
096            try { 
097                remCont = new RMIRemoteContainer(verbose); 
098            } catch(Exception e) { 
099                logger.error("newContainer("+name+
100                             "): Instantiation of RMIRemoteContainer failed",e); 
101                return null; 
102            }
103          
104            //try {
105                registerContainer(remCont, name);
106                /*
107            } catch(Exception e) {
108                // It may fail because rmiregistry is not ready yet
109                // But we don't care since Distd will retry
110                throw new RuntimeException(e.toString());
111            }
112                */
113            remCont.getDelegate().setName(getFullHostName(name));
114    
115            return remCont.getDelegate();
116        }
117      
118    
119        /**
120         * This method creates a new container, instantiates a given class, and
121         * returns the container.
122         *
123         * @param name       the container name
124         * @param className  the name of the class to instantiate
125         * @return           the container reference
126         */   
127        protected RemoteContainer newContainer(String name, String className) 
128            throws Exception 
129        {
130            RMIRemoteContainer remCont = null;
131          
132            try { 
133                remCont = new RMIRemoteContainer(className,verbose); 
134            } catch( Exception e ) { 
135                e.printStackTrace(); 
136                return null; 
137            }
138    
139            registerContainer(remCont, name);
140    
141            remCont.getDelegate().setName(getFullHostName(name));
142    
143            return remCont.getDelegate();
144        }
145       
146    
147        /**
148         * Registers a container in the RMI registry.
149         *
150         * @param container  the container reference
151         * @param name       the container name
152         */   
153        protected void registerContainer(
154            RMIRemoteContainer container,
155            String name) 
156            throws java.rmi.RemoteException 
157        {
158            /** Register the container in the RMI registry */
159            String fullName = getFullHostName(name);
160             
161            try {
162                Naming.rebind(fullName, container);
163            } catch( java.net.MalformedURLException e ) {
164                logger.error("registerContainer("+container+","+name+")",e);
165            }
166    
167            logger.info(
168                "--- JAC Distd (RMI): new container " + fullName + " ---"
169            );
170            logger.info(
171                "--- Default class repository: " + referenceContainerName + " ---"
172            );
173             
174        }
175    
176        /**
177         * This method enters the event loop of
178         * the underlying communication protocol.
179         */
180        public void run() {
181            logger.info( "--- JAC Distd (RMI) is running ---" );
182        }
183    
184        /**
185         * The is the main constructor.
186         *
187         * @param args  command line arguments
188         */   
189        public RMIDistd(String[] args) { 
190            super(args); 
191        }
192    
193        public static void main(String[] args) { 
194            new RMIDistd(args);
195        }
196       
197    }