Java에서 외부 프로그램을 실행하기 위해서는 그동안 Runtime.exec를 많이 사용해 왔다.
간단한 프로그램이나 script를 실행하는 데는 큰 무리가 없다. 본인도 유용하게 사용하고 있는 모듈이기도 하다.
그런데, Eclipse 플러그인에서 Runtime.exec를 사용하게 되면, (대부분)호출된 프로그램이 종료될때까지, eclipse를 사용할 수 없게 된다.
특히, 호출된 프로그램이 UI를 가진 프로그램이라면 당연히!!! 왜냐하면, 호출된 프로그램도 Eclipse JVM과 같은 Process 내에서 돌기 때문이다.
호출된 프로그램(특히 UI를 가진)이 끝날때까지, waitFor()를 실행시켜주지 않으면, UI 프로그램은 제대로 동작하지 않는다.
모 프로젝트에서 eclipse 플러그인 실행 중에, WinMerge 툴을 실행 시켜, Text를 비교하는 프로그램을 짜고 있었는데,
Runtime.exec를 사용한 경우, WinMerge가 실행되는 것 까지는 좋았으나, WinMerge를 실행시키고 나면, 정작 eclipse를 사용할 수 없어서,
WinMerge에서 Text를 Copy해서 Eclipse에 Paste하기가 쉽지 않았다.
여러가지 방법을 모색하던 중, Eclipse의 Java Launcher 또는 외부 실행 도구를 프로그램 적으로 호출하면 되지 않을까 생각하고 seach를 하던 중,
다음의 아주 좋은 article를 발견하여, 유용하게 활용했다.. Good!!!
Eclipse에서 WinMerge도 실행시키고, 둘다 서로 개별의 Process를 가질 수 있으니, 원활한 작업이 가능하게 된 것이다.
이중에서, "외부 도구 실행"을 위해 사용한 코드는..
ILaunchManager manager = DebugPlugin.getDefault().getLaunchManager();
ILaunchConfigurationType type = manager.getLaunchConfigurationType(org.eclipse.ui.externaltools.internal.model.IExternalToolConstants.ID_PROGRAM_LAUNCH_CONFIGURATION_TYPE);
ILaunchConfiguration[] configurations = manager.getLaunchConfigurations(type);
for (int i = 0; i < configurations.length; i++) {
ILaunchConfiguration configuration = configurations[i];
if (configuration.getName().equals("Run Diff Tool")) {
configuration.delete();
break;
}
}
ILaunchConfigurationWorkingCopy workingCopy = type.newInstance( null, "Run Diff Tool");
workingCopy.setAttribute(org.eclipse.ui.externaltools.internal.model.IExternalToolConstants.ATTR_LOCATION, winMergeExe);
workingCopy.setAttribute(org.eclipse.ui.externaltools.internal.model.IExternalToolConstants.ATTR_TOOL_ARGUMENTS, modelPath + " " + codePath);
workingCopy.setAttribute(org.eclipse.ui.externaltools.internal.model.IExternalToolConstants.ATTR_WORKING_DIRECTORY, workDir);
ILaunchConfiguration configuration = workingCopy.doSave();
DebugUITools.launch(configuration, ILaunchManager.RUN_MODE);
의외로 코드는 간단하다.
1) LauncherManager인스턴스를 얻은 후, LaunchConfiguration 종류를 선택(IExternalToolConstants.ID_PROGRAM_LAUNCH_CONFIGURATION_TYPE)
2) 기존의 같은 이름으로 Launch configuration이 있다면 삭제하고(필요한 경우만), Launch Configuration 인스턴스를 생성한다.
3) 필요한 인수를 지정한다. 프로그램명(IExternalToolConstants.ATTR_LOCATION), 파라미터(IExternalToolConstants.ATTR_TOOL_ARGUMENTS) 등
4) Launch Configuration을 저장하고, 실행한다.
왓.. 정말 간단하다.
이를 Plugin에서 사용하자면, Dependency에 org.eclipse.debug.core, org.eclipse.debug.ui 등을 선언해야 하고,
"자바 어플리케이션 실행"을 사용하려면, 추가적으로 org.eclipse.jdt.launching 등을 선언해 줘야 한다.
이 글은 스프링노트에서 작성되었습니다.