# Multiple catalogs multi-project buildSrc

**URL:** <https://discuss.gradle.org/t/multiple-catalogs-multi-project-buildsrc/45473>\
**Category:** Help/Discuss\
**Created:** [April 24, 2023, 8:03pm UTC](https://discuss.gradle.org/t/multiple-catalogs-multi-project-buildsrc/45473 "2023-04-24T20:03:02Z")\
**Posts on this page:** 5\
**Page:** 1

<div class="post-metadata">

**Author:** ![Elyrtan](https://avatars.discourse-cdn.com/v4/letter/e/c37758/32.png) [@Elyrtan](https://discuss.gradle.org/u/Elyrtan)\
**Post date:** [April 24, 2023, 8:03pm UTC](https://discuss.gradle.org/t/multiple-catalogs-multi-project-buildsrc/45473/1 "2023-04-24T20:03:02Z")

</div>

Hello,  
I’m playing around with multi project, buildSrc module as well as version catalogs.  
I’m following the [gradle guide](https://docs.gradle.org/current/userguide/platforms.html#sec:sharing-catalogs) on how to implement this.

I am facing two issues:

- I can’t seem to name the catalog anything different from `libs`
- I can’t create a second catalog, for example, a testLibs catalog like shown in the guide

Below, the relevant files:

- buildSrc/settings.gradle.kts:

```plaintext
dependencyResolutionManagement {
    versionCatalogs {
        libs {
            from(files("../gradle/libs.versions.toml"))
        }
        testLibs {
            from(files('../gradle/test-libs.versions.toml'))
        }
    }
}

```

- …/gradle/libs.versions.toml:

```toml
[versions]
springboot = "3.0.3"
spring-dependency-management = "1.1.0"
spring-docs = "2.0.4"

[libraries]
spring-docs = { module = "org.springdoc:springdoc-openapi-starter-webmvc-ui", version.ref = "spring-docs" }

[plugins]
org-springframework-boot = {id = "org.springframework.boot", version.ref = 'springboot'}
io-spring-dependency-management = { id = "io.spring.dependency-management", version.ref = 'spring-dependency-management' }

```

- …/gradle/test-libs.versions.toml:

```toml
[versions]
junit = "5.9.1"

[libraries]
org-junit = { module = "org.junit.jupiter:junit-jupiter", version.ref = "junit" }

```

- buildSrc/src/main/groovy/tmp.java-common-conventions.gradle

```groovy
dependencies {
    compileOnly libs.org.lombok
    annotationProcessor libs.org.lombok

    // Use JUnit Jupiter for testing.
    testImplementation testLibs.org.junit // testLibs is not recognized
}

```

The build results in:

```plaintext
Build file '[...]/testing-layers/testing-layers-java/application/build.gradle' line: 2

An exception occurred applying plugin request [id: 'tmp.java-common-conventions']
> Failed to apply plugin 'tmp.java-common-conventions'.
   > groovy.lang.MissingPropertyException: Could not get unknown property 'testLibs' for object of type org.gradle.api.internal.artifacts.dsl.dependencies.DefaultDependencyHandler.

```

What am I missing ?

Gradle version: 8.1.1

---

<div class="post-metadata">

**Author:** ![peter-galcik](https://avatars.discourse-cdn.com/v4/letter/p/b2d939/32.png) [@peter-galcik](https://discuss.gradle.org/u/peter-galcik)\
**Post date:** [April 24, 2023, 9:01pm UTC](https://discuss.gradle.org/t/multiple-catalogs-multi-project-buildsrc/45473/2 "2023-04-24T21:01:01Z")

</div>

> [@Elyrtan](#):
>
> 1.1

Hi, i think this url might be worth reading. I am sad of gradle state with you also… afaik there is no elegant way. Only hack/workaround approach.

> <https://github.com/gradle/gradle/issues/15383>
>
> \### Context
> 
> In a similar way to #15382, we want to make the version catalogs …accessible to precompiled script plugins. Naively, one might think that it's easier to do because precompiled script plugins are applied to the "main" build scripts, but this isn't necessarily the case:
> 
> \- first, precompiled script plugins can be \_published too\_, meaning that they are no different from regular plugins in practice
> \- second, precompiled script plugins can be declared in included builds, not just \_buildSrc\_
> 
> Therefore, the "version catalog" that a precompiled script plugin should see cannot be the catalog declared in the "main build". It cannot be, either, the catalog declared in the project which itself declares the precompiled script plugin (typically the settings file of the \`buildSrc\` project): in particular, the catalogs declared in \`buildSrc/settings.gradle\` are for the build logic of \`buildSrc\` itself, not for the "main" build.
> 
> As a consequence, we cannot guarantee that if we expose the accessors of the main build, somehow, to the precompiled script plugins, it would work when the plugin is applied.
> 
> One option to solve this problem is to have a section in the build script which defines precompiled script plugins to declare the "target version catalogs". That is to say, we explicitly declare what the expected "schema" is when the plugin will effectively be applied. It's then the build authors responsibility to make sure that it is effectively the case, by sharing the same catalog between this declaration and the main build.

---

<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:** [April 24, 2023, 9:53pm UTC](https://discuss.gradle.org/t/multiple-catalogs-multi-project-buildsrc/45473/3 "2023-04-24T21:53:34Z")

</div>

That’s not correct @peter-galcik.  
He is building his convention plugin as a Groovy DSL precompiled script plugin, so he can use `testLibs` fine, if it were available in the build where he applies it.  
The hack-around is only necessary for Kotlin DSL precompiled script plugins.

The problem is, that `testLibs` is only defined in `buildSrc` settings script.  
But you need to also define it in the project where you apply the convention plugin to.  
The naming convention for the default `libs` catalog is only valid for the `libs` catalog.  
The `testLibs` catalog you have to define manually also in the settings script of the build where you want to use it.

---

<div class="post-metadata">

**Author:** ![Elyrtan](https://avatars.discourse-cdn.com/v4/letter/e/c37758/32.png) [@Elyrtan](https://discuss.gradle.org/u/Elyrtan)\
**Post date:** [April 25, 2023, 8:12am UTC](https://discuss.gradle.org/t/multiple-catalogs-multi-project-buildsrc/45473/4 "2023-04-25T08:12:38Z")

</div>

Thank you @Vampire , @peter-galcik  
Looks like declaring testLibs in the root project is working.  
Below the root settings.gradle:

```groovy
dependencyResolutionManagement {
    versionCatalogs {
        testLibs {
            from(files('./gradle/test-libs.versions.toml'))
        }
    }
}

rootProject.name = 'testing-layers-java'

include 'domain'
include 'application'
include 'infrastructure'

```

I’m now able to use testLibs both in the sub projects as well as in the convention plugin.  
I’m not clear though as to why the testLibs catalog needs “special treatment” compared to the libs catalog.

---

<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:** [April 25, 2023, 3:13pm UTC](https://discuss.gradle.org/t/multiple-catalogs-multi-project-buildsrc/45473/5 "2023-04-25T15:13:26Z")

</div>

It does not.  
The `libs` is what is special as it is defined automatically if the file is in the conventional place which it is for you.
