| /* |
| * Copyright (c) 1997, 2012, Oracle and/or its affiliates. All rights reserved. |
| * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. |
| * |
| * This code is free software; you can redistribute it and/or modify it |
| * under the terms of the GNU General Public License version 2 only, as |
| * published by the Free Software Foundation. Oracle designates this |
| * particular file as subject to the "Classpath" exception as provided |
| * by Oracle in the LICENSE file that accompanied this code. |
| * |
| * This code is distributed in the hope that it will be useful, but WITHOUT |
| * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or |
| * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License |
| * version 2 for more details (a copy is included in the LICENSE file that |
| * accompanied this code). |
| * |
| * You should have received a copy of the GNU General Public License version |
| * 2 along with this work; if not, write to the Free Software Foundation, |
| * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. |
| * |
| * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA |
| * or visit www.oracle.com if you need additional information or have any |
| * questions. |
| */ |
| |
| package com.sun.corba.se.impl.activation; |
| |
| import java.lang.reflect.Method; |
| import java.lang.reflect.Modifier; |
| import java.io.*; |
| import java.util.Date; |
| import java.util.Properties ; |
| |
| import org.omg.CORBA.ORB ; |
| import com.sun.corba.se.spi.activation.Activator ; |
| import com.sun.corba.se.spi.activation.ActivatorHelper ; |
| import com.sun.corba.se.impl.orbutil.ORBConstants ; |
| |
| /** |
| * @author Ken Cavanaugh |
| * @since JDK1.2 |
| */ |
| public class ServerMain |
| { |
| /* TODO: |
| * 1. Rewrite all uses of ORB properties to use constants from someplace. |
| * The strings are scattered between here, the ORB classes, and |
| * ServerTableEntry. |
| * 2. Consider a more general log facility. |
| * 3. Remove ServerCallback from POAORB. |
| * 4. Needs to be merged with Harold's changes to support SSL. |
| * 5. Logs need to be internationalized. |
| */ |
| |
| public final static int OK = 0; |
| public final static int MAIN_CLASS_NOT_FOUND = 1; |
| public final static int NO_MAIN_METHOD = 2; |
| public final static int APPLICATION_ERROR = 3; |
| public final static int UNKNOWN_ERROR = 4; |
| public final static int NO_SERVER_ID = 5 ; |
| public final static int REGISTRATION_FAILED = 6; |
| |
| public static String printResult( int result ) |
| { |
| switch (result) { |
| case OK : return "Server terminated normally" ; |
| case MAIN_CLASS_NOT_FOUND : return "main class not found" ; |
| case NO_MAIN_METHOD : return "no main method" ; |
| case APPLICATION_ERROR : return "application error" ; |
| case NO_SERVER_ID : return "server ID not defined" ; |
| case REGISTRATION_FAILED: return "server registration failed" ; |
| default : return "unknown error" ; |
| } |
| } |
| |
| private void redirectIOStreams() |
| { |
| // redirect out and err streams |
| try { |
| String logDirName = |
| System.getProperty( ORBConstants.DB_DIR_PROPERTY ) + |
| System.getProperty("file.separator") + |
| ORBConstants.SERVER_LOG_DIR + |
| System.getProperty("file.separator"); |
| |
| File logDir = new File(logDirName); |
| String server = System.getProperty( |
| ORBConstants.SERVER_ID_PROPERTY ) ; |
| |
| FileOutputStream foutStream = |
| new FileOutputStream(logDirName + server+".out", true); |
| FileOutputStream ferrStream = |
| new FileOutputStream(logDirName + server+".err", true); |
| |
| PrintStream pSout = new PrintStream(foutStream, true); |
| PrintStream pSerr = new PrintStream(ferrStream, true); |
| |
| System.setOut(pSout); |
| System.setErr(pSerr); |
| |
| logInformation( "Server started" ) ; |
| |
| } catch (Exception ex) {} |
| } |
| |
| /** Write a time-stamped message to the indicated PrintStream. |
| */ |
| private static void writeLogMessage( PrintStream pstream, String msg ) |
| { |
| Date date = new Date(); |
| pstream.print( "[" + date.toString() + "] " + msg + "\n"); |
| } |
| |
| /** Write information to standard out only. |
| */ |
| public static void logInformation( String msg ) |
| { |
| writeLogMessage( System.out, " " + msg ) ; |
| } |
| |
| /** Write error message to standard out and standard err. |
| */ |
| public static void logError( String msg ) |
| { |
| writeLogMessage( System.out, "ERROR: " + msg ) ; |
| writeLogMessage( System.err, "ERROR: " + msg ) ; |
| } |
| |
| /** Write final message to log(s) and then terminate by calling |
| * System.exit( code ). If code == OK, write a normal termination |
| * message to standard out, otherwise write an abnormal termination |
| * message to standard out and standard error. |
| */ |
| public static void logTerminal( String msg, int code ) |
| { |
| if (code == 0) { |
| writeLogMessage( System.out, " " + msg ) ; |
| } else { |
| writeLogMessage( System.out, "FATAL: " + |
| printResult( code ) + ": " + msg ) ; |
| |
| writeLogMessage( System.err, "FATAL: " + |
| printResult( code ) + ": " + msg ) ; |
| } |
| |
| System.exit( code ) ; |
| } |
| |
| private Method getMainMethod( Class serverClass ) |
| { |
| Class argTypes[] = new Class[] { String[].class } ; |
| Method method = null ; |
| |
| try { |
| method = serverClass.getDeclaredMethod( "main", argTypes ) ; |
| } catch (Exception exc) { |
| logTerminal( exc.getMessage(), NO_MAIN_METHOD ) ; |
| } |
| |
| if (!isPublicStaticVoid( method )) |
| logTerminal( "", NO_MAIN_METHOD ) ; |
| |
| return method ; |
| } |
| |
| private boolean isPublicStaticVoid( Method method ) |
| { |
| // check modifiers: public static |
| int modifiers = method.getModifiers (); |
| if (!Modifier.isPublic (modifiers) || !Modifier.isStatic (modifiers)) { |
| logError( method.getName() + " is not public static" ) ; |
| return false ; |
| } |
| |
| // check return type and exceptions |
| if (method.getExceptionTypes ().length != 0) { |
| logError( method.getName() + " declares exceptions" ) ; |
| return false ; |
| } |
| |
| if (!method.getReturnType().equals (Void.TYPE)) { |
| logError( method.getName() + " does not have a void return type" ) ; |
| return false ; |
| } |
| |
| return true ; |
| } |
| |
| private Method getNamedMethod( Class serverClass, String methodName ) |
| { |
| Class argTypes[] = new Class[] { org.omg.CORBA.ORB.class } ; |
| Method method = null ; |
| |
| try { |
| method = serverClass.getDeclaredMethod( methodName, argTypes ) ; |
| } catch (Exception exc) { |
| return null ; |
| } |
| |
| if (!isPublicStaticVoid( method )) |
| return null ; |
| |
| return method ; |
| } |
| |
| private void run(String[] args) |
| { |
| try { |
| redirectIOStreams() ; |
| |
| String serverClassName = System.getProperty( |
| ORBConstants.SERVER_NAME_PROPERTY ) ; |
| |
| // determine the class loader to be used for loading the class |
| // since ServerMain is going to be in JDK and we need to have this |
| // class to load application classes, this is required here. |
| ClassLoader cl = Thread.currentThread().getContextClassLoader(); |
| |
| if (cl == null) |
| cl = ClassLoader.getSystemClassLoader(); |
| |
| // determine the main class |
| Class serverClass = null; |
| |
| try { |
| // determine the main class, try loading with current class loader |
| serverClass = Class.forName( serverClassName ) ; |
| } catch (ClassNotFoundException ex) { |
| // eat the exception and try to load using SystemClassLoader |
| serverClass = Class.forName( serverClassName, true, cl); |
| } |
| |
| if (debug) |
| System.out.println("class " + serverClassName + " found"); |
| |
| // get the main method |
| Method mainMethod = getMainMethod( serverClass ) ; |
| |
| // This piece of code is required, to verify the server definition |
| // without launching it. |
| |
| // verify the server |
| |
| boolean serverVerifyFlag = Boolean.getBoolean( |
| ORBConstants.SERVER_DEF_VERIFY_PROPERTY) ; |
| if (serverVerifyFlag) { |
| if (mainMethod == null) |
| logTerminal("", NO_MAIN_METHOD); |
| else { |
| if (debug) |
| System.out.println("Valid Server"); |
| logTerminal("", OK); |
| } |
| } |
| |
| |
| registerCallback( serverClass ) ; |
| |
| // build args to the main and call it |
| Object params [] = new Object [1]; |
| params[0] = args; |
| mainMethod.invoke(null, params); |
| |
| } catch (ClassNotFoundException e) { |
| logTerminal("ClassNotFound exception: " + e.getMessage(), |
| MAIN_CLASS_NOT_FOUND); |
| } catch (Exception e) { |
| logTerminal("Exception: " + e.getMessage(), |
| APPLICATION_ERROR); |
| } |
| } |
| |
| public static void main(String[] args) { |
| ServerMain server = new ServerMain(); |
| server.run(args); |
| } |
| |
| private static final boolean debug = false; |
| |
| private int getServerId() |
| { |
| Integer serverId = Integer.getInteger( ORBConstants.SERVER_ID_PROPERTY ) ; |
| |
| if (serverId == null) |
| logTerminal( "", NO_SERVER_ID ) ; |
| |
| return serverId.intValue() ; |
| } |
| |
| private void registerCallback( Class serverClass ) |
| { |
| Method installMethod = getNamedMethod( serverClass, "install" ) ; |
| Method uninstallMethod = getNamedMethod( serverClass, "uninstall" ) ; |
| Method shutdownMethod = getNamedMethod( serverClass, "shutdown" ) ; |
| |
| Properties props = new Properties() ; |
| props.put( "org.omg.CORBA.ORBClass", |
| "com.sun.corba.se.impl.orb.ORBImpl" ) ; |
| // NOTE: Very important to pass this property, otherwise the |
| // Persistent Server registration will be unsucessfull. |
| props.put( ORBConstants.ACTIVATED_PROPERTY, "false" ); |
| String args[] = null ; |
| ORB orb = ORB.init( args, props ) ; |
| |
| ServerCallback serverObj = new ServerCallback( orb, |
| installMethod, uninstallMethod, shutdownMethod ) ; |
| |
| int serverId = getServerId() ; |
| |
| try { |
| Activator activator = ActivatorHelper.narrow( |
| orb.resolve_initial_references( ORBConstants.SERVER_ACTIVATOR_NAME )); |
| activator.active(serverId, serverObj); |
| } catch (Exception ex) { |
| logTerminal( "exception " + ex.getMessage(), |
| REGISTRATION_FAILED ) ; |
| } |
| } |
| } |
| |
| class ServerCallback extends |
| com.sun.corba.se.spi.activation._ServerImplBase |
| { |
| private ORB orb; |
| private transient Method installMethod ; |
| private transient Method uninstallMethod ; |
| private transient Method shutdownMethod ; |
| private Object methodArgs[] ; |
| |
| ServerCallback(ORB orb, Method installMethod, Method uninstallMethod, |
| Method shutdownMethod ) |
| { |
| this.orb = orb; |
| this.installMethod = installMethod ; |
| this.uninstallMethod = uninstallMethod ; |
| this.shutdownMethod = shutdownMethod ; |
| |
| orb.connect( this ) ; |
| |
| methodArgs = new Object[] { orb } ; |
| } |
| |
| private void invokeMethod( Method method ) |
| { |
| if (method != null) |
| try { |
| method.invoke( null, methodArgs ) ; |
| } catch (Exception exc) { |
| ServerMain.logError( "could not invoke " + method.getName() + |
| " method: " + exc.getMessage() ) ; |
| } |
| } |
| |
| // shutdown the ORB and wait for completion |
| public void shutdown() |
| { |
| ServerMain.logInformation( "Shutdown starting" ) ; |
| |
| invokeMethod( shutdownMethod ) ; |
| |
| orb.shutdown(true); |
| |
| ServerMain.logTerminal( "Shutdown completed", ServerMain.OK ) ; |
| } |
| |
| public void install() |
| { |
| ServerMain.logInformation( "Install starting" ) ; |
| |
| invokeMethod( installMethod ) ; |
| |
| ServerMain.logInformation( "Install completed" ) ; |
| } |
| |
| public void uninstall() |
| { |
| ServerMain.logInformation( "uninstall starting" ) ; |
| |
| invokeMethod( uninstallMethod ) ; |
| |
| ServerMain.logInformation( "uninstall completed" ) ; |
| } |
| } |