In this article, I will explain how to create an eclipse plugin project programmatically.
Do check out the deployable plugin if you want to see the whole code or if you want to install that in your eclipse. The source plugin is also available if you want to check out the code.
The steps to create a plugin project are:
- Create a IRunnableWithProgress and write your code inside it's run() method to create the plugin since is it a long running process.
- Create a IJavaProject and attach IProjectDescription to it.
- Set required Natures to the project
- "org.eclipse.jdt.core.javanature" and "org.eclipse.pde.PluginNature" are
mandatory for any plugin project - Set required Builders to the project
- "org.eclipse.jdt.core.javabuilder", "org.eclipse.pde.ManifestBuilder",
"org.eclipse.pde.SchemaBuilder" are mandatory for any plugin project - Open the project
- Create required source folders (eg, src folder)
- Set raw Classpath to the plugin project.
- Set output location for the project
- Create Manifest file
- Create Build.props file
- Create an activator class for the project
- Create any required artifacts, for ex, Java files, props files, etc
Continue reading the rest of the article if you want to check for code snippets for each of the above steps or download the plugin from here
Below are the code snippets for the steps mentioned above:
- Since creating a plugin project could be a long running process, it is better to run it in a background thread using IRunnableWithProgress:
- Create a IJavaProject and attach IProjectDescription to it.
final IWorkspace workspace = ResourcesPlugin.getWorkspace(); project = workspace.getRoot().getProject(projectName); final IJavaProject javaProj = JavaCore.create(project); final IProjectDescription projDesc = ResourcesPlugin.getWorkspace().newProjectDescription(projectName); projDesc.setLocation(null); project.create(projDesc, monitor);
- Set required Natures to the project
private static void setNatures(final Set
natureIdsSet, final IProjectDescription projDesc, boolean isMavenProject) { Set natureIds = new HashSet<>(); natureIds.add(JavaCore.NATURE_ID); natureIds.add("org.eclipse.pde.PluginNature"); if (isMavenProject) { natureIds.add("org.eclipse.m2e.core.maven2Nature"); } natureIds.addAll(natureIdsSet); projDesc.setNatureIds(natureIds.toArray(new String[natureIds.size()])); } - Set required Builders to the project
private static void setBuilders(final Set
builderNamesSet, final IProjectDescription projDesc, boolean isMavenProject) { List builders = new ArrayList<>(); final ICommand java = projDesc.newCommand(); java.setBuilderName(JavaCore.BUILDER_ID); builders.add(java); final ICommand manifest = projDesc.newCommand(); manifest.setBuilderName("org.eclipse.pde.ManifestBuilder"); builders.add(manifest); final ICommand schema = projDesc.newCommand(); schema.setBuilderName("org.eclipse.pde.SchemaBuilder"); builders.add(schema); if (isMavenProject) { final ICommand mvn_schema = projDesc.newCommand(); mvn_schema.setBuilderName("org.eclipse.m2e.core.maven2Builder"); builders.add(mvn_schema); } for (String builderName : builderNamesSet) { final ICommand newBuilder = projDesc.newCommand(); newBuilder.setBuilderName(builderName); builders.add(newBuilder); } projDesc.setBuildSpec(builders.toArray(new ICommand[builders.size()])); } - Open the project
project.open(new SubProgressMonitor(monitor, 1)); project.setDescription(projDesc, new SubProgressMonitor(monitor, 1));
- Create required source folders and add classpath entries
final List
classpathEntries = new ArrayList (); Collections.reverse(srcFolders); for (final String srcFolder : srcFolders) { final IFolder src = project.getFolder(srcFolder); if (!src.exists()) { src.create(false, true, new SubProgressMonitor(monitor, 1)); } final IClasspathEntry srcClasspathEntry = JavaCore.newSourceEntry(src.getFullPath()); classpathEntries.add(0, srcClasspathEntry); } classpathEntries.addAll(Arrays.asList(NewJavaProjectPreferencePage.getDefaultJRELibrary())); classpathEntries.add(JavaCore.newContainerEntry(new Path("org.eclipse.pde.core.requiredPlugins"))); if (isMavenProject) { final IClasspathEntry mavenDependencies = JavaCore.newContainerEntry(new Path("org.eclipse.m2e.MAVEN2_CLASSPATH_CONTAINER"), ClasspathEntry.NO_ACCESS_RULES, new IClasspathAttribute[] { new ClasspathAttribute("maven.pomderived", "true") }, false); classpathEntries.add(mavenDependencies); } javaProj.setRawClasspath(classpathEntries.toArray(new IClasspathEntry[classpathEntries.size()]), new SubProgressMonitor(monitor, 1)); - Set output location for the project
javaProj.setOutputLocation(new Path("/" + projectName + "/bin"), new SubProgressMonitor(monitor, 1));
- Create Manifest file
private static void createManifest(final String projectName, final Set
requiredBundles, final IProgressMonitor monitor, final IProject project) throws Exception { final StringBuilder maniContent = new StringBuilder("Manifest-Version: 1.0\n"); maniContent.append("Bundle-ManifestVersion: 2\n"); maniContent.append("Bundle-Name: " + projectName + "\n"); maniContent.append("Bundle-SymbolicName: " + projectName + "; singleton:=true\n"); maniContent.append("Bundle-Version: 1.0.0\n"); if (!requiredBundles.isEmpty()) { maniContent.append("Require-Bundle:"); for (final Iterator iterator = requiredBundles.iterator(); iterator.hasNext();) { maniContent.append(iterator.next()); if (iterator.hasNext()) { maniContent.append(",\n"); } else { maniContent.append("\n"); } } } maniContent.append("Import-Package: org.osgi.framework\r\n"); maniContent.append("Bundle-RequiredExecutionEnvironment: JavaSE-1.7\r\n"); maniContent.append("Bundle-ActivationPolicy: lazy\r\n"); maniContent.append("Bundle-Activator: org.eclipse.ppc.Activator\r\n"); final IFolder metaInf = project.getFolder("META-INF"); metaInf.create(false, true, new SubProgressMonitor(monitor, 1)); FileGenerator.createFile("MANIFEST.MF", metaInf, maniContent.toString(), monitor); } - Create Build.props file
private static void createBuildProps(final IProgressMonitor monitor, final IProject project, final List
srcFolders) throws Exception { final StringBuilder bpContent = new StringBuilder("source.. = "); for (final Iterator iterator = srcFolders.iterator(); iterator.hasNext();) { bpContent.append(iterator.next()).append('/'); if (iterator.hasNext()) { bpContent.append(","); } } bpContent.append("\n"); bpContent.append("bin.includes = META-INF/,.\n"); FileGenerator.createFile("build.properties", project, bpContent.toString(), monitor); } - Create an activator class for the project
protected static void createJavaFiles(IProject pluginProject) throws Exception { String sourceFolderPath = "resrc/org/eclipse/ppc"; FileGenerator.createFile("org/eclipse/ppc/Activator.java", pluginProject.getFolder("src"), FileGenerator.getContents(sourceFolderPath, "Activator.java", PluginProjectCreator.class), new NullProgressMonitor()); }
This method can be used to create any file in the destination plugin project by copying the content from inside the source plugin project. You might also want to replace some contents in the generated file (before writing into it), based on the values given in the wizard.
final IRunnableWithProgress runnableOp = new IRunnableWithProgress() { @Override public void run(final IProgressMonitor monitor) throws InvocationTargetException, InterruptedException { try { monitor.beginTask("Creating a plugin project " + projectName, 2); IProject project = null; try { monitor.beginTask("", 10); monitor.subTask("Creating plugin project : " + projectName); } catch (final Exception e) { MessageDialog.openError(Display.getCurrent().getActiveShell(), "Error creating Project", "Error creating Project: \n" + e.getMessage()); } finally { monitor.done(); } monitor.worked(1); } finally { monitor.done(); } } try { IRunnableContext context = PlatformUI.getWorkbench() .getProgressService(); context.run(false, true, runnableOp); } catch (InvocationTargetException | InterruptedException e) { MessageDialog.openError(Display.getCurrent().getActiveShell(), "Creation problem", "Project creation failed\n"+ e.getMessage()); }