org.kchine.r.server.manager.ServerManager.java Source code

Java tutorial

Introduction

Here is the source code for org.kchine.r.server.manager.ServerManager.java

Source

/*
 * Biocep: R-based Platform for Computational e-Science.
 *
 * Copyright (C) 2007-2009 Karim Chine - karim.chine@m4x.org
 *
 * This program is free software: you can redistribute it and/or modify
 * it under the terms of the GNU General Public License as published by
 * the Free Software Foundation, either version 3 of the License, or
 * (at your option) any later version.
 *
 * This program is distributed in the hope that it will be useful,
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 * GNU General Public License for more details.
 *
 * You should have received a copy of the GNU General Public License
 * along with this program.  If not, see <http://www.gnu.org/licenses/>.
 */
package org.kchine.r.server.manager;

import static org.kchine.rpf.PoolUtils.isWindowsOs;
import static org.kchine.rpf.PoolUtils.unzip;
import java.awt.BorderLayout;
import java.awt.Color;
import java.io.BufferedReader;
import java.io.File;
import java.io.FileReader;
import java.io.FileWriter;
import java.io.FilenameFilter;
import java.io.InputStream;
import java.io.InputStreamReader;
import java.io.PrintWriter;
import java.io.RandomAccessFile;
import java.net.Socket;
import java.net.URL;
import java.rmi.RemoteException;
import java.rmi.server.UnicastRemoteObject;
import java.util.Arrays;
import java.util.HashMap;
import java.util.Map;
import java.util.Properties;
import java.util.UUID;
import java.util.Vector;
import javax.swing.BorderFactory;
import javax.swing.JFrame;
import javax.swing.JOptionPane;
import javax.swing.JPanel;
import javax.swing.JProgressBar;
import javax.swing.JScrollPane;
import javax.swing.JTextArea;
import javax.swing.SwingUtilities;
import org.kchine.r.server.DirectJNI;
import org.kchine.r.server.RServices;
import org.kchine.r.server.http.local.LocalHttpServer;
import org.kchine.r.server.manager.bootstrap.BootSsh;
import org.kchine.r.server.spreadsheet.TableModelRemoteImpl;
import org.kchine.rpf.CreationCallBack;
import org.kchine.rpf.LocalRmiRegistry;
import org.kchine.rpf.ManagedServant;
import org.kchine.rpf.PoolUtils;
import org.kchine.rpf.RemoteLogListener;
import org.kchine.rpf.SSHUtils;
import org.kchine.rpf.ServantCreationTimeout;
import org.kchine.rpf.ServerDefaults;
import ch.ethz.ssh2.ChannelCondition;
import ch.ethz.ssh2.Connection;
import ch.ethz.ssh2.SCPClient;
import ch.ethz.ssh2.Session;
import ch.ethz.ssh2.StreamGobbler;

/**
 * @author Karim Chine karim.chine@m4x.org
 */
public class ServerManager {

    public static void main(String[] args) throws Exception {

    }

    public static String INSTALL_DIR = null;
    public static String PLUGINS_DIR = null;
    public static String EXTENSIONS_DIR = null;
    public static String DOWNLOAD_DIR = null;
    public static String WWW_DIR = null;
    public static final String EMBEDDED_R = "R-version-2.9.0";
    public static final String SCILAB_VERSION = "Scilab-version-5.1";
    public static final int ENTRIES_NUMBER = 5354;

    public static String sci = null;
    public static String sci_dll_path = null;

    static {
        if (System.getenv("BIOCEP_HOME") != null) {
            INSTALL_DIR = System.getenv("BIOCEP_HOME");
        } else if (System.getProperty("biocep.home") != null && !System.getProperty("biocep.home").equals("")) {
            INSTALL_DIR = System.getProperty("biocep.home");
        } else if (new File(System.getProperty("user.dir") + "/biocep.txt").exists()) {
            INSTALL_DIR = System.getProperty("user.dir");
        } else {
            String codeUrl = ServerManager.class.getResource("/org/kchine/r/server/manager/ServerManager.class")
                    .toString();
            if (codeUrl.startsWith("jar:file:")) {
                try {
                    String jarurl = codeUrl.substring("jar:".length(),
                            codeUrl.length() - "/org/kchine/r/server/manager/ServerManager.class".length() - 1);
                    String jarfile = PoolUtils.getFileFromURL(new URL(jarurl)).getAbsolutePath().replace('\\', '/');
                    if (new File(new File(jarfile).getParent() + "/biocep.txt").exists()) {
                        INSTALL_DIR = jarfile.substring(0, jarfile.lastIndexOf("/"));
                    } else {
                        INSTALL_DIR = System.getProperty("user.home") + "/RWorkbench/";
                    }
                } catch (Exception e) {
                    e.printStackTrace();
                    INSTALL_DIR = System.getProperty("user.home") + "/RWorkbench/";
                }
            } else {
                INSTALL_DIR = System.getProperty("user.home") + "/RWorkbench/";
            }
        }
        INSTALL_DIR = new File(INSTALL_DIR).getAbsolutePath() + "/";

        new File(INSTALL_DIR).mkdirs();
        if (!new File(INSTALL_DIR + "/biocep.txt").exists()) {
            try {
                PrintWriter pw = new PrintWriter(INSTALL_DIR + "/biocep.txt");
                pw.close();
            } catch (Exception e) {
                e.printStackTrace();
            }
        }

        System.out.println("@@INSTALL_DIR=" + INSTALL_DIR);

        if (System.getenv("BIOCEP_PLUGINS_HOME") != null) {
            PLUGINS_DIR = System.getenv("BIOCEP_PLUGINS_HOME");
        } else if (System.getProperty("plugins.home") != null && !System.getProperty("plugins.home").equals("")) {
            PLUGINS_DIR = System.getProperty("plugins.home");
        } else {
            PLUGINS_DIR = INSTALL_DIR + "plugins";
        }
        if (!new File(PLUGINS_DIR).exists())
            new File(PLUGINS_DIR).mkdirs();

        if (System.getenv("BIOCEP_EXTENSIONS_HOME") != null) {
            EXTENSIONS_DIR = System.getenv("BIOCEP_EXTENSIONS_HOME");
        } else if (System.getProperty("extensions.home") != null
                && !System.getProperty("extensions.home").equals("")) {
            EXTENSIONS_DIR = System.getProperty("extensions.home");
        } else {
            EXTENSIONS_DIR = new File(INSTALL_DIR + "extensions").getAbsolutePath();
        }
        if (!new File(EXTENSIONS_DIR).exists())
            new File(EXTENSIONS_DIR).mkdirs();

        if (System.getenv("BIOCEP_DOWNLOAD_DIR") != null) {
            DOWNLOAD_DIR = System.getenv("BIOCEP_DOWNLOAD_DIR");
        } else if (System.getProperty("download.home") != null && !System.getProperty("download.home").equals("")) {
            DOWNLOAD_DIR = System.getProperty("download.home");
        } else {
            DOWNLOAD_DIR = new File(INSTALL_DIR + "download").getAbsolutePath();
        }
        if (!new File(DOWNLOAD_DIR).exists())
            new File(DOWNLOAD_DIR).mkdirs();

        if (System.getenv("BIOCEP_WWW_DIR") != null) {
            WWW_DIR = System.getenv("BIOCEP_WWW_DIR");
        } else if (System.getProperty("www.home") != null && !System.getProperty("www.home").equals("")) {
            WWW_DIR = System.getProperty("www.home");
        } else {
            WWW_DIR = new File(INSTALL_DIR + "www").getAbsolutePath();
        }
        if (!new File(WWW_DIR).exists())
            new File(WWW_DIR).mkdirs();

        sci = System.getProperty("sci");
        if (sci == null || sci.equals(""))
            sci = System.getenv("SCI");
        if (sci == null || sci.equals("")) {
            if (isWindowsOs()) {
                File embeddedScilabDir = new File(INSTALL_DIR + "scilab");
                if (!embeddedScilabDir.exists())
                    embeddedScilabDir.mkdirs();
                String[] dirList = embeddedScilabDir.list(new FilenameFilter() {
                    public boolean accept(File dir, String name) {
                        return dir.isDirectory();
                    }
                });
                if (dirList.length > 0) {
                    sci = embeddedScilabDir + "/" + dirList[0];
                } else {
                    sci = null;
                }

            } else {
                if (new File("/usr/share/scilab").exists()) {
                    sci = "/usr/share/scilab";
                } else {
                    sci = null;
                }
            }
        }

        if (sci != null) {
            sci = new File(sci).getAbsolutePath().replace('\\', '/') + "/";
            sci_dll_path = System.getProperty("sci.ld.library.path");
            if (sci_dll_path == null || sci_dll_path.equals(""))
                sci_dll_path = System.getenv("SCI_DLL");
            if (sci_dll_path == null || sci_dll_path.equals("")) {
                if (isWindowsOs()) {
                    sci_dll_path = sci + "bin";
                } else {
                    if (new File("/usr/lib64/scilab").exists()) {
                        sci_dll_path = "/usr/lib64/scilab";
                    } else if (new File("/usr/lib/scilab").exists()) {
                        sci_dll_path = "/usr/lib/scilab";
                    }
                }
            }
        }

        System.out.println("SCI:" + sci);

    }

    public static long SERVANT_CREATION_TIMEOUT_MILLISEC = 60000 * 5;
    public static int BUFFER_SIZE = 8192 * 5;
    private static final String RHOMESTART = "R$HOME$START";
    private static final String RHOMEEND = "R$HOME$END";
    private static final String RVERSTART = "R$VER$START";
    private static final String RVEREND = "R$VER$END";
    private static final String RJAVAPATHSTART = "RJAVA$PATH$START";
    private static final String RJAVAPATHEND = "RJAVA$PATH$END";

    public static TableModelRemoteImpl tmri;

    public static String[] namingVars = new String[] { "naming.mode", "registry.host", "registry.port", "db.type",
            "db.host", "db.port", "db.dir", "db.name", "db.user", "db.password", "httpregistry.url",
            "httpregistry.login", "httpregistry.password", "rmi.port.start", "job.id", "job.name", "notify.email",
            "node", "http.port", "cloud", "extensions.home", "use.default.libs", "r.options", "preprocess.help",

            // gor Gen target
            "file", "dir", "outputdir", "mappingjar", "warname", "propsembed", "keepintermediate", "formatsource",
            "ws.r.api", "targetjdk"

    };

    private static JTextArea createRSshProgressArea;
    private static JProgressBar createRSshProgressBar;
    private static JFrame createRSshProgressFrame;

    public static Properties getRegistryNamingInfo(String registryHost, int registryPort) {
        Properties result = new Properties();

        for (int i = 0; i < namingVars.length; ++i) {
            String var = namingVars[i];
            if (System.getProperty(var) != null && !System.getProperty(var).equals("")) {
                result.put(var, System.getProperty(var));
            }
        }

        result.put("naming.mode", "registry");
        result.put("registry.host", registryHost);
        result.put("registry.port", new Integer(registryPort).toString());
        return result;
    }

    public static Properties getNamingInfo() {
        Properties result = new Properties();
        for (int i = 0; i < namingVars.length; ++i) {
            String var = namingVars[i];
            if (System.getProperty(var) != null && !System.getProperty(var).equals("")) {
                result.put(var, System.getProperty(var));
            }
        }
        return result;
    }

    public static RServices createRSsh(boolean keepAlive, String codeServerHostIp, int codeServerPort,
            Properties namingInfo, int memoryMinMegabytes, int memoryMaxMegabytes, String sshHostIp, int sshPort,
            String sshLogin, String sshPwd, String name, boolean showProgress, URL[] codeUrls, String logFile)
            throws BadSshHostException, BadSshLoginPwdException, Exception {

        if (showProgress) {
            createRSshProgressArea = new JTextArea();
            createRSshProgressBar = new JProgressBar(0, 100);
            createRSshProgressFrame = new JFrame("Create R Server via SSH");

            Runnable runnable = new Runnable() {
                public void run() {
                    createRSshProgressArea.setFocusable(false);
                    createRSshProgressBar.setIndeterminate(true);
                    JPanel p = new JPanel(new BorderLayout());
                    p.add(createRSshProgressBar, BorderLayout.SOUTH);
                    p.add(new JScrollPane(createRSshProgressArea), BorderLayout.CENTER);
                    createRSshProgressFrame.add(p);
                    createRSshProgressFrame.pack();
                    createRSshProgressFrame.setSize(300, 90);
                    createRSshProgressFrame.setVisible(true);
                    createRSshProgressFrame.setDefaultCloseOperation(JFrame.HIDE_ON_CLOSE);
                    PoolUtils.locateInScreenCenter(createRSshProgressFrame);
                }
            };

            if (SwingUtilities.isEventDispatchThread())
                runnable.run();
            else {
                SwingUtilities.invokeLater(runnable);
            }
        }

        Connection conn = null;
        try {
            conn = new Connection(sshHostIp, sshPort);
            try {
                conn.connect();
            } catch (Exception e) {
                throw new BadSshHostException();
            }
            boolean isAuthenticated = conn.authenticateWithPassword(sshLogin, sshPwd);
            if (isAuthenticated == false)
                throw new BadSshLoginPwdException();

            InputStream is = ServerManager.class
                    .getResourceAsStream("/org/kchine/r/server/manager/bootstrap/BootSsh.class");
            byte[] buffer = new byte[is.available()];
            try {
                for (int i = 0; i < buffer.length; ++i) {
                    int b = is.read();
                    buffer[i] = (byte) b;
                }
            } catch (Exception e) {
                e.printStackTrace();
            }

            String bootstrapDir = INSTALL_DIR + "classes/org/kchine/r/server/manager/bootstrap";
            new File(bootstrapDir).mkdirs();
            RandomAccessFile raf = new RandomAccessFile(bootstrapDir + "/BootSsh.class", "rw");
            raf.setLength(0);
            raf.write(buffer);
            raf.close();

            Session sess = null;
            try {
                sess = conn.openSession();
                sess.execCommand("mkdir -p RWorkbench/classes/org/kchine/r/server/manager/bootstrap");
                sess.waitForCondition(ChannelCondition.EXIT_STATUS, 0);
            } finally {
                try {
                    if (sess != null)
                        sess.close();
                } catch (Exception e) {
                    e.printStackTrace();
                }
            }

            new SCPClient(conn).put(bootstrapDir + "/BootSsh.class",
                    "RWorkbench/classes/org/kchine/r/server/manager/bootstrap");
            try {
                sess = conn.openSession();

                String command = "java -classpath RWorkbench/classes org.kchine.r.server.manager.bootstrap.BootSsh"
                        + " " + new Boolean(keepAlive) + " " + codeServerHostIp + " " + codeServerPort + " "
                        + BootSsh.propertiesToString(namingInfo) + " " + "NULL" + " " + memoryMinMegabytes + " "
                        + memoryMaxMegabytes + " " + "System.out" + " "
                        + ((name == null || name.trim().equals("")) ? BootSsh.NO_NAME : name);

                if (codeUrls != null && codeUrls.length > 0) {
                    for (int i = 0; i < codeUrls.length; ++i) {
                        command = command + " " + codeUrls[i];
                    }
                }

                System.out.println("createRSsh command:" + command);
                sess.execCommand(command);

                InputStream stdout = new StreamGobbler(sess.getStdout());
                final BufferedReader brOut = new BufferedReader(new InputStreamReader(stdout));

                InputStream stderr = new StreamGobbler(sess.getStderr());
                final BufferedReader brErr = new BufferedReader(new InputStreamReader(stderr));
                final StringBuffer sshOutput = new StringBuffer();
                new Thread(new Runnable() {
                    public void run() {
                        try {
                            while (true) {
                                String line = brOut.readLine();
                                if (line == null)
                                    break;
                                sshOutput.append(line + "\n");
                                System.out.println(line);
                            }
                        } catch (Exception e) {
                            e.printStackTrace();
                        }
                        System.out.println("Out Log Thread Died");
                    }
                }).start();

                new Thread(new Runnable() {
                    public void run() {
                        try {
                            while (true) {
                                String line = brErr.readLine();
                                if (line == null)
                                    break;
                                System.out.println(line);
                            }
                        } catch (Exception e) {
                            e.printStackTrace();
                        }
                        System.out.println("Err Log Thread Died");
                    }
                }).start();

                sess.waitForCondition(ChannelCondition.EXIT_STATUS, 0);

                int eIndex = sshOutput.indexOf(BootSsh.STUB_END_MARKER);
                if (eIndex != -1) {
                    int bIndex = sshOutput.indexOf(BootSsh.STUB_BEGIN_MARKER);
                    String stub = sshOutput.substring(bIndex + BootSsh.STUB_BEGIN_MARKER.length(), eIndex);
                    return (RServices) PoolUtils.hexToStub(stub, ServerManager.class.getClassLoader());
                } else {
                    return null;
                }

            } finally {
                try {
                    if (sess != null)
                        sess.close();
                } catch (Exception e) {
                    e.printStackTrace();
                }
            }

        } finally {
            try {
                if (conn != null)
                    conn.close();
            } catch (Exception e) {
                e.printStackTrace();
            }
            if (showProgress) {
                createRSshProgressFrame.setVisible(false);
            }
        }
    }

    public static RServices createR(String name) throws Exception {
        return createR(null, false, false, PoolUtils.getHostIp(), LocalHttpServer.getLocalHttpServerPort(),
                getRegistryNamingInfo(PoolUtils.getHostIp(), LocalRmiRegistry.getLocalRmiRegistryPort()),
                ServerDefaults._memoryMin, ServerDefaults._memoryMax, name, false, null, null,
                System.getProperty("application_type"), null, null);
    }

    private interface ProgessLoggerInterface {
        void logProgress(String message);
    }

    synchronized public static RServices createR(String RBinPath, boolean forceEmbedded, boolean keepAlive,
            String codeServerHostIp, int codeServerPort, Properties namingInfo, int memoryMinMegabytes,
            int memoryMaxMegabytes, String name, final boolean showProgress, URL[] codeUrls, String logFile,
            String applicationType, final Runnable rShutdownHook, String forcedIP) throws Exception {
        return createRInternal(RBinPath, forceEmbedded, keepAlive, codeServerHostIp, codeServerPort, namingInfo,
                memoryMinMegabytes, memoryMaxMegabytes, name, showProgress, codeUrls, logFile, applicationType,
                rShutdownHook, forcedIP, "org.kchine.r.server.MainRServer", true);
    }

    synchronized public static RServices createRInternal(String RBinPath, boolean forceEmbedded, boolean keepAlive,
            String codeServerHostIp, int codeServerPort, Properties namingInfo, int memoryMinMegabytes,
            int memoryMaxMegabytes, String name, final boolean showProgress, URL[] codeUrls, String logFile,
            String applicationType, final Runnable rShutdownHook, String forcedIP, String mainClassName,
            boolean useCreationCallback) throws Exception {

        final JTextArea[] createRProgressArea = new JTextArea[1];
        final JProgressBar[] createRProgressBar = new JProgressBar[1];
        final JFrame[] createRProgressFrame = new JFrame[1];
        ProgessLoggerInterface progressLogger = new ProgessLoggerInterface() {
            public void logProgress(String message) {

                System.out.println(">>" + message);
                try {
                    if (showProgress) {
                        createRProgressArea[0].setText(message);
                    }
                } catch (Exception e) {
                    e.printStackTrace();
                }
            }
        };

        if (showProgress) {
            createRProgressArea[0] = new JTextArea();
            createRProgressBar[0] = new JProgressBar(0, 100);
            createRProgressFrame[0] = new JFrame("Creating R Server on Local Host");

            Runnable runnable = new Runnable() {
                public void run() {

                    createRProgressFrame[0].setUndecorated(true);

                    JPanel p = new JPanel(new BorderLayout());
                    createRProgressArea[0].setForeground(Color.white);
                    createRProgressArea[0].setBackground(new Color(0x00, 0x80, 0x80));
                    createRProgressArea[0]
                            .setBorder(BorderFactory.createLineBorder(new Color(0x00, 0x80, 0x80), 3));
                    createRProgressArea[0].setEditable(false);
                    p.setBorder(BorderFactory.createLineBorder(Color.black, 3));

                    createRProgressBar[0].setForeground(Color.white);
                    createRProgressBar[0].setBackground(new Color(0x00, 0x80, 0x80));
                    createRProgressBar[0].setIndeterminate(true);

                    p.setBackground(new Color(0x00, 0x80, 0x80));
                    p.add(createRProgressBar[0], BorderLayout.SOUTH);
                    p.add(createRProgressArea[0], BorderLayout.CENTER);
                    createRProgressFrame[0].add(p);

                    createRProgressFrame[0].pack();
                    createRProgressFrame[0].setSize(600, 64);
                    createRProgressFrame[0].setVisible(true);
                    createRProgressFrame[0].setDefaultCloseOperation(JFrame.DO_NOTHING_ON_CLOSE);

                    PoolUtils.locateInScreenCenter(createRProgressFrame[0]);
                }
            };
            if (SwingUtilities.isEventDispatchThread())
                runnable.run();
            else {
                SwingUtilities.invokeLater(runnable);
            }
        }

        boolean useClassPath = (codeUrls == null || codeUrls.length == 0)
                && (applicationType == null || applicationType.equals("") || applicationType.equals("standard"));
        System.out.println("application type : " + applicationType);
        System.out.println("!! use class path : " + useClassPath);
        System.out.println("java.class.path : " + System.getProperty("java.class.path"));

        try {

            progressLogger.logProgress("Inspecting R installation..");
            new File(INSTALL_DIR).mkdir();

            String rpath = null;
            String rversion = null;
            String userrjavapath = null;
            String[] rinfo = null;

            if (RBinPath != null && !RBinPath.equals("")) {
                rinfo = getRInfo(RBinPath);
                if (rinfo == null) {
                    throw new ServantCreationFailed();
                }
                rpath = rinfo[0];
                rversion = rinfo[1];
                userrjavapath = rinfo[2];
            } else if (new File(INSTALL_DIR + "R/" + EMBEDDED_R).exists()) {

                rinfo = getRInfo(INSTALL_DIR + "R/" + EMBEDDED_R + "/bin/R.exe");
                if (rinfo == null) {
                    throw new ServantCreationFailed();
                }
                rpath = rinfo[0];
                rversion = rinfo[1];
                userrjavapath = rinfo[2];

                System.setProperty("use.default.libs", "true");

            } else if (!forceEmbedded) {

                String rhome = System.getenv("R_HOME");
                if (rhome == null) {
                    rinfo = getRInfo(null);
                } else {
                    if (!rhome.endsWith("/")) {
                        rhome = rhome + "/";
                    }
                    System.out.println("R_HOME is set to :" + rhome);
                    rinfo = getRInfo(rhome + "bin/R");
                }

                System.out.println("+rinfo:" + rinfo + " " + Arrays.toString(rinfo));
                rpath = rinfo != null ? rinfo[0] : null;
                rversion = (rinfo != null ? rinfo[1] : "");
                userrjavapath = (rinfo != null ? rinfo[2] : "");
            }

            System.out.println("rpath:" + rpath);
            System.out.println("rversion:" + rversion);
            System.out.println("user rjava path:" + userrjavapath);
            if (rpath == null) {

                String noRCause = System.getenv("R_HOME") == null ? "R is not accessible from the command line"
                        : "Your R_HOME is invalid";
                if (isWindowsOs()) {

                    int n;
                    if (forceEmbedded) {
                        n = JOptionPane.OK_OPTION;
                    } else {
                        n = JOptionPane.showConfirmDialog(null,
                                noRCause + "\nWould you like to use the Embedded R?", "",
                                JOptionPane.YES_NO_OPTION);
                    }
                    if (n == JOptionPane.OK_OPTION) {
                        String rZipFileName = null;
                        rZipFileName = "http://biocep-distrib.r-forge.r-project.org/r/" + EMBEDDED_R + ".zip";
                        URL rUrl = new URL(rZipFileName);
                        InputStream is = rUrl.openConnection().getInputStream();
                        unzip(is, INSTALL_DIR + "R/", null, BUFFER_SIZE, true, "Unzipping R..", ENTRIES_NUMBER);

                        rinfo = getRInfo(INSTALL_DIR + "R/" + EMBEDDED_R + "/bin/R.exe");
                        if (rinfo == null) {
                            throw new ServantCreationFailed();
                        }
                        rpath = rinfo[0];
                        rversion = rinfo[1];
                        userrjavapath = rinfo[2];
                        System.setProperty("use.default.libs", "true");

                    } else {
                        JOptionPane.showMessageDialog(null,
                                "please add R to your System path or set R_HOME to the root Directory of your local R installation\n");
                        throw new ServantCreationFailed();
                    }

                } else {
                    if (showProgress) {
                        JOptionPane.showMessageDialog(null, noRCause
                                + "\nplease add R to your System path \nor set R_HOME to the root Directory of your local R installation\n");
                    } else {
                        System.out.println(noRCause
                                + "\n please add R to your System path \nor set R_HOME to the root Directory of your local R installation");
                    }
                    throw new ServantCreationFailed();
                }

            }

            progressLogger.logProgress("R installation inspection done.");

            boolean useDefaultUserLibs = (System.getenv("BIOCEP_USE_DEFAULT_LIBS") != null
                    && System.getenv("BIOCEP_USE_DEFAULT_LIBS").equalsIgnoreCase("false"))
                    || (System.getProperty("use.default.libs") != null
                            && System.getProperty("use.default.libs").equalsIgnoreCase("true"));

            if (System.getProperty("use.default.libs") == null
                    || System.getProperty("use.default.libs").equals("")) {
                System.setProperty("use.default.libs", new Boolean(useDefaultUserLibs).toString().toLowerCase());
            }

            if (!rpath.endsWith("/") && !rpath.endsWith("\\"))
                rpath += "/";

            String rlibs = (INSTALL_DIR + "library/"
                    + rversion.substring(0, rversion.lastIndexOf(' ')).replace(' ', '-')).replace('\\', '/');
            new File(rlibs).mkdirs();

            Vector<String> envVector = new Vector<String>();
            {
                Map<String, String> osenv = System.getenv();
                String OS_PATH = osenv.get("PATH");
                if (OS_PATH == null)
                    OS_PATH = osenv.get("Path");
                if (OS_PATH == null)
                    OS_PATH = "";

                Map<String, String> env = new HashMap<String, String>(osenv);

                env.put("Path",
                        rpath + (isWindowsOs() ? "bin" : "lib") + System.getProperty("path.separator") + OS_PATH);
                if (sci != null && isWindowsOs()) {
                    env.put("Path", sci_dll_path + System.getProperty("path.separator") + env.get("Path"));
                }

                env.put("LD_LIBRARY_PATH", rpath + (isWindowsOs() ? "bin" : "lib"));
                if (sci != null) {
                    env.put("SCI", sci);
                    env.put("SCIHOME", sci);
                    env.put("SCI_DISABLE_TK", "1");
                    env.put("SCI_JAVA_ENABLE_HEADLESS", "1");

                    if (!isWindowsOs()) {
                        env.put("LD_LIBRARY_PATH",
                                sci_dll_path + System.getProperty("path.separator") + env.get("LD_LIBRARY_PATH"));
                    }
                }

                env.put("R_HOME", rpath);

                String R_LIBS = null;
                if (useDefaultUserLibs) {
                    R_LIBS = (System.getenv("R_LIBS") != null ? System.getenv("R_LIBS") : "");
                } else {
                    R_LIBS = rlibs + System.getProperty("path.separator")
                            + (System.getenv("R_LIBS") != null ? System.getenv("R_LIBS") : "");
                }

                System.out.println("R_LIBS:" + R_LIBS);
                env.put("R_LIBS", R_LIBS);

                if (System.getenv("JDK_HOME") != null)
                    env.put("JAVA_HOME", System.getenv("JDK_HOME"));

                for (String k : env.keySet()) {
                    envVector.add(k + "=" + env.get(k));
                }
                System.out.println("envVector:" + envVector);
            }

            String[] requiredPackages = null;
            if (useDefaultUserLibs) {
                requiredPackages = new String[0];
            } else {
                if (isWindowsOs()) {
                    requiredPackages = new String[] { "rJava", "JavaGD", "iplots", "TypeInfo", "Cairo" };
                } else {
                    requiredPackages = new String[] { "rJava", "JavaGD", "iplots", "TypeInfo" };
                }
            }

            Vector<String> installLibBatch = new Vector<String>();
            installLibBatch.add("source('http://bioconductor.org/biocLite.R')");

            Vector<String> missingPackages = new Vector<String>();
            for (int i = 0; i < requiredPackages.length; ++i) {
                if (!new File(rlibs + "/" + requiredPackages[i]).exists()) {
                    installLibBatch.add("biocLite('" + requiredPackages[i] + "',lib='" + rlibs + "')");
                    missingPackages.add(requiredPackages[i]);
                }
            }

            progressLogger.logProgress("Installing missing packages " + missingPackages + "..\n"
                    + "This doesn't alter your R installation and may take several minutes. It will be done only once");

            if (installLibBatch.size() > 1) {

                File installPackagesFile = new File(INSTALL_DIR + "installRequiredPackages.R");
                File installPackagesOutputFile = new File(INSTALL_DIR + "installRequiredPackages.Rout");

                FileWriter fw = new FileWriter(installPackagesFile);
                PrintWriter pw = new PrintWriter(fw);
                for (int i = 0; i < installLibBatch.size(); ++i) {
                    pw.println(installLibBatch.elementAt(i));
                }
                fw.close();

                Vector<String> installCommand = new Vector<String>();
                installCommand.add(rpath + "bin/R");
                installCommand.add("CMD");
                installCommand.add("BATCH");
                installCommand.add("--no-save");
                installCommand.add(installPackagesFile.getAbsolutePath());
                installCommand.add(installPackagesOutputFile.getAbsolutePath());

                System.out.println(installCommand);

                final Process installProc = Runtime.getRuntime().exec(installCommand.toArray(new String[0]),
                        envVector.toArray(new String[0]));
                final Vector<String> installPrint = new Vector<String>();
                final Vector<String> installErrorPrint = new Vector<String>();

                new Thread(new Runnable() {
                    public void run() {
                        try {
                            BufferedReader br = new BufferedReader(
                                    new InputStreamReader(installProc.getErrorStream()));
                            String line = null;
                            while ((line = br.readLine()) != null) {
                                System.out.println(line);
                                installErrorPrint.add(line);
                            }
                        } catch (Exception e) {
                            e.printStackTrace();
                        }
                    }
                }).start();

                new Thread(new Runnable() {
                    public void run() {
                        try {
                            BufferedReader br = new BufferedReader(
                                    new InputStreamReader(installProc.getInputStream()));
                            String line = null;
                            while ((line = br.readLine()) != null) {
                                System.out.println(line);
                                installPrint.add(line);
                            }
                        } catch (Exception e) {
                            e.printStackTrace();
                        }
                    }
                }).start();
                installProc.waitFor();

                if (installPackagesOutputFile.exists()
                        && installPackagesOutputFile.lastModified() > installPackagesFile.lastModified()) {
                    BufferedReader br = new BufferedReader(new FileReader(installPackagesOutputFile));
                    String line = null;
                    while ((line = br.readLine()) != null) {
                        System.out.println(line);
                    }
                }

                Vector<String> missingLibs = new Vector<String>();

                for (int i = 0; i < requiredPackages.length; ++i) {
                    if (!new File(rlibs + "/" + requiredPackages[i]).exists()) {
                        missingLibs.add(requiredPackages[i]);
                    }
                    /*
                     * if (getLibraryPath(requiredPackages[i], rpath, rlibs) ==
                     * null) { missingLibs.add(requiredPackages[i]); }
                     */
                }

                if (missingLibs.size() > 0) {
                    System.out.println(
                            "The following packages probably couldn't be automatically installed\n" + missingLibs);
                    throw new ServantCreationFailed();
                }

            }

            progressLogger.logProgress("All Required Packages Are Installed.");

            progressLogger.logProgress("Generating Bootstrap Classes..");

            String bootstrap = (INSTALL_DIR + "classes/org/kchine/r/server/manager/bootstrap").replace('\\', '/');
            System.out.println(bootstrap);
            if (!new File(bootstrap).exists())
                new File(bootstrap).mkdirs();
            InputStream is = ServerManager.class
                    .getResourceAsStream("/org/kchine/r/server/manager/bootstrap/Boot.class");
            byte[] buffer = new byte[is.available()];
            try {
                for (int i = 0; i < buffer.length; ++i) {
                    int b = is.read();
                    buffer[i] = (byte) b;
                }
            } catch (Exception e) {
                e.printStackTrace();
            }
            RandomAccessFile raf = new RandomAccessFile(bootstrap + "/Boot.class", "rw");
            raf.setLength(0);
            raf.write(buffer);
            raf.close();
            progressLogger.logProgress("Bootstrap Classes Generated.");

            // ---------------------------------------

            if (!isWindowsOs() && !new File(INSTALL_DIR + "VRWorkbench.sh").exists()) {
                try {

                    progressLogger.logProgress("Generating Launcher Batch..");

                    String launcherFile = INSTALL_DIR + "VRWorkbench.sh";
                    FileWriter fw = new FileWriter(launcherFile);
                    PrintWriter pw = new PrintWriter(fw);
                    pw.println("javaws http://biocep-distrib.r-forge.r-project.org/rworkbench.jnlp");
                    fw.close();

                    progressLogger.logProgress("Launcher Batch generated..");
                } catch (Exception e) {
                    e.printStackTrace();
                }
            }

            // ---------------------------------------

            // String jripath = getLibraryPath("rJava", rpath, rlibs) + "jri/";
            String java_library_path = null;
            if (useDefaultUserLibs) {
                java_library_path = userrjavapath + "/jri/";
                System.out.println("jripath:" + java_library_path + "\n");
            } else {
                java_library_path = rlibs + "/rJava/jri/";
                System.out.println("jripath:" + java_library_path + "\n");
            }

            if (sci != null) {
                java_library_path += System.getProperty("path.separator") + sci_dll_path;
            }

            System.out.println("java.library.path" + java_library_path);

            String cp = null;
            if (useClassPath) {
                cp = PoolUtils.getAbsoluteClassPath();
            } else {
                cp = INSTALL_DIR + "classes";
            }

            if (sci != null) {
                if (isWindowsOs()) {
                    cp = cp + System.getProperty("path.separator") + sci + "modules/javasci/jar/javasci.jar";
                } else {
                    String scilabLibraryDir = INSTALL_DIR + "scilab/javasci/" + SCILAB_VERSION + "/";
                    if (new File(scilabLibraryDir).exists())
                        new File(scilabLibraryDir).mkdirs();
                    try {
                        PoolUtils.cacheJar(
                                new URL("http://www.biocep.net/scilab/" + SCILAB_VERSION + "/" + "javasci.jar"),
                                scilabLibraryDir, PoolUtils.LOG_PRGRESS_TO_SYSTEM_OUT, false);
                    } catch (Exception e) {
                        e.printStackTrace();
                    }
                    cp = cp + System.getProperty("path.separator") + scilabLibraryDir + "javasci.jar";
                }

            }

            Vector<File> extraJarFiles = new Vector<File>();

            try {

                File[] flist = new File(INSTALL_DIR).listFiles(new FilenameFilter() {
                    public boolean accept(File dir, String name) {
                        return name.endsWith(".jar");
                    }
                });
                Arrays.sort(flist);
                for (int i = 0; i < flist.length; ++i) {
                    extraJarFiles.add(flist[i]);
                }

                System.out.println("Insiders Extra Jars:" + Arrays.toString(flist));

                if (System.getenv().get("BIOCEP_EXTRA_JARS_LOCATION") != null) {
                    flist = new File(System.getenv().get("BIOCEP_EXTRA_JARS_LOCATION"))
                            .listFiles(new FilenameFilter() {
                                public boolean accept(File dir, String name) {
                                    return name.endsWith(".jar");
                                }
                            });

                    Arrays.sort(flist);
                    System.out.println("Outsiders Extra Jars:" + Arrays.toString(flist));
                    for (int i = 0; i < flist.length; ++i) {
                        extraJarFiles.add(flist[i]);
                    }
                }

            } catch (Exception e) {
                e.printStackTrace();
            }

            ManagedServant[] servantHolder = new ManagedServant[1];
            RemoteException[] exceptionHolder = new RemoteException[1];

            CreationCallBack callBack = null;
            String listenerStub = null;

            progressLogger.logProgress("Creating R Server..");

            try {

                if (useCreationCallback) {
                    callBack = new CreationCallBack(servantHolder, exceptionHolder);
                    listenerStub = PoolUtils.stubToHex(callBack);
                }

                String uid = null;

                if (name != null && !name.equals("") && name.contains("%{uid}")) {
                    if (uid == null)
                        uid = UUID.randomUUID().toString();
                    name = PoolUtils.replaceAll(name, "%{uid}", uid);
                }

                if (logFile != null && !logFile.equals("") && logFile.contains("%{uid}")) {
                    if (uid == null)
                        uid = UUID.randomUUID().toString();
                    logFile = PoolUtils.replaceAll(logFile, "%{uid}", uid);
                }

                Vector<String> command = new Vector<String>();

                command.add((isWindowsOs() ? "\"" : "") + System.getProperty("java.home") + "/bin/java"
                        + (isWindowsOs() ? "\"" : ""));

                command.add((isWindowsOs() ? "\"" : "") + "-DXms" + memoryMinMegabytes + "m"
                        + (isWindowsOs() ? "\"" : ""));
                command.add((isWindowsOs() ? "\"" : "") + "-DXmx" + memoryMaxMegabytes + "m"
                        + (isWindowsOs() ? "\"" : ""));

                command.add("-cp");
                command.add((isWindowsOs() ? "\"" : "") + cp + (isWindowsOs() ? "\"" : ""));

                command.add((isWindowsOs() ? "\"" : "") + "-Djava.library.path=" + java_library_path
                        + (isWindowsOs() ? "\"" : ""));

                String codeBase = "http://" + codeServerHostIp + ":" + codeServerPort + "/classes/";

                if (codeUrls != null && codeUrls.length > 0) {
                    for (int i = 0; i < codeUrls.length; ++i)
                        codeBase += " " + codeUrls[i].toString();
                }

                if (extraJarFiles.size() > 0) {
                    for (int i = 0; i < extraJarFiles.size(); ++i)
                        codeBase += " " + extraJarFiles.elementAt(i).toURI().toURL().toString();
                }

                command.add((isWindowsOs() ? "\"" : "") + "-Djava.rmi.server.codebase=" + codeBase
                        + (isWindowsOs() ? "\"" : ""));
                if (keepAlive) {
                    command.add((isWindowsOs() ? "\"" : "") + "-Dpreloadall=true" + (isWindowsOs() ? "\"" : ""));
                }

                command.add((isWindowsOs() ? "\"" : "") + "-Dservantclass=server.RServantImpl"
                        + (isWindowsOs() ? "\"" : ""));

                if (name == null || name.equals("")) {
                    command.add((isWindowsOs() ? "\"" : "") + "-Dprivate=true" + (isWindowsOs() ? "\"" : ""));
                } else {
                    command.add((isWindowsOs() ? "\"" : "") + "-Dname=" + name + (isWindowsOs() ? "\"" : ""));
                }

                if (useCreationCallback) {
                    command.add((isWindowsOs() ? "\"" : "") + "-Dlistener.stub=" + listenerStub
                            + (isWindowsOs() ? "\"" : ""));
                }

                if (forcedIP != null && !forcedIP.equals("")) {
                    command.add((isWindowsOs() ? "\"" : "") + "-Dhost.ip.forced=" + forcedIP
                            + (isWindowsOs() ? "\"" : ""));
                }

                command.add((isWindowsOs() ? "\"" : "") + "-Dapply.sandbox=false" + (isWindowsOs() ? "\"" : ""));
                command.add((isWindowsOs() ? "\"" : "") + "-Dworking.dir.root=" + INSTALL_DIR + "wdir"
                        + (isWindowsOs() ? "\"" : ""));

                command.add((isWindowsOs() ? "\"" : "") + "-Dkeepalive=" + keepAlive + (isWindowsOs() ? "\"" : ""));
                command.add((isWindowsOs() ? "\"" : "") + "-Dcode.server.host=" + codeServerHostIp
                        + (isWindowsOs() ? "\"" : ""));
                command.add((isWindowsOs() ? "\"" : "") + "-Dcode.server.port=" + codeServerPort
                        + (isWindowsOs() ? "\"" : ""));

                for (int i = 0; i < namingVars.length; ++i) {
                    String var = namingVars[i];
                    if (namingInfo.getProperty(var) != null && !namingInfo.getProperty(var).equals("")) {
                        command.add((isWindowsOs() ? "\"" : "") + "-D" + var + "=" + namingInfo.get(var)
                                + (isWindowsOs() ? "\"" : ""));
                    }
                }

                command.add((isWindowsOs() ? "\"" : "") + "-Dapplication_type="
                        + (applicationType == null ? "" : applicationType) + (isWindowsOs() ? "\"" : ""));

                if (logFile != null && !logFile.equals("")) {
                    command.add((isWindowsOs() ? "\"" : "")
                            + "-Dorg.apache.commons.logging.Log=org.apache.commons.logging.impl.Log4JLogger"
                            + (isWindowsOs() ? "\"" : ""));
                    command.add((isWindowsOs() ? "\"" : "") + "-Dlog4j.rootCategory=DEBUG,A1,A2,A3"
                            + (isWindowsOs() ? "\"" : ""));

                    command.add((isWindowsOs() ? "\"" : "") + "-Dlog4j.appender.A1=org.apache.log4j.ConsoleAppender"
                            + (isWindowsOs() ? "\"" : ""));
                    command.add((isWindowsOs() ? "\"" : "")
                            + "-Dlog4j.appender.A1.layout=org.apache.log4j.PatternLayout"
                            + (isWindowsOs() ? "\"" : ""));
                    command.add((isWindowsOs() ? "\"" : "")
                            + "-Dlog4j.appender.A1.layout.ConversionPattern=[%-5p] - %m%n"
                            + (isWindowsOs() ? "\"" : ""));

                    command.add((isWindowsOs() ? "\"" : "") + "-Dlog4j.appender.A2=org.kchine.rpf.RemoteAppender"
                            + (isWindowsOs() ? "\"" : ""));
                    command.add((isWindowsOs() ? "\"" : "")
                            + "-Dlog4j.appender.A2.layout=org.apache.log4j.PatternLayout"
                            + (isWindowsOs() ? "\"" : ""));
                    command.add((isWindowsOs() ? "\"" : "")
                            + "-Dlog4j.appender.A2.layout.ConversionPattern=[%-5p] - %m%n"
                            + (isWindowsOs() ? "\"" : ""));

                    command.add((isWindowsOs() ? "\"" : "") + "-Dlog4j.appender.A3=org.apache.log4j.FileAppender"
                            + (isWindowsOs() ? "\"" : ""));
                    command.add((isWindowsOs() ? "\"" : "") + "-Dlog4j.appender.A3.file=" + logFile
                            + (isWindowsOs() ? "\"" : ""));
                    command.add((isWindowsOs() ? "\"" : "")
                            + "-Dlog4j.appender.A3.layout=org.apache.log4j.PatternLayout"
                            + (isWindowsOs() ? "\"" : ""));
                    command.add((isWindowsOs() ? "\"" : "")
                            + "-Dlog4j.appender.A3.layout.ConversionPattern=[%-5p] - %m%n"
                            + (isWindowsOs() ? "\"" : ""));
                }

                if (useClassPath) {
                    command.add(mainClassName);
                } else {
                    command.add("org.kchine.r.server.manager.bootstrap.Boot");
                }

                command.add("http://" + codeServerHostIp + ":" + codeServerPort + "/classes/");

                if (codeUrls != null && codeUrls.length > 0) {
                    for (int i = 0; i < codeUrls.length; ++i) {
                        command.add(codeUrls[i].toString());
                    }
                }

                if (extraJarFiles.size() > 0) {
                    for (int i = 0; i < extraJarFiles.size(); ++i)
                        command.add(extraJarFiles.elementAt(i).toURI().toURL().toString());
                }

                final Process proc = Runtime.getRuntime().exec(command.toArray(new String[0]),
                        envVector.toArray(new String[0]));
                if (rShutdownHook != null) {
                    new Thread(new Runnable() {
                        public void run() {
                            try {
                                proc.waitFor();
                                rShutdownHook.run();
                            } catch (Exception e) {
                                e.printStackTrace();
                            }
                        }
                    }).start();
                }

                final Vector<String> outPrint = new Vector<String>();
                final Vector<String> errorPrint = new Vector<String>();

                System.out.println(" command : " + command);

                new Thread(new Runnable() {
                    public void run() {
                        try {
                            BufferedReader br = new BufferedReader(new InputStreamReader(proc.getErrorStream()));
                            String line = null;
                            while ((line = br.readLine()) != null) {
                                System.out.println(line);
                                errorPrint.add(line);
                            }
                        } catch (Exception e) {
                            e.printStackTrace();
                        }

                        System.out.println();
                    }
                }).start();

                new Thread(new Runnable() {
                    public void run() {
                        try {
                            BufferedReader br = new BufferedReader(new InputStreamReader(proc.getInputStream()));
                            String line = null;
                            while ((line = br.readLine()) != null) {
                                System.out.println(line);
                                outPrint.add(line);
                            }
                        } catch (Exception e) {
                            e.printStackTrace();
                        }
                    }
                }).start();

                if (useCreationCallback) {
                    long t1 = System.currentTimeMillis();
                    while (servantHolder[0] == null && exceptionHolder[0] == null) {
                        if (System.currentTimeMillis() - t1 >= SERVANT_CREATION_TIMEOUT_MILLISEC)
                            throw new ServantCreationTimeout();
                        try {
                            Thread.sleep(100);
                        } catch (Exception e) {
                        }
                    }
                    if (exceptionHolder[0] != null) {
                        throw exceptionHolder[0];
                    }
                    progressLogger.logProgress("R Server Created.");
                    return (RServices) servantHolder[0];
                } else {
                    return null;
                }

            } finally {
                if (callBack != null) {
                    UnicastRemoteObject.unexportObject(callBack, true);
                }
            }
        } finally {
            if (showProgress) {
                createRProgressFrame[0].dispose();
            }
        }
    }

    // incomplete
    public static String getLibraryPath(String libName, String rpath, String rlibs) {
        if (!rpath.endsWith("/") && !rpath.endsWith("\\")) {
            rpath += "/";
        }
        if (rlibs != null && !rlibs.equals("") && !rlibs.endsWith("/") && !rlibs.endsWith("\\")) {
            rlibs += "/";
        }
        if (rlibs != null && !rlibs.equals("") && new File(rlibs + libName).exists()) {
            return rlibs + libName + "/";
        } else if (new File(rpath + "library/" + libName).exists()) {
            return rpath + "library/" + libName + "/";
        } else {
            return null;
        }
    }

    public static class RemoteLogListenerImpl extends UnicastRemoteObject implements RemoteLogListener {

        public RemoteLogListenerImpl() throws RemoteException {
            super();
        }

        public void flush() throws RemoteException {
        }

        public void write(final byte[] b) throws RemoteException {
            System.out.print(new String(b));
        }

        public void write(final byte[] b, final int off, final int len) throws RemoteException {
            System.out.print(new String(b, off, len));
        }

        public void write(final int b) throws RemoteException {
            System.out.print(new String(new byte[] { (byte) b, (byte) (b >> 8) }));
        }

    }

    public static void killLocalUnixProcess(String processId, boolean isKILLSIG) throws Exception {
        PoolUtils.killLocalUnixProcess(processId, isKILLSIG);
    }

    public static void killLocalWinProcess(String processId, boolean isKILLSIG) throws Exception {
        PoolUtils.killLocalWinProcess(processId, isKILLSIG);
    }

    public static void killLocalProcess(String processId, boolean isKILLSIG) throws Exception {
        if (isWindowsOs())
            PoolUtils.killLocalWinProcess(processId, isKILLSIG);
        else
            PoolUtils.killLocalUnixProcess(processId, isKILLSIG);
    }

    public static void killSshProcess(String processId, String sshHostIp, String sshLogin, String sshPwd,
            boolean forcedKill) throws Exception {
        SSHUtils.killSshProcess(processId, sshHostIp, sshLogin, sshPwd, forcedKill);
    }

    public static String[] getRInfo(String rbin) {

        File getInfoFile = new File(INSTALL_DIR + "getInfo.R");

        File getInfoOutputFile = new File(INSTALL_DIR + "getInfo.Rout");

        try {
            getInfoOutputFile.delete();
        } catch (Exception e) {
            e.printStackTrace();
        }

        String rversion = null;

        String rlibraypath = null;

        String rjavapath = null;

        try {

            FileWriter fw = new FileWriter(getInfoFile);

            PrintWriter pw = new PrintWriter(fw);

            pw.println("paste('" + RHOMESTART + "',R.home(), '" + RHOMEEND + "',sep='%')");
            pw.println("paste('" + RVERSTART + "', R.version.string , '" + RVEREND + "', sep='%')");
            pw.println("library('rJava'); paste('" + RJAVAPATHSTART + "', .path.package('rJava') , '" + RJAVAPATHEND
                    + "', sep='%')");

            fw.close();

            Vector<String> getInfoCommand = new Vector<String>();

            String[] roptions = DirectJNI.getROptions();

            if (rbin != null && !rbin.equals("")) {
                System.out.println("trying to execute :" + rbin);
                getInfoCommand.add(rbin);
                getInfoCommand.add("CMD");
                getInfoCommand.add("BATCH");
                for (int i = 0; i < roptions.length; ++i)
                    getInfoCommand.add(roptions[i]);
                getInfoCommand.add(getInfoFile.getAbsolutePath());
                getInfoCommand.add(getInfoOutputFile.getAbsolutePath());

            } else {

                if (isWindowsOs()) {

                    getInfoCommand.add(System.getenv().get("ComSpec"));
                    getInfoCommand.add("/C");
                    getInfoCommand.add("R");
                    getInfoCommand.add("CMD");
                    getInfoCommand.add("BATCH");
                    for (int i = 0; i < roptions.length; ++i)
                        getInfoCommand.add(roptions[i]);
                    getInfoCommand.add(getInfoFile.getAbsolutePath());
                    getInfoCommand.add(getInfoOutputFile.getAbsolutePath());

                } else {
                    getInfoCommand.add(/* System.getenv().get("SHELL") */"/bin/sh");
                    getInfoCommand.add("-c");
                    StringBuffer roptions_str = new StringBuffer();
                    for (int i = 0; i < roptions.length; ++i) {
                        roptions_str.append(roptions[i]);
                        roptions_str.append(" ");
                    }
                    getInfoCommand.add("R CMD BATCH " + roptions_str + " " + getInfoFile.getAbsolutePath() + " "
                            + getInfoOutputFile.getAbsolutePath());
                }
            }

            Vector<String> systemEnvVector = new Vector<String>();
            {

                Map<String, String> osenv = System.getenv();

                Map<String, String> env = new HashMap<String, String>(osenv);

                for (String k : env.keySet()) {

                    systemEnvVector.add(k + "=" + env.get(k));

                }

            }

            System.out.println("exec->" + getInfoCommand);

            System.out.println(systemEnvVector);

            final Process getInfoProc = Runtime.getRuntime().exec(getInfoCommand.toArray(new String[0]),

                    systemEnvVector.toArray(new String[0]));

            new Thread(new Runnable() {

                public void run() {

                    try {

                        BufferedReader br = new BufferedReader(new InputStreamReader(getInfoProc.getErrorStream()));

                        String line = null;

                        while ((line = br.readLine()) != null) {

                            System.out.println(line);

                        }

                    } catch (Exception e) {

                        e.printStackTrace();

                    }

                }

            }).start();

            new Thread(new Runnable() {

                public void run() {

                    try {

                        BufferedReader br = new BufferedReader(new InputStreamReader(getInfoProc.getInputStream()));

                        String line = null;

                        while ((line = br.readLine()) != null) {

                            System.out.println(line);

                        }

                    } catch (Exception e) {

                        e.printStackTrace();

                    }

                }

            }).start();

            getInfoProc.waitFor();

            if (getInfoOutputFile.exists()) {

                BufferedReader br = new BufferedReader(new FileReader(getInfoOutputFile));

                String line = null;

                while ((line = br.readLine()) != null) {

                    // System.out.println(line);

                    if (line.contains(RHOMESTART + "%")) {

                        rlibraypath = line.substring(line.indexOf(RHOMESTART + "%") + (RHOMESTART + "%").length(),
                                (line.indexOf("%" + RHOMEEND) > 0 ? line.indexOf("%" + RHOMEEND) : line.length()));
                    }

                    if (line.contains(RVERSTART + "%")) {
                        rversion = line.substring(line.indexOf(RVERSTART + "%") + (RVERSTART + "%").length(),
                                line.indexOf("%" + RVEREND));
                    }

                    if (line.contains(RJAVAPATHSTART + "%")) {
                        rjavapath = line.substring(
                                line.indexOf(RJAVAPATHSTART + "%") + (RJAVAPATHSTART + "%").length(),
                                line.indexOf("%" + RJAVAPATHEND));
                    }

                }

            } else {
                System.out.println(getInfoOutputFile.toString() + " not found ");
            }

        } catch (Exception e) {

            e.printStackTrace();

        }

        System.out.println("+rversion:" + rversion);
        System.out.println("+rlibraypath:" + rlibraypath);
        System.out.println("+rjavapath:" + rjavapath);
        if (rlibraypath != null) {
            return new String[] { rlibraypath, rversion, rjavapath };
        } else {

            return null;

        }

    }

    public static boolean isPortInUse(String hostIp, int port) {
        Socket s = null;
        try {
            s = new Socket(hostIp, port);
        } catch (Exception e) {
            return false;
        } finally {
            if (s != null)
                try {
                    s.close();
                } catch (Exception ex) {
                }
        }
        return true;
    }

    public static void startPortInUseDogwatcher(final String hostIp, final int port, final int periodicitySec,
            final int maxFailure) {

        new Thread(new Runnable() {
            int failureCounter = maxFailure;

            public void run() {
                while (true) {
                    if (!isPortInUse(hostIp, port))
                        --failureCounter;
                    if (failureCounter == 0) {
                        System.out.println("The Creator Process doesn't respond, going to die");
                        System.exit(0);
                    }
                    try {
                        Thread.sleep(1000 * periodicitySec);
                    } catch (Exception e) {
                    }
                }
            }
        }).start();

    }

    synchronized public static void downloadBiocepCore(int logInfo) throws Exception {
        PoolUtils.cacheJar(new URL("http://biocep-distrib.r-forge.r-project.org/appletlibs/biocep-core.jar"),
                INSTALL_DIR, logInfo, false);
    }

}