Gradle non-conventional directory structure


(Bence Takács) #1

I have the following directory structure:

work

|- runnableProject_1

|- runnableProject_2

|- component_1

|- component_2

|- component_3

|- settings.gradle

- build.gradle

There are dependencies between the components, and all of them have external dependencies too, and as you can see I have different “root” (runnable) projects.

I tried the following configurations:

settings.gradle

rootProject.name = ‘runnableProject_1’

includeFlat ‘component_1’, ‘component_2’, ‘component_3’

build.gradle

apply plugin: ‘java’

group = ‘my’

version = ‘0.1’

repositories {

mavenCentral()

}

sourceSets {

main {

java {

srcDir ‘runnableProject_1/src’

}

resources {

srcDir ‘runnableProject_1/res’

}

}

}

dependencies {

compileJava project(’:component_1’)

compileJava project(’:component_2’)

compileJava project(’:component_3’)

compileJava …

}

allprojects {

task hello << {task -> println “I’m $task.project.name” }

}

result:

Could not find method compileJava() for arguments [project ‘:component_1’] on root project ‘runnableProject_1’.

Any tips how should I manage this?

  1. Fixing the actual issue

  2. organize two “main” (runnable) projects (maybe putting them into two different targets)

  3. organize the dependencies between subprojects (component_1 could depend on component_2 and their dependencies too)


(Peter Niederwieser) #2

Instead of ‘compileJava’ it needs to be ‘compile’. Apart from that, I don’t quite understand what you are trying to do here, in particular because ‘runnableProject_2’ isn’t mentioned anywhere. Which logical project hierarchy do you want to have? (Logically it’s always a tree, even if the directory structure isn’t.)


(Bence Takács) #3

When changing compileJava to compile and then call ‘gradle compile’ I get this: ‘Task ‘compile’ is ambiguous in root project ‘runnableProject_1’. Candidates are: ‘compileJava’, ‘compileTestJava’.’

Second thing: “logical project hierarchy” - do you mean the dependency graph between projects? As i pointed out it is something like this:

'runnableProject_1

|- component_1

|

- component_2

|- component_3

|

- component_2

- component_4’

and for runnableProject_2: where it uses the same first level components they have the same subDependency tree (as expected), but it has its own components too. Additionally all components have their own third party dependencies too.

Currently I’m doing the build with the ant-ivy combination: ivy resolves the third party dependencies and ant to handle everything else. But ant is hard to maintain and i choose to switch to gradle instead of using antlib extensions.


(Peter Niederwieser) #4

The task is called ‘compileJava’, but the configuration (i.e. class path) is called ‘compile’. Hence it’s ‘gradle compileJava’ but it’s ‘dependencies { compile … }’.

The logical project hierarchy and project dependency graph are different things. What I don’t understand is why you set ‘rootProject.name = ‘runnableProject_1’’ in ‘settings.gradle’ although there’s also runnableProject_2. Note that a build can only have one ‘settings.gradle’.


(Bence Takács) #5

Hi, Peter

The solution is easy: the "runnableProject"s are separate applications but I would like to build both of them, one after the other. They all part of the platform, but separate applications/servers.

But first I want to build at least one of them and then create a task for the other (see point 2. above).

Currently I’m having these config files:

settings.gradle

rootProject.name = 'runnableProject_1'
  include
'component_1', 'component_2', 'component_3'

build.gradle

apply plugin: 'java'
  group = 'my'
  version = '0.1'
  repositories {
      mavenCentral()
  }
  sourceSets {
      main {
          java {
              srcDir 'src'
          }
          resources {
              srcDir 'res'
          }
      }
  }
  dependencies {
      compile project(':component_1')
      compile project(':component_2')
      compile project(':component_3')
      compile ...
  }
    allprojects {
      task hello << {task -> println "I'm $task.project.name" }
  }

if I call “gradle compileJava” I get the following error message: > Could not determine the dependencies of task ‘:compileJava’.

If I change the dependencies from “:component_1” to “runnableProject_1:component_1” (and “:runnableProject_1:component_1”) then the message is: > Project with path ‘runnableProject_1:component_1’ could not be found in root project ‘runnableProject_1’.

I think I’m missing something in gradle’s main concept… Could you give me some pointers? In ant it was easy: there was nothing but the filesystem to deal with…


(Peter Niederwieser) #6

In a nutshell, either you use ‘include’ instead of ‘includeFlat’ and add an include for ‘runnableProject_1’, or you move ‘build.gradle’ and ‘settings.gradle’ into ‘runnableProject_1’ and invoke the Gradle build from that directory. I’d probably go with the former. You can find more information in the “multi-project builds” chapter in the Gradle User Guide and the samples in the full Gradle distribution.


(Bence Takács) #7

If I use include and put runnableProject_1 into the dependencies then

Could not determine the dependencies of task ‘:compileJava’. > Caused by: org.gradle.api.artifacts.UnknownConfigurationException: Configuration with name ‘default’ not found.

The same result when using the other scenario. It’s a little bit frustrating that I cannot get even the “I’m $task.project.name” messages.

“The logical project hierarchy and project dependency graph are different things.”

Could you please explain this to me? For me the dependency structure (including external and internal dependencies) defines the build process. Well, for packaging you would need some resoure files too. What is this “logical project hierarchy” then?

I’m checking the following parts of the documentation: http://www.gradle.org/docs/current/userguide/userguide_single.html#sec:examples http://www.gradle.org/docs/current/userguide/userguide_single.html#multi_project_builds


(Peter Niederwieser) #8

Gradle arranges all projects into a logical project hierarchy. The hierarchy affects configuration of projects (parents often configure children, e.g. ‘subprojects { … }’) and execution of tasks (e.g. running ‘gradle compileJava’ from the root project will invoke that task for all projects that have one). The logical project hierarchy is independent from the code dependencies between projects. Often, the logical project hierarchy matches the physical directory layout, though this doesn’t have to be the case. For example, when you use ‘includeFlat’ rather than ‘include’, you’ll get a flat directory layout, but the logical layout will nevertheless be hierarchical. The multi-project builds chapter talks a lot about this, though perhaps not under the same name (haven’t checked).