matrei commented on code in PR #15269:
URL: https://github.com/apache/grails-core/pull/15269#discussion_r2580477812


##########
build-logic/plugins/src/main/groovy/org/apache/grails/buildsrc/CompilePlugin.groovy:
##########
@@ -0,0 +1,137 @@
+/*
+ *  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.
+ */
+
+package org.apache.grails.buildsrc
+
+import java.nio.charset.StandardCharsets
+import java.util.concurrent.atomic.AtomicBoolean
+
+import groovy.transform.CompileStatic
+
+import org.gradle.api.Plugin
+import org.gradle.api.Project
+import org.gradle.api.file.DuplicatesStrategy
+import org.gradle.api.plugins.JavaPluginExtension
+import org.gradle.api.tasks.SourceSetContainer

Review Comment:
   Unused import



##########
build-logic/plugins/src/main/groovy/org/apache/grails/buildsrc/GradleUtils.groovy:
##########
@@ -27,18 +27,48 @@ import org.gradle.api.file.Directory
 class GradleUtils {
 
     static Directory findRootGrailsCoreDir(Project project) {
-        def rootLayout = project.rootProject.layout
+        def rootLayout = project.layout
+
         // .github / .git related directories are purged from source releases, 
so use the .asf.yaml as an indicator of
         // the parent directory
-        if (rootLayout.projectDirectory.file('.asf.yaml').asFile.exists()) {
-            return rootLayout.projectDirectory
+        findAsfRoot(rootLayout.projectDirectory)
+    }

Review Comment:
   ```suggestion
       static Directory findRootGrailsCoreDir(Project project) {
           findAsfRoot(project.layout.projectDirectory)
       }
   ```



##########
build-logic/plugins/src/main/groovy/org/apache/grails/buildsrc/GradleUtils.groovy:
##########
@@ -27,18 +27,48 @@ import org.gradle.api.file.Directory
 class GradleUtils {
 
     static Directory findRootGrailsCoreDir(Project project) {
-        def rootLayout = project.rootProject.layout
+        def rootLayout = project.layout
+
         // .github / .git related directories are purged from source releases, 
so use the .asf.yaml as an indicator of
         // the parent directory
-        if (rootLayout.projectDirectory.file('.asf.yaml').asFile.exists()) {
-            return rootLayout.projectDirectory
+        findAsfRoot(rootLayout.projectDirectory)
+    }
+
+    static Directory findAsfRoot(Directory currentDirectory) {
+        def asfFile = currentDirectory.file('.asf.yaml').asFile
+        if (asfFile.exists()) {
+            return currentDirectory
         }
 
-        // we currently only nest 1 project level deep
-        rootLayout.projectDirectory.dir('../')
+        findAsfRoot(currentDirectory.dir('../'))
     }
 
     static <T> T lookupProperty(Project project, String name, T defaultValue = 
null) {
-        project.findProperty(name) as T ?: defaultValue
+        T v = lookupPropertyByType(project, name, defaultValue?.class) as T
+        return v == null ? defaultValue : v
+    }
+
+    static <T> T lookupPropertyByType(Project project, String name, Class<T> 
type) {
+        // a cast exception will occur without this
+        if (type && (type == Integer || type == int.class)) {
+            def v = findProperty(project, name)
+            return v == null ? null : Integer.valueOf(v as String) as T
+        }
+
+        findProperty(project, name) as T
+    }
+
+    static Object findProperty(Project project, String name) {
+        def property = project.findProperty(name)
+        if (property != null) {
+            return property
+        }
+
+        def ext = project.extensions.getExtraProperties()

Review Comment:
   ```suggestion
           def ext = project.extensions.extraProperties
   ```



##########
build-logic/plugins/src/main/groovy/org/apache/grails/buildsrc/CompilePlugin.groovy:
##########
@@ -0,0 +1,137 @@
+/*
+ *  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.
+ */
+
+package org.apache.grails.buildsrc
+
+import java.nio.charset.StandardCharsets
+import java.util.concurrent.atomic.AtomicBoolean
+
+import groovy.transform.CompileStatic
+
+import org.gradle.api.Plugin
+import org.gradle.api.Project
+import org.gradle.api.file.DuplicatesStrategy
+import org.gradle.api.plugins.JavaPluginExtension
+import org.gradle.api.tasks.SourceSetContainer
+import org.gradle.api.tasks.bundling.AbstractArchiveTask
+import org.gradle.api.tasks.bundling.Jar
+import org.gradle.api.tasks.compile.GroovyCompile
+import org.gradle.api.tasks.compile.JavaCompile
+import org.gradle.api.tasks.javadoc.Javadoc
+import org.gradle.external.javadoc.StandardJavadocDocletOptions
+
+import static org.apache.grails.buildsrc.GradleUtils.lookupPropertyByType
+
+@CompileStatic
+class CompilePlugin implements Plugin<Project> {
+
+    @Override
+    void apply(Project project) {
+        def initialized = new AtomicBoolean(false)
+        project.plugins.withId('java') { // java (applied when groovy is 
applied) or java-library
+            if (initialized.compareAndSet(false, true)) {
+                configureCompile(project)
+            }
+        }
+    }
+
+    private static void configureCompile(Project project) {
+        configureJavaVersion(project)
+        configureJars(project)
+        configureCompiler(project)
+        configureReproducible(project)
+    }
+
+    private static void configureJavaVersion(Project project) {
+        project.tasks.withType(JavaCompile).configureEach {
+            it.options.release.set(lookupPropertyByType(project, 
'javaVersion', Integer))
+        }
+    }
+
+    private static void configureJars(Project project) {
+        project.extensions.configure(JavaPluginExtension) {
+            // Explicit `it` is required here

Review Comment:
   Remove comment (as this is always the case in plugin code)?



##########
grails-forge/gradle.properties:
##########


Review Comment:
   Do we need to declare `jansiVersion` here now?



##########
grails-forge/buildSrc/build.gradle:
##########
@@ -93,10 +74,9 @@ dependencies {
         exclude group: 'org.asciidoctor'
     }
     implementation "org.antlr:antlr4-runtime:$antlr4Version"
-    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}"
+    implementation 
"org.cyclonedx.bom:org.cyclonedx.bom.gradle.plugin:${gradleCycloneDxPluginVersion}"

Review Comment:
   ```suggestion
       implementation 
"org.cyclonedx.bom:org.cyclonedx.bom.gradle.plugin:$gradleCycloneDxPluginVersion"
   ```



##########
grails-dependencies/assets/build.gradle:
##########
@@ -52,11 +54,6 @@ dependencies {
     }
 }
 
-apply {
-    // java-configuration must be applied first since tasks are now lazy 
registered
-    from rootProject.layout.projectDirectory.file('gradle/java-config.gradle')
-}
-
 // these must be after the above applies because they opt out of the defaults 
created in those files

Review Comment:
   Is this comment moot now?



##########
grails-dependencies/starter-web/build.gradle:
##########
@@ -76,11 +78,6 @@ dependencies {
     }
 }
 
-apply {
-    // java-configuration must be applied first since tasks are now lazy 
registered
-    from rootProject.layout.projectDirectory.file('gradle/java-config.gradle')
-}
-
 // these must be after the above applies because they opt out of the defaults 
created in those files

Review Comment:
   Is this comment moot now?



##########
grails-test-examples/mongodb/base/build.gradle:
##########


Review Comment:
   Remove `groovy`?



##########
grails-test-examples/mongodb/test-data-service/build.gradle:
##########


Review Comment:
   Remove `groovy`?



##########
build-logic/plugins/build.gradle:
##########
@@ -50,5 +54,9 @@ gradlePlugin {
             id = 'org.apache.grails.buildsrc.sbom'
             implementationClass = 'org.apache.grails.buildsrc.SbomPlugin'
         }
+        sharedPropertyPlugin {
+            id = 'org.apache.grails.buildsrc.properties'
+            implementationClass = 
'org.apache.grails.buildsrc.SharedPropertyPlugin'
+        }

Review Comment:
   ```suggestion
           register('compilePlugin') {
               id = 'org.apache.grails.buildsrc.compile'
               implementationClass = 'org.apache.grails.buildsrc.CompilePlugin'
           }
           register('publishPlugin') {
               id = 'org.apache.grails.buildsrc.publish'
               implementationClass = 'org.apache.grails.buildsrc.PublishPlugin'
           }
           register('sbomPlugin') {
               id = 'org.apache.grails.buildsrc.sbom'
               implementationClass = 'org.apache.grails.buildsrc.SbomPlugin'
           }
           register('sharedPropertyPlugin') {
               id = 'org.apache.grails.buildsrc.properties'
               implementationClass = 
'org.apache.grails.buildsrc.SharedPropertyPlugin'
           }
   ```



##########
grails-test-examples/plugins/issue11005/build.gradle:
##########
@@ -16,6 +16,11 @@
  *  specific language governing permissions and limitations
  *  under the License.
  */
+plugins {
+    id 'java-library'

Review Comment:
   Remove `java-library`?



##########
grails-test-examples/plugins/loadsecond/build.gradle:
##########
@@ -16,6 +16,11 @@
  *  specific language governing permissions and limitations
  *  under the License.
  */
+plugins {
+    id 'java-library'

Review Comment:
   Remove `java-library`?



##########
grails-wrapper/build.gradle:
##########
@@ -19,6 +19,8 @@ plugins {
     id 'java'

Review Comment:
   Remove `java`?



##########
grails-forge/buildSrc/build.gradle:
##########
@@ -20,26 +20,7 @@
 plugins {
     id 'java-gradle-plugin'

Review Comment:
   Remove `java-gradle-plugin`?



##########
grails-test-examples/views-functional-tests/build.gradle:
##########
@@ -18,11 +18,12 @@
  */
 
 plugins {
-    id 'application'
     id 'groovy'

Review Comment:
   Remove `groovy`?



##########
build-logic/plugins/src/main/groovy/org/apache/grails/buildsrc/GradleUtils.groovy:
##########
@@ -27,18 +27,48 @@ import org.gradle.api.file.Directory
 class GradleUtils {
 
     static Directory findRootGrailsCoreDir(Project project) {
-        def rootLayout = project.rootProject.layout
+        def rootLayout = project.layout
+
         // .github / .git related directories are purged from source releases, 
so use the .asf.yaml as an indicator of
         // the parent directory
-        if (rootLayout.projectDirectory.file('.asf.yaml').asFile.exists()) {
-            return rootLayout.projectDirectory
+        findAsfRoot(rootLayout.projectDirectory)
+    }
+
+    static Directory findAsfRoot(Directory currentDirectory) {
+        def asfFile = currentDirectory.file('.asf.yaml').asFile
+        if (asfFile.exists()) {
+            return currentDirectory
         }
 
-        // we currently only nest 1 project level deep
-        rootLayout.projectDirectory.dir('../')
+        findAsfRoot(currentDirectory.dir('../'))
     }
 
     static <T> T lookupProperty(Project project, String name, T defaultValue = 
null) {
-        project.findProperty(name) as T ?: defaultValue
+        T v = lookupPropertyByType(project, name, defaultValue?.class) as T
+        return v == null ? defaultValue : v
+    }
+
+    static <T> T lookupPropertyByType(Project project, String name, Class<T> 
type) {
+        // a cast exception will occur without this

Review Comment:
   That's interesting!



##########
build-logic/plugins/src/main/groovy/org/apache/grails/buildsrc/GradleUtils.groovy:
##########
@@ -27,18 +27,48 @@ import org.gradle.api.file.Directory
 class GradleUtils {
 
     static Directory findRootGrailsCoreDir(Project project) {
-        def rootLayout = project.rootProject.layout
+        def rootLayout = project.layout
+
         // .github / .git related directories are purged from source releases, 
so use the .asf.yaml as an indicator of
         // the parent directory
-        if (rootLayout.projectDirectory.file('.asf.yaml').asFile.exists()) {
-            return rootLayout.projectDirectory
+        findAsfRoot(rootLayout.projectDirectory)
+    }
+
+    static Directory findAsfRoot(Directory currentDirectory) {
+        def asfFile = currentDirectory.file('.asf.yaml').asFile
+        if (asfFile.exists()) {
+            return currentDirectory
         }
 
-        // we currently only nest 1 project level deep
-        rootLayout.projectDirectory.dir('../')
+        findAsfRoot(currentDirectory.dir('../'))
     }

Review Comment:
   ```suggestion
       static Directory findAsfRoot(Directory currentDirectory) {
           def rootIndicator = currentDirectory.file('.asf.yaml').asFile
           rootIndicator.exists() ? currentDirectory : 
findAsfRoot(currentDirectory.dir('../'))
       }
   
   ```



##########
build-logic/plugins/src/main/groovy/org/apache/grails/buildsrc/CompilePlugin.groovy:
##########
@@ -0,0 +1,137 @@
+/*
+ *  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.
+ */
+
+package org.apache.grails.buildsrc
+
+import java.nio.charset.StandardCharsets
+import java.util.concurrent.atomic.AtomicBoolean
+
+import groovy.transform.CompileStatic
+
+import org.gradle.api.Plugin
+import org.gradle.api.Project
+import org.gradle.api.file.DuplicatesStrategy
+import org.gradle.api.plugins.JavaPluginExtension
+import org.gradle.api.tasks.SourceSetContainer
+import org.gradle.api.tasks.bundling.AbstractArchiveTask
+import org.gradle.api.tasks.bundling.Jar
+import org.gradle.api.tasks.compile.GroovyCompile
+import org.gradle.api.tasks.compile.JavaCompile
+import org.gradle.api.tasks.javadoc.Javadoc
+import org.gradle.external.javadoc.StandardJavadocDocletOptions
+
+import static org.apache.grails.buildsrc.GradleUtils.lookupPropertyByType
+
+@CompileStatic
+class CompilePlugin implements Plugin<Project> {
+
+    @Override
+    void apply(Project project) {
+        def initialized = new AtomicBoolean(false)
+        project.plugins.withId('java') { // java (applied when groovy is 
applied) or java-library
+            if (initialized.compareAndSet(false, true)) {
+                configureCompile(project)
+            }
+        }
+    }
+
+    private static void configureCompile(Project project) {
+        configureJavaVersion(project)
+        configureJars(project)
+        configureCompiler(project)
+        configureReproducible(project)
+    }
+
+    private static void configureJavaVersion(Project project) {
+        project.tasks.withType(JavaCompile).configureEach {
+            it.options.release.set(lookupPropertyByType(project, 
'javaVersion', Integer))
+        }
+    }
+
+    private static void configureJars(Project project) {
+        project.extensions.configure(JavaPluginExtension) {
+            // Explicit `it` is required here
+            it.withJavadocJar()
+            it.withSourcesJar()
+        }
+
+        // Grails determines the grails version via the META-INF/MANIFEST.MF 
file
+        // Note: we exclude attributes such as Built-By, Build-Jdk, Created-By 
to ensure the build is reproducible.
+        project.tasks.withType(Jar).configureEach { Jar jar ->
+            if (lookupPropertyByType(project, 'skipJavaComponent', Boolean)) {
+                jar.enabled = false
+                return
+            }
+
+            jar.manifest.attributes(
+                    'Implementation-Title': 'Apache Grails',
+                    'Implementation-Version': lookupPropertyByType(project, 
'grailsVersion', String),
+                    'Implementation-Vendor': 'grails.apache.org'
+            )
+            // Explicitly fail since duplicates indicate a double 
configuration that needs fixed
+            jar.duplicatesStrategy = DuplicatesStrategy.FAIL
+        }
+    }
+
+    private static void configureCompiler(Project project) {
+        project.tasks.withType(JavaCompile).configureEach {
+            // Preserve method parameter names in Groovy/Java classes for IDE 
parameter hints & bean reflection metadata.
+            it.options.compilerArgs.add('-parameters')
+            it.options.encoding = StandardCharsets.UTF_8.name()
+            // encoding needs to be the same since it's different across 
platforms

Review Comment:
   Move comment above the line it refers to?



##########
build-logic/plugins/src/main/groovy/org/apache/grails/buildsrc/CompilePlugin.groovy:
##########
@@ -0,0 +1,137 @@
+/*
+ *  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.
+ */
+
+package org.apache.grails.buildsrc
+
+import java.nio.charset.StandardCharsets
+import java.util.concurrent.atomic.AtomicBoolean
+
+import groovy.transform.CompileStatic
+
+import org.gradle.api.Plugin
+import org.gradle.api.Project
+import org.gradle.api.file.DuplicatesStrategy
+import org.gradle.api.plugins.JavaPluginExtension
+import org.gradle.api.tasks.SourceSetContainer
+import org.gradle.api.tasks.bundling.AbstractArchiveTask
+import org.gradle.api.tasks.bundling.Jar
+import org.gradle.api.tasks.compile.GroovyCompile
+import org.gradle.api.tasks.compile.JavaCompile
+import org.gradle.api.tasks.javadoc.Javadoc
+import org.gradle.external.javadoc.StandardJavadocDocletOptions
+
+import static org.apache.grails.buildsrc.GradleUtils.lookupPropertyByType
+
+@CompileStatic
+class CompilePlugin implements Plugin<Project> {
+
+    @Override
+    void apply(Project project) {
+        def initialized = new AtomicBoolean(false)
+        project.plugins.withId('java') { // java (applied when groovy is 
applied) or java-library
+            if (initialized.compareAndSet(false, true)) {
+                configureCompile(project)
+            }
+        }
+    }
+
+    private static void configureCompile(Project project) {
+        configureJavaVersion(project)
+        configureJars(project)
+        configureCompiler(project)
+        configureReproducible(project)
+    }
+
+    private static void configureJavaVersion(Project project) {
+        project.tasks.withType(JavaCompile).configureEach {
+            it.options.release.set(lookupPropertyByType(project, 
'javaVersion', Integer))
+        }
+    }
+
+    private static void configureJars(Project project) {
+        project.extensions.configure(JavaPluginExtension) {
+            // Explicit `it` is required here
+            it.withJavadocJar()
+            it.withSourcesJar()
+        }
+
+        // Grails determines the grails version via the META-INF/MANIFEST.MF 
file
+        // Note: we exclude attributes such as Built-By, Build-Jdk, Created-By 
to ensure the build is reproducible.
+        project.tasks.withType(Jar).configureEach { Jar jar ->
+            if (lookupPropertyByType(project, 'skipJavaComponent', Boolean)) {
+                jar.enabled = false
+                return
+            }
+
+            jar.manifest.attributes(
+                    'Implementation-Title': 'Apache Grails',
+                    'Implementation-Version': lookupPropertyByType(project, 
'grailsVersion', String),
+                    'Implementation-Vendor': 'grails.apache.org'
+            )
+            // Explicitly fail since duplicates indicate a double 
configuration that needs fixed
+            jar.duplicatesStrategy = DuplicatesStrategy.FAIL
+        }
+    }
+
+    private static void configureCompiler(Project project) {
+        project.tasks.withType(JavaCompile).configureEach {
+            // Preserve method parameter names in Groovy/Java classes for IDE 
parameter hints & bean reflection metadata.
+            it.options.compilerArgs.add('-parameters')
+            it.options.encoding = StandardCharsets.UTF_8.name()
+            // encoding needs to be the same since it's different across 
platforms
+            it.options.fork = true
+            it.options.forkOptions.jvmArgs = ['-Xms128M', '-Xmx2G']
+        }
+
+        project.plugins.withId('groovy') {
+            project.tasks.withType(GroovyCompile).configureEach {
+                it.groovyOptions.encoding = StandardCharsets.UTF_8.name()
+                // encoding needs to be the same since it's different across 
platforms

Review Comment:
   Move comment above the line it refers to?



##########
build-logic/plugins/src/main/groovy/org/apache/grails/buildsrc/SharedPropertyPlugin.groovy:
##########
@@ -0,0 +1,75 @@
+/*
+ *  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.
+ */
+
+package org.apache.grails.buildsrc
+
+import groovy.transform.CompileStatic
+
+import org.gradle.api.Plugin
+import org.gradle.api.Project
+import org.gradle.api.file.Directory
+import org.gradle.api.plugins.ExtraPropertiesExtension
+
+import static org.apache.grails.buildsrc.GradleUtils.findRootGrailsCoreDir
+
+/**
+ * Gradle can't share properties across buildSrc or composite projects. This 
plugin ensures that properties not defined
+ * in this project, but are in the root grails-core project, are accessible in 
this project. This plugin must be applied
+ * prior to the access of any property for it to work properly
+ */
+@CompileStatic
+class SharedPropertyPlugin implements Plugin<Project> {
+
+    @Override
+    void apply(Project project) {
+        def ext = project.extensions.getExtraProperties()
+
+        def rootGrailsCoreDir = findRootGrailsCoreDir(project)
+        populateParentProperties(project.layout.projectDirectory, 
rootGrailsCoreDir, ext, project)
+    }

Review Comment:
   ```suggestion
       void apply(Project project) {
           populateParentProperties(
                   project.layout.projectDirectory,
                   findRootGrailsCoreDir(project),
                   project.extensions.extraProperties,
                   project
           )
       }
   ```



##########
build-logic/plugins/src/main/groovy/org/apache/grails/buildsrc/CompilePlugin.groovy:
##########
@@ -0,0 +1,137 @@
+/*
+ *  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.
+ */
+
+package org.apache.grails.buildsrc
+
+import java.nio.charset.StandardCharsets
+import java.util.concurrent.atomic.AtomicBoolean
+
+import groovy.transform.CompileStatic
+
+import org.gradle.api.Plugin
+import org.gradle.api.Project
+import org.gradle.api.file.DuplicatesStrategy
+import org.gradle.api.plugins.JavaPluginExtension
+import org.gradle.api.tasks.SourceSetContainer
+import org.gradle.api.tasks.bundling.AbstractArchiveTask
+import org.gradle.api.tasks.bundling.Jar
+import org.gradle.api.tasks.compile.GroovyCompile
+import org.gradle.api.tasks.compile.JavaCompile
+import org.gradle.api.tasks.javadoc.Javadoc
+import org.gradle.external.javadoc.StandardJavadocDocletOptions
+
+import static org.apache.grails.buildsrc.GradleUtils.lookupPropertyByType
+
+@CompileStatic
+class CompilePlugin implements Plugin<Project> {
+
+    @Override
+    void apply(Project project) {
+        def initialized = new AtomicBoolean(false)
+        project.plugins.withId('java') { // java (applied when groovy is 
applied) or java-library
+            if (initialized.compareAndSet(false, true)) {
+                configureCompile(project)
+            }
+        }
+    }
+
+    private static void configureCompile(Project project) {
+        configureJavaVersion(project)
+        configureJars(project)
+        configureCompiler(project)
+        configureReproducible(project)
+    }
+
+    private static void configureJavaVersion(Project project) {
+        project.tasks.withType(JavaCompile).configureEach {
+            it.options.release.set(lookupPropertyByType(project, 
'javaVersion', Integer))
+        }
+    }
+
+    private static void configureJars(Project project) {
+        project.extensions.configure(JavaPluginExtension) {
+            // Explicit `it` is required here
+            it.withJavadocJar()
+            it.withSourcesJar()
+        }
+
+        // Grails determines the grails version via the META-INF/MANIFEST.MF 
file
+        // Note: we exclude attributes such as Built-By, Build-Jdk, Created-By 
to ensure the build is reproducible.
+        project.tasks.withType(Jar).configureEach { Jar jar ->
+            if (lookupPropertyByType(project, 'skipJavaComponent', Boolean)) {
+                jar.enabled = false
+                return
+            }
+
+            jar.manifest.attributes(
+                    'Implementation-Title': 'Apache Grails',
+                    'Implementation-Version': lookupPropertyByType(project, 
'grailsVersion', String),
+                    'Implementation-Vendor': 'grails.apache.org'
+            )
+            // Explicitly fail since duplicates indicate a double 
configuration that needs fixed
+            jar.duplicatesStrategy = DuplicatesStrategy.FAIL
+        }
+    }
+
+    private static void configureCompiler(Project project) {
+        project.tasks.withType(JavaCompile).configureEach {
+            // Preserve method parameter names in Groovy/Java classes for IDE 
parameter hints & bean reflection metadata.
+            it.options.compilerArgs.add('-parameters')
+            it.options.encoding = StandardCharsets.UTF_8.name()
+            // encoding needs to be the same since it's different across 
platforms
+            it.options.fork = true
+            it.options.forkOptions.jvmArgs = ['-Xms128M', '-Xmx2G']
+        }
+
+        project.plugins.withId('groovy') {
+            project.tasks.withType(GroovyCompile).configureEach {
+                it.groovyOptions.encoding = StandardCharsets.UTF_8.name()
+                // encoding needs to be the same since it's different across 
platforms
+                // Preserve method parameter names in Groovy/Java classes for 
IDE parameter hints & bean reflection metadata.
+                it.groovyOptions.parameters = true
+                it.options.encoding = StandardCharsets.UTF_8.name()
+                // encoding needs to be the same since it's different across 
platforms

Review Comment:
   Move comment above the line it refers to?



##########
grails-test-examples/geb/build.gradle:
##########
@@ -16,8 +16,12 @@
  *  specific language governing permissions and limitations
  *  under the License.
  */
+plugins {
+    id 'groovy'

Review Comment:
   Remove `groovy`?



##########
grails-dependencies/test/build.gradle:
##########
@@ -54,11 +56,6 @@ dependencies {
     }
 }
 
-apply {
-    // java-configuration must be applied first since tasks are now lazy 
registered
-    from rootProject.layout.projectDirectory.file('gradle/java-config.gradle')
-}
-
 // these must be after the above applies because they opt out of the defaults 
created in those files

Review Comment:
   Is this comment moot now?



##########
grails-test-examples/geb-gebconfig/build.gradle:
##########
@@ -17,7 +17,12 @@
  *  under the License.
  */
 
-apply plugin: 'groovy'
+plugins {
+    id 'groovy'

Review Comment:
   Remove `groovy`?



##########
grails-test-examples/mongodb/gson-templates/build.gradle:
##########


Review Comment:
   Remove `groovy`?



##########
grails-test-examples/mongodb/hibernate5/build.gradle:
##########


Review Comment:
   Remove `groovy`?



##########
grails-test-examples/plugins/loadafter/build.gradle:
##########
@@ -16,6 +16,11 @@
  *  specific language governing permissions and limitations
  *  under the License.
  */
+plugins {
+    id 'org.apache.grails.buildsrc.properties'
+    id 'org.apache.grails.buildsrc.compile'
+    id 'java-library'

Review Comment:
   Remove `java-library`?



##########
grails-test-examples/scaffolding/build.gradle:
##########
@@ -19,9 +19,11 @@
 
 plugins {
     id 'groovy'

Review Comment:
   Remove `groovy`?



-- 
This is an automated message from the Apache Git Service.
To respond to the message, please log on to GitHub and use the
URL above to go to the specific comment.

To unsubscribe, e-mail: [email protected]

For queries about this service, please contact Infrastructure at:
[email protected]

Reply via email to