Java - 如何跟踪" javaws"以编程方式启动时的流程?

时间:2016-08-22 18:28:58

标签: java process exec java-web-start

我知道如何开始" javaws" (Java Web Start)来自Java程序,但是在创建后跟踪流程实例时遇到了问题。

用作参数的JNLP文件包含将启动内部websocket服务器的程序的定义。主java程序(调用javaws的程序)有一个计时器任务,如果该服务器已启动,则每秒检查一次,向该服务器发送一些指令。

但有时java web启动过程因网络错误而结束,程序永远不会加载。从主程序创建的流程实例似乎失去了对已启动的javaws程序的控制" RIGHT AFTER"创建,即使我使用.waitFor();就像javaws是从我的java程序启动的那样,然后javaws创建另一个进程来继续加载java程序(jnlp),然后它杀死了原始的javaws进程。此时我无法从原始java程序中了解JNLP加载程序是否失败,或者是否花费的时间太长。

以下是示例代码:

package some.internalpackage;

import java.io.File;
import java.lang.reflect.Type;
import java.util.Arrays;
import java.util.Base64;
import java.util.Calendar;
import java.util.Map;
import java.util.Timer;
import java.util.TimerTask;
import java.util.logging.Logger;
import javax.swing.JOptionPane;

public class OtherProgramStarter {

    protected static Process process = null;

    /**
     * @param args the command line arguments
     */
    public static void main(String[] args) {

        // Try every second to connect to the internal websocket server..
        final Timer timer = new Timer();
        int begin = 1000;
        int timeinterval = 1000;
        timer.scheduleAtFixedRate(new TimerTask() {

            // Maximum 5 minutes
            private int maximumTimes = 300;

            @Override
            public void run() {

                // On time-out, display error.
                if (--maximumTimes < 1) {

                    // Show error message
                    String message = "The expected program was not started or could not be detected after 5 minutes. Please try again later.";
                    JOptionPane.showMessageDialog(null, message, "The Program", JOptionPane.ERROR_MESSAGE);
                    System.err.println(message);
                    System.exit(1);
                }

                try {

                    // Check if the process is still there
                    if (!process.isAlive()) {

                        // THIS IS ALWAYS PRINTING IN CONSOLE (every second). process is never alive!!?
                        System.out.println("Command internal process is not alive anymore.");
                    }

                    // Try to connect to an existing local server
                    throw new Exception("This is a test exception, the one expected when the internal server is not started (yet).");

                    // If the connection is successful, send some instructions and the close the current program.
                    System.exit(0);

                } catch (Throwable ex) {
                    String message = Calendar.getInstance().getTime().toString() + ": Internal connection failed...";
                    System.out.println(message);
                }
            }
        }, begin, timeinterval);

        String jnlpFileUrl = "https://some.existingfile.com/launcher.jnlp";
        try {
            String message = "JNLP URL: " + jnlpFileUrl;
            System.out.println(message);

            // String command = "javaws " + jnlpFileUrl;
            //String fullCommand = "start \"" + PROGRAM_TITLE + "\" /W " + command;
            String fullCommand = "\"" + detectJavaFullPath() + "\" " + jnlpFileUrl;
            message = "Full command: " + fullCommand;
            System.out.println(message);

            // I Have tested with all of these:
            //process = new ProcessBuilder("cmd.exe", "/c", fullCommand).start();
            //process = new ProcessBuilder(fullCommand).start();
            //process = new ProcessBuilder(detectJavaFullPath(), jnlpFileUrl, "-wait").start();
            //process.waitFor();

            String[] cmd = {detectJavaFullPath(), jnlpFileUrl};
            process = Runtime.getRuntime().exec(cmd);

        } catch (Exception err) {

            String message = "It was not possible to start the other program.";
            JOptionPane.showMessageDialog(null, message, "The program", JOptionPane.ERROR_MESSAGE);
            System.err.println(message);
            System.exit(1);
        }
    }

    public static String detectCurrentJarDirFullPath() {
        try {
            File jar = new File(OtherProgramStarter.class.getProtectionDomain().getCodeSource().getLocation().toURI().getPath());
            return jar.getParentFile().getAbsolutePath();
        } catch (Exception exp) {
            exp.printStackTrace();
        }
        return "";
    }

    public static String detectJavaFullPath() {
        String javaHome = System.getProperty("java.home");
        File f = new File(javaHome);
        f = new File(f, "bin");
        f = new File(f, "javaws.exe");
        return f.getAbsolutePath();
    }

}

请注意,这是基于真实代码的示例。

我首先启动Timer任务,等待进程存在。然后我开始这个过程并在静态类属性中保留它的引用。现在我可以从计时器任务访问它以检查它的活动状态,但它总是说它不活着,即使在javaws进程加载了jnlp和它的库之后(我可以看到它)它自己的控制台,以及从JNLP加载程序生成的额外UI反馈。)

有什么建议吗?

如果jnlp正在加载,我想要的是知道进程是活的。如果JNLP加载过程失败并停止运行,请从主程序中了解该信息以显示相应的错误消息。由于我从计时器任务(websocket连接)创建的连接成功,我已经知道JNLP程序是否正确启动。

感谢。

更新

我尝试在控制台上手动运行javaws命令,同时使用&#34; Process Explorer&#34;检查生成的进程。我看到生成的第一个进程是&#34; javaws&#34;,然后为&#34; jp2launcher.exe&#34;创建一个新进程,然后为&#34; javaws&#34;创建一个新进程。死亡。 JNLP程序继续加载,所以我认为这可能是我无法控制/知道加载JNLP进程的真实状态的原因。

0 个答案:

没有答案