| Summary: | Dynamic installation of eclipse plugins as equinox bundles, API opening | ||
|---|---|---|---|
| Product: | [Eclipse Project] Equinox | Reporter: | Laurent Goubet <laurent.goubet> |
| Component: | Framework | Assignee: | equinox.framework-inbox <equinox.framework-inbox> |
| Status: | RESOLVED WONTFIX | QA Contact: | |
| Severity: | normal | ||
| Priority: | P3 | CC: | caniszczyk, tjwatson |
| Version: | unspecified | ||
| Target Milestone: | --- | ||
| Hardware: | All | ||
| OS: | All | ||
| Whiteboard: | |||
PDE needs to do something similar when launching an Equinox instance for self-hosting. In this case equinox is launched with a set of bundle (plug-in) projects from your workspace. In this case the compiled classes are located (by default) in the "bin" folder, but a project could override the default output folder or could even have multiple output folders. As a simple proof of concept try launching your eclipse instance with the option "-dev bin". This tells Equinox to automatically add the "bin" folder to the classpath of the bundle at runtime. You can also specify a URL with the -dev option to pointto a properties file which specifies the extra development time classpath entries that are needed on a per bundle symbolic name basis. That is what PDE does when self-hosting an eclipse instance. If you are really ambitious you could develop your own framework extension that provides the API you want. See org.eclipse.osgi.internal.baseadaptor.DevClassLoadingHook for an example of an adaptor hook implementation that uses the -dev (osgi.dev property) to add develop time classpaths for self-hosting out of PDE. I'm marking as wont fix because you can do this your self by developing a framework extension that implements the ClassLoadingHook. See http://www.eclipsecon.org/2008/?page=sub/&id=118 and http://wiki.eclipse.org/Adaptor_Hooks for more details. Thanks Thomas, will try and have a look at these :). Hi Thomas, Took a quick look at the adaptor hooks that can be defined to extend the framework (I was particularly interested in the ClassLoadingHook)... yet this solution is even less acceptable from a user point of view that having them manually change all of their MANIFEST.MF to add the classpath : I cannot ask them to add command-line options to their IDE launching (-Dosgi.framework.extensions=org.eclipse.equinox.samples.simplehook) and modifying the eclipse.ini file is also out of question. Reason is : we as developers and they as clients usually don't use a single Eclipse. I have more than a dozen distinct eclipses, and I know some of the clients have even more than this. I do understand that the default "bin" folder isn't what all clients will use. I also know that the Java "output folder" I retrieve with the code I pasted in comment #0 aren't the optimal solutions. Yet this issue is for your clients' code to deal with. The main issue with your API as it is now is that there is absolutely no way of altering bundles' classpathes without referencing forbidden code (well ... there is reflection :p). In other words, we do have access to an API that can allow us to load workspace-defined bundles in the running equinox instance, but we have no way of altering these plugins so that they are _valid_ equinox bundles. This bug could also be raised with another description : within Eclipse, I can right-click a project and use "classpath => configure classpath" to edit my plugin's classpath. Within this dialog I can add source folders, libraries, ... Shouldn't that configuration be reflected in the MANIFEST? (In reply to comment #3) > Hi Thomas, > > Took a quick look at the adaptor hooks that can be defined to extend the > framework (I was particularly interested in the ClassLoadingHook)... yet this > solution is even less acceptable from a user point of view that having them > manually change all of their MANIFEST.MF to add the classpath : I cannot ask > them to add command-line options to their IDE launching > (-Dosgi.framework.extensions=org.eclipse.equinox.samples.simplehook) and > modifying the eclipse.ini file is also out of question. > > Reason is : we as developers and they as clients usually don't use a single > Eclipse. I have more than a dozen distinct eclipses, and I know some of the > clients have even more than this. I would not expect clients to do this. Rather I expect p2 to do it when the framework extension is provisioned to the eclipse installation. I would expect the extension to be part of the other tools you are installing in order to support your development workflow. See bug 241477. > > I do understand that the default "bin" folder isn't what all clients will use. > I also know that the Java "output folder" I retrieve with the code I pasted in > comment #0 aren't the optimal solutions. Yet this issue is for your clients' > code to deal with. > > The main issue with your API as it is now is that there is absolutely no way of > altering bundles' classpathes without referencing forbidden code (well ... > there is reflection :p). In other words, we do have access to an API that can > allow us to load workspace-defined bundles in the running equinox instance, but > we have no way of altering these plugins so that they are _valid_ equinox > bundles. > > This bug could also be raised with another description : within Eclipse, I can > right-click a project and use "classpath => configure classpath" to edit my > plugin's classpath. Within this dialog I can add source folders, libraries, ... > Shouldn't that configuration be reflected in the MANIFEST? > I suppose this is a possibility but in PDE we generally have kept the manifest content under the control of the developer. I know there are other work flows where developers want most if not all of the manifest generated for them. But this is more of a PDE discussion. Perhaps Chris can point you to an existing bug in PDE that is similar to this discussion. I know we have discussed having PDE generate the correct classpath in the manifest and run with that instead of depending on Equinox "magic" to run with the development time classpath in a plug-in project. (In reply to comment #4) > > Reason is : we as developers and they as clients usually don't use a single > > Eclipse. I have more than a dozen distinct eclipses, and I know some of the > > clients have even more than this. > > I would not expect clients to do this. Rather I expect p2 to do it when the > framework extension is provisioned to the eclipse installation. I would expect > the extension to be part of the other tools you are installing in order to > support your development workflow. See bug 241477. > Technically, I could also write java code that will launch netbeans instead of Eclipse :p. Jokes aside, when the user (which incidentally can be a developper) executes a given action in his workbench, I scan all workspace projects if they have a given nature and install the necessary projects in the current instance (along with their dependencies). These projects will be uninstalled as soon as the action ends. In other words this is merely to help developpers to launch this action without having to launch a new runtime eclipse, test the action, close the runtime, change what they need, relaunch a runtime, running the action again, ... I am doing this for Acceleo, an m2t code generator; and the goal is obviously to ease the creation of generators. These dynamically installed plugins (and these alone) I need to alter in order to properly set their classpath. The ClassLoadingHook is meant to hook in the framework and alter the way _all_ plugins are loaded. This is not what I am seeking to do since I know which plugins will have to be dynamically installed as bundles. > > This bug could also be raised with another description : within Eclipse, I can > > right-click a project and use "classpath => configure classpath" to edit my > > plugin's classpath. Within this dialog I can add source folders, libraries, ... > > Shouldn't that configuration be reflected in the MANIFEST? > > > > I suppose this is a possibility but in PDE we generally have kept the manifest > content under the control of the developer. I know there are other work flows > where developers want most if not all of the manifest generated for them. But > this is more of a PDE discussion. Perhaps Chris can point you to an existing > bug in PDE that is similar to this discussion. I know we have discussed having > PDE generate the correct classpath in the manifest and run with that instead of > depending on Equinox "magic" to run with the development time classpath in a > plug-in project. > Looking closely, "magic" is what I am currently trying to achieve to make my plugin a little more user-friendly. This is what made the success of another m2t code generator of ours, yet this "other code generator" made use of custom classloader searching through the entire plugins ... raising both performance issues and classloader-related issues (CNFE, LinkageErrors, ... and such other goodies). Having the PDE properly reflect the plugin classpath would work... as would having an API to alter the bundle classpath. All depends on whether we want to handle it at equinox level or pde level. I'd rather not have discouraged code in my plugins yet with no workaround available I guess I am stuck with it. |
Hi, I have no idea as if this should go in equinox or pde, chose equinox framework by default :p. I took inspiration of the org.eclipse.ui.tools project that can be found in platform-incubator/ui/other on the dev.eclipse.org CVS to try and dynamically load bundles in the running eclipse from my code. This works fine so far by retrieving the IPluginModelBase for the workspace plugins, and using code as such : ----------8<---------- IPluginModelBase candidate = PluginRegistry.getWorkspaceModels().get(0); IResource candidateManifest = candidate.getUnderlyingResource(); String candidateLocationReference = "reference:" + candidateManifest.getProject().getLocationURI().toURL().toExternalForm(); Bundle installedBundle = Activator.getDefault().getContext().installBundle(candidateLocationReference); ----------8<---------- Note that installation goes smoothly and installedBundle.getState() == Bundle.INSTALLED at this point. And then the actual issue : I cannot load any of the classes from this bundle as it isn't packaged as would a regular "eclipse" plugin to an "equinox" bundle : it still has a "bin" folder containing my compiled java classes whilst the regular eclipse plugin export would have removed this bin folder. I could work around this by adding the classpath manifest attribute to the plugin's MANIFEST.MF as "Bundle-Classpath: bin"... yet this isn't an option since I cannot force users of my plugin to manually add this clause in their plugins' manifests. I then took a look at the framework code to try and dynamically fill in the classpath for the dynamically installed plugins ... to no avail : every single line of code getting near to the plugin manifest is either internal or forbidden access. Using restricted code I finally managed to do what I wanted through : ----------8<---------- IProject project = candidateManifest.getProject(); IJavaProject javaProject = JavaCore.create(project); try { IPath output = javaProject.getOutputLocation(); BaseData bundleData = (BaseData)((AbstractBundle)bundle).getBundleData(); bundleData.setClassPathString(output.removeFirstSegments(1).toString()); } catch (JavaModelException e) { Activator.log(e, false); } ----------8<---------- And here comes the "API opening" part of this bug summary : both "org.eclipse.osgi.baseadaptor.BaseData" and "org.eclipse.osgi.framework.internal.core.AbstractBundle" are restricted access classes. An API way of doing what this code does (or properly setting the classpath when installing the bundle or refreshing its packages through PackageAdmin for that matter) would be nice. If there is no public workaround as yet, is there any chance one could be opened for 3.5 (along with the new "export and install" wizard that is now accessible in the PDE ui, that would truly bring us closer to properly leveraging OSGi :)).