This is an automated email from the ASF dual-hosted git repository.

jdaugherty pushed a commit to branch feature/sbom
in repository https://gitbox.apache.org/repos/asf/grails-core.git

commit 775b356a6de57cda3301b268665ca15164aed346
Author: James Daugherty <[email protected]>
AuthorDate: Fri Sep 19 01:44:13 2025 -0400

    feature: generate reproducible sboms that are stored in published in any 
published binary jar under META-INF/sbom.json
---
 buildSrc/build.gradle                             |   1 +
 gradle.properties                                 |   2 +
 gradle/sbom-config.gradle                         | 143 ++++++++++++++++++++++
 grails-async/core/build.gradle                    |   1 +
 grails-async/gpars/build.gradle                   |   1 +
 grails-async/plugin/build.gradle                  |   1 +
 grails-async/rxjava/build.gradle                  |   1 +
 grails-async/rxjava2/build.gradle                 |   1 +
 grails-async/rxjava3/build.gradle                 |   1 +
 grails-bom/build.gradle                           |   1 +
 grails-bootstrap/build.gradle                     |   1 +
 grails-cache/build.gradle                         |   1 +
 grails-codecs-core/build.gradle                   |   1 +
 grails-codecs/build.gradle                        |   1 +
 grails-common/build.gradle                        |   1 +
 grails-console/build.gradle                       |   1 +
 grails-controllers/build.gradle                   |   1 +
 grails-converters/build.gradle                    |   1 +
 grails-core/build.gradle                          |   1 +
 grails-data-hibernate5/boot-plugin/build.gradle   |   1 +
 grails-data-hibernate5/core/build.gradle          |   1 +
 grails-data-hibernate5/dbmigration/build.gradle   |   1 +
 grails-data-hibernate5/grails-plugin/build.gradle |   1 +
 grails-data-mongodb/boot-plugin/build.gradle      |   1 +
 grails-data-mongodb/bson/build.gradle             |   1 +
 grails-data-mongodb/core/build.gradle             |   1 +
 grails-data-mongodb/ext/build.gradle              |   1 +
 grails-data-mongodb/grails-plugin/build.gradle    |   1 +
 grails-data-mongodb/gson-templates/build.gradle   |   1 +
 grails-data-simple/build.gradle                   |   1 +
 grails-databinding-core/build.gradle              |   1 +
 grails-databinding/build.gradle                   |   1 +
 grails-datamapping-async/build.gradle             |   1 +
 grails-datamapping-core-test/build.gradle         |   1 +
 grails-datamapping-core/build.gradle              |   1 +
 grails-datamapping-rx/build.gradle                |   1 +
 grails-datamapping-support/build.gradle           |   1 +
 grails-datamapping-tck/build.gradle               |   1 +
 grails-datamapping-validation/build.gradle        |   1 +
 grails-datasource/build.gradle                    |   1 +
 grails-datastore-async/build.gradle               |   1 +
 grails-datastore-core/build.gradle                |   1 +
 grails-datastore-web/build.gradle                 |   1 +
 grails-dependencies/assets/build.gradle           |   1 +
 grails-dependencies/starter-web/build.gradle      |   1 +
 grails-dependencies/test/build.gradle             |   1 +
 grails-domain-class/build.gradle                  |   1 +
 grails-encoder/build.gradle                       |   1 +
 grails-events/compat/build.gradle                 |   1 +
 grails-events/core/build.gradle                   |   1 +
 grails-events/gpars/build.gradle                  |   1 +
 grails-events/plugin/build.gradle                 |   1 +
 grails-events/rxjava/build.gradle                 |   1 +
 grails-events/rxjava2/build.gradle                |   1 +
 grails-events/rxjava3/build.gradle                |   1 +
 grails-events/spring/build.gradle                 |   1 +
 grails-events/transforms/build.gradle             |   1 +
 grails-fields/build.gradle                        |   1 +
 grails-forge/buildSrc/build.gradle                |   1 +
 grails-forge/gradle/sbom-config.gradle            | 143 ++++++++++++++++++++++
 grails-forge/grails-cli/build.gradle              |   1 +
 grails-forge/grails-forge-cli/build.gradle        |   1 +
 grails-forge/grails-forge-core/build.gradle       |   1 +
 grails-geb/build.gradle                           |   1 +
 grails-gradle/bom/build.gradle                    |   1 +
 grails-gradle/buildSrc/build.gradle               |   1 +
 grails-gradle/common/build.gradle                 |   1 +
 grails-gradle/docs-core/build.gradle              |   2 +
 grails-gradle/gradle/sbom-config.gradle           | 143 ++++++++++++++++++++++
 grails-gradle/model/build.gradle                  |   2 +
 grails-gradle/plugins/build.gradle                |   1 +
 grails-gradle/tasks/build.gradle                  |   2 +
 grails-gsp/core/build.gradle                      |   1 +
 grails-gsp/grails-layout/build.gradle             |   1 +
 grails-gsp/grails-sitemesh3/build.gradle          |   1 +
 grails-gsp/grails-taglib/build.gradle             |   1 +
 grails-gsp/grails-web-gsp-taglib/build.gradle     |   1 +
 grails-gsp/grails-web-gsp/build.gradle            |   1 +
 grails-gsp/grails-web-jsp/build.gradle            |   1 +
 grails-gsp/grails-web-taglib/build.gradle         |   1 +
 grails-gsp/plugin/build.gradle                    |   1 +
 grails-i18n/build.gradle                          |   1 +
 grails-interceptors/build.gradle                  |   1 +
 grails-logging/build.gradle                       |   1 +
 grails-micronaut/build.gradle                     |   1 +
 grails-mimetypes/build.gradle                     |   1 +
 grails-profiles/base/build.gradle                 |   1 +
 grails-profiles/plugin/build.gradle               |   1 +
 grails-profiles/profile/build.gradle              |   1 +
 grails-profiles/rest-api-plugin/build.gradle      |   1 +
 grails-profiles/rest-api/build.gradle             |   1 +
 grails-profiles/web-plugin/build.gradle           |   1 +
 grails-profiles/web/build.gradle                  |   1 +
 grails-rest-transforms/build.gradle               |   1 +
 grails-scaffolding/build.gradle                   |   1 +
 grails-services/build.gradle                      |   1 +
 grails-shell-cli/build.gradle                     |   1 +
 grails-spring/build.gradle                        |   1 +
 grails-test-core/build.gradle                     |   1 +
 grails-testing-support-core/build.gradle          |   1 +
 grails-testing-support-datamapping/build.gradle   |   1 +
 grails-testing-support-mongodb/build.gradle       |   1 +
 grails-testing-support-views-gson/build.gradle    |   1 +
 grails-testing-support-web/build.gradle           |   1 +
 grails-url-mappings/build.gradle                  |   1 +
 grails-validation/build.gradle                    |   1 +
 grails-views-core/build.gradle                    |   1 +
 grails-views-gson/build.gradle                    |   1 +
 grails-views-markup/build.gradle                  |   1 +
 grails-web-boot/build.gradle                      |   1 +
 grails-web-common/build.gradle                    |   1 +
 grails-web-core/build.gradle                      |   1 +
 grails-web-databinding/build.gradle               |   1 +
 grails-web-mvc/build.gradle                       |   1 +
 grails-web-url-mappings/build.gradle              |   1 +
 grails-wrapper/build.gradle                       |   1 +
 116 files changed, 546 insertions(+)

diff --git a/buildSrc/build.gradle b/buildSrc/build.gradle
index ca7f53f7f2..0e5cd7f88f 100644
--- a/buildSrc/build.gradle
+++ b/buildSrc/build.gradle
@@ -73,5 +73,6 @@ dependencies {
     implementation 'org.asciidoctor:asciidoctor-gradle-jvm'
     implementation 'org.springframework.boot:spring-boot-gradle-plugin'
     implementation 
"org.nosphere.apache.rat:org.nosphere.apache.rat.gradle.plugin:${gradleProperties.apacheRatVersion}"
+    implementation 
"org.cyclonedx.bom:org.cyclonedx.bom.gradle.plugin:${gradleProperties.gradleCycloneDxPluginVersion}"
     implementation 
"org.gradle.crypto.checksum:org.gradle.crypto.checksum.gradle.plugin:${gradleProperties.gradleChecksumPluginVersion}"
 }
\ No newline at end of file
diff --git a/gradle.properties b/gradle.properties
index 986a4d5f1e..83805e20bb 100644
--- a/gradle.properties
+++ b/gradle.properties
@@ -47,6 +47,8 @@ yakworksHibernateGroovyProxyVersion=1.1
 # Build dependency versions not managed by BOMs
 apacheRatVersion=0.8.1
 gradleChecksumPluginVersion=1.4.0
+# note: the cyclonedx 3.0.0-alpha-1 still does not set the project correctly, 
so we must use the older version
+gradleCycloneDxPluginVersion=2.4.0
 gradleLicensePluginVersion=0.16.1
 
 # micronaut libraries not in the bom due to the potential for spring mismatches
diff --git a/gradle/sbom-config.gradle b/gradle/sbom-config.gradle
new file mode 100644
index 0000000000..779e6ac1f3
--- /dev/null
+++ b/gradle/sbom-config.gradle
@@ -0,0 +1,143 @@
+/*
+ *  Licensed to the Apache Software Foundation (ASF) under one
+ *  or more contributor license agreements.  See the NOTICE file
+ *  distributed with this work for additional information
+ *  regarding copyright ownership.  The ASF licenses this file
+ *  to you under the Apache License, Version 2.0 (the
+ *  "License"); you may not use this file except in compliance
+ *  with the License.  You may obtain a copy of the License at
+ *
+ *    https://www.apache.org/licenses/LICENSE-2.0
+ *
+ *  Unless required by applicable law or agreed to in writing,
+ *  software distributed under the License is distributed on an
+ *  "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ *  KIND, either express or implied.  See the License for the
+ *  specific language governing permissions and limitations
+ *  under the License.
+ */
+
+import groovy.json.JsonOutput
+import groovy.json.JsonSlurper
+import org.cyclonedx.gradle.CycloneDxTask
+import org.cyclonedx.model.ExternalReference
+import org.cyclonedx.model.LicenseChoice
+import org.cyclonedx.model.License
+import org.cyclonedx.model.OrganizationalContact
+import org.cyclonedx.model.OrganizationalEntity
+import org.cyclonedx.model.Component
+
+import java.nio.charset.StandardCharsets
+import java.time.format.DateTimeFormatter
+import java.time.temporal.ChronoUnit
+
+apply plugin: 'org.cyclonedx.bom'
+
+project.ext.setProperty('sbomOutputLocation', 
project.layout.buildDirectory.file("${findProperty('pomArtifactId') ?: 
project.name}-${projectVersion}-sbom.json"))
+
+def sbomTask = tasks.named('cyclonedxBom', CycloneDxTask)
+sbomTask.configure { CycloneDxTask it ->
+    // the 2.x version of Cyclonedx uses a legacy syntax & helpers for setting 
inputs so the syntax below
+    // is required until the 3.x version is GA
+    it.setProjectType(findProperty('sbomProjectType') ?: 
Component.Type.FRAMEWORK.name())
+    [email protected](findProperty('pomArtifactId') ?: project.name)
+    [email protected](new OrganizationalEntity().tap {
+        name = 'Apache Software Foundation'
+        urls = ['https://www.apache.org/', 'https://security.apache.org/']
+        addContact(new OrganizationalContact().tap {
+            name = 'Apache Grails Development Team'
+            email = '[email protected]'
+        })
+    })
+    [email protected](new LicenseChoice().tap {
+        addLicense(new License().tap {
+            name = 'Apache-2.0'
+            url = 'https://www.apache.org/licenses/LICENSE-2.0.txt'
+        })
+    })
+
+    [email protected]([
+            new ExternalReference().tap {
+                url = 'https://grails.apache.org/'
+                type = ExternalReference.Type.WEBSITE
+            }
+    ])
+
+    // sboms are published for the purposes of vulnerability analysis so only 
include the runtime classpath
+    [email protected](['runtimeClasspath'])
+    [email protected](['compileClasspath', 'testRuntimeClasspath'])
+
+    // disable xml output
+    it.xmlOutput.unsetConvention()
+
+    def sbomOutputLocation = findProperty('sbomOutputLocation')
+    it.jsonOutput.set(sbomOutputLocation.get())
+    it.outputs.file(sbomOutputLocation)
+
+    // cyclonedx does not support "choosing" the license placed in the sbom
+    // see: https://github.com/CycloneDX/cyclonedx-gradle-plugin/issues/16
+    it.doLast {
+        def preferredLicenses = ['Apache-2.0', 'EPL-1.0', 'BSD-3-Clause', 
'EPL-2.0', 'MIT', 'MIT-0']
+
+        def pickLicense = { List licenses ->
+            if (!(licenses instanceof List) || licenses.isEmpty()) {
+                return null
+            }
+
+            def licenseIds = licenses.findAll { it instanceof Map && 
it.license instanceof Map && it.license.id }
+            def foundLicense = preferredLicenses.find { p -> licenseIds.any { 
it.license.id == p } }
+            if (foundLicense) {
+                return licenseIds.find { it.license.id == foundLicense }
+            }
+
+            licenses[0] // pick the first one found
+        }
+
+        def rewriteSbom = { File f ->
+            def bom = new JsonSlurper().parse(f)
+
+            // timestamp is not reproducible: 
https://github.com/CycloneDX/cyclonedx-gradle-plugin/issues/292
+            bom.metadata.timestamp = 
DateTimeFormatter.ISO_INSTANT.format(buildDate.truncatedTo(ChronoUnit.SECONDS))
+
+            // components[*].licenses
+            def comps = (bom instanceof Map && bom.components instanceof List) 
? bom.components : []
+            comps.each { c ->
+                if (c instanceof Map && c.licenses instanceof List && 
!c.licenses.isEmpty()) {
+                    def chosen = pickLicense(c.licenses as List)
+                    if (chosen != null) {
+                        c.licenses = [chosen]
+                    }
+                }
+            }
+
+            // force the serialNumber to be reproducible by removing it & 
recalculating
+            bom.serialNumber = ''
+            String withOutSerial = 
JsonOutput.prettyPrint(JsonOutput.toJson(bom))
+            def uuid = 
UUID.nameUUIDFromBytes(withOutSerial.getBytes(StandardCharsets.UTF_8.name()))
+            def urn = "urn:uuid:${uuid.toString()}" as String
+            bom.serialNumber = urn
+
+            f.setText(JsonOutput.prettyPrint(JsonOutput.toJson(bom)), 
StandardCharsets.UTF_8.name())
+
+            logger.info('Rewrote JSON SBOM ({}) to pick preferred license', 
project.relativePath(f))
+        }
+
+        sbomOutputLocation.get().with { rewriteSbom(it.asFile) }
+    }
+}
+
+// for now, we only publish the sbom inside of the binary jar (our bom 
projects won't have a jar file)
+pluginManager.withPlugin('java') {
+    if (!project.findProperty('skipJavaComponent')) {
+        tasks.named('jar', Jar).configure { Jar jar ->
+            jar.dependsOn tasks.named('cyclonedxBom')
+
+            jar.from(findProperty('sbomOutputLocation')) {
+                into('META-INF')
+                rename {
+                    'sbom.json'
+                }
+            }
+        }
+    }
+}
diff --git a/grails-async/core/build.gradle b/grails-async/core/build.gradle
index a9f35631a1..232e9f93b1 100644
--- a/grails-async/core/build.gradle
+++ b/grails-async/core/build.gradle
@@ -50,5 +50,6 @@ apply {
     from 
rootProject.layout.projectDirectory.file('gradle/code-style-config.gradle')
     from rootProject.layout.projectDirectory.file('gradle/docs-config.gradle')
     from 
rootProject.layout.projectDirectory.file('gradle/publish-config.gradle')
+    from rootProject.layout.projectDirectory.file('gradle/sbom-config.gradle')
     from rootProject.layout.projectDirectory.file('gradle/test-config.gradle')
 }
\ No newline at end of file
diff --git a/grails-async/gpars/build.gradle b/grails-async/gpars/build.gradle
index daeb08a922..029f1010eb 100644
--- a/grails-async/gpars/build.gradle
+++ b/grails-async/gpars/build.gradle
@@ -50,5 +50,6 @@ apply {
     from 
rootProject.layout.projectDirectory.file('gradle/code-style-config.gradle')
     from rootProject.layout.projectDirectory.file('gradle/docs-config.gradle')
     from 
rootProject.layout.projectDirectory.file('gradle/publish-config.gradle')
+    from rootProject.layout.projectDirectory.file('gradle/sbom-config.gradle')
     from rootProject.layout.projectDirectory.file('gradle/test-config.gradle')
 }
\ No newline at end of file
diff --git a/grails-async/plugin/build.gradle b/grails-async/plugin/build.gradle
index f4078b32cf..e6ce2a446b 100644
--- a/grails-async/plugin/build.gradle
+++ b/grails-async/plugin/build.gradle
@@ -60,5 +60,6 @@ apply {
     from 
rootProject.layout.projectDirectory.file('gradle/code-style-config.gradle')
     from rootProject.layout.projectDirectory.file('gradle/docs-config.gradle')
     from 
rootProject.layout.projectDirectory.file('gradle/publish-config.gradle')
+    from rootProject.layout.projectDirectory.file('gradle/sbom-config.gradle')
     from rootProject.layout.projectDirectory.file('gradle/test-config.gradle')
 }
\ No newline at end of file
diff --git a/grails-async/rxjava/build.gradle b/grails-async/rxjava/build.gradle
index 00a583c67f..38c28e84b2 100644
--- a/grails-async/rxjava/build.gradle
+++ b/grails-async/rxjava/build.gradle
@@ -46,5 +46,6 @@ apply {
     from 
rootProject.layout.projectDirectory.file('gradle/code-style-config.gradle')
     from rootProject.layout.projectDirectory.file('gradle/docs-config.gradle')
     from 
rootProject.layout.projectDirectory.file('gradle/publish-config.gradle')
+    from rootProject.layout.projectDirectory.file('gradle/sbom-config.gradle')
     from rootProject.layout.projectDirectory.file('gradle/test-config.gradle')
 }
\ No newline at end of file
diff --git a/grails-async/rxjava2/build.gradle 
b/grails-async/rxjava2/build.gradle
index 9f1cff3f12..ddcaf3bb71 100644
--- a/grails-async/rxjava2/build.gradle
+++ b/grails-async/rxjava2/build.gradle
@@ -46,5 +46,6 @@ apply {
     from 
rootProject.layout.projectDirectory.file('gradle/code-style-config.gradle')
     from rootProject.layout.projectDirectory.file('gradle/docs-config.gradle')
     from 
rootProject.layout.projectDirectory.file('gradle/publish-config.gradle')
+    from rootProject.layout.projectDirectory.file('gradle/sbom-config.gradle')
     from rootProject.layout.projectDirectory.file('gradle/test-config.gradle')
 }
\ No newline at end of file
diff --git a/grails-async/rxjava3/build.gradle 
b/grails-async/rxjava3/build.gradle
index 2cd8942622..7bd5445bf7 100644
--- a/grails-async/rxjava3/build.gradle
+++ b/grails-async/rxjava3/build.gradle
@@ -46,5 +46,6 @@ apply {
     from 
rootProject.layout.projectDirectory.file('gradle/code-style-config.gradle')
     from rootProject.layout.projectDirectory.file('gradle/docs-config.gradle')
     from 
rootProject.layout.projectDirectory.file('gradle/publish-config.gradle')
+    from rootProject.layout.projectDirectory.file('gradle/sbom-config.gradle')
     from rootProject.layout.projectDirectory.file('gradle/test-config.gradle')
 }
\ No newline at end of file
diff --git a/grails-bom/build.gradle b/grails-bom/build.gradle
index 3824ea2c98..88b8d7fb96 100644
--- a/grails-bom/build.gradle
+++ b/grails-bom/build.gradle
@@ -202,4 +202,5 @@ ext {
 
 apply {
     from 
rootProject.layout.projectDirectory.file('gradle/publish-config.gradle')
+    from rootProject.layout.projectDirectory.file('gradle/sbom-config.gradle')
 }
diff --git a/grails-bootstrap/build.gradle b/grails-bootstrap/build.gradle
index 15017ca16b..a6ae77322a 100644
--- a/grails-bootstrap/build.gradle
+++ b/grails-bootstrap/build.gradle
@@ -84,5 +84,6 @@ apply {
     from 
rootProject.layout.projectDirectory.file('gradle/code-style-config.gradle')
     from rootProject.layout.projectDirectory.file('gradle/docs-config.gradle')
     from 
rootProject.layout.projectDirectory.file('gradle/publish-config.gradle')
+    from rootProject.layout.projectDirectory.file('gradle/sbom-config.gradle')
     from rootProject.layout.projectDirectory.file('gradle/test-config.gradle')
 }
\ No newline at end of file
diff --git a/grails-cache/build.gradle b/grails-cache/build.gradle
index 89e5a3e35e..0b16f0a774 100644
--- a/grails-cache/build.gradle
+++ b/grails-cache/build.gradle
@@ -63,6 +63,7 @@ apply {
     from 
rootProject.layout.projectDirectory.file('gradle/code-style-config.gradle')
     from rootProject.layout.projectDirectory.file('gradle/docs-config.gradle')
     from 
rootProject.layout.projectDirectory.file('gradle/publish-config.gradle')
+    from rootProject.layout.projectDirectory.file('gradle/sbom-config.gradle')
     from rootProject.layout.projectDirectory.file('gradle/test-config.gradle')
     from 
rootProject.layout.projectDirectory.file('gradle/grails-extension-gradle-config.gradle')
 }
diff --git a/grails-codecs-core/build.gradle b/grails-codecs-core/build.gradle
index 662060b41d..ac7e542a38 100644
--- a/grails-codecs-core/build.gradle
+++ b/grails-codecs-core/build.gradle
@@ -57,5 +57,6 @@ apply {
     from 
rootProject.layout.projectDirectory.file('gradle/code-style-config.gradle')
     from rootProject.layout.projectDirectory.file('gradle/docs-config.gradle')
     from 
rootProject.layout.projectDirectory.file('gradle/publish-config.gradle')
+    from rootProject.layout.projectDirectory.file('gradle/sbom-config.gradle')
     from rootProject.layout.projectDirectory.file('gradle/test-config.gradle')
 }
\ No newline at end of file
diff --git a/grails-codecs/build.gradle b/grails-codecs/build.gradle
index 26eab116b0..0815e1cf1e 100644
--- a/grails-codecs/build.gradle
+++ b/grails-codecs/build.gradle
@@ -67,5 +67,6 @@ apply {
     from 
rootProject.layout.projectDirectory.file('gradle/code-style-config.gradle')
     from rootProject.layout.projectDirectory.file('gradle/docs-config.gradle')
     from 
rootProject.layout.projectDirectory.file('gradle/publish-config.gradle')
+    from rootProject.layout.projectDirectory.file('gradle/sbom-config.gradle')
     from rootProject.layout.projectDirectory.file('gradle/test-config.gradle')
 }
\ No newline at end of file
diff --git a/grails-common/build.gradle b/grails-common/build.gradle
index e30f95621a..378584eef7 100644
--- a/grails-common/build.gradle
+++ b/grails-common/build.gradle
@@ -58,5 +58,6 @@ apply {
     from 
rootProject.layout.projectDirectory.file('gradle/code-style-config.gradle')
     from rootProject.layout.projectDirectory.file('gradle/docs-config.gradle')
     from 
rootProject.layout.projectDirectory.file('gradle/publish-config.gradle')
+    from rootProject.layout.projectDirectory.file('gradle/sbom-config.gradle')
     from rootProject.layout.projectDirectory.file('gradle/test-config.gradle')
 }
\ No newline at end of file
diff --git a/grails-console/build.gradle b/grails-console/build.gradle
index a83ac41a46..55d6a5ed6a 100644
--- a/grails-console/build.gradle
+++ b/grails-console/build.gradle
@@ -70,4 +70,5 @@ apply {
     from 
rootProject.layout.projectDirectory.file('gradle/code-style-config.gradle')
     from rootProject.layout.projectDirectory.file('gradle/docs-config.gradle')
     from 
rootProject.layout.projectDirectory.file('gradle/publish-config.gradle')
+    from rootProject.layout.projectDirectory.file('gradle/sbom-config.gradle')
 }
\ No newline at end of file
diff --git a/grails-controllers/build.gradle b/grails-controllers/build.gradle
index 3d88b08a4e..d301da5c83 100644
--- a/grails-controllers/build.gradle
+++ b/grails-controllers/build.gradle
@@ -77,5 +77,6 @@ apply {
     from 
rootProject.layout.projectDirectory.file('gradle/code-style-config.gradle')
     from rootProject.layout.projectDirectory.file('gradle/docs-config.gradle')
     from 
rootProject.layout.projectDirectory.file('gradle/publish-config.gradle')
+    from rootProject.layout.projectDirectory.file('gradle/sbom-config.gradle')
     from rootProject.layout.projectDirectory.file('gradle/test-config.gradle')
 }
\ No newline at end of file
diff --git a/grails-converters/build.gradle b/grails-converters/build.gradle
index 182b6d6ed7..7012f9dede 100644
--- a/grails-converters/build.gradle
+++ b/grails-converters/build.gradle
@@ -76,5 +76,6 @@ apply {
     from 
rootProject.layout.projectDirectory.file('gradle/code-style-config.gradle')
     from rootProject.layout.projectDirectory.file('gradle/docs-config.gradle')
     from 
rootProject.layout.projectDirectory.file('gradle/publish-config.gradle')
+    from rootProject.layout.projectDirectory.file('gradle/sbom-config.gradle')
     from rootProject.layout.projectDirectory.file('gradle/test-config.gradle')
 }
\ No newline at end of file
diff --git a/grails-core/build.gradle b/grails-core/build.gradle
index 79a030fc6e..cc8f5277f7 100644
--- a/grails-core/build.gradle
+++ b/grails-core/build.gradle
@@ -95,5 +95,6 @@ apply {
     from 
rootProject.layout.projectDirectory.file('gradle/code-style-config.gradle')
     from rootProject.layout.projectDirectory.file('gradle/docs-config.gradle')
     from 
rootProject.layout.projectDirectory.file('gradle/publish-config.gradle')
+    from rootProject.layout.projectDirectory.file('gradle/sbom-config.gradle')
     from rootProject.layout.projectDirectory.file('gradle/test-config.gradle')
 }
\ No newline at end of file
diff --git a/grails-data-hibernate5/boot-plugin/build.gradle 
b/grails-data-hibernate5/boot-plugin/build.gradle
index 52e6497737..3e9993d234 100644
--- a/grails-data-hibernate5/boot-plugin/build.gradle
+++ b/grails-data-hibernate5/boot-plugin/build.gradle
@@ -62,5 +62,6 @@ apply {
     from 
rootProject.layout.projectDirectory.file('gradle/code-style-config.gradle')
     from 
rootProject.layout.projectDirectory.file('gradle/hibernate5-test-config.gradle')
     from 
rootProject.layout.projectDirectory.file('gradle/publish-config.gradle')
+    from rootProject.layout.projectDirectory.file('gradle/sbom-config.gradle')
     from rootProject.layout.projectDirectory.file('gradle/docs-config.gradle')
 }
diff --git a/grails-data-hibernate5/core/build.gradle 
b/grails-data-hibernate5/core/build.gradle
index db4d955201..9085f64c26 100644
--- a/grails-data-hibernate5/core/build.gradle
+++ b/grails-data-hibernate5/core/build.gradle
@@ -92,6 +92,7 @@ apply {
     from 
rootProject.layout.projectDirectory.file('gradle/code-style-config.gradle')
     from 
rootProject.layout.projectDirectory.file('gradle/hibernate5-test-config.gradle')
     from 
rootProject.layout.projectDirectory.file('gradle/publish-config.gradle')
+    from rootProject.layout.projectDirectory.file('gradle/sbom-config.gradle')
     from 
rootProject.layout.projectDirectory.file('gradle/grails-data-tck-config.gradle')
     from rootProject.layout.projectDirectory.file('gradle/docs-config.gradle')
 }
diff --git a/grails-data-hibernate5/dbmigration/build.gradle 
b/grails-data-hibernate5/dbmigration/build.gradle
index 790cc41c23..792e0683f8 100644
--- a/grails-data-hibernate5/dbmigration/build.gradle
+++ b/grails-data-hibernate5/dbmigration/build.gradle
@@ -109,6 +109,7 @@ apply {
     from 
rootProject.layout.projectDirectory.file('gradle/code-style-config.gradle')
     from 
rootProject.layout.projectDirectory.file('gradle/hibernate5-test-config.gradle')
     from 
rootProject.layout.projectDirectory.file('gradle/publish-config.gradle')
+    from rootProject.layout.projectDirectory.file('gradle/sbom-config.gradle')
     from rootProject.layout.projectDirectory.file('gradle/docs-config.gradle')
     from 
rootProject.layout.projectDirectory.file('gradle/grails-extension-gradle-config.gradle')
 }
diff --git a/grails-data-hibernate5/grails-plugin/build.gradle 
b/grails-data-hibernate5/grails-plugin/build.gradle
index 892d01db72..8b05552ffb 100644
--- a/grails-data-hibernate5/grails-plugin/build.gradle
+++ b/grails-data-hibernate5/grails-plugin/build.gradle
@@ -88,6 +88,7 @@ apply {
     from 
rootProject.layout.projectDirectory.file('gradle/code-style-config.gradle')
     from 
rootProject.layout.projectDirectory.file('gradle/hibernate5-test-config.gradle')
     from 
rootProject.layout.projectDirectory.file('gradle/publish-config.gradle')
+    from rootProject.layout.projectDirectory.file('gradle/sbom-config.gradle')
     from rootProject.layout.projectDirectory.file('gradle/docs-config.gradle')
     from 
rootProject.layout.projectDirectory.file('gradle/grails-extension-gradle-config.gradle')
 }
\ No newline at end of file
diff --git a/grails-data-mongodb/boot-plugin/build.gradle 
b/grails-data-mongodb/boot-plugin/build.gradle
index 84074347a8..d0e5ee8805 100644
--- a/grails-data-mongodb/boot-plugin/build.gradle
+++ b/grails-data-mongodb/boot-plugin/build.gradle
@@ -107,5 +107,6 @@ apply {
     from 
rootProject.layout.projectDirectory.file('gradle/code-style-config.gradle')
     from 
rootProject.layout.projectDirectory.file('gradle/mongodb-test-config.gradle')
     from 
rootProject.layout.projectDirectory.file('gradle/publish-config.gradle')
+    from rootProject.layout.projectDirectory.file('gradle/sbom-config.gradle')
     from rootProject.layout.projectDirectory.file('gradle/docs-config.gradle')
 }
\ No newline at end of file
diff --git a/grails-data-mongodb/bson/build.gradle 
b/grails-data-mongodb/bson/build.gradle
index dda142f567..dcd3ea8839 100644
--- a/grails-data-mongodb/bson/build.gradle
+++ b/grails-data-mongodb/bson/build.gradle
@@ -101,5 +101,6 @@ apply {
     from 
rootProject.layout.projectDirectory.file('gradle/code-style-config.gradle')
     from 
rootProject.layout.projectDirectory.file('gradle/mongodb-test-config.gradle')
     from 
rootProject.layout.projectDirectory.file('gradle/publish-config.gradle')
+    from rootProject.layout.projectDirectory.file('gradle/sbom-config.gradle')
     from rootProject.layout.projectDirectory.file('gradle/docs-config.gradle')
 }
\ No newline at end of file
diff --git a/grails-data-mongodb/core/build.gradle 
b/grails-data-mongodb/core/build.gradle
index 6c89d15666..1a46cbc741 100644
--- a/grails-data-mongodb/core/build.gradle
+++ b/grails-data-mongodb/core/build.gradle
@@ -154,6 +154,7 @@ apply {
     from 
rootProject.layout.projectDirectory.file('gradle/code-style-config.gradle')
     from 
rootProject.layout.projectDirectory.file('gradle/mongodb-forked-test-config.gradle')
     from 
rootProject.layout.projectDirectory.file('gradle/publish-config.gradle')
+    from rootProject.layout.projectDirectory.file('gradle/sbom-config.gradle')
     from 
rootProject.layout.projectDirectory.file('gradle/grails-data-tck-config.gradle')
     from rootProject.layout.projectDirectory.file('gradle/docs-config.gradle')
 }
\ No newline at end of file
diff --git a/grails-data-mongodb/ext/build.gradle 
b/grails-data-mongodb/ext/build.gradle
index e9ba4cd762..7a91a3a342 100644
--- a/grails-data-mongodb/ext/build.gradle
+++ b/grails-data-mongodb/ext/build.gradle
@@ -90,5 +90,6 @@ apply {
     from 
rootProject.layout.projectDirectory.file('gradle/code-style-config.gradle')
     from 
rootProject.layout.projectDirectory.file('gradle/mongodb-test-config.gradle')
     from 
rootProject.layout.projectDirectory.file('gradle/publish-config.gradle')
+    from rootProject.layout.projectDirectory.file('gradle/sbom-config.gradle')
     from rootProject.layout.projectDirectory.file('gradle/docs-config.gradle')
 }
diff --git a/grails-data-mongodb/grails-plugin/build.gradle 
b/grails-data-mongodb/grails-plugin/build.gradle
index 4d63343802..44aa696418 100644
--- a/grails-data-mongodb/grails-plugin/build.gradle
+++ b/grails-data-mongodb/grails-plugin/build.gradle
@@ -132,6 +132,7 @@ apply {
     from 
rootProject.layout.projectDirectory.file('gradle/code-style-config.gradle')
     from 
rootProject.layout.projectDirectory.file('gradle/mongodb-test-config.gradle')
     from 
rootProject.layout.projectDirectory.file('gradle/publish-config.gradle')
+    from rootProject.layout.projectDirectory.file('gradle/sbom-config.gradle')
     from rootProject.layout.projectDirectory.file('gradle/docs-config.gradle')
     from 
rootProject.layout.projectDirectory.file('gradle/grails-extension-gradle-config.gradle')
 }
diff --git a/grails-data-mongodb/gson-templates/build.gradle 
b/grails-data-mongodb/gson-templates/build.gradle
index d821432f53..77d121996e 100644
--- a/grails-data-mongodb/gson-templates/build.gradle
+++ b/grails-data-mongodb/gson-templates/build.gradle
@@ -72,5 +72,6 @@ apply {
     from 
rootProject.layout.projectDirectory.file('gradle/code-style-config.gradle')
     from 
rootProject.layout.projectDirectory.file('gradle/mongodb-test-config.gradle')
     from 
rootProject.layout.projectDirectory.file('gradle/publish-config.gradle')
+    from rootProject.layout.projectDirectory.file('gradle/sbom-config.gradle')
     from rootProject.layout.projectDirectory.file('gradle/docs-config.gradle')
 }
diff --git a/grails-data-simple/build.gradle b/grails-data-simple/build.gradle
index df43a6fef7..d83119f62b 100644
--- a/grails-data-simple/build.gradle
+++ b/grails-data-simple/build.gradle
@@ -95,6 +95,7 @@ apply {
     from rootProject.layout.projectDirectory.file('gradle/java-config.gradle')
     from 
rootProject.layout.projectDirectory.file('gradle/code-style-config.gradle')
     from 
rootProject.layout.projectDirectory.file('gradle/publish-config.gradle')
+    from rootProject.layout.projectDirectory.file('gradle/sbom-config.gradle')
     from rootProject.layout.projectDirectory.file('gradle/test-config.gradle')
     from rootProject.layout.projectDirectory.file('gradle/docs-config.gradle')
 }
diff --git a/grails-databinding-core/build.gradle 
b/grails-databinding-core/build.gradle
index 28a0551fbb..6dea9c0bba 100644
--- a/grails-databinding-core/build.gradle
+++ b/grails-databinding-core/build.gradle
@@ -60,5 +60,6 @@ apply {
     from 
rootProject.layout.projectDirectory.file('gradle/code-style-config.gradle')
     from rootProject.layout.projectDirectory.file('gradle/docs-config.gradle')
     from 
rootProject.layout.projectDirectory.file('gradle/publish-config.gradle')
+    from rootProject.layout.projectDirectory.file('gradle/sbom-config.gradle')
     from rootProject.layout.projectDirectory.file('gradle/test-config.gradle')
 }
\ No newline at end of file
diff --git a/grails-databinding/build.gradle b/grails-databinding/build.gradle
index 6261cef74a..8de6190d76 100644
--- a/grails-databinding/build.gradle
+++ b/grails-databinding/build.gradle
@@ -73,5 +73,6 @@ apply {
     from 
rootProject.layout.projectDirectory.file('gradle/code-style-config.gradle')
     from rootProject.layout.projectDirectory.file('gradle/docs-config.gradle')
     from 
rootProject.layout.projectDirectory.file('gradle/publish-config.gradle')
+    from rootProject.layout.projectDirectory.file('gradle/sbom-config.gradle')
     from rootProject.layout.projectDirectory.file('gradle/test-config.gradle')
 }
\ No newline at end of file
diff --git a/grails-datamapping-async/build.gradle 
b/grails-datamapping-async/build.gradle
index 9e707b50bb..da690bb3aa 100644
--- a/grails-datamapping-async/build.gradle
+++ b/grails-datamapping-async/build.gradle
@@ -77,5 +77,6 @@ apply {
     from 
rootProject.layout.projectDirectory.file('gradle/code-style-config.gradle')
     from rootProject.layout.projectDirectory.file('gradle/test-config.gradle')
     from 
rootProject.layout.projectDirectory.file('gradle/publish-config.gradle')
+    from rootProject.layout.projectDirectory.file('gradle/sbom-config.gradle')
     from rootProject.layout.projectDirectory.file('gradle/docs-config.gradle')
 }
diff --git a/grails-datamapping-core-test/build.gradle 
b/grails-datamapping-core-test/build.gradle
index e55f775f23..62807a753c 100644
--- a/grails-datamapping-core-test/build.gradle
+++ b/grails-datamapping-core-test/build.gradle
@@ -136,5 +136,6 @@ apply {
     from rootProject.layout.projectDirectory.file('gradle/java-config.gradle')
     from rootProject.layout.projectDirectory.file('gradle/test-config.gradle')
     from 
rootProject.layout.projectDirectory.file('gradle/publish-config.gradle')
+    from rootProject.layout.projectDirectory.file('gradle/sbom-config.gradle')
     from 
rootProject.layout.projectDirectory.file('gradle/grails-data-tck-config.gradle')
 }
diff --git a/grails-datamapping-core/build.gradle 
b/grails-datamapping-core/build.gradle
index 8295b2e69e..f0b29c7a66 100644
--- a/grails-datamapping-core/build.gradle
+++ b/grails-datamapping-core/build.gradle
@@ -121,5 +121,6 @@ apply {
     from 
rootProject.layout.projectDirectory.file('gradle/code-style-config.gradle')
     from rootProject.layout.projectDirectory.file('gradle/test-config.gradle')
     from 
rootProject.layout.projectDirectory.file('gradle/publish-config.gradle')
+    from rootProject.layout.projectDirectory.file('gradle/sbom-config.gradle')
     from rootProject.layout.projectDirectory.file('gradle/docs-config.gradle')
 }
diff --git a/grails-datamapping-rx/build.gradle 
b/grails-datamapping-rx/build.gradle
index fcaf4b5b6d..071b73757c 100644
--- a/grails-datamapping-rx/build.gradle
+++ b/grails-datamapping-rx/build.gradle
@@ -68,4 +68,5 @@ apply {
     from rootProject.layout.projectDirectory.file('gradle/test-config.gradle')
     from 
rootProject.layout.projectDirectory.file('gradle/publish-config.gradle')
     from rootProject.layout.projectDirectory.file('gradle/docs-config.gradle')
+    from rootProject.layout.projectDirectory.file('gradle/sbom-config.gradle')
 }
diff --git a/grails-datamapping-support/build.gradle 
b/grails-datamapping-support/build.gradle
index b4cec37d89..f7104cabf5 100644
--- a/grails-datamapping-support/build.gradle
+++ b/grails-datamapping-support/build.gradle
@@ -122,5 +122,6 @@ apply {
     from 
rootProject.layout.projectDirectory.file('gradle/code-style-config.gradle')
     from rootProject.layout.projectDirectory.file('gradle/test-config.gradle')
     from 
rootProject.layout.projectDirectory.file('gradle/publish-config.gradle')
+    from rootProject.layout.projectDirectory.file('gradle/sbom-config.gradle')
     from rootProject.layout.projectDirectory.file('gradle/docs-config.gradle')
 }
diff --git a/grails-datamapping-tck/build.gradle 
b/grails-datamapping-tck/build.gradle
index b6ace68d75..efaf3a8960 100644
--- a/grails-datamapping-tck/build.gradle
+++ b/grails-datamapping-tck/build.gradle
@@ -117,5 +117,6 @@ apply {
     from 
rootProject.layout.projectDirectory.file('gradle/code-style-config.gradle')
     from rootProject.layout.projectDirectory.file('gradle/docs-config.gradle')
     from 
rootProject.layout.projectDirectory.file('gradle/publish-config.gradle')
+    from rootProject.layout.projectDirectory.file('gradle/sbom-config.gradle')
     // do NOT do test configuration here, this is a TCK module
 }
diff --git a/grails-datamapping-validation/build.gradle 
b/grails-datamapping-validation/build.gradle
index cabf5e7304..41715343df 100644
--- a/grails-datamapping-validation/build.gradle
+++ b/grails-datamapping-validation/build.gradle
@@ -89,6 +89,7 @@ apply {
     from 
rootProject.layout.projectDirectory.file('gradle/code-style-config.gradle')
     from rootProject.layout.projectDirectory.file('gradle/test-config.gradle')
     from 
rootProject.layout.projectDirectory.file('gradle/publish-config.gradle')
+    from rootProject.layout.projectDirectory.file('gradle/sbom-config.gradle')
     from rootProject.layout.projectDirectory.file('gradle/docs-config.gradle')
 }
 
diff --git a/grails-datasource/build.gradle b/grails-datasource/build.gradle
index 969a788109..6fdaed7990 100644
--- a/grails-datasource/build.gradle
+++ b/grails-datasource/build.gradle
@@ -74,5 +74,6 @@ apply {
     from 
rootProject.layout.projectDirectory.file('gradle/code-style-config.gradle')
     from rootProject.layout.projectDirectory.file('gradle/docs-config.gradle')
     from 
rootProject.layout.projectDirectory.file('gradle/publish-config.gradle')
+    from rootProject.layout.projectDirectory.file('gradle/sbom-config.gradle')
     from rootProject.layout.projectDirectory.file('gradle/test-config.gradle')
 }
\ No newline at end of file
diff --git a/grails-datastore-async/build.gradle 
b/grails-datastore-async/build.gradle
index 6ad2d35cb4..bebb9e40f3 100644
--- a/grails-datastore-async/build.gradle
+++ b/grails-datastore-async/build.gradle
@@ -64,5 +64,6 @@ apply {
     from 
rootProject.layout.projectDirectory.file('gradle/code-style-config.gradle')
     from rootProject.layout.projectDirectory.file('gradle/test-config.gradle')
     from 
rootProject.layout.projectDirectory.file('gradle/publish-config.gradle')
+    from rootProject.layout.projectDirectory.file('gradle/sbom-config.gradle')
     from rootProject.layout.projectDirectory.file('gradle/docs-config.gradle')
 }
diff --git a/grails-datastore-core/build.gradle 
b/grails-datastore-core/build.gradle
index 87a2d91345..43e3445932 100644
--- a/grails-datastore-core/build.gradle
+++ b/grails-datastore-core/build.gradle
@@ -101,6 +101,7 @@ apply {
     from 
rootProject.layout.projectDirectory.file('gradle/code-style-config.gradle')
     from rootProject.layout.projectDirectory.file('gradle/test-config.gradle')
     from 
rootProject.layout.projectDirectory.file('gradle/publish-config.gradle')
+    from rootProject.layout.projectDirectory.file('gradle/sbom-config.gradle')
     from rootProject.layout.projectDirectory.file('gradle/docs-config.gradle')
 }
 
diff --git a/grails-datastore-web/build.gradle 
b/grails-datastore-web/build.gradle
index 995de819b8..1ab8c3d828 100644
--- a/grails-datastore-web/build.gradle
+++ b/grails-datastore-web/build.gradle
@@ -91,6 +91,7 @@ apply {
     from 
rootProject.layout.projectDirectory.file('gradle/code-style-config.gradle')
     from rootProject.layout.projectDirectory.file('gradle/test-config.gradle')
     from 
rootProject.layout.projectDirectory.file('gradle/publish-config.gradle')
+    from rootProject.layout.projectDirectory.file('gradle/sbom-config.gradle')
     from rootProject.layout.projectDirectory.file('gradle/docs-config.gradle')
 }
 
diff --git a/grails-dependencies/assets/build.gradle 
b/grails-dependencies/assets/build.gradle
index 3828cba182..5170e847b7 100644
--- a/grails-dependencies/assets/build.gradle
+++ b/grails-dependencies/assets/build.gradle
@@ -55,6 +55,7 @@ apply {
     // java-configuration must be applied first since tasks are now lazy 
registered
     from rootProject.layout.projectDirectory.file('gradle/java-config.gradle')
     from 
rootProject.layout.projectDirectory.file('gradle/publish-config.gradle')
+    from rootProject.layout.projectDirectory.file('gradle/sbom-config.gradle')
 }
 
 // these must be after the above applies because they opt out of the defaults 
created in those files
diff --git a/grails-dependencies/starter-web/build.gradle 
b/grails-dependencies/starter-web/build.gradle
index 45cb6206fd..d342b195bb 100644
--- a/grails-dependencies/starter-web/build.gradle
+++ b/grails-dependencies/starter-web/build.gradle
@@ -79,6 +79,7 @@ apply {
     // java-configuration must be applied first since tasks are now lazy 
registered
     from rootProject.layout.projectDirectory.file('gradle/java-config.gradle')
     from 
rootProject.layout.projectDirectory.file('gradle/publish-config.gradle')
+    from rootProject.layout.projectDirectory.file('gradle/sbom-config.gradle')
 }
 
 // these must be after the above applies because they opt out of the defaults 
created in those files
diff --git a/grails-dependencies/test/build.gradle 
b/grails-dependencies/test/build.gradle
index c6d539f3c4..2fd2b1b5ae 100644
--- a/grails-dependencies/test/build.gradle
+++ b/grails-dependencies/test/build.gradle
@@ -57,6 +57,7 @@ apply {
     // java-configuration must be applied first since tasks are now lazy 
registered
     from rootProject.layout.projectDirectory.file('gradle/java-config.gradle')
     from 
rootProject.layout.projectDirectory.file('gradle/publish-config.gradle')
+    from rootProject.layout.projectDirectory.file('gradle/sbom-config.gradle')
 }
 
 // these must be after the above applies because they opt out of the defaults 
created in those files
diff --git a/grails-domain-class/build.gradle b/grails-domain-class/build.gradle
index bae1bbd4a5..da3c19dd99 100644
--- a/grails-domain-class/build.gradle
+++ b/grails-domain-class/build.gradle
@@ -80,5 +80,6 @@ apply {
     from 
rootProject.layout.projectDirectory.file('gradle/code-style-config.gradle')
     from rootProject.layout.projectDirectory.file('gradle/docs-config.gradle')
     from 
rootProject.layout.projectDirectory.file('gradle/publish-config.gradle')
+    from rootProject.layout.projectDirectory.file('gradle/sbom-config.gradle')
     from rootProject.layout.projectDirectory.file('gradle/test-config.gradle')
 }
\ No newline at end of file
diff --git a/grails-encoder/build.gradle b/grails-encoder/build.gradle
index 90ad28fbcc..7534aa64ac 100644
--- a/grails-encoder/build.gradle
+++ b/grails-encoder/build.gradle
@@ -61,5 +61,6 @@ apply {
     from 
rootProject.layout.projectDirectory.file('gradle/code-style-config.gradle')
     from rootProject.layout.projectDirectory.file('gradle/docs-config.gradle')
     from 
rootProject.layout.projectDirectory.file('gradle/publish-config.gradle')
+    from rootProject.layout.projectDirectory.file('gradle/sbom-config.gradle')
     from rootProject.layout.projectDirectory.file('gradle/test-config.gradle')
 }
\ No newline at end of file
diff --git a/grails-events/compat/build.gradle 
b/grails-events/compat/build.gradle
index d9385c97dc..05c2bc6266 100644
--- a/grails-events/compat/build.gradle
+++ b/grails-events/compat/build.gradle
@@ -41,4 +41,5 @@ apply {
     from 
rootProject.layout.projectDirectory.file('gradle/code-style-config.gradle')
     from rootProject.layout.projectDirectory.file('gradle/docs-config.gradle')
     from 
rootProject.layout.projectDirectory.file('gradle/publish-config.gradle')
+    from rootProject.layout.projectDirectory.file('gradle/sbom-config.gradle')
 }
\ No newline at end of file
diff --git a/grails-events/core/build.gradle b/grails-events/core/build.gradle
index 6e72243d77..1197a28103 100644
--- a/grails-events/core/build.gradle
+++ b/grails-events/core/build.gradle
@@ -47,5 +47,6 @@ apply {
     from 
rootProject.layout.projectDirectory.file('gradle/code-style-config.gradle')
     from rootProject.layout.projectDirectory.file('gradle/docs-config.gradle')
     from 
rootProject.layout.projectDirectory.file('gradle/publish-config.gradle')
+    from rootProject.layout.projectDirectory.file('gradle/sbom-config.gradle')
     from rootProject.layout.projectDirectory.file('gradle/test-config.gradle')
 }
\ No newline at end of file
diff --git a/grails-events/gpars/build.gradle b/grails-events/gpars/build.gradle
index 6db7a2796b..91fc424c6c 100644
--- a/grails-events/gpars/build.gradle
+++ b/grails-events/gpars/build.gradle
@@ -48,5 +48,6 @@ apply {
     from 
rootProject.layout.projectDirectory.file('gradle/code-style-config.gradle')
     from rootProject.layout.projectDirectory.file('gradle/docs-config.gradle')
     from 
rootProject.layout.projectDirectory.file('gradle/publish-config.gradle')
+    from rootProject.layout.projectDirectory.file('gradle/sbom-config.gradle')
     from rootProject.layout.projectDirectory.file('gradle/test-config.gradle')
 }
\ No newline at end of file
diff --git a/grails-events/plugin/build.gradle 
b/grails-events/plugin/build.gradle
index cdd78d8d50..a537f25922 100644
--- a/grails-events/plugin/build.gradle
+++ b/grails-events/plugin/build.gradle
@@ -54,5 +54,6 @@ apply {
     from 
rootProject.layout.projectDirectory.file('gradle/code-style-config.gradle')
     from rootProject.layout.projectDirectory.file('gradle/docs-config.gradle')
     from 
rootProject.layout.projectDirectory.file('gradle/publish-config.gradle')
+    from rootProject.layout.projectDirectory.file('gradle/sbom-config.gradle')
     from rootProject.layout.projectDirectory.file('gradle/test-config.gradle')
 }
\ No newline at end of file
diff --git a/grails-events/rxjava/build.gradle 
b/grails-events/rxjava/build.gradle
index f5421639f9..40685b5cbc 100644
--- a/grails-events/rxjava/build.gradle
+++ b/grails-events/rxjava/build.gradle
@@ -51,5 +51,6 @@ apply {
     from 
rootProject.layout.projectDirectory.file('gradle/code-style-config.gradle')
     from rootProject.layout.projectDirectory.file('gradle/docs-config.gradle')
     from 
rootProject.layout.projectDirectory.file('gradle/publish-config.gradle')
+    from rootProject.layout.projectDirectory.file('gradle/sbom-config.gradle')
     from rootProject.layout.projectDirectory.file('gradle/test-config.gradle')
 }
\ No newline at end of file
diff --git a/grails-events/rxjava2/build.gradle 
b/grails-events/rxjava2/build.gradle
index da07f0bad5..245e965371 100644
--- a/grails-events/rxjava2/build.gradle
+++ b/grails-events/rxjava2/build.gradle
@@ -47,5 +47,6 @@ apply {
     from 
rootProject.layout.projectDirectory.file('gradle/code-style-config.gradle')
     from rootProject.layout.projectDirectory.file('gradle/docs-config.gradle')
     from 
rootProject.layout.projectDirectory.file('gradle/publish-config.gradle')
+    from rootProject.layout.projectDirectory.file('gradle/sbom-config.gradle')
     from rootProject.layout.projectDirectory.file('gradle/test-config.gradle')
 }
\ No newline at end of file
diff --git a/grails-events/rxjava3/build.gradle 
b/grails-events/rxjava3/build.gradle
index 836342bd77..7c88e271f3 100644
--- a/grails-events/rxjava3/build.gradle
+++ b/grails-events/rxjava3/build.gradle
@@ -47,5 +47,6 @@ apply {
     from 
rootProject.layout.projectDirectory.file('gradle/code-style-config.gradle')
     from rootProject.layout.projectDirectory.file('gradle/docs-config.gradle')
     from 
rootProject.layout.projectDirectory.file('gradle/publish-config.gradle')
+    from rootProject.layout.projectDirectory.file('gradle/sbom-config.gradle')
     from rootProject.layout.projectDirectory.file('gradle/test-config.gradle')
 }
\ No newline at end of file
diff --git a/grails-events/spring/build.gradle 
b/grails-events/spring/build.gradle
index 94bcb75699..6d58e8837c 100644
--- a/grails-events/spring/build.gradle
+++ b/grails-events/spring/build.gradle
@@ -47,5 +47,6 @@ apply {
     from 
rootProject.layout.projectDirectory.file('gradle/code-style-config.gradle')
     from rootProject.layout.projectDirectory.file('gradle/docs-config.gradle')
     from 
rootProject.layout.projectDirectory.file('gradle/publish-config.gradle')
+    from rootProject.layout.projectDirectory.file('gradle/sbom-config.gradle')
     from rootProject.layout.projectDirectory.file('gradle/test-config.gradle')
 }
\ No newline at end of file
diff --git a/grails-events/transforms/build.gradle 
b/grails-events/transforms/build.gradle
index 8312249c11..3b63b11540 100644
--- a/grails-events/transforms/build.gradle
+++ b/grails-events/transforms/build.gradle
@@ -64,5 +64,6 @@ apply {
     from 
rootProject.layout.projectDirectory.file('gradle/code-style-config.gradle')
     from rootProject.layout.projectDirectory.file('gradle/docs-config.gradle')
     from 
rootProject.layout.projectDirectory.file('gradle/publish-config.gradle')
+    from rootProject.layout.projectDirectory.file('gradle/sbom-config.gradle')
     from rootProject.layout.projectDirectory.file('gradle/test-config.gradle')
 }
\ No newline at end of file
diff --git a/grails-fields/build.gradle b/grails-fields/build.gradle
index 98bd1f6af4..9546dfd143 100644
--- a/grails-fields/build.gradle
+++ b/grails-fields/build.gradle
@@ -63,6 +63,7 @@ apply {
     from 
rootProject.layout.projectDirectory.file('gradle/code-style-config.gradle')
     from rootProject.layout.projectDirectory.file('gradle/docs-config.gradle')
     from 
rootProject.layout.projectDirectory.file('gradle/publish-config.gradle')
+    from rootProject.layout.projectDirectory.file('gradle/sbom-config.gradle')
     from rootProject.layout.projectDirectory.file('gradle/test-config.gradle')
     from 
rootProject.layout.projectDirectory.file('gradle/grails-extension-gradle-config.gradle')
 }
\ No newline at end of file
diff --git a/grails-forge/buildSrc/build.gradle 
b/grails-forge/buildSrc/build.gradle
index 4684886d05..70b37a785d 100644
--- a/grails-forge/buildSrc/build.gradle
+++ b/grails-forge/buildSrc/build.gradle
@@ -99,6 +99,7 @@ dependencies {
     implementation 
"org.gradle.crypto.checksum:org.gradle.crypto.checksum.gradle.plugin:$gradleChecksumPluginVersion"
     implementation "org.apache.ant:ant:$antVersion"
     implementation 
"org.apache.grails.gradle:grails-gradle-common:$projectVersion"
+    implementation 
"org.cyclonedx.bom:org.cyclonedx.bom.gradle.plugin:${rootProperties.gradleCycloneDxPluginVersion}"
 }
 
 gradlePlugin {
diff --git a/grails-forge/gradle/sbom-config.gradle 
b/grails-forge/gradle/sbom-config.gradle
new file mode 100644
index 0000000000..779e6ac1f3
--- /dev/null
+++ b/grails-forge/gradle/sbom-config.gradle
@@ -0,0 +1,143 @@
+/*
+ *  Licensed to the Apache Software Foundation (ASF) under one
+ *  or more contributor license agreements.  See the NOTICE file
+ *  distributed with this work for additional information
+ *  regarding copyright ownership.  The ASF licenses this file
+ *  to you under the Apache License, Version 2.0 (the
+ *  "License"); you may not use this file except in compliance
+ *  with the License.  You may obtain a copy of the License at
+ *
+ *    https://www.apache.org/licenses/LICENSE-2.0
+ *
+ *  Unless required by applicable law or agreed to in writing,
+ *  software distributed under the License is distributed on an
+ *  "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ *  KIND, either express or implied.  See the License for the
+ *  specific language governing permissions and limitations
+ *  under the License.
+ */
+
+import groovy.json.JsonOutput
+import groovy.json.JsonSlurper
+import org.cyclonedx.gradle.CycloneDxTask
+import org.cyclonedx.model.ExternalReference
+import org.cyclonedx.model.LicenseChoice
+import org.cyclonedx.model.License
+import org.cyclonedx.model.OrganizationalContact
+import org.cyclonedx.model.OrganizationalEntity
+import org.cyclonedx.model.Component
+
+import java.nio.charset.StandardCharsets
+import java.time.format.DateTimeFormatter
+import java.time.temporal.ChronoUnit
+
+apply plugin: 'org.cyclonedx.bom'
+
+project.ext.setProperty('sbomOutputLocation', 
project.layout.buildDirectory.file("${findProperty('pomArtifactId') ?: 
project.name}-${projectVersion}-sbom.json"))
+
+def sbomTask = tasks.named('cyclonedxBom', CycloneDxTask)
+sbomTask.configure { CycloneDxTask it ->
+    // the 2.x version of Cyclonedx uses a legacy syntax & helpers for setting 
inputs so the syntax below
+    // is required until the 3.x version is GA
+    it.setProjectType(findProperty('sbomProjectType') ?: 
Component.Type.FRAMEWORK.name())
+    [email protected](findProperty('pomArtifactId') ?: project.name)
+    [email protected](new OrganizationalEntity().tap {
+        name = 'Apache Software Foundation'
+        urls = ['https://www.apache.org/', 'https://security.apache.org/']
+        addContact(new OrganizationalContact().tap {
+            name = 'Apache Grails Development Team'
+            email = '[email protected]'
+        })
+    })
+    [email protected](new LicenseChoice().tap {
+        addLicense(new License().tap {
+            name = 'Apache-2.0'
+            url = 'https://www.apache.org/licenses/LICENSE-2.0.txt'
+        })
+    })
+
+    [email protected]([
+            new ExternalReference().tap {
+                url = 'https://grails.apache.org/'
+                type = ExternalReference.Type.WEBSITE
+            }
+    ])
+
+    // sboms are published for the purposes of vulnerability analysis so only 
include the runtime classpath
+    [email protected](['runtimeClasspath'])
+    [email protected](['compileClasspath', 'testRuntimeClasspath'])
+
+    // disable xml output
+    it.xmlOutput.unsetConvention()
+
+    def sbomOutputLocation = findProperty('sbomOutputLocation')
+    it.jsonOutput.set(sbomOutputLocation.get())
+    it.outputs.file(sbomOutputLocation)
+
+    // cyclonedx does not support "choosing" the license placed in the sbom
+    // see: https://github.com/CycloneDX/cyclonedx-gradle-plugin/issues/16
+    it.doLast {
+        def preferredLicenses = ['Apache-2.0', 'EPL-1.0', 'BSD-3-Clause', 
'EPL-2.0', 'MIT', 'MIT-0']
+
+        def pickLicense = { List licenses ->
+            if (!(licenses instanceof List) || licenses.isEmpty()) {
+                return null
+            }
+
+            def licenseIds = licenses.findAll { it instanceof Map && 
it.license instanceof Map && it.license.id }
+            def foundLicense = preferredLicenses.find { p -> licenseIds.any { 
it.license.id == p } }
+            if (foundLicense) {
+                return licenseIds.find { it.license.id == foundLicense }
+            }
+
+            licenses[0] // pick the first one found
+        }
+
+        def rewriteSbom = { File f ->
+            def bom = new JsonSlurper().parse(f)
+
+            // timestamp is not reproducible: 
https://github.com/CycloneDX/cyclonedx-gradle-plugin/issues/292
+            bom.metadata.timestamp = 
DateTimeFormatter.ISO_INSTANT.format(buildDate.truncatedTo(ChronoUnit.SECONDS))
+
+            // components[*].licenses
+            def comps = (bom instanceof Map && bom.components instanceof List) 
? bom.components : []
+            comps.each { c ->
+                if (c instanceof Map && c.licenses instanceof List && 
!c.licenses.isEmpty()) {
+                    def chosen = pickLicense(c.licenses as List)
+                    if (chosen != null) {
+                        c.licenses = [chosen]
+                    }
+                }
+            }
+
+            // force the serialNumber to be reproducible by removing it & 
recalculating
+            bom.serialNumber = ''
+            String withOutSerial = 
JsonOutput.prettyPrint(JsonOutput.toJson(bom))
+            def uuid = 
UUID.nameUUIDFromBytes(withOutSerial.getBytes(StandardCharsets.UTF_8.name()))
+            def urn = "urn:uuid:${uuid.toString()}" as String
+            bom.serialNumber = urn
+
+            f.setText(JsonOutput.prettyPrint(JsonOutput.toJson(bom)), 
StandardCharsets.UTF_8.name())
+
+            logger.info('Rewrote JSON SBOM ({}) to pick preferred license', 
project.relativePath(f))
+        }
+
+        sbomOutputLocation.get().with { rewriteSbom(it.asFile) }
+    }
+}
+
+// for now, we only publish the sbom inside of the binary jar (our bom 
projects won't have a jar file)
+pluginManager.withPlugin('java') {
+    if (!project.findProperty('skipJavaComponent')) {
+        tasks.named('jar', Jar).configure { Jar jar ->
+            jar.dependsOn tasks.named('cyclonedxBom')
+
+            jar.from(findProperty('sbomOutputLocation')) {
+                into('META-INF')
+                rename {
+                    'sbom.json'
+                }
+            }
+        }
+    }
+}
diff --git a/grails-forge/grails-cli/build.gradle 
b/grails-forge/grails-cli/build.gradle
index 59e79ba704..7a31e842ba 100644
--- a/grails-forge/grails-cli/build.gradle
+++ b/grails-forge/grails-cli/build.gradle
@@ -79,6 +79,7 @@ apply {
     from rootProject.layout.projectDirectory.file('gradle/java-config.gradle')
     from 
rootProject.layout.projectDirectory.file('gradle/code-style-config.gradle')
     from 
rootProject.layout.projectDirectory.file('gradle/publish-config.gradle')
+    from rootProject.layout.projectDirectory.file('gradle/sbom-config.gradle')
 }
 
 // It's surprisingly hard to generate start scripts and *not* have them nested 
into a bin / lib directory
diff --git a/grails-forge/grails-forge-cli/build.gradle 
b/grails-forge/grails-forge-cli/build.gradle
index 2422caec5a..27cd8fb037 100644
--- a/grails-forge/grails-forge-cli/build.gradle
+++ b/grails-forge/grails-forge-cli/build.gradle
@@ -111,6 +111,7 @@ apply {
     from rootProject.layout.projectDirectory.file('gradle/java-config.gradle')
     from 
rootProject.layout.projectDirectory.file('gradle/code-style-config.gradle')
     from 
rootProject.layout.projectDirectory.file('gradle/publish-config.gradle')
+    from rootProject.layout.projectDirectory.file('gradle/sbom-config.gradle')
     from rootProject.layout.projectDirectory.file('gradle/test-config.gradle')
     from rootProject.layout.projectDirectory.file('gradle/doc-config.gradle')
 }
diff --git a/grails-forge/grails-forge-core/build.gradle 
b/grails-forge/grails-forge-core/build.gradle
index ef008f864d..ca99b008ab 100644
--- a/grails-forge/grails-forge-core/build.gradle
+++ b/grails-forge/grails-forge-core/build.gradle
@@ -117,6 +117,7 @@ apply {
     from rootProject.layout.projectDirectory.file('gradle/java-config.gradle')
     from 
rootProject.layout.projectDirectory.file('gradle/code-style-config.gradle')
     from 
rootProject.layout.projectDirectory.file('gradle/publish-config.gradle')
+    from rootProject.layout.projectDirectory.file('gradle/sbom-config.gradle')
     from rootProject.layout.projectDirectory.file('gradle/test-config.gradle')
     from rootProject.layout.projectDirectory.file('gradle/doc-config.gradle')
 }
diff --git a/grails-geb/build.gradle b/grails-geb/build.gradle
index 52428c07dd..857eb49b2c 100644
--- a/grails-geb/build.gradle
+++ b/grails-geb/build.gradle
@@ -68,6 +68,7 @@ apply {
     from 
rootProject.layout.projectDirectory.file('gradle/code-style-config.gradle')
     from rootProject.layout.projectDirectory.file('gradle/docs-config.gradle')
     from 
rootProject.layout.projectDirectory.file('gradle/publish-config.gradle')
+    from rootProject.layout.projectDirectory.file('gradle/sbom-config.gradle')
     from rootProject.layout.projectDirectory.file('gradle/test-config.gradle')
     from 
rootProject.layout.projectDirectory.file('gradle/grails-extension-gradle-config.gradle')
 }
\ No newline at end of file
diff --git a/grails-gradle/bom/build.gradle b/grails-gradle/bom/build.gradle
index 6dfe37f740..64c087c1fe 100644
--- a/grails-gradle/bom/build.gradle
+++ b/grails-gradle/bom/build.gradle
@@ -165,4 +165,5 @@ ext {
 
 apply {
     from 
rootProject.layout.projectDirectory.file('gradle/publish-config.gradle')
+    from rootProject.layout.projectDirectory.file('gradle/sbom-config.gradle')
 }
diff --git a/grails-gradle/buildSrc/build.gradle 
b/grails-gradle/buildSrc/build.gradle
index 6595dd9274..5aabb66841 100644
--- a/grails-gradle/buildSrc/build.gradle
+++ b/grails-gradle/buildSrc/build.gradle
@@ -64,4 +64,5 @@ file('../../gradle.properties').withInputStream {
 dependencies {
     implementation "${gradleBomDependencies['grails-publish-plugin']}"
     implementation 
"org.gradle.crypto.checksum:org.gradle.crypto.checksum.gradle.plugin:${gradleProperties.gradleChecksumPluginVersion}"
+    implementation 
"org.cyclonedx.bom:org.cyclonedx.bom.gradle.plugin:${gradleProperties.gradleCycloneDxPluginVersion}"
 }
\ No newline at end of file
diff --git a/grails-gradle/common/build.gradle 
b/grails-gradle/common/build.gradle
index b6cb6281e4..f1c840bfa1 100644
--- a/grails-gradle/common/build.gradle
+++ b/grails-gradle/common/build.gradle
@@ -54,4 +54,5 @@ apply {
     from rootProject.layout.projectDirectory.file('gradle/docs-config.gradle')
     from 
rootProject.layout.projectDirectory.file('gradle/publish-config.gradle')
     from rootProject.layout.projectDirectory.file('gradle/test-config.gradle')
+    from rootProject.layout.projectDirectory.file('gradle/sbom-config.gradle')
 }
\ No newline at end of file
diff --git a/grails-gradle/docs-core/build.gradle 
b/grails-gradle/docs-core/build.gradle
index 92d81c72ab..b98045ea34 100644
--- a/grails-gradle/docs-core/build.gradle
+++ b/grails-gradle/docs-core/build.gradle
@@ -33,6 +33,7 @@ configurations {
 
 ext {
     pomDescription = 'Support for Grails documentation generation in Gradle 
builds.'
+    sbomProjectType = org.cyclonedx.model.Component.Type.LIBRARY.name()
 }
 
 dependencies {
@@ -91,4 +92,5 @@ apply {
     from rootProject.layout.projectDirectory.file('gradle/docs-config.gradle')
     from rootProject.layout.projectDirectory.file('gradle/test-config.gradle')
     from 
rootProject.layout.projectDirectory.file('gradle/publish-config.gradle')
+    from rootProject.layout.projectDirectory.file('gradle/sbom-config.gradle')
 }
\ No newline at end of file
diff --git a/grails-gradle/gradle/sbom-config.gradle 
b/grails-gradle/gradle/sbom-config.gradle
new file mode 100644
index 0000000000..bab4a25f05
--- /dev/null
+++ b/grails-gradle/gradle/sbom-config.gradle
@@ -0,0 +1,143 @@
+/*
+ *  Licensed to the Apache Software Foundation (ASF) under one
+ *  or more contributor license agreements.  See the NOTICE file
+ *  distributed with this work for additional information
+ *  regarding copyright ownership.  The ASF licenses this file
+ *  to you under the Apache License, Version 2.0 (the
+ *  "License"); you may not use this file except in compliance
+ *  with the License.  You may obtain a copy of the License at
+ *
+ *    https://www.apache.org/licenses/LICENSE-2.0
+ *
+ *  Unless required by applicable law or agreed to in writing,
+ *  software distributed under the License is distributed on an
+ *  "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ *  KIND, either express or implied.  See the License for the
+ *  specific language governing permissions and limitations
+ *  under the License.
+ */
+
+import groovy.json.JsonOutput
+import groovy.json.JsonSlurper
+import org.cyclonedx.gradle.CycloneDxTask
+import org.cyclonedx.model.ExternalReference
+import org.cyclonedx.model.LicenseChoice
+import org.cyclonedx.model.License
+import org.cyclonedx.model.OrganizationalContact
+import org.cyclonedx.model.OrganizationalEntity
+import org.cyclonedx.model.Component
+
+import java.nio.charset.StandardCharsets
+import java.time.format.DateTimeFormatter
+import java.time.temporal.ChronoUnit
+
+apply plugin: 'org.cyclonedx.bom'
+
+project.ext.setProperty('sbomOutputLocation', 
project.layout.buildDirectory.file("${findProperty('pomArtifactId') ?: 
project.name}-${projectVersion}-sbom.json"))
+
+def sbomTask = tasks.named('cyclonedxBom', CycloneDxTask)
+sbomTask.configure { CycloneDxTask it ->
+    // the 2.x version of Cyclonedx uses a legacy syntax & helpers for setting 
inputs so the syntax below
+    // is required until the 3.x version is GA
+    it.setProjectType(findProperty('sbomProjectType') ?: 
Component.Type.FRAMEWORK.name())
+    [email protected](findProperty('pomArtifactId') ?: project.name)
+    [email protected](new OrganizationalEntity().tap {
+        name = 'Apache Software Foundation'
+        urls = ['https://www.apache.org/', 'https://security.apache.org/']
+        addContact(new OrganizationalContact().tap {
+            name = 'Apache Grails Development Team'
+            email = '[email protected]'
+        })
+    })
+    [email protected](new LicenseChoice().tap {
+        addLicense(new License().tap {
+            name = 'Apache-2.0'
+            url = 'https://www.apache.org/licenses/LICENSE-2.0.txt'
+        })
+    })
+
+    [email protected]([
+            new ExternalReference().tap {
+                url = 'https://grails.apache.org/'
+                type = ExternalReference.Type.WEBSITE
+            }
+    ])
+
+    // sboms are published for the purposes of vulnerability analysis so only 
include the runtime classpath
+    [email protected](['runtimeClasspath'])
+    [email protected](['compileClasspath', 'testRuntimeClasspath'])
+
+    // disable xml output
+    it.xmlOutput.unsetConvention()
+
+    def sbomOutputLocation = findProperty('sbomOutputLocation')
+    it.jsonOutput.set(sbomOutputLocation.get())
+    it.outputs.file(sbomOutputLocation)
+
+    // cyclonedx does not support "choosing" the license placed in the sbom
+    // see: https://github.com/CycloneDX/cyclonedx-gradle-plugin/issues/16
+    it.doLast {
+        def preferredLicenses = ['Apache-2.0', 'EPL-1.0', 'BSD-3-Clause', 
'EPL-2.0', 'MIT', 'MIT-0']
+
+        def pickLicense = { List licenses ->
+            if (!(licenses instanceof List) || licenses.isEmpty()) {
+                return null
+            }
+
+            def licenseIds = licenses.findAll { it instanceof Map && 
it.license instanceof Map && it.license.id }
+            def foundLicense = preferredLicenses.find { p -> licenseIds.any { 
it.license.id == p } }
+            if (foundLicense) {
+                return licenseIds.find { it.license.id == foundLicense }
+            }
+
+            licenses[0] // pick the first one found
+        }
+
+        def rewriteSbom = { File f ->
+            def bom = new JsonSlurper().parse(f)
+
+            // timestamp is not reproducible: 
https://github.com/CycloneDX/cyclonedx-gradle-plugin/issues/292
+            bom.metadata.timestamp = 
DateTimeFormatter.ISO_INSTANT.format(buildDate.truncatedTo(ChronoUnit.SECONDS))
+
+            // components[*].licenses
+            def comps = (bom instanceof Map && bom.components instanceof List) 
? bom.components : []
+            comps.each { c ->
+                if (c instanceof Map && c.licenses instanceof List && 
!c.licenses.isEmpty()) {
+                    def chosen = pickLicense(c.licenses as List)
+                    if (chosen != null) {
+                        c.licenses = [chosen]
+                    }
+                }
+            }
+
+            // force the serialNumber to be reproducible by removing it & 
recalculating
+            bom.serialNumber = ''
+            String withOutSerial = 
JsonOutput.prettyPrint(JsonOutput.toJson(bom))
+            def uuid = 
UUID.nameUUIDFromBytes(withOutSerial.getBytes(StandardCharsets.UTF_8.name()))
+            def urn = "urn:uuid:${uuid.toString()}" as String
+            bom.serialNumber = urn
+
+            f.setText(JsonOutput.prettyPrint(JsonOutput.toJson(bom)), 
StandardCharsets.UTF_8.name())
+
+            logger.info('Rewrote JSON SBOM ({}) to pick preferred license', 
project.relativePath(f))
+        }
+
+        sbomOutputLocation.get().with { rewriteSbom(it.asFile) }
+    }
+}
+
+// for now, we only publish the sbom inside of the binary jar (our bom 
projects won't have a jar file nor will starters that just collect dependencies)
+pluginManager.withPlugin('java') {
+    if (!project.findProperty('skipJavaComponent')) {
+        tasks.named('jar', Jar).configure { Jar jar ->
+            jar.dependsOn tasks.named('cyclonedxBom')
+
+            jar.from(findProperty('sbomOutputLocation')) {
+                into('META-INF')
+                rename {
+                    'sbom.json'
+                }
+            }
+        }
+    }
+}
diff --git a/grails-gradle/model/build.gradle b/grails-gradle/model/build.gradle
index 5ee6d02e96..08c5fa86c6 100644
--- a/grails-gradle/model/build.gradle
+++ b/grails-gradle/model/build.gradle
@@ -31,6 +31,7 @@ ext {
     pomTitle = 'Grails Gradle Model'
     pomDescription = 'Classes to support the Grails Gradle Plugins'
     pomDevelopers = [graemerocher: 'Graeme Rocher']
+    sbomProjectType = org.cyclonedx.model.Component.Type.LIBRARY.name()
 }
 
 dependencies {
@@ -80,4 +81,5 @@ apply {
     from rootProject.layout.projectDirectory.file('gradle/docs-config.gradle')
     from rootProject.layout.projectDirectory.file('gradle/test-config.gradle')
     from 
rootProject.layout.projectDirectory.file('gradle/publish-config.gradle')
+    from rootProject.layout.projectDirectory.file('gradle/sbom-config.gradle')
 }
\ No newline at end of file
diff --git a/grails-gradle/plugins/build.gradle 
b/grails-gradle/plugins/build.gradle
index 01b230951e..68b8cda97b 100644
--- a/grails-gradle/plugins/build.gradle
+++ b/grails-gradle/plugins/build.gradle
@@ -124,4 +124,5 @@ apply {
     from 
rootProject.layout.projectDirectory.file('gradle/code-style-config.gradle')
     from rootProject.layout.projectDirectory.file('gradle/docs-config.gradle')
     from 
rootProject.layout.projectDirectory.file('gradle/publish-config.gradle')
+    from rootProject.layout.projectDirectory.file('gradle/sbom-config.gradle')
 }
diff --git a/grails-gradle/tasks/build.gradle b/grails-gradle/tasks/build.gradle
index 8e20aeb902..e72a1d82e6 100644
--- a/grails-gradle/tasks/build.gradle
+++ b/grails-gradle/tasks/build.gradle
@@ -29,6 +29,7 @@ group = 'org.apache.grails'
 ext {
     pomTitle = 'Grails Gradle Tasks'
     pomDescription = 'Various bundled Gradle tasks for Grails projects'
+    sbomProjectType = org.cyclonedx.model.Component.Type.LIBRARY.name()
 }
 
 dependencies {
@@ -52,4 +53,5 @@ apply {
     from rootProject.layout.projectDirectory.file('gradle/docs-config.gradle')
     from rootProject.layout.projectDirectory.file('gradle/test-config.gradle')
     from 
rootProject.layout.projectDirectory.file('gradle/publish-config.gradle')
+    from rootProject.layout.projectDirectory.file('gradle/sbom-config.gradle')
 }
\ No newline at end of file
diff --git a/grails-gsp/core/build.gradle b/grails-gsp/core/build.gradle
index 07b4d5a5f1..b9acca589b 100644
--- a/grails-gsp/core/build.gradle
+++ b/grails-gsp/core/build.gradle
@@ -93,5 +93,6 @@ apply {
     from 
rootProject.layout.projectDirectory.file('gradle/code-style-config.gradle')
     from rootProject.layout.projectDirectory.file('gradle/docs-config.gradle')
     from 
rootProject.layout.projectDirectory.file('gradle/publish-config.gradle')
+    from rootProject.layout.projectDirectory.file('gradle/sbom-config.gradle')
     from rootProject.layout.projectDirectory.file('gradle/test-config.gradle')
 }
\ No newline at end of file
diff --git a/grails-gsp/grails-layout/build.gradle 
b/grails-gsp/grails-layout/build.gradle
index 7a1403ac62..389897eefb 100644
--- a/grails-gsp/grails-layout/build.gradle
+++ b/grails-gsp/grails-layout/build.gradle
@@ -64,6 +64,7 @@ apply {
     from 
rootProject.layout.projectDirectory.file('gradle/code-style-config.gradle')
     from rootProject.layout.projectDirectory.file('gradle/docs-config.gradle')
     from 
rootProject.layout.projectDirectory.file('gradle/publish-config.gradle')
+    from rootProject.layout.projectDirectory.file('gradle/sbom-config.gradle')
     from rootProject.layout.projectDirectory.file('gradle/test-config.gradle')
     from 
rootProject.layout.projectDirectory.file('gradle/grails-extension-gradle-config.gradle')
 }
\ No newline at end of file
diff --git a/grails-gsp/grails-sitemesh3/build.gradle 
b/grails-gsp/grails-sitemesh3/build.gradle
index 5453a52427..edbe66e4fb 100644
--- a/grails-gsp/grails-sitemesh3/build.gradle
+++ b/grails-gsp/grails-sitemesh3/build.gradle
@@ -85,6 +85,7 @@ apply {
     from 
rootProject.layout.projectDirectory.file('gradle/code-style-config.gradle')
     from rootProject.layout.projectDirectory.file('gradle/docs-config.gradle')
     from 
rootProject.layout.projectDirectory.file('gradle/publish-config.gradle')
+    from rootProject.layout.projectDirectory.file('gradle/sbom-config.gradle')
     from rootProject.layout.projectDirectory.file('gradle/test-config.gradle')
     from 
rootProject.layout.projectDirectory.file('gradle/grails-extension-gradle-config.gradle')
 }
\ No newline at end of file
diff --git a/grails-gsp/grails-taglib/build.gradle 
b/grails-gsp/grails-taglib/build.gradle
index ca0d47a9aa..09f4fe203c 100644
--- a/grails-gsp/grails-taglib/build.gradle
+++ b/grails-gsp/grails-taglib/build.gradle
@@ -84,5 +84,6 @@ apply {
     from 
rootProject.layout.projectDirectory.file('gradle/code-style-config.gradle')
     from rootProject.layout.projectDirectory.file('gradle/docs-config.gradle')
     from 
rootProject.layout.projectDirectory.file('gradle/publish-config.gradle')
+    from rootProject.layout.projectDirectory.file('gradle/sbom-config.gradle')
     from rootProject.layout.projectDirectory.file('gradle/test-config.gradle')
 }
diff --git a/grails-gsp/grails-web-gsp-taglib/build.gradle 
b/grails-gsp/grails-web-gsp-taglib/build.gradle
index a566d7346b..5e4b6d7ae4 100644
--- a/grails-gsp/grails-web-gsp-taglib/build.gradle
+++ b/grails-gsp/grails-web-gsp-taglib/build.gradle
@@ -63,5 +63,6 @@ apply {
     from 
rootProject.layout.projectDirectory.file('gradle/code-style-config.gradle')
     from rootProject.layout.projectDirectory.file('gradle/docs-config.gradle')
     from 
rootProject.layout.projectDirectory.file('gradle/publish-config.gradle')
+    from rootProject.layout.projectDirectory.file('gradle/sbom-config.gradle')
     from rootProject.layout.projectDirectory.file('gradle/test-config.gradle')
 }
diff --git a/grails-gsp/grails-web-gsp/build.gradle 
b/grails-gsp/grails-web-gsp/build.gradle
index 5fdf157503..dd1050a901 100644
--- a/grails-gsp/grails-web-gsp/build.gradle
+++ b/grails-gsp/grails-web-gsp/build.gradle
@@ -131,5 +131,6 @@ apply {
     from 
rootProject.layout.projectDirectory.file('gradle/code-style-config.gradle')
     from rootProject.layout.projectDirectory.file('gradle/docs-config.gradle')
     from 
rootProject.layout.projectDirectory.file('gradle/publish-config.gradle')
+    from rootProject.layout.projectDirectory.file('gradle/sbom-config.gradle')
     from rootProject.layout.projectDirectory.file('gradle/test-config.gradle')
 }
diff --git a/grails-gsp/grails-web-jsp/build.gradle 
b/grails-gsp/grails-web-jsp/build.gradle
index d2ac2fcedf..c4420a7db0 100644
--- a/grails-gsp/grails-web-jsp/build.gradle
+++ b/grails-gsp/grails-web-jsp/build.gradle
@@ -112,5 +112,6 @@ apply {
     from 
rootProject.layout.projectDirectory.file('gradle/code-style-config.gradle')
     from rootProject.layout.projectDirectory.file('gradle/docs-config.gradle')
     from 
rootProject.layout.projectDirectory.file('gradle/publish-config.gradle')
+    from rootProject.layout.projectDirectory.file('gradle/sbom-config.gradle')
     from rootProject.layout.projectDirectory.file('gradle/test-config.gradle')
 }
diff --git a/grails-gsp/grails-web-taglib/build.gradle 
b/grails-gsp/grails-web-taglib/build.gradle
index 3e646f238a..ba730c2ac3 100644
--- a/grails-gsp/grails-web-taglib/build.gradle
+++ b/grails-gsp/grails-web-taglib/build.gradle
@@ -116,5 +116,6 @@ apply {
     from 
rootProject.layout.projectDirectory.file('gradle/code-style-config.gradle')
     from rootProject.layout.projectDirectory.file('gradle/docs-config.gradle')
     from 
rootProject.layout.projectDirectory.file('gradle/publish-config.gradle')
+    from rootProject.layout.projectDirectory.file('gradle/sbom-config.gradle')
     from rootProject.layout.projectDirectory.file('gradle/test-config.gradle')
 }
\ No newline at end of file
diff --git a/grails-gsp/plugin/build.gradle b/grails-gsp/plugin/build.gradle
index 5b2320d89e..8903ee9d0a 100644
--- a/grails-gsp/plugin/build.gradle
+++ b/grails-gsp/plugin/build.gradle
@@ -184,6 +184,7 @@ apply {
     from 
rootProject.layout.projectDirectory.file('gradle/code-style-config.gradle')
     from rootProject.layout.projectDirectory.file('gradle/docs-config.gradle')
     from 
rootProject.layout.projectDirectory.file('gradle/publish-config.gradle')
+    from rootProject.layout.projectDirectory.file('gradle/sbom-config.gradle')
     from rootProject.layout.projectDirectory.file('gradle/test-config.gradle')
     from 
rootProject.layout.projectDirectory.file('gradle/grails-extension-gradle-config.gradle')
 }
diff --git a/grails-i18n/build.gradle b/grails-i18n/build.gradle
index 5575f1bcc6..707abd5fd0 100644
--- a/grails-i18n/build.gradle
+++ b/grails-i18n/build.gradle
@@ -67,4 +67,5 @@ apply {
     from 
rootProject.layout.projectDirectory.file('gradle/code-style-config.gradle')
     from rootProject.layout.projectDirectory.file('gradle/docs-config.gradle')
     from 
rootProject.layout.projectDirectory.file('gradle/publish-config.gradle')
+    from rootProject.layout.projectDirectory.file('gradle/sbom-config.gradle')
 }
\ No newline at end of file
diff --git a/grails-interceptors/build.gradle b/grails-interceptors/build.gradle
index 178cc862cb..023bf496ff 100644
--- a/grails-interceptors/build.gradle
+++ b/grails-interceptors/build.gradle
@@ -66,5 +66,6 @@ apply {
     from 
rootProject.layout.projectDirectory.file('gradle/code-style-config.gradle')
     from rootProject.layout.projectDirectory.file('gradle/docs-config.gradle')
     from 
rootProject.layout.projectDirectory.file('gradle/publish-config.gradle')
+    from rootProject.layout.projectDirectory.file('gradle/sbom-config.gradle')
     from rootProject.layout.projectDirectory.file('gradle/test-config.gradle')
 }
\ No newline at end of file
diff --git a/grails-logging/build.gradle b/grails-logging/build.gradle
index beef4f2268..d0c256a007 100644
--- a/grails-logging/build.gradle
+++ b/grails-logging/build.gradle
@@ -57,5 +57,6 @@ apply {
     from 
rootProject.layout.projectDirectory.file('gradle/code-style-config.gradle')
     from rootProject.layout.projectDirectory.file('gradle/docs-config.gradle')
     from 
rootProject.layout.projectDirectory.file('gradle/publish-config.gradle')
+    from rootProject.layout.projectDirectory.file('gradle/sbom-config.gradle')
     from rootProject.layout.projectDirectory.file('gradle/test-config.gradle')
 }
\ No newline at end of file
diff --git a/grails-micronaut/build.gradle b/grails-micronaut/build.gradle
index 8648a52771..21cfa03d6f 100644
--- a/grails-micronaut/build.gradle
+++ b/grails-micronaut/build.gradle
@@ -45,4 +45,5 @@ apply {
     from rootProject.layout.projectDirectory.file('gradle/java-config.gradle')
     from rootProject.layout.projectDirectory.file('gradle/docs-config.gradle')
     from 
rootProject.layout.projectDirectory.file('gradle/publish-config.gradle')
+    from rootProject.layout.projectDirectory.file('gradle/sbom-config.gradle')
 }
\ No newline at end of file
diff --git a/grails-mimetypes/build.gradle b/grails-mimetypes/build.gradle
index 4fb2f63bec..ddac43902a 100644
--- a/grails-mimetypes/build.gradle
+++ b/grails-mimetypes/build.gradle
@@ -65,5 +65,6 @@ apply {
     from 
rootProject.layout.projectDirectory.file('gradle/code-style-config.gradle')
     from rootProject.layout.projectDirectory.file('gradle/docs-config.gradle')
     from 
rootProject.layout.projectDirectory.file('gradle/publish-config.gradle')
+    from rootProject.layout.projectDirectory.file('gradle/sbom-config.gradle')
     from rootProject.layout.projectDirectory.file('gradle/test-config.gradle')
 }
\ No newline at end of file
diff --git a/grails-profiles/base/build.gradle 
b/grails-profiles/base/build.gradle
index 305150a2bb..c8139b9999 100644
--- a/grails-profiles/base/build.gradle
+++ b/grails-profiles/base/build.gradle
@@ -60,4 +60,5 @@ tasks.named('compileProfile').configure {
 
 apply {
     from 
rootProject.layout.projectDirectory.file('gradle/publish-config.gradle')
+    from rootProject.layout.projectDirectory.file('gradle/sbom-config.gradle')
 }
\ No newline at end of file
diff --git a/grails-profiles/plugin/build.gradle 
b/grails-profiles/plugin/build.gradle
index c20f6499d3..a52fd75f3f 100644
--- a/grails-profiles/plugin/build.gradle
+++ b/grails-profiles/plugin/build.gradle
@@ -34,4 +34,5 @@ dependencies {
 
 apply {
     from 
rootProject.layout.projectDirectory.file('gradle/publish-config.gradle')
+    from rootProject.layout.projectDirectory.file('gradle/sbom-config.gradle')
 }
\ No newline at end of file
diff --git a/grails-profiles/profile/build.gradle 
b/grails-profiles/profile/build.gradle
index 7c62b1c9c4..30d5c394e7 100644
--- a/grails-profiles/profile/build.gradle
+++ b/grails-profiles/profile/build.gradle
@@ -54,4 +54,5 @@ tasks.named('compileProfile').configure {
 
 apply {
        from 
rootProject.layout.projectDirectory.file('gradle/publish-config.gradle')
+       from 
rootProject.layout.projectDirectory.file('gradle/sbom-config.gradle')
 }
\ No newline at end of file
diff --git a/grails-profiles/rest-api-plugin/build.gradle 
b/grails-profiles/rest-api-plugin/build.gradle
index 136581327e..42979ed9fb 100644
--- a/grails-profiles/rest-api-plugin/build.gradle
+++ b/grails-profiles/rest-api-plugin/build.gradle
@@ -35,4 +35,5 @@ dependencies {
 
 apply {
        from 
rootProject.layout.projectDirectory.file('gradle/publish-config.gradle')
+       from 
rootProject.layout.projectDirectory.file('gradle/sbom-config.gradle')
 }
\ No newline at end of file
diff --git a/grails-profiles/rest-api/build.gradle 
b/grails-profiles/rest-api/build.gradle
index c257beb5be..ea994484a8 100644
--- a/grails-profiles/rest-api/build.gradle
+++ b/grails-profiles/rest-api/build.gradle
@@ -34,4 +34,5 @@ dependencies {
 
 apply {
     from 
rootProject.layout.projectDirectory.file('gradle/publish-config.gradle')
+    from rootProject.layout.projectDirectory.file('gradle/sbom-config.gradle')
 }
\ No newline at end of file
diff --git a/grails-profiles/web-plugin/build.gradle 
b/grails-profiles/web-plugin/build.gradle
index ffed8372fe..614567b345 100644
--- a/grails-profiles/web-plugin/build.gradle
+++ b/grails-profiles/web-plugin/build.gradle
@@ -35,4 +35,5 @@ dependencies {
 
 apply {
     from 
rootProject.layout.projectDirectory.file('gradle/publish-config.gradle')
+    from rootProject.layout.projectDirectory.file('gradle/sbom-config.gradle')
 }
diff --git a/grails-profiles/web/build.gradle b/grails-profiles/web/build.gradle
index cf2d6c335e..b73180727e 100644
--- a/grails-profiles/web/build.gradle
+++ b/grails-profiles/web/build.gradle
@@ -34,4 +34,5 @@ dependencies {
 
 apply {
        from 
rootProject.layout.projectDirectory.file('gradle/publish-config.gradle')
+       from 
rootProject.layout.projectDirectory.file('gradle/sbom-config.gradle')
 }
diff --git a/grails-rest-transforms/build.gradle 
b/grails-rest-transforms/build.gradle
index 40e93a7563..be8345be3d 100644
--- a/grails-rest-transforms/build.gradle
+++ b/grails-rest-transforms/build.gradle
@@ -77,5 +77,6 @@ apply {
     from 
rootProject.layout.projectDirectory.file('gradle/code-style-config.gradle')
     from rootProject.layout.projectDirectory.file('gradle/docs-config.gradle')
     from 
rootProject.layout.projectDirectory.file('gradle/publish-config.gradle')
+    from rootProject.layout.projectDirectory.file('gradle/sbom-config.gradle')
     from rootProject.layout.projectDirectory.file('gradle/test-config.gradle')
 }
\ No newline at end of file
diff --git a/grails-scaffolding/build.gradle b/grails-scaffolding/build.gradle
index c21a4e5c04..bc0b3f118b 100644
--- a/grails-scaffolding/build.gradle
+++ b/grails-scaffolding/build.gradle
@@ -47,6 +47,7 @@ apply {
     from 
rootProject.layout.projectDirectory.file('gradle/code-style-config.gradle')
     from rootProject.layout.projectDirectory.file('gradle/docs-config.gradle')
     from 
rootProject.layout.projectDirectory.file('gradle/publish-config.gradle')
+    from rootProject.layout.projectDirectory.file('gradle/sbom-config.gradle')
     from rootProject.layout.projectDirectory.file('gradle/test-config.gradle')
     from 
rootProject.layout.projectDirectory.file('gradle/grails-extension-gradle-config.gradle')
 }
\ No newline at end of file
diff --git a/grails-services/build.gradle b/grails-services/build.gradle
index b4da45e80d..dc94db6afd 100644
--- a/grails-services/build.gradle
+++ b/grails-services/build.gradle
@@ -68,4 +68,5 @@ apply {
     from 
rootProject.layout.projectDirectory.file('gradle/code-style-config.gradle')
     from rootProject.layout.projectDirectory.file('gradle/docs-config.gradle')
     from 
rootProject.layout.projectDirectory.file('gradle/publish-config.gradle')
+    from rootProject.layout.projectDirectory.file('gradle/sbom-config.gradle')
 }
\ No newline at end of file
diff --git a/grails-shell-cli/build.gradle b/grails-shell-cli/build.gradle
index ee78975196..cd70c43d95 100644
--- a/grails-shell-cli/build.gradle
+++ b/grails-shell-cli/build.gradle
@@ -127,6 +127,7 @@ apply {
     from 
rootProject.layout.projectDirectory.file('gradle/code-style-config.gradle')
     from rootProject.layout.projectDirectory.file('gradle/docs-config.gradle')
     from 
rootProject.layout.projectDirectory.file('gradle/publish-config.gradle')
+    from rootProject.layout.projectDirectory.file('gradle/sbom-config.gradle')
     from rootProject.layout.projectDirectory.file('gradle/test-config.gradle')
 }
 
diff --git a/grails-spring/build.gradle b/grails-spring/build.gradle
index ef54cccd23..9395164cb6 100644
--- a/grails-spring/build.gradle
+++ b/grails-spring/build.gradle
@@ -61,4 +61,5 @@ apply {
     from 
rootProject.layout.projectDirectory.file('gradle/code-style-config.gradle')
     from rootProject.layout.projectDirectory.file('gradle/docs-config.gradle')
     from 
rootProject.layout.projectDirectory.file('gradle/publish-config.gradle')
+    from rootProject.layout.projectDirectory.file('gradle/sbom-config.gradle')
 }
\ No newline at end of file
diff --git a/grails-test-core/build.gradle b/grails-test-core/build.gradle
index d698522617..b619710528 100644
--- a/grails-test-core/build.gradle
+++ b/grails-test-core/build.gradle
@@ -88,4 +88,5 @@ apply {
     from 
rootProject.layout.projectDirectory.file('gradle/code-style-config.gradle')
     from rootProject.layout.projectDirectory.file('gradle/docs-config.gradle')
     from 
rootProject.layout.projectDirectory.file('gradle/publish-config.gradle')
+    from rootProject.layout.projectDirectory.file('gradle/sbom-config.gradle')
 }
\ No newline at end of file
diff --git a/grails-testing-support-core/build.gradle 
b/grails-testing-support-core/build.gradle
index 4a816f0f60..e509bb2738 100644
--- a/grails-testing-support-core/build.gradle
+++ b/grails-testing-support-core/build.gradle
@@ -78,5 +78,6 @@ apply {
     from 
rootProject.layout.projectDirectory.file('gradle/code-style-config.gradle')
     from rootProject.layout.projectDirectory.file('gradle/docs-config.gradle')
     from 
rootProject.layout.projectDirectory.file('gradle/publish-config.gradle')
+    from rootProject.layout.projectDirectory.file('gradle/sbom-config.gradle')
     from rootProject.layout.projectDirectory.file('gradle/test-config.gradle')
 }
\ No newline at end of file
diff --git a/grails-testing-support-datamapping/build.gradle 
b/grails-testing-support-datamapping/build.gradle
index eed573a286..9ab8606bc9 100755
--- a/grails-testing-support-datamapping/build.gradle
+++ b/grails-testing-support-datamapping/build.gradle
@@ -139,5 +139,6 @@ apply {
     from 
rootProject.layout.projectDirectory.file('gradle/code-style-config.gradle')
     from rootProject.layout.projectDirectory.file('gradle/test-config.gradle')
     from 
rootProject.layout.projectDirectory.file('gradle/publish-config.gradle')
+    from rootProject.layout.projectDirectory.file('gradle/sbom-config.gradle')
     from rootProject.layout.projectDirectory.file('gradle/docs-config.gradle')
 }
diff --git a/grails-testing-support-mongodb/build.gradle 
b/grails-testing-support-mongodb/build.gradle
index 7f480cebb2..938c1867f1 100644
--- a/grails-testing-support-mongodb/build.gradle
+++ b/grails-testing-support-mongodb/build.gradle
@@ -47,5 +47,6 @@ apply {
     from 
rootProject.layout.projectDirectory.file('gradle/code-style-config.gradle')
     from rootProject.layout.projectDirectory.file('gradle/test-config.gradle')
     from 
rootProject.layout.projectDirectory.file('gradle/publish-config.gradle')
+    from rootProject.layout.projectDirectory.file('gradle/sbom-config.gradle')
     from rootProject.layout.projectDirectory.file('gradle/docs-config.gradle')
 }
\ No newline at end of file
diff --git a/grails-testing-support-views-gson/build.gradle 
b/grails-testing-support-views-gson/build.gradle
index b8f42edf2e..3de827ad7f 100644
--- a/grails-testing-support-views-gson/build.gradle
+++ b/grails-testing-support-views-gson/build.gradle
@@ -53,5 +53,6 @@ apply {
     from 
rootProject.layout.projectDirectory.file('gradle/code-style-config.gradle')
     from rootProject.layout.projectDirectory.file('gradle/test-config.gradle')
     from 
rootProject.layout.projectDirectory.file('gradle/publish-config.gradle')
+    from rootProject.layout.projectDirectory.file('gradle/sbom-config.gradle')
     from rootProject.layout.projectDirectory.file('gradle/docs-config.gradle')
 }
diff --git a/grails-testing-support-web/build.gradle 
b/grails-testing-support-web/build.gradle
index e5f8bc9938..299bee05cd 100755
--- a/grails-testing-support-web/build.gradle
+++ b/grails-testing-support-web/build.gradle
@@ -53,5 +53,6 @@ apply {
     from 
rootProject.layout.projectDirectory.file('gradle/code-style-config.gradle')
     from rootProject.layout.projectDirectory.file('gradle/docs-config.gradle')
     from 
rootProject.layout.projectDirectory.file('gradle/publish-config.gradle')
+    from rootProject.layout.projectDirectory.file('gradle/sbom-config.gradle')
     from rootProject.layout.projectDirectory.file('gradle/test-config.gradle')
 }
\ No newline at end of file
diff --git a/grails-url-mappings/build.gradle b/grails-url-mappings/build.gradle
index 2d917cee1f..ef6482702e 100644
--- a/grails-url-mappings/build.gradle
+++ b/grails-url-mappings/build.gradle
@@ -68,4 +68,5 @@ apply {
     from 
rootProject.layout.projectDirectory.file('gradle/code-style-config.gradle')
     from rootProject.layout.projectDirectory.file('gradle/docs-config.gradle')
     from 
rootProject.layout.projectDirectory.file('gradle/publish-config.gradle')
+    from rootProject.layout.projectDirectory.file('gradle/sbom-config.gradle')
 }
\ No newline at end of file
diff --git a/grails-validation/build.gradle b/grails-validation/build.gradle
index 26e5bb3434..74d9d7f4a4 100644
--- a/grails-validation/build.gradle
+++ b/grails-validation/build.gradle
@@ -66,5 +66,6 @@ apply {
     from 
rootProject.layout.projectDirectory.file('gradle/code-style-config.gradle')
     from rootProject.layout.projectDirectory.file('gradle/docs-config.gradle')
     from 
rootProject.layout.projectDirectory.file('gradle/publish-config.gradle')
+    from rootProject.layout.projectDirectory.file('gradle/sbom-config.gradle')
     from rootProject.layout.projectDirectory.file('gradle/test-config.gradle')
 }
\ No newline at end of file
diff --git a/grails-views-core/build.gradle b/grails-views-core/build.gradle
index a54475a5f9..d9a310b17a 100644
--- a/grails-views-core/build.gradle
+++ b/grails-views-core/build.gradle
@@ -56,5 +56,6 @@ apply {
     from 
rootProject.layout.projectDirectory.file('gradle/code-style-config.gradle')
     from rootProject.layout.projectDirectory.file('gradle/docs-config.gradle')
     from 
rootProject.layout.projectDirectory.file('gradle/publish-config.gradle')
+    from rootProject.layout.projectDirectory.file('gradle/sbom-config.gradle')
     from rootProject.layout.projectDirectory.file('gradle/test-config.gradle')
 }
\ No newline at end of file
diff --git a/grails-views-gson/build.gradle b/grails-views-gson/build.gradle
index c7fbbdcbe0..6b271697b4 100644
--- a/grails-views-gson/build.gradle
+++ b/grails-views-gson/build.gradle
@@ -68,6 +68,7 @@ apply {
     from 
rootProject.layout.projectDirectory.file('gradle/code-style-config.gradle')
     from rootProject.layout.projectDirectory.file('gradle/docs-config.gradle')
     from 
rootProject.layout.projectDirectory.file('gradle/publish-config.gradle')
+    from rootProject.layout.projectDirectory.file('gradle/sbom-config.gradle')
     from rootProject.layout.projectDirectory.file('gradle/test-config.gradle')
     from 
rootProject.layout.projectDirectory.file('gradle/grails-extension-gradle-config.gradle')
 }
\ No newline at end of file
diff --git a/grails-views-markup/build.gradle b/grails-views-markup/build.gradle
index 4530280e2e..910af14a1f 100644
--- a/grails-views-markup/build.gradle
+++ b/grails-views-markup/build.gradle
@@ -57,6 +57,7 @@ apply {
     from 
rootProject.layout.projectDirectory.file('gradle/code-style-config.gradle')
     from rootProject.layout.projectDirectory.file('gradle/docs-config.gradle')
     from 
rootProject.layout.projectDirectory.file('gradle/publish-config.gradle')
+    from rootProject.layout.projectDirectory.file('gradle/sbom-config.gradle')
     from rootProject.layout.projectDirectory.file('gradle/test-config.gradle')
     from 
rootProject.layout.projectDirectory.file('gradle/grails-extension-gradle-config.gradle')
 }
\ No newline at end of file
diff --git a/grails-web-boot/build.gradle b/grails-web-boot/build.gradle
index f1e2455cd5..5d387223f8 100644
--- a/grails-web-boot/build.gradle
+++ b/grails-web-boot/build.gradle
@@ -70,5 +70,6 @@ apply {
     from 
rootProject.layout.projectDirectory.file('gradle/code-style-config.gradle')
     from rootProject.layout.projectDirectory.file('gradle/docs-config.gradle')
     from 
rootProject.layout.projectDirectory.file('gradle/publish-config.gradle')
+    from rootProject.layout.projectDirectory.file('gradle/sbom-config.gradle')
     from rootProject.layout.projectDirectory.file('gradle/test-config.gradle')
 }
\ No newline at end of file
diff --git a/grails-web-common/build.gradle b/grails-web-common/build.gradle
index 189b9677a6..7eb8bce67d 100644
--- a/grails-web-common/build.gradle
+++ b/grails-web-common/build.gradle
@@ -81,5 +81,6 @@ apply {
     from 
rootProject.layout.projectDirectory.file('gradle/code-style-config.gradle')
     from rootProject.layout.projectDirectory.file('gradle/docs-config.gradle')
     from 
rootProject.layout.projectDirectory.file('gradle/publish-config.gradle')
+    from rootProject.layout.projectDirectory.file('gradle/sbom-config.gradle')
     from rootProject.layout.projectDirectory.file('gradle/test-config.gradle')
 }
\ No newline at end of file
diff --git a/grails-web-core/build.gradle b/grails-web-core/build.gradle
index a434004036..867bc32f79 100644
--- a/grails-web-core/build.gradle
+++ b/grails-web-core/build.gradle
@@ -75,5 +75,6 @@ apply {
     from 
rootProject.layout.projectDirectory.file('gradle/code-style-config.gradle')
     from rootProject.layout.projectDirectory.file('gradle/docs-config.gradle')
     from 
rootProject.layout.projectDirectory.file('gradle/publish-config.gradle')
+    from rootProject.layout.projectDirectory.file('gradle/sbom-config.gradle')
     from rootProject.layout.projectDirectory.file('gradle/test-config.gradle')
 }
\ No newline at end of file
diff --git a/grails-web-databinding/build.gradle 
b/grails-web-databinding/build.gradle
index 73f47df139..8fda4ed286 100644
--- a/grails-web-databinding/build.gradle
+++ b/grails-web-databinding/build.gradle
@@ -74,5 +74,6 @@ apply {
     from 
rootProject.layout.projectDirectory.file('gradle/code-style-config.gradle')
     from rootProject.layout.projectDirectory.file('gradle/docs-config.gradle')
     from 
rootProject.layout.projectDirectory.file('gradle/publish-config.gradle')
+    from rootProject.layout.projectDirectory.file('gradle/sbom-config.gradle')
     from rootProject.layout.projectDirectory.file('gradle/test-config.gradle')
 }
\ No newline at end of file
diff --git a/grails-web-mvc/build.gradle b/grails-web-mvc/build.gradle
index 0f4923c764..e4b08ea68b 100644
--- a/grails-web-mvc/build.gradle
+++ b/grails-web-mvc/build.gradle
@@ -66,5 +66,6 @@ apply {
     from 
rootProject.layout.projectDirectory.file('gradle/code-style-config.gradle')
     from rootProject.layout.projectDirectory.file('gradle/docs-config.gradle')
     from 
rootProject.layout.projectDirectory.file('gradle/publish-config.gradle')
+    from rootProject.layout.projectDirectory.file('gradle/sbom-config.gradle')
     from rootProject.layout.projectDirectory.file('gradle/test-config.gradle')
 }
\ No newline at end of file
diff --git a/grails-web-url-mappings/build.gradle 
b/grails-web-url-mappings/build.gradle
index 7e67bdb748..b97d7a0c0e 100644
--- a/grails-web-url-mappings/build.gradle
+++ b/grails-web-url-mappings/build.gradle
@@ -79,5 +79,6 @@ apply {
     from 
rootProject.layout.projectDirectory.file('gradle/code-style-config.gradle')
     from rootProject.layout.projectDirectory.file('gradle/docs-config.gradle')
     from 
rootProject.layout.projectDirectory.file('gradle/publish-config.gradle')
+    from rootProject.layout.projectDirectory.file('gradle/sbom-config.gradle')
     from rootProject.layout.projectDirectory.file('gradle/test-config.gradle')
 }
\ No newline at end of file
diff --git a/grails-wrapper/build.gradle b/grails-wrapper/build.gradle
index 82e67d1727..8d70f1b80b 100644
--- a/grails-wrapper/build.gradle
+++ b/grails-wrapper/build.gradle
@@ -56,6 +56,7 @@ apply {
     from rootProject.layout.projectDirectory.file('gradle/test-config.gradle')
     from rootProject.layout.projectDirectory.file('gradle/docs-config.gradle')
     from 
rootProject.layout.projectDirectory.file('gradle/publish-config.gradle')
+    from rootProject.layout.projectDirectory.file('gradle/sbom-config.gradle')
 }
 
 // It's surprisingly hard to generate start scripts and *not* have them nested 
into a bin / lib directory

Reply via email to