Community
Participate
Working Groups
In the current .classpath file there appears to be no way to mark an output folder as not exported. We have cases where a plugin which has many different pieces internally. Some are public some are not. At build time we compile into different jars and our plugin.xml uses the appropriate markup to not export those jars. Unfortunately, there is no way to model this in the .classpath file. As a result, consumers of the plugin project are able to compile against classes that will not be visible at runtime. This is quite confusing to downstream users as code completion offers many choices that are just not applicable. It is made worse by the fact that many of the API interfaces which are exported are implemented using classes of the same name (not under our control). Proposal: - The .classpath file should be enhanced to allow for an export="true|false" attribute on SOURCE folder entries (default would be true) - If any source folder contributing to an output folder is marked as export=true (or has not markup) then the corresponding output folder is made available to consumers of the project. - As a UI enhancement, the list on the Order and Export tab could show ouput folders with check marks beside them. If the user deselects an output folder then all source folders contributing to that ouptut folder are marked as export="false". This is based on the idea of users modeling their jars with ouptut folders and as such managing what others see at the level of jars rather than source folders.
Currently, you'd have to use several projects to setup the proper dependency (think of API projects and implementation projects). This being said, if we were to evolve the classpath to support yet another property, it would need to take into account that only multiple source folders could share the same output and thus the information should be kept consistently. Feels like an orthogonal property which should be queued at the end of the classpath sequence. However, being able to not export on a source folder basis would likely make the most sense to end users.
If not using several projects, one could still achieve what you want by using library entries rather than project ones in dependent projects. Thus instead of prerequisiting an entire project, you could simply rather reference one of its output folder which contains the information you want. If the information about what is internal vs. external can be inferred, then a classpath container could directly encapsulate these details, and compute the proper set of library folders to contribute to dependents.
We are seeing the problem in plugin development. In this domain there is a reasonably strong 1:1 relationship between plugin and project. That is not a particular design point but rather how the world and tooling have evolved. Having said that, I think many of the points raised generalize well. So, we had multiple projects but that was artificial and counterintuitive for the developers. It also causes alot of trouble for PDE selfhosting and build. Having downstream users link to libraries would work but is not intuitive. In their plugin.xml they just say they need plugin X so in the class path they would like to just list project X. Users would need continuous guidance and would likely end up confused. PDE classpath containers may (be made to) handle this but that feels like compensation that leaves the underlying need unaddressed. I'm not too fussed about whether the user spec export on source or bin folders. Personally bin folders makes most for the following reasons: - seems unlikely that you will be able to implement exporting code from just one of many source folders contributed to a bin folder. That is, what happens when the users selects just one of the source folders? - users think of compiled stuff going on a classpath.
As far as I know, there is no mechanism for implementing plug-ins with a clear separation between API and implementation, thus I don't see how having such a support in JDT Core would help when PDE is in charge of computing a plugin classpath.
The plugin.xml markup <library name="foo.jar"> <export name="[filter here]"/> </library> allows one to identify the code which is to be publicly visible for each given jar. Most of Eclipse draws a clear distinction between packages which are API and those which are not. Currently we do not attempt to filter using this information but various upper layer componentes (e.g., GEF) do. If one wanted to be serious about this they could separate their API and non-API into different jars (ala Xerces) and setup the export rules accordingly. While self- hosting (with these as source projects) however there is no way to model this in JDT classpaths. Concretely, in Equinox right now, the runtime has an extremely clearly defined API which is entirely contained in one jar. That jar is the only thing visible to outsiders at runtime. People developing with the org.eclipse.osgi project in their workspace (in source form at least) unfortunately see way more stuff than they should and than they will be able to use at runtime. Again, while the particulars of these examples are from Eclipse and PDE, I believe the concepts and scenarios are more generally relevant. It comes down to providing support for accurately modeling runtime classpaths in environments with non-trivial classpath/classloader structures (eg., Eclipse, JBoss, OSGi, ...) The approach I suggest is just that, a suggestion. I'm sure there are other approaches which address the basic issues outlined.
I understand, and was hoping you would point at this (unused) mechanism. Then if it can be automated based on the plugin.xml info, a PDE container could simply properly reflect this information. Instead of simply adding a project entry for each prereq plugin, it would rather associate its output folders as library folders (only those which are exported from a plugin.xml angle). I see what you want, but as of today there is no support for this, and I am suggesting a workaround. I am not saying that this isn't a valid suggestion, and project entries could be made even more intelligent so as to tackle this information. I was actually rather thinking of some exclusion rules which one could use to exclude some files from being contributed to dependents. This wouldn't require to separate API from non-API, but you could instead discriminate on the package location (e.g. exclude '**/internal/**'). Though I suspect the only granularity which really matters at runtime is a JAR separation...
More thinking... at compile time, one cannot simply exclude some output folders, as these might be required to support the exported API. It is quite common for API types to inherit from an internal type, which is to be found at compile time indirectly so as to construct the hierarchy of the API type. I think that the exclusion rules should be used to achieve this, and it would not exclude internal types, but rather discourage external usage of these. Something along the line of deprecation. Wondering if we should add notion of rules or an extra tag to decorate @internal types ?
Will reconsider post 3.0
Same issue as bug 29865
*** This bug has been marked as a duplicate of 29865 ***