Source Code Cross Referenced for ProcessBuilder.java in  » 6.0-JDK-Core » lang » java » lang » Java Source Code / Java DocumentationJava Source Code and Java Documentation

Home
Java Source Code / Java Documentation
1.6.0 JDK Core
2.6.0 JDK Modules
3.6.0 JDK Modules com.sun
4.6.0 JDK Modules com.sun.java
5.6.0 JDK Modules sun
6.6.0 JDK Platform
7.Ajax
8.Apache Harmony Java SE
9.Aspect oriented
10.Authentication Authorization
11.Blogger System
12.Build
13.Byte Code
14.Cache
15.Chart
16.Chat
17.Code Analyzer
18.Collaboration
19.Content Management System
20.Database Client
21.Database DBMS
22.Database JDBC Connection Pool
23.Database ORM
24.Development
25.EJB Server
26.ERP CRM Financial
27.ESB
28.Forum
29.Game
30.GIS
31.Graphic 3D
32.Graphic Library
33.Groupware
34.HTML Parser
35.IDE
36.IDE Eclipse
37.IDE Netbeans
38.Installer
39.Internationalization Localization
40.Inversion of Control
41.Issue Tracking
42.J2EE
43.J2ME
44.JBoss
45.JMS
46.JMX
47.Library
48.Mail Clients
49.Music
50.Net
51.Parser
52.PDF
53.Portal
54.Profiler
55.Project Management
56.Report
57.RSS RDF
58.Rule Engine
59.Science
60.Scripting
61.Search Engine
62.Security
63.Sevlet Container
64.Source Control
65.Swing Library
66.Template Engine
67.Test Coverage
68.Testing
69.UML
70.Web Crawler
71.Web Framework
72.Web Mail
73.Web Server
74.Web Services
75.Web Services apache cxf 2.2.6
76.Web Services AXIS2
77.Wiki Engine
78.Workflow Engines
79.XML
80.XML UI
Java Source Code / Java Documentation » 6.0 JDK Core » lang » java.lang 
Source Cross Referenced  Class Diagram Java Document (Java Doc) 


001        /*
002         * Copyright 2003-2006 Sun Microsystems, Inc.  All Rights Reserved.
003         * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
004         *
005         * This code is free software; you can redistribute it and/or modify it
006         * under the terms of the GNU General Public License version 2 only, as
007         * published by the Free Software Foundation.  Sun designates this
008         * particular file as subject to the "Classpath" exception as provided
009         * by Sun in the LICENSE file that accompanied this code.
010         *
011         * This code is distributed in the hope that it will be useful, but WITHOUT
012         * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
013         * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
014         * version 2 for more details (a copy is included in the LICENSE file that
015         * accompanied this code).
016         *
017         * You should have received a copy of the GNU General Public License version
018         * 2 along with this work; if not, write to the Free Software Foundation,
019         * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
020         *
021         * Please contact Sun Microsystems, Inc., 4150 Network Circle, Santa Clara,
022         * CA 95054 USA or visit www.sun.com if you need additional information or
023         * have any questions.
024         */
025
026        package java.lang;
027
028        import java.io.File;
029        import java.io.IOException;
030        import java.util.ArrayList;
031        import java.util.List;
032        import java.util.Map;
033
034        /**
035         * This class is used to create operating system processes.
036         *
037         * <p>Each <code>ProcessBuilder</code> instance manages a collection
038         * of process attributes.  The {@link #start()} method creates a new
039         * {@link Process} instance with those attributes.  The {@link
040         * #start()} method can be invoked repeatedly from the same instance
041         * to create new subprocesses with identical or related attributes.
042         *
043         * <p>Each process builder manages these process attributes:
044         *
045         * <ul>
046         *
047         * <li>a <i>command</i>, a list of strings which signifies the
048         * external program file to be invoked and its arguments, if any.
049         * Which string lists represent a valid operating system command is
050         * system-dependent.  For example, it is common for each conceptual
051         * argument to be an element in this list, but there are operating
052         * systems where programs are expected to tokenize command line
053         * strings themselves - on such a system a Java implementation might
054         * require commands to contain exactly two elements.
055         *
056         * <li>an <i>environment</i>, which is a system-dependent mapping from
057         * <i>variables</i> to <i>values</i>.  The initial value is a copy of
058         * the environment of the current process (see {@link System#getenv()}).
059         *
060         * <li>a <i>working directory</i>.  The default value is the current
061         * working directory of the current process, usually the directory
062         * named by the system property <code>user.dir</code>.
063         *
064         * <li>a <i>redirectErrorStream</i> property.  Initially, this property
065         * is <code>false</code>, meaning that the standard output and error
066         * output of a subprocess are sent to two separate streams, which can
067         * be accessed using the {@link Process#getInputStream()} and {@link
068         * Process#getErrorStream()} methods.  If the value is set to
069         * <code>true</code>, the standard error is merged with the standard
070         * output.  This makes it easier to correlate error messages with the
071         * corresponding output.  In this case, the merged data can be read
072         * from the stream returned by {@link Process#getInputStream()}, while
073         * reading from the stream returned by {@link
074         * Process#getErrorStream()} will get an immediate end of file.
075         *
076         * </ul>
077         *
078         * <p>Modifying a process builder's attributes will affect processes
079         * subsequently started by that object's {@link #start()} method, but
080         * will never affect previously started processes or the Java process
081         * itself.
082         *
083         * <p>Most error checking is performed by the {@link #start()} method.
084         * It is possible to modify the state of an object so that {@link
085         * #start()} will fail.  For example, setting the command attribute to
086         * an empty list will not throw an exception unless {@link #start()}
087         * is invoked.
088         *
089         * <p><strong>Note that this class is not synchronized.</strong>
090         * If multiple threads access a <code>ProcessBuilder</code> instance
091         * concurrently, and at least one of the threads modifies one of the
092         * attributes structurally, it <i>must</i> be synchronized externally.
093         *
094         * <p>Starting a new process which uses the default working directory
095         * and environment is easy:
096         *
097         * <blockquote><pre>
098         * Process p = new ProcessBuilder("myCommand", "myArg").start();
099         * </pre></blockquote>
100         *
101         * <p>Here is an example that starts a process with a modified working
102         * directory and environment:
103         *
104         * <blockquote><pre>
105         * ProcessBuilder pb = new ProcessBuilder("myCommand", "myArg1", "myArg2");
106         * Map&lt;String, String&gt; env = pb.environment();
107         * env.put("VAR1", "myValue");
108         * env.remove("OTHERVAR");
109         * env.put("VAR2", env.get("VAR1") + "suffix");
110         * pb.directory(new File("myDir"));
111         * Process p = pb.start();
112         * </pre></blockquote>
113         *
114         * <p>To start a process with an explicit set of environment
115         * variables, first call {@link java.util.Map#clear() Map.clear()}
116         * before adding environment variables.
117         *
118         * @since 1.5
119         */
120
121        public final class ProcessBuilder {
122            private List<String> command;
123            private File directory;
124            private Map<String, String> environment;
125            private boolean redirectErrorStream;
126
127            /**
128             * Constructs a process builder with the specified operating
129             * system program and arguments.  This constructor does <i>not</i>
130             * make a copy of the <code>command</code> list.  Subsequent
131             * updates to the list will be reflected in the state of the
132             * process builder.  It is not checked whether
133             * <code>command</code> corresponds to a valid operating system
134             * command.</p>
135             *
136             * @param   command  The list containing the program and its arguments
137             *
138             * @throws  NullPointerException
139             *          If the argument is <code>null</code>
140             */
141            public ProcessBuilder(List<String> command) {
142                if (command == null)
143                    throw new NullPointerException();
144                this .command = command;
145            }
146
147            /**
148             * Constructs a process builder with the specified operating
149             * system program and arguments.  This is a convenience
150             * constructor that sets the process builder's command to a string
151             * list containing the same strings as the <code>command</code>
152             * array, in the same order.  It is not checked whether
153             * <code>command</code> corresponds to a valid operating system
154             * command.</p>
155             *
156             * @param   command  A string array containing the program and its arguments
157             */
158            public ProcessBuilder(String... command) {
159                this .command = new ArrayList<String>(command.length);
160                for (String arg : command)
161                    this .command.add(arg);
162            }
163
164            /**
165             * Sets this process builder's operating system program and
166             * arguments.  This method does <i>not</i> make a copy of the
167             * <code>command</code> list.  Subsequent updates to the list will
168             * be reflected in the state of the process builder.  It is not
169             * checked whether <code>command</code> corresponds to a valid
170             * operating system command.</p>
171             *
172             * @param   command  The list containing the program and its arguments
173             * @return  This process builder
174             *
175             * @throws  NullPointerException
176             *          If the argument is <code>null</code>
177             */
178            public ProcessBuilder command(List<String> command) {
179                if (command == null)
180                    throw new NullPointerException();
181                this .command = command;
182                return this ;
183            }
184
185            /**
186             * Sets this process builder's operating system program and
187             * arguments.  This is a convenience method that sets the command
188             * to a string list containing the same strings as the
189             * <code>command</code> array, in the same order.  It is not
190             * checked whether <code>command</code> corresponds to a valid
191             * operating system command.</p>
192             *
193             * @param   command  A string array containing the program and its arguments
194             * @return  This process builder
195             */
196            public ProcessBuilder command(String... command) {
197                this .command = new ArrayList<String>(command.length);
198                for (String arg : command)
199                    this .command.add(arg);
200                return this ;
201            }
202
203            /**
204             * Returns this process builder's operating system program and
205             * arguments.  The returned list is <i>not</i> a copy.  Subsequent
206             * updates to the list will be reflected in the state of this
207             * process builder.</p>
208             *
209             * @return  This process builder's program and its arguments
210             */
211            public List<String> command() {
212                return command;
213            }
214
215            /**
216             * Returns a string map view of this process builder's environment.
217             *
218             * Whenever a process builder is created, the environment is
219             * initialized to a copy of the current process environment (see
220             * {@link System#getenv()}).  Subprocesses subsequently started by
221             * this object's {@link #start()} method will use this map as
222             * their environment.
223             *
224             * <p>The returned object may be modified using ordinary {@link
225             * java.util.Map Map} operations.  These modifications will be
226             * visible to subprocesses started via the {@link #start()}
227             * method.  Two <code>ProcessBuilder</code> instances always
228             * contain independent process environments, so changes to the
229             * returned map will never be reflected in any other
230             * <code>ProcessBuilder</code> instance or the values returned by
231             * {@link System#getenv System.getenv}.
232             *
233             * <p>If the system does not support environment variables, an
234             * empty map is returned.
235             *
236             * <p>The returned map does not permit null keys or values.
237             * Attempting to insert or query the presence of a null key or
238             * value will throw a {@link NullPointerException}.
239             * Attempting to query the presence of a key or value which is not
240             * of type {@link String} will throw a {@link ClassCastException}.
241             *
242             * <p>The behavior of the returned map is system-dependent.  A
243             * system may not allow modifications to environment variables or
244             * may forbid certain variable names or values.  For this reason,
245             * attempts to modify the map may fail with
246             * {@link UnsupportedOperationException} or
247             * {@link IllegalArgumentException}
248             * if the modification is not permitted by the operating system.
249             *
250             * <p>Since the external format of environment variable names and
251             * values is system-dependent, there may not be a one-to-one
252             * mapping between them and Java's Unicode strings.  Nevertheless,
253             * the map is implemented in such a way that environment variables
254             * which are not modified by Java code will have an unmodified
255             * native representation in the subprocess.
256             *
257             * <p>The returned map and its collection views may not obey the
258             * general contract of the {@link Object#equals} and
259             * {@link Object#hashCode} methods.
260             *
261             * <p>The returned map is typically case-sensitive on all platforms.
262             *
263             * <p>If a security manager exists, its
264             * {@link SecurityManager#checkPermission checkPermission}
265             * method is called with a
266             * <code>{@link RuntimePermission}("getenv.*")</code>
267             * permission.  This may result in a {@link SecurityException} being
268             * thrown.
269             *
270             * <p>When passing information to a Java subprocess,
271             * <a href=System.html#EnvironmentVSSystemProperties>system properties</a>
272             * are generally preferred over environment variables.</p>
273             *
274             * @return  This process builder's environment
275             *
276             * @throws  SecurityException
277             *          If a security manager exists and its
278             *          {@link SecurityManager#checkPermission checkPermission}
279             *          method doesn't allow access to the process environment
280             *
281             * @see     Runtime#exec(String[],String[],java.io.File)
282             * @see     System#getenv()
283             */
284            public Map<String, String> environment() {
285                SecurityManager security = System.getSecurityManager();
286                if (security != null)
287                    security.checkPermission(new RuntimePermission("getenv.*"));
288
289                if (environment == null)
290                    environment = ProcessEnvironment.environment();
291
292                assert environment != null;
293
294                return environment;
295            }
296
297            // Only for use by Runtime.exec(...envp...)
298            ProcessBuilder environment(String[] envp) {
299                assert environment == null;
300                if (envp != null) {
301                    environment = ProcessEnvironment
302                            .emptyEnvironment(envp.length);
303                    assert environment != null;
304
305                    for (String envstring : envp) {
306                        // Before 1.5, we blindly passed invalid envstrings
307                        // to the child process.
308                        // We would like to throw an exception, but do not,
309                        // for compatibility with old broken code.
310
311                        // Silently discard any trailing junk.
312                        if (envstring.indexOf((int) '\u0000') != -1)
313                            envstring = envstring.replaceFirst("\u0000.*", "");
314
315                        int eqlsign = envstring.indexOf('=',
316                                ProcessEnvironment.MIN_NAME_LENGTH);
317                        // Silently ignore envstrings lacking the required `='.
318                        if (eqlsign != -1)
319                            environment.put(envstring.substring(0, eqlsign),
320                                    envstring.substring(eqlsign + 1));
321                    }
322                }
323                return this ;
324            }
325
326            /**
327             * Returns this process builder's working directory.
328             *
329             * Subprocesses subsequently started by this object's {@link
330             * #start()} method will use this as their working directory.
331             * The returned value may be <code>null</code> -- this means to use
332             * the working directory of the current Java process, usually the
333             * directory named by the system property <code>user.dir</code>,
334             * as the working directory of the child process.</p>
335             *
336             * @return  This process builder's working directory
337             */
338            public File directory() {
339                return directory;
340            }
341
342            /**
343             * Sets this process builder's working directory.
344             *
345             * Subprocesses subsequently started by this object's {@link
346             * #start()} method will use this as their working directory.
347             * The argument may be <code>null</code> -- this means to use the
348             * working directory of the current Java process, usually the
349             * directory named by the system property <code>user.dir</code>,
350             * as the working directory of the child process.</p>
351             *
352             * @param   directory  The new working directory
353             * @return  This process builder
354             */
355            public ProcessBuilder directory(File directory) {
356                this .directory = directory;
357                return this ;
358            }
359
360            /**
361             * Tells whether this process builder merges standard error and
362             * standard output.
363             *
364             * <p>If this property is <code>true</code>, then any error output
365             * generated by subprocesses subsequently started by this object's
366             * {@link #start()} method will be merged with the standard
367             * output, so that both can be read using the
368             * {@link Process#getInputStream()} method.  This makes it easier
369             * to correlate error messages with the corresponding output.
370             * The initial value is <code>false</code>.</p>
371             *
372             * @return  This process builder's <code>redirectErrorStream</code> property
373             */
374            public boolean redirectErrorStream() {
375                return redirectErrorStream;
376            }
377
378            /**
379             * Sets this process builder's <code>redirectErrorStream</code> property.
380             *
381             * <p>If this property is <code>true</code>, then any error output
382             * generated by subprocesses subsequently started by this object's
383             * {@link #start()} method will be merged with the standard
384             * output, so that both can be read using the
385             * {@link Process#getInputStream()} method.  This makes it easier
386             * to correlate error messages with the corresponding output.
387             * The initial value is <code>false</code>.</p>
388             *
389             * @param   redirectErrorStream  The new property value
390             * @return  This process builder
391             */
392            public ProcessBuilder redirectErrorStream(
393                    boolean redirectErrorStream) {
394                this .redirectErrorStream = redirectErrorStream;
395                return this ;
396            }
397
398            /**
399             * Starts a new process using the attributes of this process builder.
400             *
401             * <p>The new process will
402             * invoke the command and arguments given by {@link #command()},
403             * in a working directory as given by {@link #directory()},
404             * with a process environment as given by {@link #environment()}.
405             *
406             * <p>This method checks that the command is a valid operating
407             * system command.  Which commands are valid is system-dependent,
408             * but at the very least the command must be a non-empty list of
409             * non-null strings.
410             *
411             * <p>If there is a security manager, its
412             * {@link SecurityManager#checkExec checkExec}
413             * method is called with the first component of this object's
414             * <code>command</code> array as its argument. This may result in
415             * a {@link SecurityException} being thrown.
416             *
417             * <p>Starting an operating system process is highly system-dependent.
418             * Among the many things that can go wrong are:
419             * <ul>
420             * <li>The operating system program file was not found.
421             * <li>Access to the program file was denied.
422             * <li>The working directory does not exist.
423             * </ul>
424             *
425             * <p>In such cases an exception will be thrown.  The exact nature
426             * of the exception is system-dependent, but it will always be a
427             * subclass of {@link IOException}.
428             *
429             * <p>Subsequent modifications to this process builder will not
430             * affect the returned {@link Process}.</p>
431             *
432             * @return  A new {@link Process} object for managing the subprocess
433             *
434             * @throws  NullPointerException
435             *          If an element of the command list is null
436             *
437             * @throws  IndexOutOfBoundsException
438             *          If the command is an empty list (has size <code>0</code>)
439             *
440             * @throws  SecurityException
441             *          If a security manager exists and its
442             *          {@link SecurityManager#checkExec checkExec}
443             *          method doesn't allow creation of the subprocess
444             *
445             * @throws  IOException
446             *          If an I/O error occurs
447             *
448             * @see     Runtime#exec(String[], String[], java.io.File)
449             * @see     SecurityManager#checkExec(String)
450             */
451            public Process start() throws IOException {
452                // Must convert to array first -- a malicious user-supplied
453                // list might try to circumvent the security check.
454                String[] cmdarray = command.toArray(new String[command.size()]);
455                for (String arg : cmdarray)
456                    if (arg == null)
457                        throw new NullPointerException();
458                // Throws IndexOutOfBoundsException if command is empty
459                String prog = cmdarray[0];
460
461                SecurityManager security = System.getSecurityManager();
462                if (security != null)
463                    security.checkExec(prog);
464
465                String dir = directory == null ? null : directory.toString();
466
467                try {
468                    return ProcessImpl.start(cmdarray, environment, dir,
469                            redirectErrorStream);
470                } catch (IOException e) {
471                    // It's much easier for us to create a high-quality error
472                    // message than the low-level C code which found the problem.
473                    throw new IOException("Cannot run program \""
474                            + prog
475                            + "\""
476                            + (dir == null ? "" : " (in directory \"" + dir
477                                    + "\")") + ": " + e.getMessage(), e);
478                }
479            }
480        }
www.java2java.com | Contact Us
Copyright 2009 - 12 Demo Source and Support. All rights reserved.
All other trademarks are property of their respective owners.