How to prevent the creating of subprojects in Eclipse?

We have in the settings.gradle some include for creating variants of the artifacts in the build system.

The buildship plugin create for every of the subprojects its own eclipse project. The disadvantages:

  • The count of project incrments
  • The subproject contains the same content as the main project
  • There are conflicts with other projects because the subprojects has ever the same names like “demo”, “client”, “server”, …

Is there an option to prevent this eclipse subprojects? For example with the eclipse task in the gradle script.

2 Likes

A first and bad hack is the follow code in the settings.gradle:

if( file('bin').isDirectory() ) {
    println '=========================================='
    println 'Inside from Eclipse IDE'
    println '=========================================='
    return
}

before the includes of the subprojects. The disadvantages is that we can not run any tasks in the subprojects inside Eclipse.

The next step is to differ between gradle refresh and gradle task run.

I’m afraid I don’t understand the setup or what problems in Eclipse it causes. Could you create an example on GitHub and elaborate more on the problem you are trying to solve?

There is no way to prevent creation of an Eclipse project per sub-project. You can certainly modify them to make them essentially empty if that would help. E.g. remove source folders, dependencies etc. That’s the best advice I can give without understanding the project better.

You can use every sample from your documentation with subprojects.

Our solution already prevent the creation of subprojects. We need only to differ between “Refesh Gradle Project” and “Run Gradle Tasks” do do it perfect.

We have one Eclipse project that produce multiple jar files.The project has only one “src” folder and “test” folder. It look like:

  • src
  • test
  • .project
  • .classpath
  • settings.gradle
  • build.gradle
  • client\build.gradle
  • server\build.gradle
  • demo\build.gradle
  • stup\build.gradle
  • rmi\build.gralde

All the build files use mostly the same source files. There are only different annotation processing. One project, multiple artifacts.

Now I see what you are doing, thanks for the explanation. This should be one project with multiple compile/jar tasks instead of creating multiple projects “linking” the same sources.

How is this possible without multiple build files? Many attributes in a build file are singleton.

That’s not the case. There are some top-level convenience methods like sourceCompatibility, but everything can be configured on a lower (e.g. task) level as well.

For instance, you can create additional SourceSets and you will automatically get a compile task wired up for them. You can set all kinds of options on the specific compile task directly. Similarly you can create jar task that packages the output of such a custom SourceSet and give it a custom classifier for publishing.

If that seems too far from your current setup and you’d rather like a quick fix for Eclipse, then something like the following should work for the “variant projects”:

eclipse {
  classpath.file.whenMerged {
    entries.clear() //this will remove all source folders and dependencies
  }
}

You might be interested in my java-flavours-plugin plugin. Interesting code is in JavaFlavoursPlugin.groovy

You forgot the dependency chain of the tasks. We have more as only compile and jar task. The task use the outputs from the previous task. compile, jar, obfuscate, sign, plugin, etc. Currently the sub builds has only a few line. This is the great feature of Gradle. Our old ant files was thousand line long. We add only a script plugin from our pool an no extra configuration is needed.

Does not prevent the creation of subprojects in Eclipse.

How should this help?

How should this help?

It’s an example of what @st_oehme was suggesting. Multiple build variants (flavours) within a single project

You would do exactly the same, just for every flavor instead of for every “project”. Have a look at @Lance plugin, it goes into the direction you are talking about. You could easily add more logic on top like “create a sign task for every flavor” etc.

I know, it’s just a workaround. Our Eclipse plugin assumes that if you have a project, then that project is actually meaningful by itself. Your case stretches the concept of a project beyond that definition, because really they are all the same project. That’s a use case we don’t support, so I can only give you workarounds and advice on how to structure the project better.

Disclaimer: I work together with @Horcrux7

The Flavours-Plugin looks like something for very simple projects. It can not replicate and duplicate our whole dependency tree. Especially since our setup has worked for over a year - it might have worked when we started from scratch.

To not create subprojects as Eclipse projects would be the optimal solution and as far as I can see we would only need a hint - a variable, a task / doFirst, doLast - when buildship is about to refresh the workspace.

Alternatively - and something that I would have expected from the beginning - is a better Name for the subproject. I have not yet checked, but what happens when several projects have the same subproject names? They will not be distinguishable any more.
The name of a subproject should be derived from the main project name in combination with the subproject name.

I think I have found a solution to differ between “Gradle Refresh Project” and “Run Gradle Task”. On refresh there is no task set. I use the follow hack/solution now:

if( getStartParameter().getTaskNames().isEmpty() ) {
    println '=========================================='
    println 'Inside from Eclipse IDE. Subpjoject was killed.'
    println '=========================================='
    return
}
include 'foo'
include 'bar'
1 Like

Perhaps another alternative is

boolean isEclipse = System.getProperties().containsKey('osgi.requiredJavaVersion')

Never tried it but can see that system property in eclipse.ini

You can easily change that, see the first item on our FAQ.

2 Likes

“Gradle Refresh Project” and “Run Gradle Task” are both inside of Eclipse that this will not work.

I would also love a first-class way to prevent Buildship from importing certain subprojects in our Gradle build as Eclipse projects. Certainly we could use the hacky workaround of examining getStartParameter(), but that seems pretty fragile and likely-to-break.

The reason this is an issue in our project is because we have a number of “virtual” Gradle projects that don’t actually correspond to real directories or files on disk in any meaningful way. In fact, buildship cannot actually import our project at all without some hacks in place because these virtual projects all share the same project directory (and the buildship import process fails if multiple projects share the same project directory).

Why would you ever want or need to do that?

In addition to building, jarring, and obfuscating our Java code, we also use Gradle to produce the entire runtime distribution of our desktop application. This includes tasks such as building an MSI installer for our Windows distribution and a PKG installer for our mac distribution. Many of these tasks are quite time-consuming and thus we are motivated to take advantage of Gradle’s parallel execution functionality to make the build run as quickly as possible. The problem is that Gradle only allows running tasks in parallel if they live in different projects. Hence, we have a rather complex web of virtual projects to allow for optimal parallelization during our build process. It would be obnoxious to have to give all these virtual projects their own private empty directories just for the purpose of appeasing Buildship, and, even if we did, nobody really wants to see these projects in Eclipse cluttering up the navigator / project explorer (we already have 33 “real” sub-projects to deal with, we don’t need even more crap to wade through~)