# Place for properties visible from both buildSrc and project

**URL:** https://discuss.gradle.org/t/place-for-properties-visible-from-both-buildsrc-and-project/18916
**Category:** Help/Discuss
**Created:** [August 12, 2016, 9:55am UTC](https://discuss.gradle.org/t/place-for-properties-visible-from-both-buildsrc-and-project/18916 "2016-08-12T09:55:06Z")
**Posts on this page:** 18
**Page:** 1

<div class="post-metadata">

### Author: ![dsvoronin](https://sea1.discourse-cdn.com/gradle/user_avatar/discuss.gradle.org/dsvoronin/32/4236_2.png) [@dsvoronin](https://discuss.gradle.org/u/dsvoronin)
#### Post date: [August 12, 2016, 9:55am UTC](https://discuss.gradle.org/t/place-for-properties-visible-from-both-buildsrc-and-project/18916/1 "2016-08-12T09:55:06Z")

</div>

Where can i set a property that will be available both from buildSrc’s build.gradle and my projects build.gradle’s?

project level gradle.properties not available from buildSrc

Goal: I want to share some props, like repo url’s

---

<div class="post-metadata">

### Author: ![mark\_vieira](https://sea1.discourse-cdn.com/gradle/user_avatar/discuss.gradle.org/mark_vieira/32/5396_2.png) [@mark\_vieira](https://discuss.gradle.org/u/mark_vieira)
#### Post date: [August 12, 2016, 7:34pm UTC](https://discuss.gradle.org/t/place-for-properties-visible-from-both-buildsrc-and-project/18916/2 "2016-08-12T19:34:53Z")

</div>

The buildSrc project is looking for properties in a gradle.properties file in the buildSrc directory. A simple thing would just be to create a symbolic link there to the gradle.properties file in the root project.

```
├── buildSrc
│ ├── build.gradle
│ └── gradle.properties -> ../gradle.properties
└── gradle.properties
```

---

<div class="post-metadata">

### Author: ![mark\_vieira](https://sea1.discourse-cdn.com/gradle/user_avatar/discuss.gradle.org/mark_vieira/32/5396_2.png) [@mark\_vieira](https://discuss.gradle.org/u/mark_vieira)
#### Post date: [August 12, 2016, 7:38pm UTC](https://discuss.gradle.org/t/place-for-properties-visible-from-both-buildsrc-and-project/18916/3 "2016-08-12T19:38:12Z")

</div>

Alternatively if you want a more cross-platform way of doing this you could put properties in a .gradle file and then just apply to both projects.

**properties.gradle**

```
ext {
  repoUrl = 'http://repo.mycompany.org'
}

```

**build.gradle**

```
apply from: 'properties.gradle'

```

**buildSrc/build.gradle**

```
apply from: "${rootDir.parentFile}/properties.gradle"
```

---

<div class="post-metadata">

### Author: ![robleach](https://avatars.discourse-cdn.com/v4/letter/r/dc4da7/32.png) [@robleach](https://discuss.gradle.org/u/robleach)
#### Post date: [August 24, 2016, 8:16pm UTC](https://discuss.gradle.org/t/place-for-properties-visible-from-both-buildsrc-and-project/18916/4 "2016-08-24T20:16:06Z")

</div>

This is what I was looking for, however I do have a follow up question.

I found this answer: [How to share variable between Gradle buildSrc and rest of project? - Stack Overflow](http://stackoverflow.com/a/26598652)  
So based on using `java.lang.Properties` as an alternative solution, how do you tell code in buildSrc where the root or base directory is.

It appears that the relative path from the perspective of code in buildSrc is always where you execute the build from.

So if I wanted to do something like this:

> Properties projectProperties = new java.util.Properties()  
> FileInputStream fis = new FileInputStream(“gradle.properties”)  
> projectProperties.load(fis)

If you’re not in the root directory when you execute the build then it won’t find the file.

Can you do this:

> Properties projectProperties = new java.util.Properties()  
> FileInputStream fis = new FileInputStream(“$rootDir/gradle.properties”)  
> projectProperties.load(fis)

This is with a situation where you don’t have a `buildSrc/build.gradle` file.

---

<div class="post-metadata">

### Author: ![mark\_vieira](https://sea1.discourse-cdn.com/gradle/user_avatar/discuss.gradle.org/mark_vieira/32/5396_2.png) [@mark\_vieira](https://discuss.gradle.org/u/mark_vieira)
#### Post date: [August 24, 2016, 8:20pm UTC](https://discuss.gradle.org/t/place-for-properties-visible-from-both-buildsrc-and-project/18916/5 "2016-08-24T20:20:16Z")

</div>

@robleach It’s not clear to me where this code you are showing will live? Is this in a build script or in a Java source file that lives in the `buildSrc` project?

---

<div class="post-metadata">

### Author: ![robleach](https://avatars.discourse-cdn.com/v4/letter/r/dc4da7/32.png) [@robleach](https://discuss.gradle.org/u/robleach)
#### Post date: [August 24, 2016, 8:26pm UTC](https://discuss.gradle.org/t/place-for-properties-visible-from-both-buildsrc-and-project/18916/6 "2016-08-24T20:26:11Z")

</div>

Sorry, it is Groovy code under `buildSrc/src/main/groovy/UCD.groovy`.

---

<div class="post-metadata">

### Author: ![mark\_vieira](https://sea1.discourse-cdn.com/gradle/user_avatar/discuss.gradle.org/mark_vieira/32/5396_2.png) [@mark\_vieira](https://discuss.gradle.org/u/mark_vieira)
#### Post date: [August 24, 2016, 8:29pm UTC](https://discuss.gradle.org/t/place-for-properties-visible-from-both-buildsrc-and-project/18916/7 "2016-08-24T20:29:49Z")

</div>

I think what I would do is restructure your code to take the file location as some kind of argument. The working directory is not going to be predictable and `project.rootDir` is only available from within a build script.

---

<div class="post-metadata">

### Author: ![robleach](https://avatars.discourse-cdn.com/v4/letter/r/dc4da7/32.png) [@robleach](https://discuss.gradle.org/u/robleach)
#### Post date: [August 24, 2016, 8:32pm UTC](https://discuss.gradle.org/t/place-for-properties-visible-from-both-buildsrc-and-project/18916/8 "2016-08-24T20:32:01Z")

</div>

Okay at least that answers my follow up question. Thanks.

---

<div class="post-metadata">

### Author: ![Ned\_Twigg](https://sea1.discourse-cdn.com/gradle/user_avatar/discuss.gradle.org/ned_twigg/32/1516_2.png) [@Ned\_Twigg](https://discuss.gradle.org/u/Ned_Twigg)
#### Post date: [November 23, 2016, 11:35pm UTC](https://discuss.gradle.org/t/place-for-properties-visible-from-both-buildsrc-and-project/18916/9 "2016-11-23T23:35:41Z")

</div>

Here’s a copy-paste snippet for anyone else who comes along and wants `gradle.properties` in their root dir to be visible to `buildSrc`.

```gradle
/ ***file: gradle/loadProps.gradle*** /
Properties properties = new Properties()
FileInputStream input = new FileInputStream(file('../gradle.properties'))
properties.load(input)
input.close()

for (String key : properties.stringPropertyNames()) {
	ext.set(key, properties.getProperty(key))
}

/ ***file: buildSrc/build.gradle*** /
apply from: '../gradle/loadProps.gradle'

```

---

<div class="post-metadata">

### Author: ![grv87](https://sea1.discourse-cdn.com/gradle/user_avatar/discuss.gradle.org/grv87/32/5767_2.png) [@grv87](https://discuss.gradle.org/u/grv87)
#### Post date: [October 28, 2017, 2:47pm UTC](https://discuss.gradle.org/t/place-for-properties-visible-from-both-buildsrc-and-project/18916/10 "2017-10-28T14:47:00Z")

</div>

How about properties visible from `buildSrc/settings.gradle`?

---

<div class="post-metadata">

### Author: ![Abhijit\_Sarkar](https://sea1.discourse-cdn.com/gradle/user_avatar/discuss.gradle.org/abhijit_sarkar/32/11598_2.png) [@Abhijit\_Sarkar](https://discuss.gradle.org/u/Abhijit_Sarkar)
#### Post date: [May 15, 2025, 8:23am UTC](https://discuss.gradle.org/t/place-for-properties-visible-from-both-buildsrc-and-project/18916/11 "2025-05-15T08:23:49Z")

</div>

Sorry to bump an old topic, but since the problem still exists, I hope my comment will be helpful to anyone coming across this topic from a Google search, just like I did.

Using Gradle 8.14, and Kotlin DSL.

buildSrc/build.gradle.kts

```gradle
projectDir.parentFile
    .resolve("gradle.properties")
    .readLines()
    .filter { it.contains("Version") } // I only wanted the versions
    .forEach { line ->
        val pieces = line.split("=").map { it.trim() }
        project.extra[pieces.first()] = pieces.last()
    }

```

You could also load a Java `Properties` file, but given it’s pathetic API (you create an empty `Properties` , then `load` it 🤔), I decided not to.

buildSrc/src/main/kotlin/java-conventions.gradle.kts

```gradle
val junit5Version: String by project

```

submodule/build.gradle.kts

```gradle
plugins {
    id("java-conventions")
}

```

---

<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: [May 15, 2025, 8:29am UTC](https://discuss.gradle.org/t/place-for-properties-visible-from-both-buildsrc-and-project/18916/12 "2025-05-15T08:29:44Z")

</div>

Better use a version catalog for centrally declaring versions and coordinates though. 🙂

---

<div class="post-metadata">

### Author: ![Abhijit\_Sarkar](https://sea1.discourse-cdn.com/gradle/user_avatar/discuss.gradle.org/abhijit_sarkar/32/11598_2.png) [@Abhijit\_Sarkar](https://discuss.gradle.org/u/Abhijit_Sarkar)
#### Post date: [May 15, 2025, 8:31am UTC](https://discuss.gradle.org/t/place-for-properties-visible-from-both-buildsrc-and-project/18916/13 "2025-05-15T08:31:34Z")

</div>

`buildSrc` plugins can’t access versions catalogs without bending over backwards, and falling over.

---

<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: [May 15, 2025, 9:02am UTC](https://discuss.gradle.org/t/place-for-properties-visible-from-both-buildsrc-and-project/18916/14 "2025-05-15T09:02:12Z")

</div>

That’s not true.  
Kotlin DSL precompiled script plugins cannot use the type-safe accessors without my hack-around, that is true.  
But for example Groovy DSL precompiled script plugins can do.  
And any build-logic code can use the `VersionCatalogsExtension` and still benefit from the advantages of version catalogs like when doing `the<VersionCatalogsExtension>().named("libs").findVersion("junit5")` in a Kotlin DSL precompiled script plugin.

---

<div class="post-metadata">

### Author: ![Abhijit\_Sarkar](https://sea1.discourse-cdn.com/gradle/user_avatar/discuss.gradle.org/abhijit_sarkar/32/11598_2.png) [@Abhijit\_Sarkar](https://discuss.gradle.org/u/Abhijit_Sarkar)
#### Post date: [May 15, 2025, 10:11am UTC](https://discuss.gradle.org/t/place-for-properties-visible-from-both-buildsrc-and-project/18916/15 "2025-05-15T10:11:06Z")

</div>

> Kotlin DSL precompiled script plugins cannot use the type-safe accessors without my hack-around, that is true.

That’s what I said.

```gradle
the<VersionCatalogsExtension>().named("libs").findVersion("junit5")

```

Using string keys wouldn’t be type safe. Besides, this is just version, finding plugins is even messier.

---

<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: [May 15, 2025, 2:17pm UTC](https://discuss.gradle.org/t/place-for-properties-visible-from-both-buildsrc-and-project/18916/16 "2025-05-15T14:17:47Z")

</div>

```kotlin
the<VersionCatalogsExtension>().named("libs").findVersion("junit5")

```

is just as type-safe as

```kotlin
val junit5Version: String by project

```

with the added value that you benefit from the version catalog advantages.

> Besides, this is just version, finding plugins is even messier.

Not really.  
Plugins you anyway apply only by ID in a convention plugin and have it as dependency in the buildscript of the build logic project.  
And there you can use the `libs....` accessors if you just reference the TOML file in its settings script.

---

<div class="post-metadata">

### Author: ![Abhijit\_Sarkar](https://sea1.discourse-cdn.com/gradle/user_avatar/discuss.gradle.org/abhijit_sarkar/32/11598_2.png) [@Abhijit\_Sarkar](https://discuss.gradle.org/u/Abhijit_Sarkar)
#### Post date: [May 15, 2025, 3:10pm UTC](https://discuss.gradle.org/t/place-for-properties-visible-from-both-buildsrc-and-project/18916/17 "2025-05-15T15:10:17Z")

</div>

> [@Vampire](#):
>
> `the<VersionCatalogsExtension>().named("libs").findVersion("junit5")`

Well, if you insist that this monstrosity is equally type-safe and developer-friendly as `val junit5Version: String by project`, then it’s a matter of your personal opinion, which I’d refrain from delving into.

What is a fact is that there are many developers who tried to use `gradle.properties` or `libs.versions.toml` in a similar manner in `buildSrc` as they would do in a regular module, and found to their surprise that they couldn’t. It’s just bad design that no amount of insistence will change.

---

<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: [May 15, 2025, 3:56pm UTC](https://discuss.gradle.org/t/place-for-properties-visible-from-both-buildsrc-and-project/18916/18 "2025-05-15T15:56:06Z")

</div>

> Well, if you insist that this monstrosity

It’s only a “monstrosity” because it is written as one-liner.  
Typically you would get multiple things so for example have a variable called `libs`.

> is equally type-safe

That’s just a fact.  
`val junit5Version: String by project` is not more than syntactic sugar over `val junit5Version = project.getProperty("junit5Version")` which just the same uses a string to lookup the version,  
so **is** equally typesafe as `val junit5Version = libs.findVersion("junit5")`.

> and developer-friendly

I did not say it is as developer-friendly.  
But the big points are, that

- version catalogs are the idiomatic way how to centralize versions
- with version catalogs you have significant advantages over such a property approach  
For example changing just a version in the version catalog does only make those tasks out-of-date that actually use that version in some way, tools that understand the format like `refreshVersions` Gradle plugin, dependency updater bots, … can easily understand the format and work with it, …

But hey, it is just a recommendation after all.  
You are free to use whatever works for you, you have to live with the consequences, I just share my expertise with you, what you do with the information is up to you. 🙂

> It’s just bad design that no amount of insistence will change.

No, it’s not.  
The point is, that `buildSrc` or an included build with build logic is a completely separate standalone build, that runs before your build and produces plugins that you then apply to your project.  
Version catalogs are not baked-in, they are defined by the consumer of your plugin, so you cannot easily provide types-safe accessors for the entries, because type-safe accessors are only generated for the things that Gradle **knows** will be there when used. But when compiling the plugin, Gradle simply cannot know what version catalogs or version catalog entries will be there in the project that is going to apply the plugin, unless you tell it, for example using my hack-around for which an essential part is, that you apply the exact same verison catalog to your main build and the build-logic build. Because my hack-around has the exact same pre-requisite as using the `VersionCatalogsExtension`, namely that the consuming project has to define a version catalog with the expected entries, just like with your solution where you require that the consuming project has the expected entries in the properties file. So design-wise it is just the same as your solution. 😉

But hey, if you don’t like the design, feel free to suggest to the Gradle folks to change it in an GitHub issue, I’m just a user like you. 🙂
