Since Buildship 2.0.1 (see Issue Remove user-defined lib entries from classpath · Issue #239 · eclipse/buildship · GitHub) classpath entries are removed from the .classpath file.
In our project we have a few legacy OSGI bundles that serve as “library projects” by exporting several JARs and their packages to make them usable in our other Eclipse RCP bundles. This was done by copying the dependencies to the root of the bundle and adding them as exported class path entries in the classpath file.
Up to Buildship 2.0.0 this was working fine but now all those entries in the .classpath file are removed by Buildship resulting in multiple compile errors and “Package … does not exist”.
Can you please provide a small example project that shows the problem on GitHub? Handwritten dependencies should not be necessary, unless there is some problem in PDE that prevents it from referencing things in other classpath containers.
It consists of a library plugin exporting Groovy to a demo RCP bundle. The groovy lib needs to be pulled into the “libs” plugin by executing the task “retrieveJars” after importing it with Buildship to make it work in an RCP environment.
This setup works with Buildship 2.0.0 but with 2.0.1 the “libs” plugin will have “Package ‘groovy.*’ does not exist in this plugin” errors.
Note that if you comment out line 7 in “client-libraries.gradle” the module “rcp_bundle” will also start having Groovy compile errors.
Are you trying to work on Buildship? In that case please use our Oomph setup.
In case you copied this plugin for your own project: The lib dependencies should be defined as normal file dependencies in the build and any adjustments should be made through the eclipse.classpath DSL instead of the file mangling that we currently do.
So the file.whenMerged hook it used to change the model of the classpath for a project? When I add something in the hook it is reflected in the Gradle / Buildship Classpath Container but not in the .classpath file.
So please correct me if I’m wrong here. The .classpath file is read and then augmented by the Buildship plugin. The result is visible under “Project and External Dependencies”.
So the problem I am facing now is that the bundle project (which has the Jar in /ib dir) compiles fine in the IDE but other projects that depend on this project cannot resolve their dependencies since the Jar file from the lib directory is not exported anymore. I could probably export the whole gradle classpath container but that would be too much of course.
So what could I do to further work with plugin-projects that wrap a Jar?
What I am observing is that I add a Library in the file.whenMerged hook and that library appears in the classpath container. The .classpath file is not changed.
So the modifications I make in the hook should appear there? Maybe the don’t appear because the change only has an influence on the classpath container. Is it still possible to add a classpath entry of type lib with the hook? I see a getKind() method in org.gradle.plugins.ide.eclipse.model.Library but no setter.
That’s the point of having a classpath container. The container is a placeholder that Buildship knows how to populate. It makes .classpath files portable.
Yes, of course. They are added to the container.
User-defined == Not defined in the build, but added manually in the IDE.
They are added to the container, where all lib/project entries belong.
You can add it using the eclipse.classpath.container method and then configure it as exported. Buildship just adds it by default if it wasn’t explicitly added to the model.
I honestly haven’t worked much with the combination of PDE and Buildship. If you could experiment with the export setting (both on the container and on individual libs) and report your results, we could put together some reusable advice for others. The main problem seems to be that PDE doesn’t work well with other classpath containers.
Letting Buildship keep lib-entries outside of the container around is problematic because it can quickly lead to inconsistency between the command line and IDE classpath. That’s why we switched to actively removing them. However, if this turns out to be a blocker for PDE development together with Buildship, we might have to find a different compromise.
I am currently trying to migrate all my bundle projects that until now had custom lib entries in the .classpath file. I do this by using the whenMerged hook and adding a library. Now, I have come across a constelation that does not work. But let me explain what works first:
The bundle projects that include a JAR file in their lib subdirectory are changed so that a new Library is added to the entries in the hook. The fileReference method is passed a String like e.g.
lib/some.jar
This works as expected. The PDE tooling now somehow recognizes this as “part” of the bundle project and does not complain about the exported package names that come from the packages inside that JAR file and are written in the MANIFEST.MF file.
Now I got one “special” setup for one of my bundle projects. In that project I used to have custom library JARs added in the .classpath file. They look like this:
/someOtherProject/lib/subdir/someother.jar
The difference here is that the JAR file is located in some other project (that project is also used by Gradle using flatDir repository style). At build-time the JARs do not need to be included in the actual bundle because a custom class loading hook is active which loads the JARs from some pre-exisiting application on the file system. This explains the strange setup to some extend…
So, now when I add a library with fileReference(’/someOtherProject/lib/subdir/someother.jar’) I would have expected the same behaviour as I had with the custom entries in the .classpath file.
What actually happens is that the Gradle classpath container is using
C:\someOtherProject\lib\subdir\someother.jar
as path. I can see that because I have an error marker on the project. It says:
The container 'Project and External Dependencies' references non existing library 'C:\someOtherProject\lib\subdir\someother.jar
I know that this is probably a real strange setup but shouldn’t it be possible to add the same library entry (beginning with a / ) that I can make manually? I think eclipse will treat such entries relative to the workspace and not the filesystem.
This part is confusing and something we need to fix (cc @donat). When you pass a String to the fileReference method, that is treated as a project-relative variable. Instead, you can pass a File and it should work.
You are creating an absolute path, that cannot work. Keep in mind we are talking about plain old java.io.File here, this has nothing to do with the Eclipse workspace model. You need to use file("path/of/lib/relative/to/project").