001    /**
002     * Copyright (c) 2000-2011 Liferay, Inc. All rights reserved.
003     *
004     * The contents of this file are subject to the terms of the Liferay Enterprise
005     * Subscription License ("License"). You may not use this file except in
006     * compliance with the License. You can obtain a copy of the License by
007     * contacting Liferay, Inc. See the License for the specific language governing
008     * permissions and limitations under the License, including but not limited to
009     * distribution rights of the Software.
010     *
011     *
012     *
013     */
014    
015    package com.liferay.portal.kernel.process;
016    
017    import java.io.IOException;
018    import java.io.InputStream;
019    import java.io.ObjectInputStream;
020    import java.io.ObjectOutputStream;
021    import java.io.OutputStream;
022    import java.io.Serializable;
023    
024    /**
025     * @author Shuyang Zhou
026     */
027    public class ProcessExecutor {
028    
029            public static <T extends Serializable> T execute(
030                            ProcessCallable<T> processCallable, String classPath)
031                    throws ProcessException {
032    
033                    try {
034                            ProcessBuilder processBuilder = new ProcessBuilder(
035                                    "java", "-cp", classPath, ProcessExecutor.class.getName());
036    
037                            Process process = processBuilder.start();
038    
039                            _writeObject(process.getOutputStream(), processCallable, true);
040    
041                            int exitCode = process.waitFor();
042    
043                            if (exitCode != 0) {
044                                    throw new ProcessException(
045                                            "Subprocess terminated with exit code " + exitCode);
046                            }
047    
048                            InputStream errorInputStream = process.getErrorStream();
049    
050                            if (errorInputStream.available() > 0) {
051                                    ProcessException processException =
052                                            (ProcessException)_readObject(errorInputStream, true);
053    
054                                    throw processException;
055                            }
056    
057                            return (T)_readObject(process.getInputStream(), true);
058                    }
059                    catch (Exception e) {
060                            throw new ProcessException(e);
061                    }
062            }
063    
064            public static void main(String[] arguments)
065                    throws ClassNotFoundException, IOException {
066    
067                    try {
068                            ProcessCallable<?> processCallable =
069                                    (ProcessCallable<?>)_readObject(System.in, false);
070    
071                            Object result = processCallable.call();
072    
073                            _writeObject(System.out, result, false);
074                    }
075                    catch (ProcessException pe) {
076                            _writeObject(System.err, pe, false);
077                    }
078            }
079    
080            private static Object _readObject(InputStream inputStream, boolean close)
081                    throws ClassNotFoundException, IOException {
082    
083                    ObjectInputStream objectInputStream = new ObjectInputStream(
084                            inputStream);
085    
086                    try {
087                            return objectInputStream.readObject();
088                    }
089                    finally {
090                            if (close) {
091                                    objectInputStream.close();
092                            }
093                    }
094            }
095    
096            private static void _writeObject(
097                            OutputStream outputStream, Object object, boolean close)
098                    throws IOException {
099    
100                    ObjectOutputStream objectOutputStream = new ObjectOutputStream(
101                            outputStream);
102    
103                    try {
104                            objectOutputStream.writeObject(object);
105                    }
106                    finally {
107                            if (close) {
108                                    objectOutputStream.close();
109                            }
110                            else {
111                                    objectOutputStream.flush();
112                            }
113                    }
114            }
115    
116    }