Buildship plugin does not import project correctly

Eclipse 4.4.2
Buidlship 1.0.9.v20160211-1429

I had installed the Spring Gradle plugin and had nothing but trouble with it so I uninstalled it. I deleted my project (builds a gradle plugin used by other projects) which still can be built on the command line and which is saved in git. I deleted the Eclipse project and the git repository and cloned a new version of the project. Everything pulled down correctly. I then tried to import this as a Gradle project. It seems to import well, but when I switch from the Git perspective to the Java EE perspective to look at my project, instead of the src/main/groovy source directory tree, with some dummy classes that Gradle has created for me (src/main/java/LIbrary.java and src/test/java/LibraryTest.java). They each have a comment like this:

/*
 * This Java source file was auto generated by running 'gradle buildInit --type java-library'
 * by 'SC1478' at '3/3/16 8:03 AM' with Gradle 2.11
 *
 * @author SC1478, @date 3/3/16 8:03 AM
 */

Why DIDNā€™T it import the files I supplied it, and why DID it create these?
Have I done something wrong?

I tried several things, none of which altered this behavior. I deleted all the .project, ā€¦classpath files generated by Eclipse and figured I would let Gradle do its own thing, none of which worked. I tried using the same directory for the Git repo as for the Eclipse project and using different directories. Nothing worked.

OK, I found that running import from the Git Repository view has this behavior, but, I can do a successful import from the Project Explorer View, importing the folder of the Git Repo as a Gradle project. I have also found that the clone operation in the Git Repository view does not work correctly if I specify immediate import of the repository. there is no opportunity there to specify import as a Gradle project, and although everything gets imported, It is not a Gradle project after it is done.

In summary:

  1. Import function from Gradle Repo View, even specifying Gradle project, ignores source and initializes with dummy samples.
  2. Import function selected as checkbox within Git clone view imports everything correctly but does not create a Gradle project. This is probably because it offers no opportunity to specify a Gradle project there.
  3. Import function from Project Explorer as a Gradle project after cloning git repository works correctly.

Alas, it is not the case that the import function from the Project Explorer works correctly on a multi-module project. I donā€™t want the child projects to be separate Eclipse projects. In fact, I canā€™t have this, since many subprojects will have the same names as other subprojects of different parents.I want one project containing the subprojects as subdirectories.

And so it would appear, buildship is currently useless in my situation. I must have the ability to import a multiproject, with each subprobject visible ONLY as a subdirectory. I cannot use a setup in which the subprojects are separate Eclipse projects. What I require is a setup that treats subprojects exactly as command-line Gradle treats them. I understand that this may or may not be possible, given the constraints of Eclipse. And so I must use Eclipse only as an editor and import these beasts as General projects only.

Is mine a use case that Buildship plans to support?

This is not possible in Eclipse.

However, the composite build feature planned for Buildship 1.1 will de-duplicate project names across all Gradle builds in the workspace, getting rid of your root problem.

I noticed in the release notes from the recent Mars incremental release a mention of ā€œNested/Hierarchical view of projectsā€. How does this relate to this issue?

Itā€™s only a UI feature and only works for physically nested projects. The projects are still put into a flat workspace internally.

Thatā€™s easy to fix using something like

if (project != rootProject) {
  eclipse.project.name = (rootProject.name + project.path).replaceAll(':', '-')
}

This will make sure all your projects have long, unlikely-to-clash names. You just need to make sure the root projects have unique names.

1 Like

That might be what I need. My projects will be physically nested (which also will apply to version control). If they are internally separate for Eclipse, (and appropriately renamed to avoid name clashes) then as long as I can commit child project code from the parent project, Iā€™ll be all right. Is that how it works?

So if Iā€™m understanding all this my solution would be
Mars +
Buildship 1.1 (when will that be available?) or your eclipse.project.name fix until it is available?

I thought probably not. Maven has also had issues with this - for years.

It only works for the project explorer, not the package explorer that most people use for Java development. All in all, it is a very undercooked feature.

Eclipse Neon if everything goes well. But donā€™t hold your breath yet :slight_smile:

Yes, you can put that in an init script in your Gradle user home, so it is applied to all projects you work with, without changing their build script.

Hi, Stefan, at long last I come back to this and I am trying to follow your suggestion, which gives me the following error:

Synchronize Gradle builds with workspace failed due to an error in the referenced Gradle build.
Could not fetch model of type ā€˜EclipseProjectā€™ using Gradle distribution ā€˜https://services.gradle.org/distributions/gradle-2.12-bin.zipā€™.

Build file ā€˜C:\Users\SC1478\git\transw\transw\rms64\build.gradleā€™ line: 10
A problem occurred evaluating project ā€˜:rms64ā€™.
Could not find property ā€˜eclipseā€™ on project ā€˜:rms64ā€™.
org.gradle.tooling.BuildException: Could not fetch model of type ā€˜EclipseProjectā€™ using Gradle distribution ā€˜https://services.gradle.org/distributions/gradle-2.12-bin.zipā€™.
at org.gradle.tooling.internal.consumer.ResultHandlerAdapter.onFailure(ResultHandlerAdapter.java:58)
ā€¦
where line 10 is your suggested:

eclipse.project.name = (rootProject.name + project.path).replaceAll(':', '-')

What else is required to make this work?

Thanks.

Looks like you didnā€™t apply the eclipse plugin.

Actually, I did try that and found it wasnā€™t sufficient. It did make the earlier-reported error go away, but still left an error:

org.eclipse.buildship.core.GradlePluginsRuntimeException: A project with the name rms64 already exists.
	at org.eclipse.buildship.core.workspace.internal.ProjectNameUpdater.ensureProjectNameIsFree(ProjectNameUpdater.java:78)
	at org.eclipse.buildship.core.workspace.internal.ProjectNameUpdater.ensureProjectNameIsFree(ProjectNameUpdater.java:67)
	at org.eclipse.buildship.core.workspace.internal.SynchronizeGradleBuildOperation.addNewEclipseProjectToWorkspace(SynchronizeGradleBuildOperation.java:271)
	at org.eclipse.buildship.core.workspace.internal.SynchronizeGradleBuildOperation.synchronizeNonWorkspaceProject(SynchronizeGradleBuildOperation.java:255)
	at org.eclipse.buildship.core.workspace.internal.SynchronizeGradleBuildOperation.synchronizeGradleProjectWithWorkspaceProject(SynchronizeGradleBuildOperation.java:180)
	at org.eclipse.buildship.core.workspace.internal.SynchronizeGradleBuildOperation.synchronizeGradleBuildWithWorkspace(SynchronizeGradleBuildOperation.java:143)
	at org.eclipse.buildship.core.workspace.internal.SynchronizeGradleBuildOperation.access$000(SynchronizeGradleBuildOperation.java:108)
	at org.eclipse.buildship.core.workspace.internal.SynchronizeGradleBuildOperation$1.run(SynchronizeGradleBuildOperation.java:125)
	at org.eclipse.jdt.internal.core.BatchOperation.executeOperation(BatchOperation.java:39)
	at org.eclipse.jdt.internal.core.JavaModelOperation.run(JavaModelOperation.java:729)
	at org.eclipse.core.internal.resources.Workspace.run(Workspace.java:2313)
	at org.eclipse.jdt.core.JavaCore.run(JavaCore.java:5358)
	at org.eclipse.jdt.core.JavaCore.run(JavaCore.java:5315)
	at org.eclipse.buildship.core.workspace.internal.SynchronizeGradleBuildOperation.run(SynchronizeGradleBuildOperation.java:122)
	at org.eclipse.buildship.core.workspace.internal.SynchronizeGradleBuildsJob.synchronizeBuild(SynchronizeGradleBuildsJob.java:78)
	at org.eclipse.buildship.core.workspace.internal.SynchronizeGradleBuildsJob.runToolingApiJob(SynchronizeGradleBuildsJob.java:69)
	at org.eclipse.buildship.core.util.progress.ToolingApiJob$1.run(ToolingApiJob.java:73)
	at org.eclipse.buildship.core.util.progress.ToolingApiInvoker.invoke(ToolingApiInvoker.java:63)
	at org.eclipse.buildship.core.util.progress.ToolingApiJob.run(ToolingApiJob.java:70)
	at org.eclipse.core.internal.jobs.Worker.run(Worker.java:54)

This is the build script producing this:

ext.baseName ='transw'
version '12.0.2'
apply plugin: "eclipse"
subprojects { Project proj ->
    proj.eclipse.project.name = (this.name + proj.path).replaceAll(':', '-')
}

I was going to leave it there, but then it occurred to me that I hadnā€™t put the same strategy into effect in the OTHER project, the already-imported project that also had a subproject named rms64.

So I made this same change to the other project, deleted the original project from Eclipse and tried reimporting it. This did not give me the error (as of course it wouldnā€™t, since there was no duplicate) but I found that it ONLY imported the subporject. It did not create an Eclipse project for the parent.

I tried several; variants of this strategy, none of which behaved as I expected. I finally found this strategy, which works:

In EVERY project, root and subprojects, I have the following code:

apply plugin: 'eclipse'
if (project != rootProject) {
   eclipse.project.name = (rootProject.name + project.path).replaceAll(':', '-')
} else {
    eclipse.project.name = rootProject.name
}

This does work. And of course, so does this:
In root project:

    apply plugin: 'eclipse'
    eclipse.project.name = rootProject.name

In subprojects:

    apply plugin: 'eclipse'
    eclipse.project.name = (rootProject.name + project.path).replaceAll(':', '-')

But I could not find a solution that could be implemented using just a subprojects{} closure in the parent project. From the results I got I assume this is because trying to do so all in the root project only creates one ā€œeclipseā€ object. Eclipse must be applied separately in both parents and children to get ā€œeclipseā€ objects in both.

And now I have:

allprojects { Project proj ->
    proj.apply plugin:'eclipse'
    if (proj != rootProject) {
        eclipse.project.name = (rootProject.name + proj.path).replaceAll(':', '-')
    } else {
        eclipse.project.name = rootProject.name
    }
}

The else branch is unnecessary, as thatā€™s the default implementation. Also, you can put this code into an init script in your user home, so you donā€™t have to add it to all build scripts.

Ok, thanks. The key point was applying the plugin to every project, not just the root projectā€¦ Glad I got it working.