I am trying to migrate a large Maven multiproject setup to Gradle (4.8.1). Many projects are Java but there are also C/C++ projects but I am not dealing with that yet - neither does/did Maven.
I am facing some challenges that seem to be caused by a combination of following characteristics:
-
Not all projects are siblings in the same folder. There is a deeper structure to them - i.e. from the root project’s (root) directory there are zero, one or two folders before the subproject folders. These aren’t “real projects” in a sense that they themselves contain no source code, though - they are just grouping folders, but I include them as folders and configure their location in settings.dir using:
include projectId;
project(projectId).projectDir = dir; -
We want to benefit from strict dependency scoping and control. Any and all “implementation” dependencies we declare as both a non-transitive implementation dependency and as a transitive runtimeClasspath dependency. Same goes with testImplementation and testRuntimeClasspath. We do not add these to (test)runtimeOnly to honour the word “only” in their names.
-
Projects depend on other projects in “simple” Java terms and we’re not using the java-library plugin - i.e. we’re not “exporting” any api dependencies by default. If a project A depends on project B that means:
- A’s implementation depends on B’s implementation non-transitively (without transitive dependencies - any dependencies have to be explicitly declared)
- A’s runtime depends on B’s runtime transitively (transitive dependencies included)
- A’s testImplementation depends on B’s testImplementation non-transitively
- A’s runtime depends on B’s testRuntime transitively
- We would like to automate Eclipse IDE and Eclipse workspace setup.
I was able to make the above work from command line (no Eclipse support) but I had to explicitly state that testImplementation configuration of dependent projects depend on either jars or test classes (build output) folders of dependency projects. But, when I do that, that messes up eclipseClasspath (used via the goomph plugin) a these end up being file dependencies not recognized as project ones.
To make Eclipse classpaths work I can just leave the “implementation project(…)” because Eclipse does not differentiate between scopes to the extent we need anyway (Photon does between main and test but not between compile and runtime).
If I try to not use goomph/eclipse plugins with eclipseClasspath task but Buildship (import Gradle projects) I face a different issue. If I don’t customize Eclipse project names then I get invalid project references in dependencies. If I add the following I resolve that issue (as also needed for goomph/eclipse - and it works there):
thatProject.eclipse {
project {
name = thatProject.path.substring(1).replace(':', '-');
}
… I instead get an error during importing:
Synchronize Gradle projects with workspace failed due to an unexpected error.
java.lang.IllegalArgumentException: Path for project must have only one segment.
at org.eclipse.core.runtime.Assert.isLegal(Assert.java:63)
at org.eclipse.core.internal.resources.WorkspaceRoot.getProject(WorkspaceRoot.java:147)
at org.eclipse.core.internal.resources.Project.move(Project.java:961)
at org.eclipse.core.internal.resources.Project.move(Project.java:951)
at org.eclipse.buildship.core.workspace.internal.DefaultWorkspaceOperations.renameProject(DefaultWorkspaceOperations.java:354)
at org.eclipse.buildship.core.workspace.internal.ProjectNameUpdater.updateProjectName(ProjectNameUpdater.java:50)
How should this be approached correctly and cleanly?