Recipe 26.1 Running a Program


Problem

You want to run a program.

Solution

Use one of the exec( ) methods in the java.lang.Runtime class. Or, on JDK 1.5, use the start( ) method of ProcessBuilder.

Discussion

The exec( ) method in the Runtime class lets you run an external program. The command line you give is broken into strings by a simple StringTokenizer (Recipe 3.2) and passed on to the operating system's "execute a program" system call. As an example, here is a simple program that uses exec( ) to run kwrite , a windowed text editor program.[1] On Windows, you'd have to change the name to notepad or wordpad, possibly including the full pathname; e.g., c:/windows/notepad.exe (you can also use backslashes, but be careful to double them because the backslash is special in Java strings):

[1] kwrite is Unix-specific; it's a part of the K Desktop Environment (KDE). See http://www.kde.org.

// file ExecDemoSimple.java public class ExecDemoSimple {     public static void main(String av[]) throws java.io.IOException {          // Run an editor         Process p = Runtime.getRuntime( ).exec("kwrite");     } }

When you compile and run it, the appropriate editor window appears:

$ jr ExecDemoSimple + jikes +E -d . ExecDemoSimple.java + java ExecDemoSimple # causes a KWrite window to appear. $

This version of exec( ) assumes that the pathname contains no blanks because these break proper operation of the StringTokenizer. To overcome this potential problem, use an overloaded form of exec( ), taking an array of strings as arguments. Example 26-1 runs the Windows or Unix version of Netscape, assuming Netscape was installed in the default directory. It passes the name of a help file as an argument, offering a kind of primitive help mechanism, as displayed in Figure 26-1.

Example 26-1. ExecDemoNS.java
import java.awt.*; import java.awt.event.*; import javax.swing.*; import java.io.*; import java.net.*; import java.util.*; import com.darwinsys.util.Debug; /**  * ExecDemoNS shows how to execute a program from within Java.  */ public class ExecDemoNS extends JFrame {     /** The name of the help file. */     protected final static String HELPFILE = "./help/index.html";     /** A stack of process objects; each entry tracks one external running process */     Stack<Process> pStack = new Stack<Process>( );     /** main - instantiate and run */     public static void main(String av[]) throws Exception {         String program = av.length == 0 ? "netscape" : av[0];         new ExecDemoNS(program).setVisible(true);     }     /** The path to the binary executable that we will run */     protected static String program;     /** Constructor - set up strings and things. */     public ExecDemoNS(String prog) {         super("ExecDemo: " + prog);         String osname = System.getProperty("os.name");         if (osname == null)             throw new IllegalArgumentException("no os.name");         if (prog.equals("netscape"))             program = // Windows or UNIX only for now, sorry Mac fans                 (osname.toLowerCase( ).indexOf("windows")!=-1) ?                 "c:/program files/netscape/communicator/program/netscape.exe" :                 "/usr/local/netscape/netscape";         else             program = prog;         Container cp = getContentPane( );         cp.setLayout(new FlowLayout( ));         JButton b;         cp.add(b=new JButton("Exec"));         b.addActionListener(new ActionListener( ) {             public void actionPerformed(ActionEvent evt) {                 runProg( );             }         });         cp.add(b=new JButton("Wait"));         b.addActionListener(new ActionListener( ) {             public void actionPerformed(ActionEvent evt) {                 doWait( );             }         });         cp.add(b=new JButton("Exit"));         b.addActionListener(new ActionListener( ) {             public void actionPerformed(ActionEvent evt) {                 System.exit(0);             }         });         pack( );     }     /** Start the help, in its own Thread. */     public void runProg( ) {         new Thread( ) {             public void run( ) {                 try {                     // Get the URL for the Help File                     URL helpURL = this.getClass( ).getClassLoader( ).                         getResource(HELPFILE);                     // Start Netscape from the Java Application.                     pStack.push(Runtime.getRuntime( ).exec(program + " " + helpURL));                     Debug.println("trace", "In main after exec " + pStack.size( ));                 } catch (Exception ex) {                     JOptionPane.showMessageDialog(ExecDemoNS.this,                         "Error" + ex, "Error",                         JOptionPane.ERROR_MESSAGE);                 }             }         }.start( );     }     public void doWait( ) {         if (pStack.size( ) == 0) return;         Debug.println("trace", "Waiting for process " + pStack.size( ));         try {             pStack.peek( ).waitFor( );                 // wait for process to complete              Debug.println("trace", "Process " + pStack.size( ) + " is done");         } catch (Exception ex) {             JOptionPane.showMessageDialog(this,                 "Error" + ex, "Error",                 JOptionPane.ERROR_MESSAGE);         }         pStack.pop( );     } }

Figure 26-1. ExecDemoNS in action
figs/jcb2_2601.gif


JDK 1.5 includes a new class, ProcesssBuilder , that is designed to replace most nontrivial uses of Runtime.exec( ) . ProcessBuilder uses the 1.5 Generic Collections discussed in Chapter 8 to let you modify or replace the environment. For details, see the Javadoc for java.lang.ProcessBuilder.



Java Cookbook
Java Cookbook, Second Edition
ISBN: 0596007019
EAN: 2147483647
Year: 2003
Pages: 409
Authors: Ian F Darwin

flylib.com © 2008-2017.
If you may any questions please contact us: flylib@qtcs.net