2010-09-16 47 views
1

我嘗試在eclipse插件中啓動java程序,但失敗。在eclipse插件中啓動java程序失敗

我所要做的就是讓「來自日食的貢獻」的例子起作用。
在這個例子中,插件貢獻一個菜單項來日食,當你選擇一個測試類時,你可以使用菜單在類中運行測試用例。

要運行測試用例,有兩個類TestRunnerSocketTestRunner
TestRunner作爲一個單獨的java程序啓動SocketTestRunner,並通過套接字通信

TestRunner相關的代碼來啓動java程序:

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)測試,我創建了一個簡單的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(); 
    } 
} 

但我不知道爲什麼,任何意見將不勝感激。

+0

有同樣的問題。爲什麼調用vmConfig.setWorkingDirectory(...)解決問題?你能聯繫我嗎? leo here mathtech.ru – outmind 2011-07-28 15:22:01

回答

0

可以,但問題出現在連接方法被調用之前。因此,在連接被調用等待SocketTestRunner啓動之前,插件會掛鉤。

+0

在我的情況下,它也與SocketTestRunner的類路徑中'junit.jar'的缺失有關。在computeClasspath方法中添加了classPath [2] = ...「junit.jar」。 – outmind 2011-07-28 19:29:30

相關問題