Reputation: 522
I'm building a simple Eclipse plug-in out of preexisting Java application project that relays on 2 external files, one x-executable/application and one .sh script. The call is implemented in application like this, (which wouldn't work in plug-in):
Process p = new ProcessBuilder("external/application_name", "-d", path).start();
I used External Tool Configuration to define how I want this external files to be launch (when user clicks button on View) and I've exported configuration (example of one):
<?xml version="1.0" encoding="UTF-8" standalone="no"?>
<launchConfiguration type="org.eclipse.ui.externaltools.ProgramLaunchConfigurationType">
<stringAttribute key="org.eclipse.ui.externaltools.ATTR_LOCATION" value="${workspace_loc:/softwareevolution/external/application_name}"/>
<stringAttribute key="org.eclipse.ui.externaltools.ATTR_TOOL_ARGUMENTS" value="-d ${project_loc}"/>
<stringAttribute key="org.eclipse.ui.externaltools.ATTR_WORKING_DIRECTORY" value="${project_loc}"/>
</launchConfiguration>
The application is supposed to produce 2 files on the path where it is executed from. I am facing permission denied when trying to launch it in terminal from plug-in's install directory but not when launching in workspace. (see @howlger answer billow) - Upon exporting the plugin, initial permissions of application had changed. Used instructions in p2.inf to chmod them back.
The newly generated files (from runing .sh script) are missing write permission.
After finally setting up plugin correctly and adding ProcessBuilder I was getting exception message : Cannot run program "rfind_20" (in directory "home/adminuser/.p2/pool/plugins/rFindTest3_1.0.0.201809030453/external" error=2:, No such file or directory
File rfind_20 did exist and permission were 777. The targeted project also existed.
Although the working directory was set to applications folder, the application name was not enough, the absolute path was required as command argument.
pb = new ProcessBuilder(url.getPath(), "-d", project.getProject().getLocation().toString());
@Override
public Object execute(ExecutionEvent event) throws ExecutionException {
IProject project= sampleGetSelectedProject();
ProcessBuilder pb;
Process rfind, ajust, copy;
Bundle bundle = FrameworkUtil.getBundle(getClass());//Bundle bundle = Platform.getBundle("rFindTest3");
URL url = FileLocator.find(bundle, new Path("external/rfind_20"), null);
URL dirurl = FileLocator.find(bundle, new Path("external/"), null);
IWorkbenchWindow window = HandlerUtil.getActiveWorkbenchWindowChecked(event);
try {
MessageDialog.openInformation(
window.getShell(),
"Test",
project.getProject().getLocation().toString());
url = FileLocator.toFileURL(url);
dirurl = FileLocator.toFileURL(dirurl);
pb = new ProcessBuilder(url.getPath(), "-d", project.getProject().getLocation().toString());
//no matter the working directory the absolute path was required!! sending "rfind_20" as command did not work as command
pb.directory(new File(dirurl.getFile()));
rfind = pb.start();
rfind.waitFor();
rfind.destroy();
}catch(Exception e) {
MessageDialog.openInformation(
window.getShell(),
"Test",
e.getMessage());
}
return null;
}
The only remaining mystery is why my sampleGetProject() method wouldn't work in Plug-in Perspective. So just keep in mind to switch to other Perspectives when testing your plug-in.
Upvotes: 1
Views: 1555
Reputation: 34137
There are two ways to ship an application as part of a plugin and run it via ProcessBuilder
(the *.launch
file cannot be used inside a plugin for that):
META-INF/MANIFEST.MF
add the line Eclipse-BundleShape: dir
(see "The Eclipse-BundleShape Header" in Eclipse help - Platform Plug-in Developer Guide - OSGi Bundle Manifest Headers)META-INF/p2.inf
file that contains the following (see Eclipse help - Platform Plug-in Developer Guide: "Touchpoint Instruction Advice" in Customizing p2 metadata and "chmod" in Provisioning Actions and Touchpoints):instructions.install = \
chmod(targetDir:${artifact.location},targetFile:path/to/executable1,permissions:755);\
chmod(targetDir:${artifact.location},targetFile:path/to-executale_which_generates_files/executable2,permissions:733);\
chmod(targetDir:${artifact.location},targetFile:path/to-executale_which_generates_files/,permissions:766);
instructions.install.import = org.eclipse.equinox.p2.touchpoint.eclipse.chmod
Upvotes: 1
Reputation: 111142
If you have a xxx.launch
file in the workspace you can launch it using
IFile file = ... get IFile for workspace file
ILaunchConfiguration config = DebugPlugin.getDefault().getLaunchManager().getLaunchConfiguration(file);
DebugUITools.launch(config, ILaunchManager.RUN_MODE, false);
If you have an executable as part of a plug-in then you can't use a .launch file. Instead use FileLocator
to get the location of the executable and run it with ProcessBuilder
Bundle bundle = FrameworkUtil.getBundle(getClass());
URL url = FileLocator.find(bundle, new Path("relative path to executable"));
url = FileLocator.toFileURL(url);
Upvotes: 1