We had a need to have arbitrary additional java code run inside of the
Jonas VM. To accomplish this we modified the Server.java class to allow
for startup classes. The only requirements on the startup class is that
it have a constructor that takes a Properties object and a String array.
The Properties object is the Servers environment, the String array is
the command line arguments at startup.

The code uses the "services" property to find the names of classes to
startup. It expects this as a comma seperated list...

Please consider the inclusion of our code in the Jonas project. It will
help folks who want to run Servlet engines inside of the server, or
other arbitrary RMI services and have them all be part of a single happy
family. It also allows for easy extension of the server for local
customizations....

thanx,
-gabe
/*
 * The contents of this file are subject to the JOnAS Public License Version
 * 1.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License on the JOnAS web site.
 *
 * Software distributed under the License is distributed on an "AS IS" basis,
 * WITHOUT WARRANTY OF ANY KIND, either express or implied.
 * See the License for the specific terms governing rights and limitations under
 * the License.
 *
 * The Original Code is JOnAS application server code released July 1999.
 *
 * The Initial Developer of the Original Code is Bull S.A.
 * The Original Code and portions created by Bull S.A. are
 *    Copyright (C) 1999 Bull S.A. All Rights Reserved.
 *
 * Contributor(s): ______________________________________.
 *
 * --------------------------------------------------------------------------
 * $Id: Server.java,v 1.3 2000/01/14 10:22:19 durieuph Exp $
 * --------------------------------------------------------------------------
 */


package org.objectweb.jonas.server;

import java.rmi.RMISecurityManager;
import java.util.Vector;
import java.util.Properties;
import java.util.StringTokenizer;
import java.lang.reflect.Constructor;
import javax.naming.Context;         // jndi
import javax.naming.NamingException; // jndi
import org.objectweb.jonas.adm.Adm;
import org.objectweb.jonas.common.Env;
import org.objectweb.jonas.common.Prop;
import org.objectweb.jonas.common.Trace;
import org.objectweb.jonas.container.Container;
import org.objectweb.jonas.jta.Current;
import org.objectweb.jonas.jtm.TMServer;
import org.objectweb.jonas.jtm.TransactionFactory;


/**
 * This class implements an EJB Server.
 *  Only one method: main().
 */
public class Server {

    static private final int trace = Trace.DB_14;

    static public  Container cont         = null;
    static public  Adm       adm          = null;
    static         Current   current      = null;
    static public  Context initialContext = null;

    /**
     * EJBServer main routine. No args.
     */
    public static void main(String args[]) {

        // Print version
        String orbs = null;
        if (Env.isJeremie()) {
            orbs = "Jeremie.";
        } else {
            orbs = "rmi.";
        }
        System.out.println("JOnAS Server, version 1.6.1, running on " + orbs);

        // Inits environment
        Trace.configure();

        // RMI Security Maqnager
        if (System.getSecurityManager() == null) {
            System.setSecurityManager(new RMISecurityManager());
            Trace.outln(trace, "RMISecurityManager loaded");
        }

        // Checks Naming Service
        try {
            initialContext = Env.getInitialContext();
            initialContext.list("");
        } catch (NamingException n) {
            Throwable t = n.getRootCause();
            if (t.getMessage().startsWith("Connection refused to host:")) {
                // Problem with Naming Service: probably not started
                Trace.errln("JOnAS configuration error!");
                Trace.errln("    Connection to Naming Service failed. Please check 
that Naming Service runs properly.");
                System.exit(2);
            } else {
                Trace.errln("JOnAS configuration error!");
                Trace.errln("    "+t.getMessage());
                n.printStackTrace();
                System.exit(2);
            }
        } catch (Exception e) {
                Trace.errln("JOnAS configuration error!");
                e.printStackTrace();
                System.exit(2);
        }

        // TM factory may be local or remote.
        // The TM factory is used by the JTA implementation when transactions
        // are distributed among several JVM (EJBServer or applet client)
        TransactionFactory tm = null;
        String tmRemote = Prop.svr.getValue("jonas.tm.remote");

        if (tmRemote.equalsIgnoreCase("true")) {
            // TM is remote, finds it by JNDI
            Trace.outln(trace, "    Working with a remote Transaction Manager ");
            try {
                tm = (TransactionFactory) initialContext.lookup("TMFactory");
            } catch (Exception e) {
                Trace.errln("Cannot get TM factory\n"+e);
                System.exit(2);
            }
        } else {
            // TM is colocated: initializes it:
            //   - Starts recovery
            //   - Starts timers
            //   - rebind TMFactory in JNDI
            Trace.outln(trace, "    Working with a colocated Transaction Manager ");
            tm = TMServer.init();
        }

        // Create and init the Current object, unique in an EJBServer.
        current = new Current(tm);

        // Register a UserTransactionFactory in JNDI.
        // Do this even if TM is remote, because JTM does not do this anymore.
        // This should be done at JTA level: JTM does not know JTA.
        try {
            Trace.outln(trace, "Register UserTransactionFactory");
            initialContext.rebind("javax.transaction.UserTransaction", current);
        } catch (Exception e) {
            Trace.errln("Cannot rebind UserTransaction:\n"+e);
            return;
        }

        // Creates the Container instance
        // Only one container per EJBServer for now.
        try {
            cont = new Container(current);
            // Adds beans whose deployment descriptor are set in properties.
            cont.addBeans(Env.getDescBeans());
        } catch(Exception e) {
            Trace.errln ("Cannot create Container : " + e);
            return;
        }
        Trace.outln(trace, "Server.main() : Container() call successfull\n");


        // Creates the Adm instance for remote administration
        try {
            adm =  new Adm(cont);
        } catch(Exception e) {
            Trace.errln ("Cannot create Adm : " + e);
            return;
        }

        try {
            Properties p=Prop.svr.getEnv();

            String serv=p.getProperty("services");
            if (serv!=null) {
                StringTokenizer st = new StringTokenizer(serv,",");
                Class[] cargs = {p.getClass(),args.getClass()};
                Object[] vargs = {p,args};
                while (st.hasMoreTokens()) {
                    String name=st.nextToken();
                    try {
                        Class clazz = Class.forName(name.trim());
                        Constructor cons = clazz.getConstructor(cargs);
                        Object o=cons.newInstance(vargs);
                    } catch (Exception ex) {
                        ex.printStackTrace();
                        Trace.errln ("Unable to create "+name+" : " + ex);
                    }
                }
            }
        } catch (Exception e) {
            Trace.errln ("Cannot create Services : " + e);
            return;
        }
    }

}

Reply via email to