KickJava   Java API By Example, From Geeks To Geeks.

Java > Open Source Codes > edu > rice > cs > util > newjvm > ExecJVM


1 /*BEGIN_COPYRIGHT_BLOCK
2  *
3  * This file is part of DrJava. Download the current version of this project from http://www.drjava.org/
4  * or http://sourceforge.net/projects/drjava/
5  *
6  * DrJava Open Source License
7  *
8  * Copyright (C) 2001-2005 JavaPLT group at Rice University (javaplt@rice.edu). All rights reserved.
9  *
10  * Developed by: Java Programming Languages Team, Rice University, http://www.cs.rice.edu/~javaplt/
11  *
12  * Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated
13  * documentation files (the "Software"), to deal with the Software without restriction, including without limitation
14  * the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and
15  * to permit persons to whom the Software is furnished to do so, subject to the following conditions:
16  *
17  * - Redistributions of source code must retain the above copyright notice, this list of conditions and the
18  * following disclaimers.
19  * - Redistributions in binary form must reproduce the above copyright notice, this list of conditions and the
20  * following disclaimers in the documentation and/or other materials provided with the distribution.
21  * - Neither the names of DrJava, the JavaPLT, Rice University, nor the names of its contributors may be used to
22  * endorse or promote products derived from this Software without specific prior written permission.
23  * - Products derived from this software may not be called "DrJava" nor use the term "DrJava" as part of their
24  * names without prior written permission from the JavaPLT group. For permission, write to javaplt@rice.edu.
25  *
26  * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO
27  * THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
28  * CONTRIBUTORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF
29  * CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS
30  * WITH THE SOFTWARE.
31  *
32 END_COPYRIGHT_BLOCK*/

33
34 package edu.rice.cs.util.newjvm;
35
36 import edu.rice.cs.drjava.config.FileOption;
37 import edu.rice.cs.util.swing.Utilities;
38 import edu.rice.cs.plt.io.IOUtil;
39
40 import java.io.BufferedReader JavaDoc;
41 import java.io.File JavaDoc;
42 import java.io.IOException JavaDoc;
43 import java.io.InputStreamReader JavaDoc;
44 import java.util.Iterator JavaDoc;
45 import java.util.LinkedList JavaDoc;
46 import java.util.Locale JavaDoc;
47
48 /** A utility class to allow executing another JVM.
49  * @version $Id: ExecJVM.java 4079 2007-01-22 20:20:33Z dlsmith $
50  */

51 public final class ExecJVM {
52   private static final String JavaDoc PATH_SEPARATOR = System.getProperty("path.separator");
53   private static final String JavaDoc OS_NAME = System.getProperty("os.name").toLowerCase(Locale.US);
54
55   private ExecJVM() { }
56
57   /** Runs a new JVM.
58    * @param mainClass Class to run
59    * @param classParams Parameters to pass to the main class
60    * @param classPath Array of items to put in classpath of new JVM
61    * @param jvmParams Array of additional command-line parameters to pass to JVM
62    * @return {@link Process} object corresponding to the executed JVM
63    */

64   public static Process JavaDoc runJVM(String JavaDoc mainClass, String JavaDoc[] classParams, String JavaDoc[] classPath, String JavaDoc[] jvmParams, File JavaDoc workDir)
65     throws IOException JavaDoc {
66
67     final StringBuilder JavaDoc buf = new StringBuilder JavaDoc();
68     for (int i = 0; i < classPath.length; i++) {
69       if (i != 0) buf.append(PATH_SEPARATOR);
70
71       buf.append(classPath[i]);
72     }
73
74     return runJVM(mainClass, classParams, buf.toString(), jvmParams, workDir);
75   }
76
77   /** Runs a new JVM.
78    * @param mainClass Class to run
79    * @param classParams Parameters to pass to the main class
80    * @param classPath Pre-formatted classpath parameter
81    * @param jvmParams Array of additional command-line parameters to pass to JVM
82    *
83    * @return {@link Process} object corresponding to the executed JVM
84    */

85   public static Process JavaDoc runJVM(String JavaDoc mainClass, String JavaDoc[] classParams, String JavaDoc classPath, String JavaDoc[] jvmParams, File JavaDoc workDir)
86     throws IOException JavaDoc {
87
88     LinkedList JavaDoc<String JavaDoc> args = new LinkedList JavaDoc<String JavaDoc>();
89     args.add("-classpath");
90     args.add(classPath);
91     _addArray(args, jvmParams);
92     String JavaDoc[] jvmWithCP = args.toArray(new String JavaDoc[args.size()]);
93
94     return _runJVM(mainClass, classParams, jvmWithCP, workDir);
95   }
96
97   /** Runs a new JVM, propagating the present classpath. It changes the entries in the class path to absolute form.
98    * @param mainClass Class to run
99    * @param classParams Parameters to pass to the main class
100    * @param jvmParams Array of additional command-line parameters to pass to JVM
101    * @return {@link Process} object corresponding to the executed JVM
102    */

103   public static Process JavaDoc runJVMPropagateClassPath(String JavaDoc mainClass, String JavaDoc[] classParams, String JavaDoc[] jvmParams, File JavaDoc workDir)
104     throws IOException JavaDoc {
105     Iterable JavaDoc<File JavaDoc> cp = IOUtil.parsePath(System.getProperty("java.class.path"));
106     cp = IOUtil.getAbsoluteFiles(cp);
107     return runJVM(mainClass, classParams, IOUtil.pathToString(cp), jvmParams, workDir);
108   }
109
110   /** Runs a new JVM, propagating the present classpath.
111    * @param mainClass Class to run
112    * @param classParams Parameters to pass to the main class
113    * @return {@link Process} object corresponding to the new JVM process
114    */

115   public static Process JavaDoc runJVMPropagateClassPath(String JavaDoc mainClass, String JavaDoc[] classParams, File JavaDoc workDir)
116     throws IOException JavaDoc {
117     return runJVMPropagateClassPath(mainClass, classParams, new String JavaDoc[0], workDir);
118   }
119
120   /** Creates and runs a new JVM. This method is private now because it cannot change the classpath entries to
121    * absolute paths, so it should not be used.
122    *
123    * @param mainClass Class to run
124    * @param classParams Parameters to pass to the main class
125    * @param jvmParams Array of additional command-line parameters to pass to JVM
126    *
127    * @return {@link Process} object corresponding to the executed JVM
128    */

129   private static Process JavaDoc _runJVM(String JavaDoc mainClass, String JavaDoc[] classParams, String JavaDoc[] jvmParams, File JavaDoc workDir) throws IOException JavaDoc {
130     LinkedList JavaDoc<String JavaDoc> args = new LinkedList JavaDoc<String JavaDoc>();
131     args.add(_getExecutable());
132     _addArray(args, jvmParams);
133     args.add(mainClass);
134     _addArray(args, classParams);
135
136     String JavaDoc[] argArray = args.toArray(new String JavaDoc[args.size()]);
137
138     // exec our "java" command in the specified working directory setting
139
Process JavaDoc p;
140     if ((workDir != null) && (workDir != FileOption.NULL_FILE)) {
141       // execute in the working directory
142
if (workDir.exists()) p = Runtime.getRuntime().exec(argArray, null, workDir);
143       else {
144         Utilities.showMessageBox("Working directory does not exist:\n" + workDir +
145                                                         "\nThe setting will be ignored. Press OK to continue.",
146                                                         "Configuration Error");
147         p = Runtime.getRuntime().exec(argArray);
148       }
149     }
150     else {
151       // execute without caring about working directory
152
p = Runtime.getRuntime().exec(argArray);
153     }
154     return p;
155   }
156
157   /** Empties BufferedReaders by copying lines into LinkedLists.
158    * This is intended for use with the output streams from an ExecJVM process.
159    * Source and destination objects are specified for stdout and for stderr.
160    * @param theProc a Process object whose output will be handled
161    * @param outLines the LinkedList of Strings to be filled with the lines read from outBuf
162    * @param errLines the LinkedList of Strings to be filled with the lines read from errBuf
163    */

164   public static void ventBuffers(Process JavaDoc theProc, LinkedList JavaDoc<String JavaDoc> outLines,
165                                  LinkedList JavaDoc<String JavaDoc> errLines) throws IOException JavaDoc {
166     // getInputStream actually gives us the stdout from the Process.
167
BufferedReader JavaDoc outBuf = new BufferedReader JavaDoc(new InputStreamReader JavaDoc(theProc.getInputStream()));
168     BufferedReader JavaDoc errBuf = new BufferedReader JavaDoc(new InputStreamReader JavaDoc(theProc.getErrorStream()));
169     String JavaDoc output;
170
171     if (outBuf.ready()) {
172       output = outBuf.readLine();
173
174       while (output != null) {
175         // System.out.println("[stdout]: " + output);
176
outLines.add(output);
177         if (outBuf.ready()) output = outBuf.readLine();
178         else output = null;
179       }
180     }
181     outBuf.close();
182
183     if (errBuf.ready()) {
184       output = errBuf.readLine();
185       while (output != null) {
186         // System.out.println("[stderr] " + output);
187
errLines.add(output);
188         if (errBuf.ready()) {
189           output = errBuf.readLine();
190         }
191         else {
192           output = null;
193         }
194       }
195     }
196     errBuf.close();
197   }
198
199   /** Prints the stdout and stderr of the given process, line by line. Adds a message and tag to identify the source
200     * of the output. Note that this code will print all available stdout before all stderr, since it is impossible
201     * to determine in which order lines were added to the respective buffers.
202     * @param theProc a Process object whose output will be handled
203     * @param msg an initial message to print before output
204     * @param sourceName a short string to identify the process
205     * @throws IOException if there is a problem with the streams
206     */

207   public static void printOutput(Process JavaDoc theProc, String JavaDoc msg, String JavaDoc sourceName)
208     throws IOException JavaDoc {
209     // First, write out our opening message.
210
System.out.println(msg);
211
212     LinkedList JavaDoc<String JavaDoc> outLines = new LinkedList JavaDoc<String JavaDoc>();
213     LinkedList JavaDoc<String JavaDoc> errLines = new LinkedList JavaDoc<String JavaDoc>();
214
215     ventBuffers(theProc, outLines, errLines);
216
217     Iterator JavaDoc<String JavaDoc> it = outLines.iterator();
218     String JavaDoc output;
219     while (it.hasNext()) {
220       output = it.next();
221       System.out.println(" [" +sourceName + " stdout]: " + output);
222     }
223
224     it = errLines.iterator();
225     while (it.hasNext()) {
226       output = it.next();
227       System.out.println(" [" +sourceName + " stderr]: " + output);
228     }
229   }
230
231   private static void _addArray(LinkedList JavaDoc<String JavaDoc> list, String JavaDoc[] array) {
232     if (array != null) {
233       for (int i = 0; i < array.length; i++) {
234         list.add(array[i]);
235       }
236     }
237   }
238
239   /** DOS/Windows family OS's use ; to separate paths. */
240   private static boolean _isDOS() {
241     return PATH_SEPARATOR.equals(";");
242   }
243
244   private static boolean _isNetware() {
245     return OS_NAME.indexOf("netware") != -1;
246   }
247
248   /**
249    * Find the java executable.
250    * This logic comes from Ant.
251    */

252   private static String JavaDoc _getExecutable() {
253     // this netware thing is based on comments from ant's code
254
if (_isNetware()) return "java";
255
256     File JavaDoc executable;
257
258     String JavaDoc java_home = System.getProperty("java.home") + "/";
259
260     String JavaDoc[] candidates = { java_home + "../bin/java", java_home + "bin/java", java_home + "java", };
261
262     // search all the candidates to find java
263
for (int i = 0; i < candidates.length; i++) {
264       String JavaDoc current = candidates[i];
265
266       // try javaw.exe first for dos, otherwise try java.exe for dos
267
if (_isDOS()) {
268         executable = new File JavaDoc(current + "w.exe");
269         if (! executable.exists()) executable = new File JavaDoc(current + ".exe");
270       }
271       else executable = new File JavaDoc(current);
272
273       //System.err.println("checking: " + executable);
274

275       if (executable.exists()) {
276         //System.err.println("JVM executable found: " + executable.getAbsolutePath());
277
return executable.getAbsolutePath();
278       }
279     }
280
281     // hope for the best using the system's path!
282
//System.err.println("Could not find java executable, using 'java'!");
283
return "java";
284   }
285 }
286
287
Popular Tags