KickJava   Java API By Example, From Geeks To Geeks.

Java > Open Source Codes > com > sun > enterprise > tools > launcher > ProcessLauncher


1 /*
2  * The contents of this file are subject to the terms
3  * of the Common Development and Distribution License
4  * (the License). You may not use this file except in
5  * compliance with the License.
6  *
7  * You can obtain a copy of the license at
8  * https://glassfish.dev.java.net/public/CDDLv1.0.html or
9  * glassfish/bootstrap/legal/CDDLv1.0.txt.
10  * See the License for the specific language governing
11  * permissions and limitations under the License.
12  *
13  * When distributing Covered Code, include this CDDL
14  * Header Notice in each file and include the License file
15  * at glassfish/bootstrap/legal/CDDLv1.0.txt.
16  * If applicable, add the following below the CDDL Header,
17  * with the fields enclosed by brackets [] replaced by
18  * you own identifying information:
19  * "Portions Copyrighted [year] [name of copyright owner]"
20  *
21  * Copyright 2006 Sun Microsystems, Inc. All rights reserved.
22  */

23
24
25 package com.sun.enterprise.tools.launcher;
26
27 import java.io.FileWriter JavaDoc;
28 import java.io.File JavaDoc;
29 import java.io.FilenameFilter JavaDoc;
30 import java.io.IOException JavaDoc;
31 import java.io.BufferedReader JavaDoc;
32 import java.io.InputStreamReader JavaDoc;
33 import java.io.InputStream JavaDoc;
34 import java.io.OutputStream JavaDoc;
35 import java.io.ByteArrayOutputStream JavaDoc;
36 import java.io.OutputStreamWriter JavaDoc;
37 import java.io.PrintWriter JavaDoc;
38 import java.io.PrintStream JavaDoc;
39 import java.io.FileOutputStream JavaDoc;
40 import java.io.FileNotFoundException JavaDoc;
41 import java.io.BufferedWriter JavaDoc;
42 import java.io.PushbackInputStream JavaDoc;
43 import java.lang.InterruptedException JavaDoc;
44 import java.util.Iterator JavaDoc;
45 import java.util.StringTokenizer JavaDoc;
46 import java.util.ArrayList JavaDoc;
47 import java.util.Properties JavaDoc;
48 import java.util.regex.Pattern JavaDoc;
49 import java.util.logging.Logger JavaDoc;
50 import java.util.logging.Level JavaDoc;
51 import java.util.logging.FileHandler JavaDoc;
52 import java.util.logging.Handler JavaDoc;
53 import java.util.logging.SimpleFormatter JavaDoc;
54 import java.util.List JavaDoc;
55 import java.util.ArrayList JavaDoc;
56 import javax.xml.parsers.DocumentBuilder JavaDoc;
57 import javax.xml.parsers.DocumentBuilderFactory JavaDoc;
58 import org.w3c.dom.Document JavaDoc;
59 import org.w3c.dom.Node JavaDoc;
60 import org.w3c.dom.Element JavaDoc;
61 import org.w3c.dom.NodeList JavaDoc;
62 import org.xml.sax.SAXException JavaDoc;
63 import javax.xml.parsers.ParserConfigurationException JavaDoc;
64
65 import com.sun.logging.LogDomains;
66 import com.sun.enterprise.util.OS;
67 import com.sun.enterprise.util.RelativePathResolver;
68 import com.sun.enterprise.util.ASenvPropertyReader;
69 import com.sun.enterprise.util.SystemPropertyConstants;
70 import com.sun.enterprise.util.ProcessExecutor;
71 import com.sun.enterprise.util.i18n.StringManager;
72 import com.sun.enterprise.config.ConfigContext;
73 import com.sun.enterprise.config.ConfigException;
74 import com.sun.enterprise.config.ConfigFactory;
75 import com.sun.enterprise.config.ConfigBean;
76 import com.sun.enterprise.config.serverbeans.Config;
77 import com.sun.enterprise.config.serverbeans.Domain;
78 import com.sun.enterprise.config.serverbeans.Server;
79 import com.sun.enterprise.config.serverbeans.NodeAgent;
80 import com.sun.enterprise.config.serverbeans.Cluster;
81 import com.sun.enterprise.config.serverbeans.JavaConfig;
82 import com.sun.enterprise.config.serverbeans.LogService;
83 import com.sun.enterprise.config.serverbeans.Profiler;
84 import com.sun.enterprise.config.serverbeans.ElementProperty;
85 import com.sun.enterprise.config.serverbeans.SystemProperty;
86 import com.sun.enterprise.config.serverbeans.ConfigAPIHelper;
87 import com.sun.enterprise.config.serverbeans.ServerBeansFactory;
88 import com.sun.enterprise.config.serverbeans.ServerHelper;
89 import com.sun.enterprise.config.serverbeans.NodeAgentHelper;
90 import com.sun.enterprise.config.serverbeans.ClusterHelper;
91 import com.sun.enterprise.cli.framework.CliUtil;
92 import com.sun.enterprise.security.store.IdentityManager;
93 import com.sun.enterprise.admin.util.JvmOptionsHelper;
94
95 /**
96  * This is the main class for the new ProcessLauncher which is responcible for creating and
97  * executing a java command. There are two general types of commands, internal and external.
98  * An internal command is basically one that is mostly defined by domain.xml. The command's
99  * java-config (classpath, jvm option, system properties, debug info, ...) is extracted from
100  * domain.xml using the config-api who's information is coupled with more general information
101  * from the processLauncher.xml file. How the final command is executed is based on the
102  * "com.sun.aas.launcherReturn" system property:
103  *
104  * "return" - denotes that the command is executed via the Runtime .exec and immediately returns.
105  * If the "verbose" option is present as an argurment then the processes' stdout and stderr is
106  * attached to and sent to the stderr of the calling process.
107  *
108  * "hold" - denotes that the command is written to a temporary script in the calling scripts
109  * directory, then once the ProcessLauncher's java command returns the script is executed as the
110  * next command in the script and doesn't return until the temportary script finishes execution.
111  */

112
113 public class ProcessLauncher {
114     
115     protected static final String JavaDoc RELATIVE_LOCATION_DOMAIN_XML="/config/domain.xml";
116     protected static final String JavaDoc CLASSPATH_ENV_NAME="CLASSPATH";
117     protected static final String JavaDoc JAVA_HOME_PROPERTY="JAVA_HOME";
118     protected static final String JavaDoc LAUNCHER_PROFILE_NAME="com.sun.aas.processName";
119     protected static final String JavaDoc LAUNCHER_RETURN_FUNCTION="com.sun.aas.launcherReturn";
120     protected static final String JavaDoc LAUNCHER_RETURN_FUNCTION_WAIT="hold";
121     protected static final String JavaDoc LAUNCHER_SCRIPT_LOCATION="bin";
122     protected static final String JavaDoc LAUNCHER_START_ACTION="start";
123     protected static final String JavaDoc LAUNCHER_STOP_ACTION="stop";
124     protected static final String JavaDoc INTERNAL_SERVER_PROFILE="s1as8-server";
125     protected static final String JavaDoc AS9_INTERNAL_SERVER_PROFILE="as9-server";
126     protected static final String JavaDoc INTERNAL_NODE_AGENT_PROFILE="s1as8-nodeagent";
127     protected static final int SLEEP_TIME_FOR_PROCESS_START=2000;
128     protected static final String JavaDoc COMMAND_LINE_ARG_VERBOSE="verbose";
129     protected static final String JavaDoc COMMAND_LINE_ARG_DEBUG="debug";
130     protected static final String JavaDoc COMMAND_LINE_ARG_DISPLAY="display";
131     protected static final String JavaDoc COMMAND_LINE_ARG_NATIVE="native";
132     protected static final char COMMAND_DELIMITER_LIST[] = {'_','+','^','@','!','?','(',')','~','`','{','}'};
133     
134     public static final String JavaDoc DEBUG_OPTIONS = "com.sun.aas.jdwpOptions";
135     public static final String JavaDoc VERBOSE_SYSTEM_PROPERTY = "com.sun.aas.verboseMode";
136     public static final String JavaDoc LOGFILE_SYSTEM_PROPERTY = "com.sun.aas.defaultLogFile";
137     public static final String JavaDoc PROPMPT_FOR_IDENTITY_SYSTEM_PROPERTY = "com.sun.aas.promptForIdentity";
138     public static final String JavaDoc SPARC = "sparc";
139     public static final String JavaDoc SPARCV9 = "sparcv9";
140     public static final String JavaDoc X86 = "x86";
141     public static final String JavaDoc AMD64 = "amd64";
142     public static final String JavaDoc JVM_OPTION_FOR_64BIT = "-d64";
143     
144     private static final String JavaDoc CLASSPATH_PREFIX_PROPERTY = "com.sun.aas.ClassPathPrefix";
145     private static final String JavaDoc CLASSPATH_SUFFIX_PROPERTY = "com.sun.aas.ClassPathSuffix";
146     private static final String JavaDoc SERVER_CLASSPATH_PROPERTY = "com.sun.aas.ServerClassPath";
147
148     
149     
150     private Logger JavaDoc _logger = null;
151     private String JavaDoc[] _args=null;
152     private static boolean bDebug=false;
153     
154     
155     public static void main(String JavaDoc[] args) {
156         ProcessLauncher pl=new ProcessLauncher();
157     
158         pl.process(args);
159     }
160     
161     
162     /**
163      * This method is meant to be called from the PLBootstrap.class to finish the setup
164      * of the ProcessLauncher to execute normally
165      *
166      * arg[0] - should be the name of the profile to use from processLauncher.xml
167      * arg[1] - should be the action to run (default is "start")
168      */

169     public static void bootstrap(String JavaDoc[] args) {
170         ProcessLauncher pl=new ProcessLauncher();
171         
172         // set to nodeagent, by default
173
String JavaDoc profile="s1as-deploytool";
174         if (args != null && args.length >= 1) {
175             // set to argument profile
176
profile=args[0];
177             
178             // shift args
179
String JavaDoc[] newArgs=new String JavaDoc[args.length - 1];
180             for (int ii=0; ii < newArgs.length; ii++) {
181                 newArgs[ii]=args[ii + 1];
182             }
183             
184             // set back to args
185
args=newArgs;
186         }
187         
188         // put profile in properties for later use
189
System.setProperty(LAUNCHER_PROFILE_NAME, profile);
190         
191         if (bDebug) System.out.println("bootstrapping profile - " + profile);
192         
193         // start processing
194
pl.process(args);
195     }
196     
197     
198     /**
199      * process - This is the method that performs the work of creating the java command line to execute.
200      * This is where the BootStrap launcher and general launcher execute the same track
201      */

202     public void process(String JavaDoc[] args) {
203         int iRet=1;
204         try {
205             
206             // store args for later use (e.g. debug, verbose)
207
setArgs(args);
208             
209             // look for Debug system property
210
if (System.getProperty("Debug") != null) {
211                 // turn on debug, this option was added to help developers
212
// debug the their code what adding/modifying tasks that are executed via
213
// the ProcessLauncher
214
bDebug=true;
215             }
216             
217             // Set verboseMode early so logger will also show verbose output.
218
// Each command type will take care of adding it again, but that is okay.
219
// Only set it not being displayed for native launcher
220
if (isVerboseEnabled() && !isDisplayEnabled()) {
221                 // add to System.properties for config conditional adds
222
System.setProperty(VERBOSE_SYSTEM_PROPERTY, "true");
223             }
224             
225             String JavaDoc passArg=null;
226             if (args != null && args.length >= 1) {
227                 passArg=args[0];
228             } else {
229                 passArg=LAUNCHER_START_ACTION;
230             }
231             
232             // Build command and pass in action
233
if (bDebug) System.out.println("ProcessLauncher Building command ..");
234             Command command=buildCommand(passArg);
235             
236             // execute command that was build and pass in action
237
if (bDebug) System.out.println("ProcessLauncher Executing command ..");
238             executeCommand(command, passArg);
239             
240             // if no exception, should have executed properly or logged errors
241
iRet=0;
242         } catch (ConfigException ce) {
243             // try to log but the log main not be set up properly if domain.xml had a problem
244
getLogger().log(Level.SEVERE, "launcher.config_exception", ce);
245             ce.printStackTrace();
246         } catch (Exception JavaDoc e) {
247             // show in server log
248
getLogger().log(Level.SEVERE, "enterprise.launcher_exception_startup",e);
249             e.printStackTrace();
250         }
251         System.exit(iRet);
252     }
253     
254     
255     /**
256      * executeCommand
257      * @param cmd - command to execute
258      * @param action - action to take, should be start or stop. defaults to "start"
259      */

260     public void executeCommand(Command command, String JavaDoc action) throws IOException JavaDoc {
261         
262         String JavaDoc[] cmd=null;
263         
264         // For native launcher and service, must send command to stdout in know format for
265
// parsing by native code. The purpose is to keep as much of the launcher functionality in
266
// java as possible, keeping maintanance low and staying within a skillset that we have in abundance
267
// It also is a easy way to show the command that is generated
268
if (isDisplayEnabled()) {
269             
270             
271             // First remove display argument that is used to trigger this action
272
// This is the only arg that should be removed, all the rest should be passed through
273
command.removeArg(COMMAND_LINE_ARG_DISPLAY);
274             command.removeArg(COMMAND_LINE_ARG_NATIVE);
275     
276             // add launcher type for display to native exe, so the exe can desice whether to hold the child's
277
// process or not.
278
String JavaDoc launcherRet=System.getProperty(LAUNCHER_RETURN_FUNCTION);
279             if (launcherRet != null ) {
280                 if (bDebug) System.out.println("-D" + LAUNCHER_RETURN_FUNCTION + "=" + launcherRet);
281                 command.addSystemVariable("-D" + LAUNCHER_RETURN_FUNCTION + "=" + launcherRet);
282             }
283             
284             // display java command to stdout in the following format.
285
// NOTE: if this becomes externally available, use xml, for now its an internal structure.
286
// Class Name (path is seperated by "/" |
287
// Java Args |
288
// everything else (should start with a "-") |
289
// classpath should be prepended with "-Djava.class.path="
290
cmd=command.getCommandInJNIFormatAsArray();
291             
292             // Find delimiter that doesn't exist in command, just to be safe
293
boolean found=false;
294             String JavaDoc sxDelim="|";
295             for(int ii=0; ii < COMMAND_DELIMITER_LIST.length; ii++) {
296                 // reset found to false for new delimiter
297
found=false;
298                 // first character should delimiter to used to parse command
299
for(int jj=0; jj < cmd.length; jj++) {
300                     if(cmd[jj].indexOf(COMMAND_DELIMITER_LIST[ii]) < 0) {
301                         // delimiter is found in string
302
found=true;
303                         break;
304                     }
305                 }
306                 
307                 // see if char not found in any string
308
if (!found) {
309                     // didn't find delimiter, so set and exit
310
sxDelim=String.valueOf(COMMAND_DELIMITER_LIST[ii]);
311                     break;
312                 }
313             }
314             
315             // INCREDIBLY IMPORTANT for native processing.
316
// The only data the native process expects is the commandline
317
// any other data sent to stdout will throw off the command parsing
318
// Needed to make the native side have a synch string, because anything could go wrong
319
// with either the script that initiates this class or the preBuildProcessing.
320
System.out.print("STARTOFCOMMAND" + sxDelim);
321             for(int ii=0; ii < cmd.length; ii++) {
322                 System.out.print(cmd[ii] + sxDelim);
323             }
324             System.out.print("ENDOFCOMMAND" + sxDelim);
325             
326         } else { // all other execution paths
327
executeBackgroundCommand(command, isVerboseEnabled(), action);
328         }
329         
330     }
331     
332     
333     protected void preBuildProcessing() {
334         // this is a place holder so ee can put in its
335
// sychronization code
336
}
337     
338     
339     public void executeBackgroundCommand(Command command, boolean verbose, String JavaDoc action) throws IOException JavaDoc {
340         
341         // execute the command as a runtime.exec and immediately return,
342
// return will not pertain to the the executed process
343
getLogger().log(Level.FINE, "ProcessLauncher: executing Runtime execute...");
344         
345         // run command
346
String JavaDoc[] cmd=command.getCommandAsArray();
347         Process JavaDoc process=Runtime.getRuntime().exec(cmd);
348         
349         
350         // See is there is input that needs to be sent to the process
351
if (System.getProperty(PROPMPT_FOR_IDENTITY_SYSTEM_PROPERTY) != null && action.equals(LAUNCHER_START_ACTION)) {
352             sendInputToProcessInput(System.in, process);
353         }
354         
355         // start stream flusher to push output to parent streams and log if they exist
356
StreamFlusher sfErr=new StreamFlusher(process.getErrorStream(), System.err, command.getLogFile());
357         sfErr.start();
358         
359         if (verbose || isWaitEnabled()) {
360             // need to keep client around for start
361
// this should only be invoked for start-domain command
362

363             // set flusher on stdout also
364
StreamFlusher sfOut=new StreamFlusher(process.getInputStream(), System.out, command.getLogFile());
365             sfOut.start();
366             
367             try {
368                 process.waitFor();
369                 sfOut.join();
370                 sfErr.join();
371             } catch (InterruptedException JavaDoc ie) {
372                 // just let fall through, but log at finest level
373
System.out.println("While waiting in verbose mode, an InterruptedException was thrown ");
374             }
375         } else {
376             
377             // set flusher on stdout also, if not could stop with too much output
378
StreamFlusher sfOut=new StreamFlusher(process.getInputStream(), System.out);
379             sfOut.start();
380
381             // if executing in the background and a log exists, print log location
382
String JavaDoc logFile=command.getLogFile();
383             if (logFile != null) {
384                 System.out.println(StringManager.getManager(ProcessLauncher.class).getString("launcher.redirecting.output",
385                 logFile));
386             }
387             
388             // must sleep for a couple of seconds, so if there is a jvm startup error, the parent process
389
// is around to catch and report it when the process in executed in verbose mode.
390
try {
391                 Thread.currentThread().sleep(SLEEP_TIME_FOR_PROCESS_START);
392             } catch (InterruptedException JavaDoc ie) {}
393         }
394     }
395     
396     private void sendInputToProcessInput(InputStream JavaDoc in, Process JavaDoc subProcess) {
397         // return if no input
398
if (in == null || subProcess == null) return;
399         
400         PrintWriter JavaDoc out=null;
401         BufferedReader JavaDoc br=null;
402         try {
403             // open the output stream on the process which excepts the input
404
out = new PrintWriter JavaDoc(new BufferedWriter JavaDoc(
405             new OutputStreamWriter JavaDoc(subProcess.getOutputStream())));
406             
407             // read in each line and resend it to sub process
408
br=new BufferedReader JavaDoc(new InputStreamReader JavaDoc(System.in));
409             String JavaDoc sxLine=null;
410             while ((sxLine=br.readLine()) != null) {
411                 // get input lines from process if any
412
out.println(sxLine);
413                 if (bDebug) System.out.println("Feeding in Line:" + sxLine);
414             }
415             out.flush();
416         } catch (Exception JavaDoc e) {
417             getLogger().log(Level.INFO,"WRITE TO INPUT ERROR", e);
418         } finally {
419             try {
420                 if (out != null) out.close();
421             } catch (Throwable JavaDoc t) {}
422         }
423     }
424     
425     public Command buildCommand(String JavaDoc action) throws ConfigException {
426         
427         // execute any preprocessing,
428
preBuildProcessing();
429         String JavaDoc processName=System.getProperty(LAUNCHER_PROFILE_NAME, INTERNAL_SERVER_PROFILE);
430         
431         // check to see whether to build external or internal (domain.xml) command
432
Command command=null;
433         if (isServerProfile()) {
434             command=buildInternalCommand(action);
435         } else {
436             command=buildExternalCommand(action);
437         }
438         
439         // log final command
440
String JavaDoc finalCommand=command.toStringWithLines();
441         getLogger().log(Level.INFO, finalCommand);
442         
443         return command;
444     }
445     
446     
447     /**
448      * buildInternalCommand - This Method build san internal server command from domain.xml, so this
449      * method is specifically used for server instances
450      */

451     public Command buildInternalCommand(String JavaDoc action) throws ConfigException {
452         
453         StringManager _strMgr=StringManager.getManager(ProcessLauncher.class);
454         
455         // derive domain.xml location and create config to be used by config api
456
String JavaDoc domainXMLLocation=System.getProperty(SystemPropertyConstants.INSTANCE_ROOT_PROPERTY)
457         + RELATIVE_LOCATION_DOMAIN_XML;
458         ConfigContext configCtxt=ConfigFactory.createConfigContext(domainXMLLocation);
459         Domain domain=ConfigAPIHelper.getDomainConfigBean(configCtxt);
460         // get the server's config by name, need it as soon as possible for logging
461
String JavaDoc serverName=System.getProperty(SystemPropertyConstants.SERVER_NAME);
462         Server server=ServerHelper.getServerByName(configCtxt, serverName);
463         String JavaDoc configRef=server.getConfigRef();
464         
465         // create the command to execute
466
Command command=new Command();
467         
468         // set jvmargs for thread dump to go to child process log, workaround for bug #4957071
469
//command.addJvmOption("-XX:+UnlockDiagnosticVMOptions");
470
//command.addJvmOption("-XX:+LogVMOutput");
471
//command.addJvmOption("-XX:LogFile=" + logFile);
472
//command.addJvmOption("-XX:LogFile=/tmp/threadDump.txt");
473

474         // get server's config
475
Config config=ServerHelper.getConfigForServer(configCtxt, serverName);
476         
477         // configure log service and print redirect message
478
String JavaDoc logFile=configureLogService(config);
479         if (bDebug) System.out.println("LOGFILE = " + logFile);
480         
481         // make sure log is writable, if not a message will be logged to the screen if in verbose mode
482
createFileStructure(logFile);
483         command.setLogFile(logFile);
484         
485         // should NOT need to addLogFileToLogger(logFile), logManager should already do this for us
486
// may need to enable if log is movable ???
487
//addLogFileToLogger(logFile);
488

489         // add log to properties so PEMAIN will redirect is applicable
490
command.addSystemVariable("-D" + LOGFILE_SYSTEM_PROPERTY + "=" + logFile);
491         
492         getLogger().log(Level.FINE,"Retrieved domain.xml from " + domainXMLLocation);
493         getLogger().log(Level.FINE,"Start building the command the to execute.");
494         
495         //Set system properties that correspond directly to asenv.conf/bat. This
496
//keeps us from having to pass them all from -D on the command line.
497
ASenvPropertyReader reader = new ASenvPropertyReader(System.getProperty(SystemPropertyConstants.CONFIG_ROOT_PROPERTY));
498         reader.setSystemProperties();
499         
500         // verbose set, flag used in ServerLogManager to send logs to stderr
501
if (isVerboseEnabled()) {
502             command.addSystemVariable("-D" + VERBOSE_SYSTEM_PROPERTY + "=true");
503             // add to System.properties for config conditional adds (could be set about if not native launcher)
504
System.setProperty(VERBOSE_SYSTEM_PROPERTY, "true");
505         }
506         
507         // read in ProcessLauncherConfig
508
String JavaDoc launcherConfigFile=System.getProperty(SystemPropertyConstants.INSTALL_ROOT_PROPERTY)
509         + File.separator + "lib" + File.separator + "processLauncher.xml";
510         
511         String JavaDoc processName=System.getProperty(LAUNCHER_PROFILE_NAME, INTERNAL_SERVER_PROFILE);
512         getLogger().log(Level.FINE,"Loading ProcessLauncher config from: " + launcherConfigFile
513         + " - for the process named: " + processName);
514         
515         ProcessLauncherConfig plConfig=new ProcessLauncherConfig(launcherConfigFile, processName);
516         
517         // take plConfig properties as the base for the system jvm args for the new process
518
Properties JavaDoc systemProperties=plConfig.getSystemProperties();
519
520         // add domain.xml property elements to the jvm args in reverse order of precedence.
521
// First add the domain properties
522
addSystemProperties(domain.getSystemProperty(), systemProperties);
523
524         // set config name (which is retrieved from domain.xml) into System properties to be used for path resolution
525
System.setProperty(SystemPropertyConstants.CONFIG_NAME_PROPERTY, configRef);
526         systemProperties.put(SystemPropertyConstants.CONFIG_NAME_PROPERTY, configRef);
527         
528         // get javaconfig for server that is being started
529
JavaConfig javaConfig=config.getJavaConfig();
530         
531         // derive and add java command to Command
532
String JavaDoc jvmCmd=javaConfig.getJavaHome() + File.separator + "bin"
533             + File.separator + "java";
534
535         command.setJavaCommand(jvmCmd);
536         
537
538         // fix for bug# 6323645
539
// Do not add options which are not applicable for stop action.
540
// For ex. debug options and profiler options.
541
// In other words add the following options ony when the action
542
// is other than stop.
543

544         Profiler profiler=javaConfig.getProfiler();
545         String JavaDoc profilerClasspath=null;
546
547         if (!action.equals(LAUNCHER_STOP_ACTION)) {
548
549         // The debug options including the debug port would be added
550
// to the command when the action is start.
551
// If the action is stop adding the same port to the java command
552
// would stack up the ports and block until the port assigned for
553
// start action is released. To avoid this we check for stop action.
554

555         // If the stop action needs to be debugged then one work around is to
556
// copy the java command from server.log, change the debug settings and
557
// run the command.
558

559         // debug options
560
if ((javaConfig.isDebugEnabled() || isDebugEnabled())) {
561                 // add debug statements
562
addDebugOptions(command, javaConfig.getDebugOptions());
563             }
564
565             // add profiler properties & jvm args
566
if (profiler != null && profiler.isEnabled()) {
567                 // add config properties
568
addElementProperties(profiler.getElementProperty(), systemProperties);
569                 String JavaDoc [] jvmOptions=profiler.getJvmOptions();
570                 addJvmOptions(command, jvmOptions);
571                 profilerClasspath=profiler.getClasspath();
572             }
573         }
574         
575         // set the default locale specified in domain.xml config file
576
String JavaDoc locale=domain.getLocale();
577         if (locale == null || locale.equals("")) {
578             // if not specified in domain try system
579
locale=System.getProperty(SystemPropertyConstants.DEFAULT_LOCALE_PROPERTY);
580         }
581         // make sure locale is specified before setting it
582
if (locale != null && !locale.equals("")) {
583             command.addSystemVariable("-D" + SystemPropertyConstants.DEFAULT_LOCALE_PROPERTY + "=" + locale);
584         }
585         
586         //
587
// add jvm args, look for combined jvm options
588
String JavaDoc[] jvmOptions=javaConfig.getJvmOptions();
589
590         //
591
// fix for bug# 6416997 so that the memory options
592
// -Xmx and -Xms are not passed to jvm for stop command
593
//
594
if (LAUNCHER_STOP_ACTION.equals(action) && (jvmOptions != null)) {
595             try {
596                 jvmOptions = (new JvmOptionsHelper(jvmOptions)).getJvmOptions();
597             } catch (Exception JavaDoc e) {
598                 if ((getLogger()) != null) {
599                     getLogger().log(Level.SEVERE, "launcher.jvmoptions_exception", e);
600                 }
601                 e.printStackTrace();
602             }
603             jvmOptions = removeJVMStopOptions(jvmOptions);
604         }
605
606         addJvmOptions(command, jvmOptions);
607         
608         //
609
// add config system properties
610
addSystemProperties(config.getSystemProperty(), systemProperties);
611         
612         //
613
// add cluster system properties if the server instance is clustered
614
if (ServerHelper.isServerClustered(configCtxt, server)) {
615             Cluster cluster = ClusterHelper.getClusterForInstance(configCtxt,
616             server.getName());
617             addSystemProperties(cluster.getSystemProperty(), systemProperties);
618         }
619         
620         //
621
// add server system properties
622
addSystemProperties(server.getSystemProperty(), systemProperties);
623         
624         //
625
// add classpath
626
// check to see if jvmCmd starts with same as processLauncher jvm.
627
// if so, use the system property java-version to determine jvm version
628
if(OS.isWindows()) {
629             // make sure all delimeters are the same
630
jvmCmd=jvmCmd.replace('/', '\\');
631         }
632         
633         if (jvmCmd.startsWith(System.getProperty(SystemPropertyConstants.JAVA_ROOT_PROPERTY))) {
634             // jvm command are the same, so use processLauncher jvm version
635
jvmCmd=null;
636         }
637         String JavaDoc classpath=deriveClasspath(plConfig, jvmCmd, javaConfig, profilerClasspath);
638         getLogger().log(Level.FINE, "Complete process classpath = " + classpath);
639         command.setClasspath(classpath);
640         
641         //
642
//add main class
643
command.setMainClass(plConfig.getMainClass());
644         
645         //
646
// native library path to java path and system properties
647
deriveNativeClasspath(command, javaConfig, profiler, systemProperties);
648         
649         //
650
// add all system properties to command as jvm args
651
Iterator JavaDoc it=systemProperties.keySet().iterator();
652         String JavaDoc key=null;
653         String JavaDoc property=null, value=null;;
654         while(it.hasNext()) {
655             key=(String JavaDoc)it.next();
656             value=systemProperties.getProperty(key);
657             
658             // take care of vm arg that are sent in via the processlauncher.xml file
659
if (key.startsWith("-")) {
660                 property = key;
661                 if (value != null && !value.equals("")) {
662                     property += "=" + value;
663                 }
664                 command.addJvmOption(property);
665                 getLogger().log(Level.FINE, "JVM Option: " + property);
666             } else {
667                 // regular system property
668
property = "-D" + key + "=" + value;
669                 command.addSystemVariable(property);
670                 getLogger().log(Level.FINE, "System Property: " + property);
671             }
672         }
673
674         //Add prefix and suffix for AS9Profile
675
if (getProcessLauncherProfile().equals(AS9_INTERNAL_SERVER_PROFILE)) {
676             String JavaDoc classpathPrefix=javaConfig.getClasspathPrefix();
677             String JavaDoc classpathSuffix=javaConfig.getClasspathSuffix();
678             String JavaDoc serverClasspath=javaConfig.getServerClasspath();
679             getLogger().log(Level.FINE, " prefix :: " + classpathPrefix
680                                           + " suffix :: " + classpathSuffix);
681             if (classpathPrefix == null) classpathPrefix = "";
682             command.addSystemVariable("-D" + CLASSPATH_PREFIX_PROPERTY + "=" + classpathPrefix);
683             if (classpathSuffix == null) classpathSuffix = "";
684             command.addSystemVariable("-D" + CLASSPATH_SUFFIX_PROPERTY + "=" + classpathSuffix);
685             if (serverClasspath == null) serverClasspath = "";
686             command.addSystemVariable("-D" + SERVER_CLASSPATH_PROPERTY + "=" + serverClasspath);
687         }
688         
689         
690         //
691
// add command args from script
692
String JavaDoc[] args=getArgs();
693         for(int ii=0; ii < args.length; ii++) {
694             command.addArg(args[ii]);
695         }
696         return command;
697     }
698     
699     
700     /**
701      * This Method builds an external java command to execute componets like the nodeagent
702      * and the deploy tool
703      */

704     public Command buildExternalCommand(String JavaDoc action) throws ConfigException {
705         
706         // create the command to execute
707
Command command=new Command();
708         
709         getLogger().log(Level.FINE,"Start building the command the to execute.");
710         
711         // read in ProcessLauncherConfig
712
String JavaDoc launcherConfigFile=System.getProperty(SystemPropertyConstants.INSTALL_ROOT_PROPERTY)
713         + File.separator + "lib" + File.separator + "processLauncher.xml";
714         
715         String JavaDoc processName=System.getProperty(LAUNCHER_PROFILE_NAME, "s1as8-nodeagent");
716         getLogger().log(Level.FINE,"Loading ProcessLauncher config from: " + launcherConfigFile +
717         " - for the process named: " + processName);
718         
719         // see if we have a config root set
720
String JavaDoc configRoot=System.getProperty(SystemPropertyConstants.CONFIG_ROOT_PROPERTY);
721         if (configRoot == null) {
722             // no config root try and make one from install root
723
configRoot=System.getProperty(SystemPropertyConstants.INSTALL_ROOT_PROPERTY) + File.separator + "config";
724         }
725         //Set system properties that correspond directly to asenv.conf/bat. This
726
//keeps us from having to pass them all from -D on the command line.
727
ASenvPropertyReader reader = new ASenvPropertyReader(configRoot);
728         reader.setSystemProperties();
729         
730         // verbose set, flag used in ServerLogManager to send logs to stderr
731
if (isVerboseEnabled()) {
732             command.addSystemVariable("-D" + VERBOSE_SYSTEM_PROPERTY + "=true");
733             // add to System.properties for config conditional adds (could be set about if not native launcher)
734
System.setProperty(VERBOSE_SYSTEM_PROPERTY, "true");
735         }
736         
737         // get configuration
738
ProcessLauncherConfig plConfig=new ProcessLauncherConfig(launcherConfigFile, processName);
739         
740         // take plConfig properties as the base for the system jvm args for the new process
741
Properties JavaDoc systemProperties=plConfig.getSystemProperties();
742         
743         // check for log file location
744
String JavaDoc logFile=systemProperties.getProperty(LOGFILE_SYSTEM_PROPERTY);
745         if(bDebug) System.out.println("Is external command nodeagent - " + isNodeAgentProfile());
746         if (isNodeAgentProfile()) {
747             // need to get log info from domain.xml
748
getLogger().log(Level.FINE,"BuildExternalCommand for NodeAgent");
749             
750             try {
751                 // derive domain.xml location and create config to be used by config api
752
String JavaDoc domainXMLLocation=System.getProperty(SystemPropertyConstants.INSTANCE_ROOT_PROPERTY)
753                 + RELATIVE_LOCATION_DOMAIN_XML;
754                 ConfigContext configCtxt=ConfigFactory.createConfigContext(domainXMLLocation);
755                 Domain domain=ConfigAPIHelper.getDomainConfigBean(configCtxt);
756
757                 // get the nodeagent by name, need it as soon as possible for logging
758
String JavaDoc nodeAgentName=System.getProperty(SystemPropertyConstants.SERVER_NAME);
759                 NodeAgent nodeAgent=NodeAgentHelper.getNodeAgentByName(configCtxt, nodeAgentName);
760                 LogService logService=nodeAgent.getLogService();
761
762                 if(logService != null) {
763                     getLogger().log(Level.FINE, "LogService found for nodeagent");
764                     // get logservice info from config beans
765
String JavaDoc logFileX=logService.getFile();
766
767                     if (logFileX !=null) {
768                         logFile=logFileX;
769                         // add log to properties so NodeAgentMain will redirect is applicable
770
systemProperties.setProperty(LOGFILE_SYSTEM_PROPERTY, logFile);
771                     }
772
773                     // set log level to the level that the nodeagent is set to
774
String JavaDoc logLevel=logService.getModuleLogLevels().getNodeAgent();
775                     getLogger().setLevel(Level.parse(logLevel));
776                 }
777             } catch (ConfigException ce) {
778                 // domain.xml should not be there on first start up, just log
779
getLogger().log(Level.FINE,"domain.xml does not exist yet for the nodeagent");
780             }
781         }
782
783         // set log file for logger and native launcher
784
if (logFile != null) {
785             // make sure log is writable, if not a message will be logged to the screen if in verbose mode
786
if(createFileStructure(logFile) && !isInternalLogger()) {
787                 // add this file to the logger so at least some of the launcher info gets propagated
788
addLogFileToLogger(logFile);
789             }
790             command.setLogFile(logFile);
791         }
792         
793         // derive and add java command to Command
794
String JavaDoc javaHome=System.getProperty(JAVA_HOME_PROPERTY);
795         // use javaw for windows instead of java
796
String JavaDoc javaCall="java", javaCmd=null;
797         if(OS.isWindows()) {
798             javaCall="javaw";
799         }
800         
801         if (javaHome != null) {
802             // use standard java home
803
javaCmd=javaHome + File.separator + "bin" + File.separator + javaCall;
804         } else {
805             // use executed jmv location of java.home
806
String JavaDoc javaInt=System.getProperty("java.home");
807             javaCmd=javaInt + File.separator + "bin" + File.separator + javaCall;
808         }
809         
810         command.setJavaCommand(javaCmd);
811         
812         //
813
// add classpath
814
String JavaDoc classpath=deriveClasspath(plConfig, null);
815         command.setClasspath(classpath);
816         
817         //
818
//add main class
819
command.setMainClass(plConfig.getMainClass());
820         
821         //
822
// add all system properties to command as system variables args
823
Iterator JavaDoc it=systemProperties.keySet().iterator();
824         String JavaDoc key=null;
825         
826         String JavaDoc property=null, value=null;;
827         while(it.hasNext()) {
828             key=(String JavaDoc)it.next();
829             value=systemProperties.getProperty(key);
830             
831             // take care of vm arg that are sent in via the processlauncher.xml file
832
if (key.startsWith("-")) {
833                 property = key;
834                 if (value != null && !value.equals("")) {
835                     property += "=" + value;
836                 }
837                 if ( ( key.equals("-client")) || (key.equals("-server")) ) {
838                     // If user sets server or client mode for VM
839
// then use that over default which is "client"
840
// As we want to keep this as first arg don't add
841
// to the jvmArgsList yet
842
command.setMode(key);
843                 } else {
844                     command.addJvmOption(property);
845                 }
846             } else {
847                 // regular system property
848
property = "-D" + key + "=" + value;
849                 command.addSystemVariable(property);
850             }
851         }
852
853         //
854
// derive native library path for native part of launcher
855
command.addSystemVariable("-Djava.library.path=" + deriveNativeClasspath(command, null, null, systemProperties));
856         
857         //
858
// add command args from script
859
String JavaDoc[] args=getArgs();
860         for(int ii=0; ii < args.length; ii++) {
861             command.addArg(args[ii]);
862         }
863         return command;
864     }
865     
866     
867     /**
868      * configureLogService - get log information out of domain.xml and set the processLaunchers log level
869      * to that of the instance log level
870      *
871      * @param config This represents the config element in domain.xml for the server
872      * @return logFile Log file for server
873      */

874     protected String JavaDoc configureLogService(Config config) {
875         String JavaDoc logFile="";
876         LogService logService=config.getLogService();
877         if(logService != null) {
878             // get logservice info from config beans
879
logFile=logService.getFile();
880             String JavaDoc logLevel=logService.getModuleLogLevels().getAdmin();
881             
882             // set log level to the level that the instance is set to (for internal instances only
883
getLogger().setLevel(Level.parse(logLevel));
884         }
885         return logFile;
886     }
887     
888     
889     /**
890      * This method derives the classpath by using the information from the processLauncher.xml file which gives criteria for the classpath
891      * to be derived from the library directory.
892      */

893     protected String JavaDoc deriveClasspath(ProcessLauncherConfig plConfig, String JavaDoc jvmCmd) {
894         return deriveClasspath(plConfig, jvmCmd, null, null);
895     }
896     
897     
898     /**
899      * This method derives the classpath by using the information from the processLauncher.xml file which gives criteria for the classpath
900      * to be derived from the library directory. It also will include the javaConfig classpath and profilerClasspath if they are passed in
901      *
902      * classpath construction hierarchy:
903      * (javaConfig.getClasspathPrefix)
904      * (processLauncher.Classpath.prefix)
905      * (processLauncher.Classpath.j2se1_4_prefix or processLauncher.Classpath.j2se1_5_or_later_prefix)
906      * (derivedClasspath based on processLauncher.Classpath excludes and includes)
907      * (javaConfig.getSystemClasspath)
908      * (javaConfig.getClasspathSuffix)
909      * (javaConfig.profilerClasspath if enabled)
910      * (Environment classpath if enabled)
911      *
912      */

913     protected String JavaDoc deriveClasspath(ProcessLauncherConfig plConfig, String JavaDoc jvmCmd, JavaConfig javaConfig, String JavaDoc profilerClasspath) {
914         // add classpath
915
String JavaDoc libDir=RelativePathResolver.resolvePath(plConfig.getClasspathLibDir());
916         String JavaDoc classpath=Classpath.getLibClasspath(libDir, plConfig.getClasspathIncludes(),
917             plConfig.getClasspathExcludes());
918         getLogger().log(Level.FINE, "Derived Classpath from " + libDir + " - \n" + classpath);
919
920         // handle processLauncher.xml j2se prefixes always go first
921
// check to see what jdk we are using
922
String JavaDoc javaVersion=System.getProperty("java.version"); // default to 1.5 or later
923
if (jvmCmd != null) {
924             try {
925                 // execute the java command with version option
926
Process JavaDoc process=Runtime.getRuntime().exec(jvmCmd + " -version");
927                 // get streams and capture output
928
ByteArrayOutputStream JavaDoc baosOut= new ByteArrayOutputStream JavaDoc();
929                 ByteArrayOutputStream JavaDoc baosErr= new ByteArrayOutputStream JavaDoc();
930                 StreamFlusher sfOut=new StreamFlusher(process.getInputStream(), baosOut);
931                 StreamFlusher sfErr=new StreamFlusher(process.getErrorStream(), baosErr);
932                 sfOut.start();
933                 sfErr.start();
934                 // wait for process to end, should be fast
935
process.waitFor();
936                 javaVersion=baosErr.toString();
937             } catch (Exception JavaDoc e) {
938                 // log at fine incase of problem
939
getLogger().log(Level.FINE,"Java version retrieving error, will default to 1.5 or later!", e);
940             }
941         }
942         
943         // put in jdk prefix, if exits, goes before what currently has been built
944
String JavaDoc prefix="";
945         String JavaDoc jvmv="";
946         if(javaVersion.indexOf("1.4") >= 0) {
947             // j2se 1.4
948
jvmv="j2se 1.4";
949             prefix=plConfig.getClasspathJ2se14Prefix();
950         } else {
951             // j2se 1.5 or later
952
jvmv="j2se 1.5 or later";
953             prefix=plConfig.getClasspathJ2se15OrLaterPrefix();
954         }
955         // log java version
956
getLogger().log(Level.FINE,"Java version being used is: ->" + jvmv +
957             "<- based on ->" + javaVersion + "<-");
958         
959         // set j2se prefix, this alway goes first so the components classpath doesn't interfer with
960
// the j2se's requirements
961
if(prefix != null && !prefix.equals("")) {
962
963             // resolve any tokens in the prefix
964
prefix=RelativePathResolver.resolvePath(prefix);
965
966             // only add prefix to path if one exists.
967
if(classpath.equals("")) {
968                 // no other classpath information so only use prefix, could be know classpath
969
classpath=prefix;
970             } else {
971                 // prepend prefix to path
972
classpath=prefix + File.pathSeparator + classpath;
973             }
974         }
975
976         
977         // handle processLauncher.xml prefix, if exits, goes before what currently has been built
978
prefix=plConfig.getClasspathPrefix();
979         // set prefix, this also can be used as a method for entering a know classpath.
980
if(prefix != null && !prefix.equals("")) {
981
982             // resolve any tokens in the prefix
983
prefix=RelativePathResolver.resolvePath(prefix);
984
985             // only add prefix to path if one exists.
986
if(classpath.equals("")) {
987                 // no other classpath information so only use prefix, could be know classpath
988
classpath=prefix;
989             } else {
990                 // prepend prefix to path
991
classpath=prefix + File.pathSeparator + classpath;
992             }
993         }
994         
995         
996         // add in the javaconfig paths
997
if(javaConfig != null) {
998             String JavaDoc classpathPrefix=javaConfig.getClasspathPrefix();
999             String JavaDoc classpathSystem=javaConfig.getSystemClasspath();
1000            String JavaDoc classpathSuffix=javaConfig.getClasspathSuffix();
1001            
1002            if(classpathSystem != null) {
1003                classpath += File.pathSeparator + classpathSystem;
1004            }
1005            
1006            //Classpath prefix/suffix and server classpath gets now prefixed/suffixed to
1007
//the shared classloader at PELaunch.java. Instead of setting it here, set
1008
//system properties, so that the system properties could be used to construct
1009
//the classpaths in PELaunch
1010
if (getProcessLauncherProfile().equals(INTERNAL_SERVER_PROFILE)){
1011                if(classpathPrefix != null) {
1012                    classpath=classpathPrefix + File.pathSeparator + classpath;
1013                }
1014                if(classpathSuffix != null) {
1015                    classpath=classpath + File.pathSeparator + classpathSuffix;
1016                }
1017            }
1018            
1019            // add profiler information
1020
if(profilerClasspath != null) {
1021                classpath += File.pathSeparator + profilerClasspath;
1022            }
1023            
1024            // See if need to add user classpath
1025
if(!javaConfig.isEnvClasspathIgnored()) {
1026                // Add user classpath with native code CliUtil.java
1027
String JavaDoc envClassPath="";
1028                String JavaDoc [] sxEnv = new CliUtil().getAllEnv();
1029                for(int ii=0; ii < sxEnv.length; ii++) {
1030                    if(sxEnv[ii].trim().startsWith(CLASSPATH_ENV_NAME)) {
1031                        String JavaDoc userCp=sxEnv[ii].substring(CLASSPATH_ENV_NAME.length() + 1).trim();
1032                        classpath += (userCp.equals("") ? "" : File.pathSeparator + userCp);
1033                        break;
1034                    }
1035                }
1036            }
1037        }
1038        
1039        getLogger().log(Level.FINE, "Final classpath - \n" + classpath);
1040        if (bDebug) System.out.println("Final classpath=" + classpath);
1041        return classpath;
1042    }
1043    
1044    protected String JavaDoc deriveNativeClasspath(Command command, JavaConfig javaConfig, Profiler profiler, Properties JavaDoc systemProperties) {
1045        // native path works in native launcher
1046
String JavaDoc javaLibPath = System.getProperty("java.library.path");
1047        if (bDebug) System.out.println("Current java.library.path=" + javaLibPath + "\n");
1048        if (javaLibPath == null) javaLibPath="";
1049        String JavaDoc libDirFor64Bit = "";
1050       
1051        if (javaConfig != null) {
1052            String JavaDoc nativePrefix=javaConfig.getNativeLibraryPathPrefix();
1053            String JavaDoc nativeSuffix=javaConfig.getNativeLibraryPathSuffix();
1054
1055            String JavaDoc nativeProfiler=null;
1056            if(profiler != null && profiler.isEnabled()) {
1057                nativeProfiler=profiler.getNativeLibraryPath();
1058            }
1059
1060            // put native path together in designated order
1061
if ( (nativePrefix != null ) && !nativePrefix.trim().equals("")) {
1062                javaLibPath=nativePrefix + (javaLibPath.equals("") ? "" : File.pathSeparator + javaLibPath);
1063            }
1064            if ( (nativeSuffix != null ) && !nativeSuffix.trim().equals("")) {
1065                javaLibPath=(javaLibPath.equals("") ? "" : javaLibPath + File.pathSeparator) + nativeSuffix ;
1066            }
1067            if (( nativeProfiler!= null ) && !nativeProfiler.trim().equals("")) {
1068                javaLibPath=(javaLibPath.equals("") ? "" : javaLibPath + File.pathSeparator) + nativeProfiler ;
1069            }
1070
1071           
1072        String JavaDoc[] jvmOptions=javaConfig.getJvmOptions();
1073        for(String JavaDoc s:jvmOptions){
1074        if(s.indexOf(JVM_OPTION_FOR_64BIT)!=-1){
1075                String JavaDoc osArch = System.getProperty("os.arch");
1076                if(osArch.equals(SPARC)) libDirFor64Bit = SPARCV9;
1077                else if(osArch.equals(X86)) libDirFor64Bit = AMD64;
1078     
1079                String JavaDoc nssRoot=System.getProperty(SystemPropertyConstants.NSS_ROOT_PROPERTY);
1080                String JavaDoc installRoot=System.getProperty(SystemPropertyConstants.INSTALL_ROOT_PROPERTY);
1081            String JavaDoc imqLib=System.getProperty(SystemPropertyConstants.IMQ_LIB_PROPERTY);
1082                String JavaDoc icuLib=System.getProperty(SystemPropertyConstants.ICU_LIB_PROPERTY);
1083                String JavaDoc java64BitLibPath = "";
1084                if (installRoot != null){
1085                    if(nssRoot != null){
1086                        java64BitLibPath= nssRoot + File.separator + libDirFor64Bit;
1087                    }
1088                    if(imqLib != null){
1089                        java64BitLibPath = imqLib + File.separator + libDirFor64Bit + File.pathSeparator + java64BitLibPath;
1090                    }
1091            
1092                    if(icuLib != null){
1093                        java64BitLibPath = icuLib + File.separator + libDirFor64Bit + File.pathSeparator + java64BitLibPath;
1094                    }
1095                    javaLibPath = java64BitLibPath + File.pathSeparator + javaLibPath;
1096                }
1097           }
1098       }
1099        }
1100        // add nss and lib directories to from of java.library.path if windows to get around jdk
1101
// addition of c:\windows\system32
1102
if (OS.isWindows()) {
1103            String JavaDoc nssRoot=System.getProperty(SystemPropertyConstants.NSS_ROOT_PROPERTY);
1104            String JavaDoc installRoot=System.getProperty(SystemPropertyConstants.INSTALL_ROOT_PROPERTY);
1105
1106            if (installRoot != null && nssRoot != null) {
1107                javaLibPath= nssRoot + File.pathSeparator +
1108                    installRoot + File.separator + "lib" + File.pathSeparator + javaLibPath;
1109            }
1110        }
1111        
1112        if (isDisplayEnabled()) {
1113            // need to add the path the correct jvm library so the native portion will
1114
// switch jvm modes, it should be set to client by default, but set it just in case
1115

1116        // fix for bug# 6240672 and 6318497
1117
// This fix enables the use of java_home available in java-config.
1118
// If the java_home picked up from java-config is invalid then it falls back
1119
// to default java_home of config/asenv.conf
1120

1121        String JavaDoc java_home = null;
1122        if ((javaConfig != null) && (javaConfig.getJavaHome() != null)) {
1123        java_home = javaConfig.getJavaHome();
1124        } else {
1125        java_home = SystemPropertyConstants.JAVA_ROOT_PROPERTY;
1126        }
1127            String JavaDoc jvmLibPath = java_home +
1128                System.getProperty(SystemPropertyConstants.NATIVE_LAUNCHER_LIB_PREFIX);
1129
1130            // remove default jvm mode and add proper one
1131
if (command.getMode() != null) {
1132                jvmLibPath=jvmLibPath.substring(0, jvmLibPath.lastIndexOf(File.separator) + 1) +
1133                    command.getMode().substring(1);
1134            }
1135                
1136            if (javaLibPath != null) {
1137                javaLibPath=jvmLibPath + File.pathSeparator + javaLibPath;
1138            } else {
1139                javaLibPath=jvmLibPath;
1140            }
1141        }
1142
1143        
1144        // now check for spaces in path
1145
if(javaLibPath.indexOf(" ") >= 0) {
1146            // there are spaces in the path so send warning message
1147
// Almost every Windows user has spaces in their path.
1148
// Bug 6342806 determined that this is "noise"
1149
// I changed the message to FINE and I added in the names of the items
1150
// in the path that have spaces...
1151
String JavaDoc items = getPathItemsWithSpaces(javaLibPath);
1152            getLogger().log(Level.FINE,"launcher.spacesInPath", new Object JavaDoc[] { items });
1153            
1154            // remove all quotes, because either the java or native launchers will not consistenly
1155
// accept the mix in the java.library.path
1156
// This is a problem between the JNI invocation api and the straight java command.
1157
javaLibPath=javaLibPath.replaceAll("\"", "");
1158        }
1159
1160        systemProperties.put("java.library.path" , javaLibPath);
1161        
1162
1163        
1164        System.setProperty("java.library.path", javaLibPath );
1165        command.setNativeClasspath(javaLibPath);
1166        
1167        
1168        if (bDebug) System.out.println("Final java.library.path=" + javaLibPath + "\n");
1169        return javaLibPath;
1170    }
1171    
1172    
1173    protected void addSystemProperties(SystemProperty sp[], Properties JavaDoc systemProperties) {
1174        if(sp != null) {
1175            for(int ii=0; ii < sp.length; ii++) {
1176                systemProperties.put(sp[ii].getName(), sp[ii].getValue());
1177            }
1178        }
1179    }
1180    
1181    protected void addElementProperties(ElementProperty ep[], Properties JavaDoc systemProperties) {
1182        if(ep != null) {
1183            for(int ii=0; ii < ep.length; ii++) {
1184                systemProperties.put(ep[ii].getName(), ep[ii].getValue());
1185            }
1186        }
1187    }
1188    
1189   
1190    
1191    
1192    protected Logger JavaDoc getLogger() {
1193        if (_logger == null) {
1194            // check log manager to see if it is internal or external
1195
// if (!isInternalLogger()) {
1196
// external log manager, add resource bundle for i18n
1197
// will associate a file to the logger if it is specified in the system args
1198
_logger = Logger.getLogger(LogDomains.PROCESS_LAUNCHER_LOGGER, "com.sun.logging.enterprise.system.tools.launcher.LogStrings");
1199                
1200                // check to see if in verbose mode, if not remove default console handler
1201
if (!isVerboseEnabled()) {
1202                    Handler JavaDoc[] h=_logger.getParent().getHandlers();
1203                    for (int ii=0; ii < h.length; ii++) {
1204                        if (h[ii].getClass().getName().equals("java.util.logging.ConsoleHandler")) {
1205                            _logger.getParent().removeHandler(h[ii]);
1206                        }
1207                    }
1208                }
1209                
1210            //} else {
1211
// use internal log manager which associates the resource bundle and
1212
// log file automatically
1213
// _logger = Logger.getLogger(LogDomains.PROCESS_LAUNCHER_LOGGER, "com.sun.logging.enterprise.system.tools.launcher.LogStrings");
1214
//}
1215
}
1216        
1217        // set each time reguardless of what is preset in domain.xml (for internals)
1218
if (bDebug) _logger.setLevel(Level.FINEST);
1219        return _logger;
1220    }
1221    
1222    
1223    protected boolean isInternalLogger() {
1224        boolean bRet=false;
1225        // check log manager to see if it is internal or external
1226
String JavaDoc logManager=System.getProperty("java.util.logging.manager");
1227        if (logManager != null && logManager.equals("com.sun.enterprise.server.logging.ServerLogManager")) {
1228            bRet=true;
1229        }
1230        return bRet;
1231    }
1232    
1233    protected void addLogFileToLogger(String JavaDoc logFile) {
1234        if (logFile == null) return;
1235        
1236        // Send logger output to our FileHandler.
1237
getLogger().log(Level.FINE, "*** Adding logFileHandler - " + logFile);
1238        // already created directory structure for log file, so just add log
1239
try {
1240            FileHandler JavaDoc fh = new FileHandler JavaDoc(logFile, true);
1241            fh.setFormatter(new SimpleFormatter JavaDoc());
1242            fh.setLevel(Level.ALL);
1243            getLogger().addHandler(fh);
1244        } catch(IOException JavaDoc e) {
1245            // should be seen in verbose mode for debugging
1246
e.printStackTrace();
1247        }
1248    }
1249    
1250    
1251    /**
1252     * This method handles the jvm options and was pulled from the LaunchFilter
1253     */

1254    protected void addJvmOptions(Command command, String JavaDoc[] args) {
1255        String JavaDoc systemProperty = null;
1256        String JavaDoc property = null;
1257        String JavaDoc value = null;
1258        String JavaDoc[] jvmOptions = null;
1259        
1260        try {
1261          jvmOptions = (new JvmOptionsHelper(args)).getJvmOptions();
1262        } catch(Exception JavaDoc e) {
1263        }
1264        if(jvmOptions!=null)
1265        {
1266            for(int i=0; i<jvmOptions.length; i++)
1267            {
1268                addJvmArg(command, jvmOptions[i]);
1269            }
1270            return;
1271        }
1272        
1273        //here we are only in case if jvm-options helper had exception
1274
// then - old style of parsing, to avoid exception
1275
if(args != null) {
1276            // loop through args
1277
for(int ii=0; ii < args.length; ii++) {
1278                // remove leading and trailing spaces
1279
systemProperty=args[ii].trim();
1280                
1281                if (bDebug) System.out.println("addJvmOptions: IN Property " + systemProperty);
1282                
1283                // ignore white space
1284
if(systemProperty.trim().equals("")) {
1285                    continue;
1286                }
1287                
1288                int iSpace=0, iQuote1=0, iQuote2=0;
1289                // loop through jvm-options line and see if multple entries on one line
1290
while(systemProperty.length() > 0) {
1291                            
1292                    // Find first space and quote
1293
iSpace=systemProperty.indexOf(" -");
1294                    iQuote1=systemProperty.indexOf("\"");
1295                        
1296                    // see if it has a space that may specify 2 args
1297
if (iSpace >= 0) {
1298                        // see if there are double quotes, which could mean the space is part of the value
1299
if (iQuote1 >= 0) {
1300                            // see where quote is in relation to space, if a space exists
1301
if (iQuote1 > iSpace && iSpace >= 0 ) {
1302                                // quote is before space so break up to space, should be full arg
1303
addJvmArg(command, systemProperty.substring(0, iSpace));
1304                                // set remainder string, minus space delimiter
1305
systemProperty=systemProperty.substring(iSpace + 1).trim();
1306                                if (bDebug) System.out.println("*** left 1:" + systemProperty);
1307                            } else {
1308                                // quote is first, could have a space in quotes, or just quoted string at end
1309

1310                                // loop to find next un-escaped quote
1311
int iQuoteStartPos=iQuote1 + 1;
1312                                while (true) {
1313                                    iQuote2=systemProperty.indexOf("\"", iQuoteStartPos);
1314                                    if (iQuote2 < 0) {
1315                                        // error can't find last quote, so log and exit loop
1316
getLogger().log(Level.WARNING, "launcher.missMatchQuotesInArg", systemProperty);
1317                                        // set to "" to end multiple arg loop
1318
systemProperty="";
1319                                        // breakout of inner quote loop
1320
break;
1321                                    }
1322
1323                                    // found second quote see if it is escaped,which means the
1324
// value has internal quotes
1325
if (systemProperty.charAt(iQuote2 - 1) == '\\') {
1326                                        // quote escaped, look for next quote
1327
iQuoteStartPos=iQuote2 + 1;
1328                                        continue;
1329                                    } else {
1330                                        // found end quote that is not escaped
1331

1332                                        // see if there are any more spaces after second quote
1333
// this happends when directories are added with spaces in them
1334
// like java.dirs.ext system property
1335
if (systemProperty.indexOf(" -", iQuote2) < 0) {
1336                                            // no more space, so space was enclosed in quotes
1337
// send total line as one
1338
addJvmArg(command, systemProperty);
1339                                            
1340                                            // should be at the end
1341
// set to "" to end multiple arg loop
1342
systemProperty="";
1343                                        } else {
1344                                            // another space was found in the line
1345
iQuote2++; // add on to include quote in arg
1346
addJvmArg(command, systemProperty.substring(0, iQuote2));
1347                                            // set remainder string minus space delimiter
1348
if (iQuote2 < systemProperty.length()) {
1349                                                systemProperty=systemProperty.substring(iQuote2 + 1).trim();
1350                                                if (bDebug) System.out.println("*** left 2:" + systemProperty);
1351                                            } else {
1352                                                // should be at the end
1353
// set to "" to end multiple arg loop
1354
systemProperty="";
1355                                            }
1356                                        }
1357                                        // breakout of inner quote loop
1358
break;
1359                                    }
1360                                }
1361                            }
1362                            
1363                        } else {
1364                            // no quotes, just break on " -" for multiple args
1365
// space could be non-quoted like in java.ext.dirs
1366
int iDel=systemProperty.indexOf(" -");
1367                            while(iDel >= 0) {
1368                                // found token
1369
addJvmArg(command, systemProperty.substring(0, iDel));
1370                                systemProperty=systemProperty.substring(iDel + 1).trim();
1371                                iDel=systemProperty.indexOf(" -");
1372                            }
1373                            
1374                            // make sure you get the last one
1375
if (!systemProperty.equals("")) {
1376                                addJvmArg(command, systemProperty);
1377                            }
1378                            
1379                            // break out of multiple arg loop
1380
break;
1381                        }
1382                    } else {
1383                        // no spaces, should just be one value so add
1384
addJvmArg(command, systemProperty);
1385                        // break out of multiple arg loop
1386
break;
1387                    }
1388                }
1389            }
1390        }
1391    
1392    }
1393    
1394
1395    protected void addJvmArg(Command command, String JavaDoc option) {
1396        if ( option.startsWith("-D") ) {
1397                // set to systemvaiables for commandline ordering
1398
command.addSystemVariable(option);
1399        } else {
1400            if ( ( option.equals("-client")) || (option.equals("-server")) ) {
1401                //If user mentions server or client mode for VM
1402
// then use that over default which is "server"
1403
// As we want to keep this as first arg don't add
1404
// to the jvmArgsList yet
1405
command.setMode(option);
1406            } else {
1407                // just add the option to the jvm options
1408
command.addJvmOption(option);
1409            }
1410        }
1411        
1412        //getLogger().log(Level.INFO,"addJvmOptions: OUT Property " + option);
1413
if (bDebug) System.out.println("addJvmOptions: OUT Property " + option);
1414    }
1415    
1416    
1417    /**
1418     * This method handles the debug options and was pulled from the LaunchFilter
1419     */

1420    protected void addDebugOptions(Command command, String JavaDoc debug_options) {
1421        // only do for start action, not stop
1422

1423        // If debug is enabled, then we need to pass on -Xdebug option
1424
command.addDebugOption("-Xdebug");
1425        
1426        // It seems that -Xdebug and other debug options shouldn't go
1427
// as one argument So we will check if debug_options starts
1428
// with that and give it as separate argument
1429
debug_options=debug_options.trim();
1430        if ( debug_options.startsWith("-Xdebug") ) {
1431            debug_options =debug_options.substring("-Xdebug".length()).trim();
1432        }
1433        
1434        // Get the JPDA transport and address (port) from the
1435
// debug_options. If address is not specified in debug_options
1436
// for transport=dt_socket, we find a free port
1437
// and add it to -Xrunjdwp.
1438
//
1439
// If address is specified in -Xrunjdwp, then the JVM
1440
// does not print any debug message, so we need to print it for
1441
// easy viewing by the user.
1442
// If address is not specified in debug_options,
1443
// then the JVM will print a message like:
1444
// Listening for transport dt_socket at address: 33305
1445
// This is only visible with "asadmin start-domain --verbose"
1446
//
1447
// The format of debug_options is:
1448
// -Xrunjdwp:<name1>[=<value1>],<name2>[=<value2>]
1449

1450        String JavaDoc transport = getDebugProperty(debug_options, "transport");
1451        String JavaDoc addr = getDebugProperty(debug_options, "address");
1452        
1453        if ( transport == null || transport.equals("") ) {
1454            // XXX I18N this
1455
// throw exception
1456
System.out.println("Cannot start server in debug mode: no transport specified in debug-options in domain.xml.");
1457        }
1458        
1459        if ( transport.equals("dt_socket") ) {
1460            if ( addr != null && !addr.equals("") ) {
1461                // XXX Should we check if the port is free using
1462
// com.sun.enterprise.util.net.NetUtils.isPortFree(port)
1463
}
1464            else {
1465                // Get a free port
1466
int port =
1467                com.sun.enterprise.util.net.NetUtils.getFreePort();
1468                if ( port == 0 ) {
1469                    // XXX I18N this
1470
// throw exception ???
1471
System.out.println("Cannot start server in debug mode: unable to obtain a free port for transport dt_socket.");
1472                }
1473                addr = String.valueOf(port);
1474                
1475                debug_options = debug_options + ",address=" + addr;
1476            }
1477        }
1478        
1479        command.addDebugOption(debug_options);
1480        
1481        // Provide the actual JDWP options to the server using a
1482
// system property. This allow the server to make it available
1483
// to the debugger (e.g. S1 Studio) using an API.
1484
String JavaDoc jdwpOptions = debug_options.substring(
1485        debug_options.indexOf("-Xrunjdwp:") + "-Xrunjdwp:".length());
1486        
1487        command.addSystemVariable("-D" + DEBUG_OPTIONS + "=" + jdwpOptions);
1488        
1489    }
1490    
1491    protected String JavaDoc getDebugProperty(String JavaDoc debug_options, String JavaDoc name) {
1492        int nameIndex;
1493        if ( (nameIndex = debug_options.indexOf(name)) != -1 ) {
1494            // format is "name=value"
1495
String JavaDoc value = debug_options.substring(nameIndex
1496            + name.length() + 1);
1497            int commaIndex;
1498            if ( (commaIndex = value.indexOf(",")) != -1 ) {
1499                value = value.substring(0, commaIndex);
1500            }
1501            return value;
1502        }
1503        return null;
1504    }
1505    
1506    protected boolean isWaitEnabled() {
1507        boolean bRet=false;
1508        String JavaDoc launcherRet=System.getProperty(LAUNCHER_RETURN_FUNCTION);
1509        if(launcherRet != null && launcherRet.equals(LAUNCHER_RETURN_FUNCTION_WAIT)) {
1510            bRet=true;
1511        }
1512        return bRet;
1513    }
1514    
1515    protected boolean isVerboseEnabled() {
1516        return argExists(COMMAND_LINE_ARG_VERBOSE);
1517    }
1518    
1519    
1520    protected boolean isDebugEnabled() {
1521        return argExists(COMMAND_LINE_ARG_DEBUG);
1522    }
1523    
1524    protected boolean isDisplayEnabled() {
1525        return argExists(COMMAND_LINE_ARG_DISPLAY);
1526    }
1527    
1528    protected boolean isServerProfile() {
1529        String JavaDoc processName=getProcessLauncherProfile();
1530        return processName.equals(INTERNAL_SERVER_PROFILE) ||
1531                                           processName.equals(AS9_INTERNAL_SERVER_PROFILE);
1532    }
1533    
1534    protected boolean isNodeAgentProfile() {
1535        String JavaDoc processName=getProcessLauncherProfile();
1536        return processName.equals(INTERNAL_NODE_AGENT_PROFILE);
1537    }
1538    
1539    
1540    protected String JavaDoc getFiletRelativeName(String JavaDoc action) {
1541        return System.getProperty(SystemPropertyConstants.INSTANCE_ROOT_PROPERTY) + File.separator
1542        + LAUNCHER_SCRIPT_LOCATION + File.separator + action;
1543    }
1544
1545    
1546    protected String JavaDoc getProcessLauncherProfile() {
1547        return System.getProperty(LAUNCHER_PROFILE_NAME, INTERNAL_SERVER_PROFILE);
1548    }
1549    
1550    protected String JavaDoc getScriptRelativeName(String JavaDoc action) {
1551        String JavaDoc sxRet=getFiletRelativeName(action);
1552        if(OS.isWindows()) {
1553            sxRet+="_temp.bat";
1554        } else {
1555            sxRet+="_temp.sh";
1556        }
1557        return sxRet;
1558    }
1559    
1560    protected void setArgs(String JavaDoc[] args) {
1561        this._args=args;
1562    }
1563    
1564    protected String JavaDoc[] getArgs() {
1565        return _args;
1566    }
1567    
1568    protected boolean argExists(String JavaDoc arg) {
1569        boolean bRet=false;
1570        String JavaDoc[] args=getArgs();
1571        if(args != null) {
1572            for(int ii=0; ii < args.length; ii++) {
1573                if(args[ii].equals(arg)) {
1574                    bRet=true;
1575                    break;
1576                }
1577            }
1578        }
1579        return bRet;
1580    }
1581    
1582   
1583    /**
1584     * createFileStructure - This method validates that that the file can be written to. It the
1585     * if the parent directory structure does not exist, it will be created
1586     *
1587     * @param logFile - fully qualified path of the logfile
1588     */

1589    protected boolean createFileStructure(String JavaDoc logFile) {
1590        boolean bRet=false;
1591        File JavaDoc outputFile=new File JavaDoc(logFile);
1592        
1593        try {
1594            // Verify that we can write to the output file
1595
File JavaDoc parentFile = new File JavaDoc(outputFile.getParent());
1596            // To take care of non-existent log directories
1597
if ( !parentFile.exists() ) {
1598                // Trying to create non-existent parent directories
1599
parentFile.mkdirs();
1600            }
1601            // create the file if it doesn't exist
1602
if (!outputFile.exists()) {
1603                outputFile.createNewFile();
1604            }
1605            if (outputFile.canWrite()) {
1606                // everything is okay to logfile
1607
bRet=true;
1608            }
1609        } catch (IOException JavaDoc e) {
1610            // will only see on verbose more, so okay
1611
e.printStackTrace();
1612        }
1613
1614        if (!bRet) {
1615            // log can't be created or isn't writtable
1616
getLogger().log(Level.WARNING,"launcher.logWriteFailure", logFile);
1617        }
1618
1619        return bRet;
1620    }
1621    
1622    private String JavaDoc getPathItemsWithSpaces(String JavaDoc path)
1623    {
1624        StringTokenizer JavaDoc st = new StringTokenizer JavaDoc(path, File.pathSeparator);
1625        String JavaDoc ret = "";
1626        boolean firstItem = true;
1627        
1628        while (st.hasMoreTokens())
1629        {
1630            String JavaDoc item = st.nextToken();
1631            
1632            if(item.indexOf(' ') >= 0)
1633            {
1634                if(!firstItem)
1635                    ret += File.pathSeparator;
1636                else
1637                    firstItem = false;
1638                
1639                ret += item;
1640            }
1641        }
1642        
1643        return ret;
1644    }
1645
1646
1647    private String JavaDoc [] removeJVMStopOptions(String JavaDoc [] jvmOptions) {
1648    for (int i=0; i<jvmOptions.length; i++) {
1649        if (jvmOptions[i].startsWith("-X")) {
1650            jvmOptions[i] = "";
1651        }
1652        if (jvmOptions[i].startsWith("-server")) {
1653            jvmOptions[i] = "-client";
1654        }
1655    }
1656    return jvmOptions;
1657    }
1658
1659    //**************************************************************************
1660
// *********** protected inner Command class *****************
1661
//**************************************************************************
1662
/**
1663     * This class is a structure class that holds the executable command as it is compiled. Once the
1664     * command is completed, an instance method returns the command in the form of a
1665     * string array, with or without the classpath information present. The without
1666     * classpath option is triggered by having the commands "com.sun.aas.launcherReturn"
1667     * is flagged as "hold", setting the "com.sun.aas.limitedCommamdExecution" and being on
1668     * the Windows platform. This was used as an intermediate solution to get around the
1669     * command execution length limitation on Windows. The classpath information was
1670     * written out to be executed as a separate "set" command.
1671     */

1672    protected class Command {
1673        
1674        private ArrayList JavaDoc _jvmOptions=new ArrayList JavaDoc();
1675        private ArrayList JavaDoc _systemVariables=new ArrayList JavaDoc();
1676        private ArrayList JavaDoc _args=new ArrayList JavaDoc();
1677        private ArrayList JavaDoc _debugOptions=new ArrayList JavaDoc();
1678        private String JavaDoc _mainClass=null;
1679        private String JavaDoc _classpath=null;
1680        private String JavaDoc _javaCommand=null;
1681        private String JavaDoc _mode=null;
1682        private String JavaDoc _logFile=null;
1683        private String JavaDoc _nativeClasspath=null;
1684        
1685        
1686        protected void addJvmOption(String JavaDoc jvmOptions) {
1687            // must trim these or Runtime.exec will blow with leading spaces
1688
_jvmOptions.add(jvmOptions.trim());
1689        }
1690        
1691        protected void addSystemVariable(String JavaDoc systemVariable) {
1692            // must trim these or Runtime.exec will blow with leading spaces
1693
_systemVariables.add(systemVariable.trim());
1694        }
1695        
1696        protected void addArg(String JavaDoc arg) {
1697            _args.add(arg);
1698        }
1699        protected String JavaDoc[] getArgs() {
1700            return (String JavaDoc[])_args.toArray(new String JavaDoc[_args.size()]);
1701        }
1702        protected void removeArg(String JavaDoc arg) {
1703            _args.remove(arg);
1704        }
1705        
1706        protected void addDebugOption(String JavaDoc debugOption) {
1707            _debugOptions.add(debugOption);
1708        }
1709        protected String JavaDoc[] getDebugOptions() {
1710            return (String JavaDoc[])_debugOptions.toArray(new String JavaDoc[_debugOptions.size()]);
1711        }
1712        
1713        protected void setMode(String JavaDoc mode) {
1714            _mode=mode;
1715        }
1716        protected String JavaDoc getMode() {
1717            return _mode;
1718        }
1719        
1720        protected void setMainClass(String JavaDoc mainClass) {
1721            _mainClass=mainClass;
1722        }
1723        protected String JavaDoc getMainClass() {
1724            return _mainClass;
1725        }
1726        
1727        protected void setNativeClasspath(String JavaDoc classpath) {
1728            _nativeClasspath=classpath;
1729        }
1730        protected String JavaDoc getNativeClasspath() {
1731            return _nativeClasspath;
1732        }
1733        
1734        protected void setClasspath(String JavaDoc classpath) {
1735            _classpath=classpath;
1736        }
1737        protected String JavaDoc getClasspath() {
1738            return _classpath;
1739        }
1740        
1741        protected void setJavaCommand(String JavaDoc javaCommand) {
1742            _javaCommand=javaCommand;
1743        }
1744        protected String JavaDoc getJavaCommand() {
1745            return _javaCommand;
1746        }
1747        
1748        protected void setLogFile(String JavaDoc logFile) {
1749            if (bDebug) System.out.println("Logfile set to " + logFile);
1750            _logFile=logFile;
1751        }
1752        protected String JavaDoc getLogFile() {
1753            return _logFile;
1754        }
1755        
1756        /*
1757         * This method returns the command in standard java format
1758         * which can be used by Runtime.execute
1759         */

1760        protected String JavaDoc[] getCommandAsArray() {
1761            ArrayList JavaDoc cmd=new ArrayList JavaDoc();
1762            cmd.add(_javaCommand);
1763            if(_mode != null) {
1764                cmd.add(_mode);
1765            }
1766            cmd.addAll(_debugOptions);
1767            cmd.addAll(_jvmOptions);
1768            cmd.addAll(_systemVariables);
1769            // put cp on separate line of Runtimes execute
1770
// doesn't work
1771
cmd.add("-cp");
1772            cmd.add(_classpath);
1773            cmd.add(_mainClass);
1774            cmd.addAll(_args);
1775            return (String JavaDoc[])cmd.toArray(new String JavaDoc[cmd.size()]);
1776        }
1777        
1778        /**
1779         * This method return the executable command without the classpath attached
1780         * It is used when building scripts that
1781         * are executed in an environment with a limited command line length like
1782         * windows 2000 - 2071 character limit and XP - 8000 character limit
1783         * To get full command use getClasspath() also
1784         */

1785        protected String JavaDoc[] getLimitedCommandAsArray() {
1786            ArrayList JavaDoc cmd=new ArrayList JavaDoc();
1787            cmd.add(_javaCommand);
1788            if(_mode != null) {
1789                cmd.add(_mode);
1790            }
1791            cmd.addAll(_debugOptions);
1792            cmd.addAll(_jvmOptions);
1793            cmd.addAll(_systemVariables);
1794            cmd.add(_mainClass);
1795            cmd.addAll(_args);
1796            return (String JavaDoc[])cmd.toArray(new String JavaDoc[cmd.size()]);
1797        }
1798        
1799        
1800        /*
1801         * This method returns the command in a format that is JNI invocation api friendly and
1802         * can be easely digested in the native environment
1803         */

1804        protected String JavaDoc[] getCommandInJNIFormatAsArray() {
1805            // display java command to stdout in the following format.
1806
// NOTE: if this becomes externally available, use xml, for now its an internal structure.
1807
// Class Name (path is seperated by "/"
1808
// commandline Args
1809
// everything else (should start with a "-")
1810
// classpath should be prepended with "-Djava.class.path="
1811

1812            // alter main class path for jni invocation api, do it here to keep as much out of native as possible
1813
String JavaDoc jniMainClassName=_mainClass;
1814            int iPos=0;
1815            while((iPos=jniMainClassName.indexOf(".")) >= 0) {
1816                jniMainClassName=jniMainClassName.substring(0, iPos) + "/" + jniMainClassName.substring(iPos + 1);
1817            }
1818            
1819            ArrayList JavaDoc cmd=new ArrayList JavaDoc();
1820            if(_mode != null) {
1821                cmd.add(_mode);
1822            }
1823            cmd.addAll(_debugOptions);
1824            cmd.addAll(_jvmOptions);
1825            cmd.addAll(_systemVariables);
1826            cmd.add("-Djava.class.path=" + _classpath);
1827            cmd.add(_mainClass);
1828            cmd.addAll(_args);
1829            return (String JavaDoc[])cmd.toArray(new String JavaDoc[cmd.size()]);
1830        }
1831        
1832        
1833        /**
1834         * This method returns only the system variables for the command to execute
1835         */

1836        protected String JavaDoc[] getSystemVariablesAsArray() {
1837            ArrayList JavaDoc cmd=new ArrayList JavaDoc();
1838            cmd.addAll(_systemVariables);
1839            return (String JavaDoc[])cmd.toArray(new String JavaDoc[cmd.size()]);
1840        }
1841        
1842        
1843        public String JavaDoc toString() {
1844            StringBuffer JavaDoc cmd= new StringBuffer JavaDoc();
1845            
1846            String JavaDoc[] ret=getCommandAsArray();
1847            for(int ii=0; ii < ret.length; ii++) {
1848                cmd.append(ret[ii]);
1849            }
1850            
1851            return cmd.toString();
1852        }
1853        
1854        public String JavaDoc toStringWithLines() {
1855            StringBuffer JavaDoc cmd= new StringBuffer JavaDoc();
1856            
1857            String JavaDoc[] ret=getCommandAsArray();
1858            for(int ii=0; ii < ret.length; ii++) {
1859                cmd.append("\n" + ret[ii]);
1860            }
1861            return cmd.toString();
1862        }
1863    }
1864    
1865    
1866    //**************************************************************************
1867
//*********** protected inner Classpath class *****************
1868
//**************************************************************************
1869
/**
1870     * A class that encaspilates the functionality required to derive the classpath from criteria in
1871     * attributes of the classpath element that is present in the processLauncher.xml file.
1872     */

1873    protected static class Classpath {
1874        /**
1875         * getLibClasspath - This method returns a string classpath which represents the items in the
1876         * lib directory in accordance with the regular expressions that represents the
1877         * include and excludes attributes of the processLaunher.xml
1878         */

1879        protected static String JavaDoc getLibClasspath(String JavaDoc libDir, String JavaDoc includes, String JavaDoc excludes) {
1880            ArrayList JavaDoc arIncludes=new ArrayList JavaDoc();
1881            ArrayList JavaDoc arExcludes=new ArrayList JavaDoc();
1882            
1883            // construct include and excludes for comparison
1884
StringTokenizer JavaDoc st=new StringTokenizer JavaDoc(includes, ",");
1885            while(st.hasMoreTokens()) {
1886                arIncludes.add(st.nextToken().trim());
1887            }
1888            st=new StringTokenizer JavaDoc(excludes, ",");
1889            while(st.hasMoreTokens()) {
1890                arExcludes.add(st.nextToken().trim());
1891            }
1892            
1893            String JavaDoc path="";
1894            // if lib dir exists then see if items can be included or excluded.
1895
if (libDir != null && !libDir.equals("")) {
1896                // get file dir
1897
File JavaDoc dir=new File JavaDoc(libDir);
1898                
1899                // loop through items in directory
1900
String JavaDoc[] filenames=dir.list();
1901                for(int ii=0; ii < filenames.length; ii++) {
1902                    
1903                    // see if should be included
1904
if(matchStringToList(filenames[ii], arIncludes) && !matchStringToList(filenames[ii], arExcludes)) {
1905                        // see if in excluded list
1906
path += libDir + File.separator + filenames[ii] + File.pathSeparator;
1907                    }
1908                }
1909                
1910                // remove last pasthSeparator
1911
if(path.endsWith(File.pathSeparator)) {
1912                    path=path.substring(0, path.length()-1);
1913                }
1914            }
1915
1916            return path;
1917        }
1918        
1919        
1920        /**
1921         * matchStringToList - This method performs a match to each item in the arraylist to the
1922         * filename.
1923         */

1924        protected static boolean matchStringToList(String JavaDoc filename, ArrayList JavaDoc list) {
1925            boolean bRet=false;
1926            
1927            String JavaDoc criteria=null, endMatch=null;
1928            Iterator JavaDoc it=list.iterator();
1929            while(it.hasNext()) {
1930                criteria=(String JavaDoc)it.next();
1931                
1932                if (criteria.startsWith("*")) {
1933                    // give a work around for people who don't know regular expressions
1934
// legacy functionality
1935
endMatch=criteria.substring(1);
1936                    // see if end matches rest of criteria string
1937
if (filename.endsWith(endMatch)) {
1938                        // match, so set return and break out
1939
bRet=true;
1940                        break;
1941                    }
1942                } else if (isRegularExpression(criteria)) {
1943                    // contains wildcard use regexpression
1944
if(Pattern.matches(criteria, filename)) {
1945                        // equals, so set return and break out
1946
bRet=true;
1947                        break;
1948                    }
1949                } else {
1950                    // perform straight equals
1951
if(filename.equals(criteria)) {
1952                        // equals, so set return and break out
1953
bRet=true;
1954                        break;
1955                    }
1956                }
1957            }
1958            
1959            return bRet;
1960        }
1961        
1962        /**
1963         * isRegularExpression - This method checks to see if the item in the arraylist could be a regular expression.
1964         * This method is not full proof and may need to be modified to suite the appservers needs
1965         */

1966        protected static boolean isRegularExpression(String JavaDoc criteria) {
1967            boolean bRet=false;
1968            if(criteria.indexOf("^") > -1 || criteria.indexOf("$") > -1 || criteria.indexOf("[") > -1
1969            || criteria.indexOf("]") > -1 || criteria.indexOf("*") > -1) {
1970                bRet=true;
1971            }
1972            return bRet;
1973        }
1974    }
1975    
1976    
1977    
1978    //**************************************************************************
1979
//*********** protected inner StreamFlusher class *****************
1980
//**************************************************************************
1981
/**
1982     * A class that attaches to the output streams of the executed process and sends the data
1983     * to the calling processes output streams
1984     */

1985    protected class StreamFlusher extends Thread JavaDoc {
1986        
1987        private InputStream JavaDoc _input=null;
1988        private OutputStream JavaDoc _output=null;
1989        private String JavaDoc _logFile=null;
1990
1991        
1992        public StreamFlusher(InputStream JavaDoc input, OutputStream JavaDoc output) {
1993            this(input, output, null);
1994        }
1995        
1996        public StreamFlusher(InputStream JavaDoc input, OutputStream JavaDoc output, String JavaDoc logFile) {
1997            this._input=input;
1998            this._output=output;
1999            this._logFile=logFile;
2000        }
2001        
2002        public void run() {
2003            
2004            // check for null stream
2005
if (_input == null) return;
2006            
2007            PrintStream JavaDoc printStream=null;
2008            
2009            // If applicable, write to a log file
2010
if (_logFile != null) {
2011                try {
2012                    if(createFileStructure(_logFile)) {
2013                        // reset streams to logfile
2014
printStream = new PrintStream JavaDoc(new FileOutputStream JavaDoc(_logFile, true), true);
2015                    } else {
2016                        // could not write to log for some reason
2017
_logFile=null;
2018                    }
2019                } catch (IOException JavaDoc ie) {
2020                    ie.printStackTrace();
2021                    _logFile=null;
2022                }
2023            }
2024            
2025            // transfer bytes from input to output stream
2026
try {
2027                int byteCnt=0;
2028                byte[] buffer=new byte[4096];
2029                while ((byteCnt=_input.read(buffer)) != -1) {
2030                    if (_output != null && byteCnt > 0) {
2031                        _output.write(buffer, 0, byteCnt);
2032                        _output.flush();
2033                        
2034                        // also send to log, if it exists
2035
if (_logFile != null) {
2036                            printStream.write(buffer, 0, byteCnt);
2037                            printStream.flush();
2038                        }
2039                    }
2040                    yield();
2041                }
2042            } catch (IOException JavaDoc e) {
2043                // just log this as an finest exception, because it really should matter
2044
//getLogger().log(Level.FINEST,"Exception thrown while reading/writing verbose error stream", e);
2045
}
2046        }
2047        
2048    }
2049}
2050
Popular Tags