Runtime.exec Usage


Runtime.exec Usage

My program calls Runtime.exec(String) to run another external java application, it runs well in windows, but in Linux platform, it always throws error:
The java class is not found:  com/**/MainClass
From the error message, it is obvious that JVM can not find the main class; usually this is because class path is not correctly configured.
But when I paste that string to shell, external program can be successfully started.
After goggle search, I figured out the root cause,
It's recommended to use Runtime.exec(String[]), and add each argument in its own element of the string array. Never add 2 arguments in one element.
Normally, in each element, we should not add ' or ", if we did that, it may cause exception or incorrect value that is not we want.

The following is a sample application to call another java application:
import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStreamReader;

public class AppInvoker
{
    public static void main(String[] args)
    {
        try
        {
            String[] cmds = new String[] { "C:\\Program Files\\Java\\jdk1.6.0_23\\bin\\java",
                // with "-ms64m -mx512m", it would fail: Invalid initial heap size: -Xms64m -mx512m
                "-ms64m",
                "-mx512m",
                // if -Dfoo='D:\java projects', the foo value would be 'D:\java projects'
                // if -Dfoo=\"D:\\java projects\", java.lang.ClassNotFoundException: projects, projects would be thought as main class.
                // with "-Dfoo=D:\\java projects -Dbar=bar", value of foo would be - D:\java projects -Dbar=bar -.,
                // bar is null, as it's not set.
                "-Dfoo=D:\\java projects",
                "-Dbar=bar",
                "-classpath",
                // don't add ' before classpath, otherwise it will throw ClassNotFoundException.
                // "" is ok.
                // safe way is to not add ' or " at all.
                "D:\\java projects\\arguments.jar",
                "CommandArguments",
                "-nickname",
                // with 'johnny depp', then value of nickname would be 'johnny depp'.
                // with \"johnny depp\", then value of nickname is still johnny depp.
                "johnny depp",
                "-user",
                "depp",
                "-passwd",
                "depp",
                "-cfg",
                "D:\\java projects\\my.cfg" };

            final Process p = Runtime.getRuntime().exec(cmds);

            // read input stream
            new Thread()
            {
                public void run()
                {
                    try
                    {
                        BufferedReader in = new BufferedReader(new InputStreamReader(p.getInputStream()));
                        String line;
                        while ((line = in.readLine()) != null)
                        {
                            System.out.println(line);
                        }
                    }
                    catch (Exception e)
                    {
                        e.printStackTrace();
                    }
                };
            }.start();

            // read error stream
            new Thread()
            {
                public void run()
                {
                    try
                    {
                        BufferedReader errReader = new BufferedReader(new InputStreamReader(p.getErrorStream()));
                        String line;
                        while ((line = errReader.readLine()) != null)
                        {
                            System.err.println(line);
                        }
                    }
                    catch (Exception e)
                    {
                        e.printStackTrace();
                    }
                };
            }.start();
        }
        catch (IOException e)
        {
            e.printStackTrace();
        }
    }
}

public class CommandArguments
{
    public static void main(String[] args)
    {
        // ready system property
        System.out.println("foo:" + System.getProperty("foo"));
        System.out.println("bar:" + System.getProperty("bar"));
        System.out.println("infile:" + System.getProperty("infile"));
        // read parameters
        for (int i = 0; i < args.length; i++)
        {
            System.out.println("args[" + i + "] = " + args[i]);
        }
    }
}

From JDK5, it's recommended to use ProcessBuilder, which provides more functions and deal with spaces much better than Runtime.exec().


Coding Notes 1


Coding Notes 1

Builder Pattern
The intention is to abstract steps of construction of objects so that different implementations of these steps can construct different representations of objects.
Usage
The client calls a constructor (or static factory) with all of the required parameters and gets a builder object. Then the client calls setter-like methods on the builder object to set each optional parameter of interest. Finally, the client calls a parameter-less build method to generate the object, which is immutable.
NutritionFacts cocaCola = new NutritionFacts.Builder(240, 8).
calories(100).sodium(35).carbohydrate(27).build();
The Builder pattern is a good choice when designing classes whose constructors or static factories would have more than a handful of parameters, especially if most of those parameters are optional.
Telescoping constructor pattern
Provide a constructor with only the required parameters, another with a single optional parameter, a third with two optional parameters, and so on, culminating in a constructor with all the optional parameters.
Disadvantages:
Long sequences of identically typed parameters can causesubtle bugs.
JavaBeans constructor pattern
Disadvantages:
It allows inconsistency, mandates mutability
Factory pattern is typically used to create an object in a single step.
If you need to create an object in multiple steps, and those steps may change (some times you may want to ignore some steps), in this case you would use the builder pattern.
Method chaining enables terser and more natural interaction with objects.
To achieve this, return this in method such as setter instead of return void.
toast.makeText(text).setGravity(Gravity.TOP,
0, 0).setView(layout).show();
Status transition
private static final String[] STATUS = new String[] { // used in toString()
"STATUS1",
"STATUS2",
"STATUS3",
"STATUS4",
};
private static final boolean STATUS_CONVERTIBLE[][] = new boolean[][] {
/*********** STATUS1 STATUS2 STATUS3 STATUS4 */
/* STATUS1 */{ false, true, true, true},
/* STATUS2 */{ false, false, true, true},
/* STATUS3 */{ false, false, false, true},
/* STATUS4 */{ false, false, false, false}};
public boolean accept(int newStatus)
{
return STATUS_CONVERTIBLE[this.status][newStatus];
}
Use ByteArray Stream to deep clone object
Sometimes we want to create a deep clone object, but we don't want to implement the class's clone method, maybe this way we have to implement clone method in many classes.
In this situation, we can use stream to create a new same object.
public class DeepClone
{
public static void main(String[] args) throws IOException, ClassNotFoundException
{
Student ra = new Student("Jane", 20);
byte[] resultBtye = serialize(ra);
Student rb = (Student) deserialize(resultBtye);
System.err.println("ra == rb: " + (ra == rb)); // false
System.err.println(ra.name.equals(rb.name)); // true
System.err.println(ra.age == rb.age); // true
}
private static byte[] serialize(Object o) throws IOException
{
ByteArrayOutputStream baos = new ByteArrayOutputStream();
ObjectOutputStream oos = new ObjectOutputStream(baos);
oos.writeObject(o);
return baos.toByteArray();
}
private static Object deserialize(byte[] data) throws IOException, ClassNotFoundException
{
ByteArrayInputStream bais = new ByteArrayInputStream(data);
ObjectInputStream ois = new ObjectInputStream(bais);
return ois.readObject();
}
}
class Student implements Serializable
{
private static final long serialVersionUID = 1L;
public String name;
public int age;
public Student(String name, int age)
{
this.name = name;
this.age = age;
}
}
Interface Names
public interface Closeable {
public void close() throws IOException;
}

Labels

adsense (5) Algorithm (69) Algorithm Series (35) Android (7) ANT (6) bat (8) Big Data (7) Blogger (14) Bugs (6) Cache (5) Chrome (19) Code Example (29) Code Quality (7) Coding Skills (5) Database (7) Debug (16) Design (5) Dev Tips (63) Eclipse (32) Git (5) Google (33) Guava (7) How to (9) Http Client (8) IDE (7) Interview (88) J2EE (13) J2SE (49) Java (186) JavaScript (27) JSON (7) Learning code (9) Lesson Learned (6) Linux (26) Lucene-Solr (112) Mac (10) Maven (8) Network (9) Nutch2 (18) Performance (9) PowerShell (11) Problem Solving (11) Programmer Skills (6) regex (5) Scala (6) Security (9) Soft Skills (38) Spring (22) System Design (11) Testing (7) Text Mining (14) Tips (17) Tools (24) Troubleshooting (29) UIMA (9) Web Development (19) Windows (21) xml (5)