KickJava   Java API By Example, From Geeks To Geeks.

Java > Open Source Codes > org > eclipse > jdt > internal > launching > StandardVMRunner


1 /*******************************************************************************
2  * Copyright (c) 2000, 2007 IBM Corporation and others.
3  * All rights reserved. This program and the accompanying materials
4  * are made available under the terms of the Eclipse Public License v1.0
5  * which accompanies this distribution, and is available at
6  * http://www.eclipse.org/legal/epl-v10.html
7  *
8  * Contributors:
9  * IBM Corporation - initial API and implementation
10  *******************************************************************************/

11 package org.eclipse.jdt.internal.launching;
12
13
14 import java.io.File JavaDoc;
15 import java.util.ArrayList JavaDoc;
16 import java.util.Date JavaDoc;
17 import java.util.Iterator JavaDoc;
18 import java.util.List JavaDoc;
19 import java.util.Map JavaDoc;
20 import java.util.Map.Entry;
21
22 import org.eclipse.core.runtime.CoreException;
23 import org.eclipse.core.runtime.IPath;
24 import org.eclipse.core.runtime.IProgressMonitor;
25 import org.eclipse.core.runtime.NullProgressMonitor;
26 import org.eclipse.core.runtime.Path;
27 import org.eclipse.core.runtime.Platform;
28 import org.eclipse.core.runtime.SubProgressMonitor;
29 import org.eclipse.debug.core.DebugPlugin;
30 import org.eclipse.debug.core.ILaunch;
31 import org.eclipse.debug.core.model.IProcess;
32 import org.eclipse.jdt.launching.AbstractVMRunner;
33 import org.eclipse.jdt.launching.IJavaLaunchConfigurationConstants;
34 import org.eclipse.jdt.launching.IVMInstall;
35 import org.eclipse.jdt.launching.IVMInstall2;
36 import org.eclipse.jdt.launching.VMRunnerConfiguration;
37
38 import com.ibm.icu.text.DateFormat;
39 import com.ibm.icu.text.MessageFormat;
40
41 /**
42  * A launcher for running Java main classes.
43  */

44 public class StandardVMRunner extends AbstractVMRunner {
45     
46     /**
47      * The VM install instance
48      */

49     protected IVMInstall fVMInstance;
50
51     /**
52      * Constructor
53      * @param vmInstance
54      */

55     public StandardVMRunner(IVMInstall vmInstance) {
56         fVMInstance= vmInstance;
57     }
58     
59     /**
60      * Returns the 'rendered' name for the current target
61      * @param classToRun
62      * @param host
63      * @return the name for the current target
64      */

65     protected String JavaDoc renderDebugTarget(String JavaDoc classToRun, int host) {
66         String JavaDoc format= LaunchingMessages.StandardVMRunner__0__at_localhost__1__1;
67         return MessageFormat.format(format, new String JavaDoc[] { classToRun, String.valueOf(host) });
68     }
69
70     /**
71      * Returns the 'rendered' name for the specified command line
72      * @param commandLine
73      * @return the name for the process
74      */

75     public static String JavaDoc renderProcessLabel(String JavaDoc[] commandLine) {
76         String JavaDoc format= LaunchingMessages.StandardVMRunner__0____1___2;
77         String JavaDoc timestamp= DateFormat.getDateTimeInstance(DateFormat.MEDIUM, DateFormat.MEDIUM).format(new Date JavaDoc(System.currentTimeMillis()));
78         return MessageFormat.format(format, new String JavaDoc[] { commandLine[0], timestamp });
79     }
80     
81     /**
82      * Prepares the command line from the specified array of strings
83      * @param commandLine
84      * @return
85      */

86     protected static String JavaDoc renderCommandLine(String JavaDoc[] commandLine) {
87         if (commandLine.length < 1)
88             return ""; //$NON-NLS-1$
89
StringBuffer JavaDoc buf= new StringBuffer JavaDoc();
90         for (int i= 0; i < commandLine.length; i++) {
91             buf.append(' ');
92             char[] characters= commandLine[i].toCharArray();
93             StringBuffer JavaDoc command= new StringBuffer JavaDoc();
94             boolean containsSpace= false;
95             for (int j = 0; j < characters.length; j++) {
96                 char character= characters[j];
97                 if (character == '\"') {
98                     command.append('\\');
99                 } else if (character == ' ') {
100                     containsSpace = true;
101                 }
102                 command.append(character);
103             }
104             if (containsSpace) {
105                 buf.append('\"');
106                 buf.append(command.toString());
107                 buf.append('\"');
108             } else {
109                 buf.append(command.toString());
110             }
111         }
112         return buf.toString();
113     }
114     
115     /**
116      * Adds the values of args to the given list v
117      * @param args
118      * @param v
119      */

120     protected void addArguments(String JavaDoc[] args, List JavaDoc v) {
121         if (args == null) {
122             return;
123         }
124         for (int i= 0; i < args.length; i++) {
125             v.add(args[i]);
126         }
127     }
128     
129     /**
130      * Returns the working directory to use for the launched VM,
131      * or <code>null</code> if the working directory is to be inherited
132      * from the current process.
133      *
134      * @return the working directory to use
135      * @exception CoreException if the working directory specified by
136      * the configuration does not exist or is not a directory
137      */

138     protected File JavaDoc getWorkingDir(VMRunnerConfiguration config) throws CoreException {
139         String JavaDoc path = config.getWorkingDirectory();
140         if (path == null) {
141             return null;
142         }
143         File JavaDoc dir = new File JavaDoc(path);
144         if (!dir.isDirectory()) {
145             abort(MessageFormat.format(LaunchingMessages.StandardVMRunner_Specified_working_directory_does_not_exist_or_is_not_a_directory___0__3, new String JavaDoc[] {path}), null, IJavaLaunchConfigurationConstants.ERR_WORKING_DIRECTORY_DOES_NOT_EXIST);
146         }
147         return dir;
148     }
149     
150     /**
151      * @see VMRunner#getPluginIdentifier()
152      */

153     protected String JavaDoc getPluginIdentifier() {
154         return LaunchingPlugin.getUniqueIdentifier();
155     }
156     
157     /**
158      * Construct and return a String containing the full path of a java executable
159      * command such as 'java' or 'javaw.exe'. If the configuration specifies an
160      * explicit executable, that is used.
161      *
162      * @return full path to java executable
163      * @exception CoreException if unable to locate an executable
164      */

165     protected String JavaDoc constructProgramString(VMRunnerConfiguration config) throws CoreException {
166
167         // Look for the user-specified java executable command
168
String JavaDoc command= null;
169         Map JavaDoc map= config.getVMSpecificAttributesMap();
170         if (map != null) {
171             command = (String JavaDoc)map.get(IJavaLaunchConfigurationConstants.ATTR_JAVA_COMMAND);
172         }
173         
174         // If no java command was specified, use default executable
175
if (command == null) {
176             File JavaDoc exe = StandardVMType.findJavaExecutable(fVMInstance.getInstallLocation());
177             if (exe == null) {
178                 abort(MessageFormat.format(LaunchingMessages.StandardVMRunner_Unable_to_locate_executable_for__0__1, new String JavaDoc[]{fVMInstance.getName()}), null, IJavaLaunchConfigurationConstants.ERR_INTERNAL_ERROR);
179             }
180             return exe.getAbsolutePath();
181         }
182                 
183         // Build the path to the java executable. First try 'bin', and if that
184
// doesn't exist, try 'jre/bin'
185
String JavaDoc installLocation = fVMInstance.getInstallLocation().getAbsolutePath() + File.separatorChar;
186         File JavaDoc exe = new File JavaDoc(installLocation + "bin" + File.separatorChar + command); //$NON-NLS-1$
187
if (fileExists(exe)){
188             return exe.getAbsolutePath();
189         }
190         exe = new File JavaDoc(exe.getAbsolutePath() + ".exe"); //$NON-NLS-1$
191
if (fileExists(exe)){
192             return exe.getAbsolutePath();
193         }
194         exe = new File JavaDoc(installLocation + "jre" + File.separatorChar + "bin" + File.separatorChar + command); //$NON-NLS-1$ //$NON-NLS-2$
195
if (fileExists(exe)) {
196             return exe.getAbsolutePath();
197         }
198         exe = new File JavaDoc(exe.getAbsolutePath() + ".exe"); //$NON-NLS-1$
199
if (fileExists(exe)) {
200             return exe.getAbsolutePath();
201         }
202
203         
204         // not found
205
abort(MessageFormat.format(LaunchingMessages.StandardVMRunner_Specified_executable__0__does_not_exist_for__1__4, new String JavaDoc[]{command, fVMInstance.getName()}), null, IJavaLaunchConfigurationConstants.ERR_INTERNAL_ERROR);
206         // NOTE: an exception will be thrown - null cannot be returned
207
return null;
208     }
209     
210     /**
211      * Convenience method to determine if the specified file exists or not
212      * @param file
213      * @return true if the file indeed exists, false otherwise
214      */

215     protected boolean fileExists(File JavaDoc file) {
216         return file.exists() && file.isFile();
217     }
218
219     protected String JavaDoc convertClassPath(String JavaDoc[] cp) {
220         int pathCount= 0;
221         StringBuffer JavaDoc buf= new StringBuffer JavaDoc();
222         if (cp.length == 0) {
223             return ""; //$NON-NLS-1$
224
}
225         for (int i= 0; i < cp.length; i++) {
226             if (pathCount > 0) {
227                 buf.append(File.pathSeparator);
228             }
229             buf.append(cp[i]);
230             pathCount++;
231         }
232         return buf.toString();
233     }
234
235
236     /* (non-Javadoc)
237      * @see org.eclipse.jdt.launching.IVMRunner#run(org.eclipse.jdt.launching.VMRunnerConfiguration, org.eclipse.debug.core.ILaunch, org.eclipse.core.runtime.IProgressMonitor)
238      */

239     public void run(VMRunnerConfiguration config, ILaunch launch, IProgressMonitor monitor) throws CoreException {
240
241         if (monitor == null) {
242             monitor = new NullProgressMonitor();
243         }
244         
245         IProgressMonitor subMonitor = new SubProgressMonitor(monitor, 1);
246         subMonitor.beginTask(LaunchingMessages.StandardVMRunner_Launching_VM____1, 2);
247         subMonitor.subTask(LaunchingMessages.StandardVMRunner_Constructing_command_line____2);
248         
249         String JavaDoc program= constructProgramString(config);
250         
251         List JavaDoc arguments= new ArrayList JavaDoc();
252         arguments.add(program);
253                 
254         // VM args are the first thing after the java program so that users can specify
255
// options like '-client' & '-server' which are required to be the first option
256
String JavaDoc[] allVMArgs = combineVmArgs(config, fVMInstance);
257         addArguments(allVMArgs, arguments);
258         
259         addBootClassPathArguments(arguments, config);
260         
261         String JavaDoc[] cp= config.getClassPath();
262         if (cp.length > 0) {
263             arguments.add("-classpath"); //$NON-NLS-1$
264
arguments.add(convertClassPath(cp));
265         }
266         arguments.add(config.getClassToLaunch());
267         
268         String JavaDoc[] programArgs= config.getProgramArguments();
269         addArguments(programArgs, arguments);
270                 
271         String JavaDoc[] cmdLine= new String JavaDoc[arguments.size()];
272         arguments.toArray(cmdLine);
273         
274         String JavaDoc[] envp = prependJREPath(config.getEnvironment(), new Path(program));
275         
276         subMonitor.worked(1);
277
278         // check for cancellation
279
if (monitor.isCanceled()) {
280             return;
281         }
282         
283         subMonitor.subTask(LaunchingMessages.StandardVMRunner_Starting_virtual_machine____3);
284         Process JavaDoc p= null;
285         File JavaDoc workingDir = getWorkingDir(config);
286         p= exec(cmdLine, workingDir, envp);
287         if (p == null) {
288             return;
289         }
290         
291         // check for cancellation
292
if (monitor.isCanceled()) {
293             p.destroy();
294             return;
295         }
296         
297         IProcess process= newProcess(launch, p, renderProcessLabel(cmdLine), getDefaultProcessMap());
298         process.setAttribute(IProcess.ATTR_CMDLINE, renderCommandLine(cmdLine));
299         subMonitor.worked(1);
300         subMonitor.done();
301     }
302     
303     /**
304      * Prepends the correct java version variable state to the environment path for Mac VMs
305      *
306      * @param env the current array of environment variables to run with
307      * @param jdkpath the path of the current jdk
308      * @since 3.3
309      */

310     protected String JavaDoc[] prependJREPath(String JavaDoc[] env, IPath jdkpath) {
311         if (Platform.OS_MACOSX.equals(Platform.getOS())) {
312             if (fVMInstance instanceof IVMInstall2) {
313                 IVMInstall2 vm = (IVMInstall2) fVMInstance;
314                 String JavaDoc javaVersion = vm.getJavaVersion();
315                 if (javaVersion != null) {
316                     if (env == null) {
317                         Map JavaDoc map = DebugPlugin.getDefault().getLaunchManager().getNativeEnvironmentCasePreserved();
318                         if (map.containsKey(StandardVMDebugger.JAVA_JVM_VERSION)) {
319                             String JavaDoc[] env2 = new String JavaDoc[map.size()];
320                             Iterator JavaDoc iterator = map.entrySet().iterator();
321                             int i = 0;
322                             while (iterator.hasNext()) {
323                                 Entry entry = (Entry) iterator.next();
324                                 String JavaDoc key = (String JavaDoc) entry.getKey();
325                                 if (StandardVMDebugger.JAVA_JVM_VERSION.equals(key)) {
326                                     env2[i] = key + "=" + javaVersion; //$NON-NLS-1$
327
} else {
328                                     env2[i] = key + "=" + (String JavaDoc)entry.getValue(); //$NON-NLS-1$
329
}
330                                 i++;
331                             }
332                             env = env2;
333                         }
334                     } else {
335                         for (int i = 0; i < env.length; i++) {
336                             String JavaDoc string = env[i];
337                             if (string.startsWith(StandardVMDebugger.JAVA_JVM_VERSION)) {
338                                 env[i]=StandardVMDebugger.JAVA_JVM_VERSION+"="+javaVersion; //$NON-NLS-1$
339
break;
340                             }
341                         }
342                     }
343                 }
344             }
345         }
346         return env;
347     }
348
349     /**
350      * Adds arguments to the bootpath
351      * @param arguments
352      * @param config
353      */

354     protected void addBootClassPathArguments(List JavaDoc arguments, VMRunnerConfiguration config) {
355         String JavaDoc[] prependBootCP= null;
356         String JavaDoc[] bootCP= null;
357         String JavaDoc[] appendBootCP= null;
358         Map JavaDoc map = config.getVMSpecificAttributesMap();
359         if (map != null) {
360             prependBootCP= (String JavaDoc[]) map.get(IJavaLaunchConfigurationConstants.ATTR_BOOTPATH_PREPEND);
361             bootCP= (String JavaDoc[]) map.get(IJavaLaunchConfigurationConstants.ATTR_BOOTPATH);
362             appendBootCP= (String JavaDoc[]) map.get(IJavaLaunchConfigurationConstants.ATTR_BOOTPATH_APPEND);
363         }
364         if (prependBootCP == null && bootCP == null && appendBootCP == null) {
365             // use old single attribute instead of new attributes if not specified
366
bootCP = config.getBootClassPath();
367         }
368         if (prependBootCP != null) {
369             arguments.add("-Xbootclasspath/p:" + convertClassPath(prependBootCP)); //$NON-NLS-1$
370
}
371         if (bootCP != null) {
372             if (bootCP.length > 0) {
373                 arguments.add("-Xbootclasspath:" + convertClassPath(bootCP)); //$NON-NLS-1$
374
}
375         }
376         if (appendBootCP != null) {
377             arguments.add("-Xbootclasspath/a:" + convertClassPath(appendBootCP)); //$NON-NLS-1$
378
}
379     }
380
381 }
382
Popular Tags