在eclipse插件中启动java程序失败

时间:2010-09-16 07:00:20

标签: java eclipse plugins

我尝试在eclipse插件中启动一个java程序,但失败了。

我尝试做的是让“对日食的贡献”的例子起作用 在该示例中,插件为eclipse提供了一个菜单项,
当您选择测试类时,可以使用该菜单在类中运行测试用例。

要运行测试用例,有两个类TestRunnerSocketTestRunner TestRunner启动SocketTestRunner作为单独的java程序,并进行通信 通过套接字。

与启动java程序相关的TestRunner代码:

final String MAIN_CLASS = "org.eclipse.contribution.junit.SocketTestRunner";
public TestRunner() {
}

public void run(IType type) throws CoreException {
    project = type.getJavaProject();
    run(new IType[] { type });
}

public void run(IType[] classes) throws CoreException {
    IVMInstall vmInstall = JavaRuntime.getVMInstall(project);
    if (vmInstall == null)
        vmInstall = JavaRuntime.getDefaultVMInstall();
    if (vmInstall == null)
        return;

    IVMRunner vmRunner = vmInstall.getVMRunner(ILaunchManager.RUN_MODE);
    if (vmRunner == null)
        return;

    String[] classPath = computeClasspath();

    // prepare arguments:
    // Argument[0] = port
    // Argument[1-n] = types
    port = SocketUtil.findFreePort();
    String[] args = new String[classes.length + 1];
    args[0] = Integer.toString(port);
    for (int i = 0; i < classes.length; i++) {
        args[1 + i] = classes[i].getFullyQualifiedName();
    }
    VMRunnerConfiguration vmConfig = new VMRunnerConfiguration(MAIN_CLASS,
            classPath);
    vmConfig.setProgramArguments(args);     

    ILaunch launch = new Launch(null, ILaunchManager.RUN_MODE, null);
    vmRunner.run(vmConfig, launch, null);

    connect();
}

SocketTestRunner代码:

public static void main(String[] args) {
    try {
        logger = new PrintWriter(new FileWriter("log.txt"), true);

        logger.println("main");
        for (int i = 0; i < args.length; i++) {
            logger.println(args[i]);
        }

        new SocketTestRunner().runTests(args);          
    } catch (IOException e) {
        e.printStackTrace();
    } finally {
        if (logger != null) {
            logger.close();
        }
    }
}

private void runTests(String[] args) {      
    port = Integer.parseInt(args[0]);
    logger.println("port: " + port);
    openClientSocket();
    try {
        logger.println("Befor new TestSuite");
        TestSuite suite = new TestSuite();
        for (int i = 1; i < args.length; i++) {
            logger.println("add TestSuite");
            suite.addTestSuite(Class.forName(args[i]).asSubclass(TestCase.class));
        }

        logger.println("starting tests " + suite.countTestCases());         
        //writer.println("starting tests " + suite.countTestCases());

        logger.println("Before TestResult");
        TestResult result = new TestResult();
        logger.println("After TestResult");
        result.addListener(this);
        suite.run(result);
        //writer.println("ending tests ");
        logger.println("ending tests ");
    } catch (Exception e) {
        logger.println("exception: " + e.getMessage());
        logger.println(e.toString());
        e.printStackTrace(logger);
        e.printStackTrace();
    } finally {
        closeClientSocket();
    }
}

private void closeClientSocket() {
    logger.println("closeClientSocket");
    if (writer != null) {
        writer.close();
    }

    try {
        socket.close();
    } catch (IOException e) {
        e.printStackTrace();
    }
}

private void openClientSocket() {
    logger.println("openClientSocket");
    try {
        socket = new Socket("localhost", port);
        writer = new PrintWriter(socket.getOutputStream(), true);
        return;
    } catch (UnknownHostException e) {
        e.printStackTrace();
    } catch (IOException e) {
        e.printStackTrace();
    }
}

当我在eclipse(3.6.0 HELIOS)中测试时,我在运行时eclipse中创建了一个简单的JUnit测试用例,
选择测试类并单击上下文菜单中的菜单项,
然后运行时eclipse不会响应任何进一步的交互,
让ServerSocket继续监听,我没有为调试添加测试日志。

我可以获得eclipse用于启动SocketTestRunner的命令行:

"C:\Program Files\Java\jre6\bin\javaw.exe" -classpath C:\Users\User\workspace\org.eclipse.contribution.junit\bin;C:\Users\User\workspace\org.eclipse.contribution.junit\plugins\org.eclipse.contribution.junit_1.0.0.201009102354.jar;C:\Users\User\runtime-EclipseApplication\Hello\bin;C:\Users\User\workspace\org.junit\junit.jar;"C:\Program Files\eclipse\plugins\org.hamcrest.core_1.1.0.v20090501071000.jar" org.eclipse.contribution.junit.SocketTestRunner 41872 org.eclipse.contribution.hello.HelloTest

当我手动使用此命令时,我可以运行测试用例成功(在评论套接字相关writer之后),因为我可以获得测试日志。

main
41872
org.eclipse.contribution.hello.HelloTest
port: 41872
openClientSocket
Befor new TestSuite
add TestSuite
starting tests 1
Before TestResult
After TestResult
starting test testSayHi(org.eclipse.contribution.hello.HelloTest)
failing test testSayHi(org.eclipse.contribution.hello.HelloTest)
END TRACE
ending tests 
closeClientSocket

任何建议将不胜感激,谢谢。

最后我得到这个插件来运行 你应该设置工作目录。

vmConfig.setWorkingDirectory("C:\\Users\\User");

当我尝试获取工作目录时,我得到null

您不能在调用connect()函数的行中设置断点。

private void connect() {
    try {
        ServerSocket server = new ServerSocket(port);
        try {
            Socket socket = server.accept();
            try {
                readMessage(socket);
            } finally {
                socket.close();
            }
        } finally {
            server.close();
        }
    } catch (IOException e) {
        e.printStackTrace();
    }
}

但我不知道为什么,任何建议都会受到赞赏。

1 个答案:

答案 0 :(得分:0)

您可以,但问题出现在调用connect方法之前。因此,调用connect之前的插件挂钩会等待SocketTestRunner启动。