# Multi-module build doesn't see configurations from java plugin

**URL:** https://discuss.gradle.org/t/multi-module-build-doesnt-see-configurations-from-java-plugin/42262
**Category:** Help/Discuss
**Created:** [February 20, 2022, 11:56am UTC](https://discuss.gradle.org/t/multi-module-build-doesnt-see-configurations-from-java-plugin/42262 "2022-02-20T11:56:39Z")
**Posts on this page:** 7
**Page:** 1

<div class="post-metadata">

### Author: ![evkaky](https://avatars.discourse-cdn.com/v4/letter/e/3e96dc/32.png) [@evkaky](https://discuss.gradle.org/u/evkaky)
#### Post date: [February 20, 2022, 11:56am UTC](https://discuss.gradle.org/t/multi-module-build-doesnt-see-configurations-from-java-plugin/42262/1 "2022-02-20T11:56:39Z")

</div>

Hi folks.  
Trying to bootstrap a simple multi-module project in Kotlin. Have “server” and “client” modules inside root one. Here is a folder structure:

```gradle
/settings.gradle.kts
/build.gradle.kts
/client/src/main/kotlin/...
/server/src/main/kotlin/...
...

```

I want to configure both “server” and “client” modules in a root build.gradle.kts:

```gradle
subprojects {
    apply(plugin = "kotlin")
    apply(plugin = "application")
    apply(plugin = "org.jetbrains.kotlin.plugin.serialization")
    repositories {
        mavenCentral()
    }
    dependencies {
        testImplementation("org.jetbrains.kotlin:kotlin-test-junit:$kotlin_version")
    }
}
project(":client") {
    dependencies {
        ...
    }
}
project(":server") {
    apply(plugin = "com.google.cloud.tools.appengine")
    dependencies {
        ...
    }
}

```

The build fails with `Unresolved reference: testImplementation`. It’s weird for me since I specified `apply(plugin = "kotlin")` in the `subproject` section. That plugin should bring `testImplementation` and other configurations into scope!

---

<div class="post-metadata">

### Author: ![Vampire](https://sea1.discourse-cdn.com/gradle/user_avatar/discuss.gradle.org/vampire/32/9082_2.png) [@Vampire](https://discuss.gradle.org/u/Vampire)
#### Post date: [February 20, 2022, 10:27pm UTC](https://discuss.gradle.org/t/multi-module-build-doesnt-see-configurations-from-java-plugin/42262/2 "2022-02-20T22:27:52Z")

</div>

Besides that it is bad practice to cross-configure projects like that, you only get the accessor you expect if you apply a plugin using the `plugins` DSL, not if you use the legacy `apply` method you are using there. It should work if you make `testImplementation` a string iirc though.

---

<div class="post-metadata">

### Author: ![evkaky](https://avatars.discourse-cdn.com/v4/letter/e/3e96dc/32.png) [@evkaky](https://discuss.gradle.org/u/evkaky)
#### Post date: [February 21, 2022, 8:55am UTC](https://discuss.gradle.org/t/multi-module-build-doesnt-see-configurations-from-java-plugin/42262/3 "2022-02-21T08:55:59Z")

</div>

What’s the reason behind to not configure multiple projects from within root `build.gradle.kts` like I did? Why it’s a bad practice?  
How can I then apply a bunch of plugins to all subproject without duplicating

```gradle
plugins {
    application
    kotlin("jvm") version "1.6.10"
    ...
}

```

across all `build.gradle.kts` files?  
Or I shouldn’t care about such kind of duplicating?

---

<div class="post-metadata">

### Author: ![Vampire](https://sea1.discourse-cdn.com/gradle/user_avatar/discuss.gradle.org/vampire/32/9082_2.png) [@Vampire](https://discuss.gradle.org/u/Vampire)
#### Post date: [February 21, 2022, 11:27am UTC](https://discuss.gradle.org/t/multi-module-build-doesnt-see-configurations-from-java-plugin/42262/4 "2022-02-21T11:27:29Z")

</div>

That has multiple reasons and I might miss some, but some are:

- it’s cleaner if a project defines it’s own build and not configuration comes from other projects injected
- that also increases maintainability
- you cannot use the recommended `plugins` DSL, but only the legacy `apply` function
- with Kotlin DSL you don’t get type safe accessor generated for plugins applied the legacy way
- cross project configuration like that couples projects, which prevents some advanced optimizations like configuration cache or configure on demand
- …  
There are probably some others in just don’t have on mind right now.

The idiomatic way is to have a convention plugin either in `buildSrc` or - what I prefer - in an included build, which you then apply to the projects directly. This way you don’t have duplication and the actual project build scripts often just apply one to a few convention plugins and define a list of dependencies. And if you write the convention plugin as precompiled script plugin, it looks almost like a normal build script.

---

<div class="post-metadata">

### Author: ![christianGen](https://avatars.discourse-cdn.com/v4/letter/c/e495f1/32.png) [@christianGen](https://discuss.gradle.org/u/christianGen)
#### Post date: [February 21, 2022, 11:47am UTC](https://discuss.gradle.org/t/multi-module-build-doesnt-see-configurations-from-java-plugin/42262/5 "2022-02-21T11:47:00Z")

</div>

onepiece.software has a nice video explaining convention plugins: [Understanding Gradle #03 – Plugins - YouTube](https://www.youtube.com/watch?v=N95YI-szd78)

---

<div class="post-metadata">

### Author: ![evkaky](https://avatars.discourse-cdn.com/v4/letter/e/3e96dc/32.png) [@evkaky](https://discuss.gradle.org/u/evkaky)
#### Post date: [February 23, 2022, 9:57am UTC](https://discuss.gradle.org/t/multi-module-build-doesnt-see-configurations-from-java-plugin/42262/6 "2022-02-23T09:57:56Z")

</div>

Should **any** usage of `allprojects { ... }` or `subprojects { ... }` be considered as a bad practice?

---

<div class="post-metadata">

### Author: ![Vampire](https://sea1.discourse-cdn.com/gradle/user_avatar/discuss.gradle.org/vampire/32/9082_2.png) [@Vampire](https://discuss.gradle.org/u/Vampire)
#### Post date: [February 23, 2022, 7:47pm UTC](https://discuss.gradle.org/t/multi-module-build-doesnt-see-configurations-from-java-plugin/42262/7 "2022-02-23T19:47:31Z")

</div>

I think so, yes.  
Well, let’s say 98.7 % to keep a small window open. 😃
