Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
14 changes: 7 additions & 7 deletions .agents/skills/grails-developer/SKILL.md
Original file line number Diff line number Diff line change
Expand Up @@ -13,7 +13,7 @@ Licensed to the Apache Software Foundation (ASF) under one or more contributor l

- Provide detailed guidance for building current Grails web applications and REST APIs.
- Assist with GORM for data modeling, controllers for request handling, services for business logic, and views (GSP, JSON, Markup).
- Support testing with Spock 2.3 (unit/integration tests) and Geb for browser automation.
- Support testing with Spock 2.4 (unit/integration tests) and Geb for browser automation.
- Guide plugin usage and development, security implementation, and deployment strategies.
- Help with configuration, internationalization, async programming, and performance optimization.

Expand All @@ -31,11 +31,11 @@ Activate this skill when developing with current Grails, including:
## Technology Stack

Current Grails is built on:
- **Spring Boot**: 4.0.x
- **Spring Boot**: 4.1.x
- **Spring Framework**: 7.0.x
- **Groovy**: 4.0.x
- **Gradle**: 8.14.x
- **Spock**: 2.3-groovy-4.0
- **Groovy**: 5.0.x
- **Gradle**: 9.6.x
- **Spock**: 2.4-groovy-5.0
- **Jakarta EE**: 10 (migrated from javax.*)
- **Micronaut**: Optional via `grails-micronaut` plugin

Expand Down Expand Up @@ -865,6 +865,6 @@ grails.plugin.springsecurity.controllerAnnotations.staticRules = [
- **Grails User Guide**: https://grails.apache.org/docs/latest/guide/single.html
- **GORM Documentation**: https://grails.apache.org/docs/latest/grails-data/
- **Grails Plugins**: https://grails.apache.org/plugins.html
- **Groovy 4 Documentation**: https://docs.groovy-lang.org/docs/groovy-4.0.30/html/documentation/
- **Spock Framework**: https://spockframework.org/spock/docs/2.3/all_in_one.html
- **Groovy 5 Documentation**: https://docs.groovy-lang.org/docs/groovy-5.0.7/html/documentation/
- **Spock Framework**: https://spockframework.org/spock/docs/2.4/all_in_one.html
- **Geb Manual**: https://groovy.apache.org/geb/manual/current/
14 changes: 7 additions & 7 deletions .agents/skills/groovy-developer/SKILL.md
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
---
name: groovy-developer
description: Expert guide for Groovy 4 development, covering concise syntax, closures, DSLs, metaprogramming, static compilation, and integration with Java 17 and Grails
description: Expert guide for Groovy 5 development, covering concise syntax, closures, DSLs, metaprogramming, static compilation, and integration with Java 21 and Grails
license: Apache-2.0
---
<!--
Expand All @@ -11,11 +11,11 @@ Licensed to the Apache Software Foundation (ASF) under one or more contributor l

## What I Do

- Provide deep expertise in Groovy 4.0, including core language features: syntax, closures, traits, GStrings, operators, and Groovy Truth.
- Provide deep expertise in Groovy 5.0, including core language features: syntax, closures, traits, GStrings, operators, and Groovy Truth.
- Guide metaprogramming techniques: runtime (categories, ExpandoMetaClass, extension modules) and compile-time (AST transformations like @Immutable, @Builder, @Delegate, @Singleton, @Log, @Memoized).
- Assist with DSL creation and usage (MarkupBuilder, JsonBuilder, builders for configuration).
- Support testing with Spock Framework (BDD, data-driven tests, mocking) and built-in power assertions.
- Help integrate Groovy with Java 17: joint compilation, Gradle builds, Grails, and Spring Boot.
- Help integrate Groovy with Java 21: joint compilation, Gradle builds, Grails, and Spring Boot.
- Cover data handling: JSON/XML parsing and building, Groovy SQL, collection processing.
- Advise on performance: @CompileStatic, @TypeChecked, @GrailsCompileStatic for optimal execution.

Expand All @@ -27,11 +27,11 @@ Activate this skill for any Groovy-related task, including:
- Building or enhancing Gradle build scripts (build.gradle).
- Creating DSLs for configuration, testing, or business rules.
- Writing Spock specifications for unit and integration tests.
- Migrating from older Groovy versions (2.x/3.x) to 4.0.
- Migrating from older Groovy versions (2.x/3.x/4.x) to 5.0.
- Performance optimization with static compilation.
- Working with JSON/XML data, GORM criteria queries, or builders.

## Groovy 4 Key Features
## Groovy 5 Key Features

### Concise Syntax
```groovy
Expand Down Expand Up @@ -499,7 +499,7 @@ sql.execute("INSERT INTO books (title) VALUES ($title)")

## Resources

- **Groovy 4 Documentation**: https://docs.groovy-lang.org/docs/groovy-4.0.30/html/documentation/
- **Groovy 5 Documentation**: https://docs.groovy-lang.org/docs/groovy-5.0.7/html/documentation/
- **Groovy Style Guide**: https://groovy-lang.org/style-guide.html
- **GORM Documentation**: https://grails.apache.org/docs/latest/grails-data/
- **Spock Framework**: https://spockframework.org/spock/docs/2.3/all_in_one.html
- **Spock Framework**: https://spockframework.org/spock/docs/2.4/all_in_one.html
20 changes: 10 additions & 10 deletions .agents/skills/java-developer/SKILL.md
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
---
name: java-developer
description: Guide for developing in Java 17 LTS, including modern features, best practices, and integration with Groovy/Grails projects
description: Guide for developing on the Java 21 baseline, including modern features, best practices, and integration with Groovy/Grails projects
license: Apache-2.0
---
<!--
Expand All @@ -11,8 +11,8 @@ Licensed to the Apache Software Foundation (ASF) under one or more contributor l

## What I Do

- Provide guidance on Java 17 LTS syntax, features, and APIs for use in Grails/Groovy projects.
- Assist with code generation, refactoring, and debugging using Java 17 enhancements like records, sealed classes, pattern matching, and text blocks.
- Provide guidance on Java 21 syntax, features, and APIs for use in Grails/Groovy projects.
- Assist with code generation, refactoring, and debugging using modern Java features like records, sealed classes, pattern matching, and text blocks.
- Recommend best practices for Java code that interoperates with Groovy in mixed-language projects.
- Guide on tooling: Gradle builds, JDK setup, testing with JUnit 5/Spock, and profiling.

Expand All @@ -21,11 +21,11 @@ Licensed to the Apache Software Foundation (ASF) under one or more contributor l
Use this skill when working on Java code within this repository, especially for:
- Writing Java classes that will be used alongside Groovy code.
- Implementing features using records, sealed classes, or pattern matching for instanceof.
- Migrating older Java code (e.g., Java 8/11) to Java 17 idioms.
- Migrating older Java code (e.g., Java 8/11/17) to Java 21 idioms.
- Performance optimization, security hardening, or module system (JPMS) questions.
- Understanding how Java code integrates with Groovy's dynamic features.

## Java 17 Key Features
## Java 21 Baseline Features

### Records (JEP 395)
Immutable data carriers with auto-generated constructors, accessors, equals, hashCode, and toString:
Expand Down Expand Up @@ -61,13 +61,13 @@ public non-sealed class Rectangle implements Shape {
### Pattern Matching for instanceof (JEP 394)
Eliminate redundant casts:
```java
// Before Java 17
// Before pattern matching
if (obj instanceof String) {
String s = (String) obj;
System.out.println(s.length());
}

// Java 17
// Modern Java
if (obj instanceof String s) {
System.out.println(s.length());
}
Expand Down Expand Up @@ -200,7 +200,7 @@ def "Java record should work in Spock tests"() {

## Performance and Profiling

### JVM Options for Java 17
### JVM Options for Java 21
```bash
# Recommended GC for most workloads
-XX:+UseG1GC
Expand Down Expand Up @@ -266,6 +266,6 @@ List<String> copy = List.copyOf(mutableList);

## Resources

- **Java 17 Documentation**: https://docs.oracle.com/en/java/javase/17/
- **Java Language Updates**: https://docs.oracle.com/en/java/javase/17/language/
- **Java 21 Documentation**: https://docs.oracle.com/en/java/javase/21/
- **Java Language Updates**: https://docs.oracle.com/en/java/javase/21/language/
- **JEP Index**: https://openjdk.org/jeps/0
16 changes: 8 additions & 8 deletions AGENTS.md
Original file line number Diff line number Diff line change
Expand Up @@ -72,9 +72,9 @@ export GRADLE_OPTS="-Xms2G -Xmx5G"
| Skill | Path | Use For |
|-------|------|---------|
| **grails-developer** | `.agents/skills/grails-developer/SKILL.md` | Current Grails apps, GORM, controllers, views |
| **groovy-developer** | `.agents/skills/groovy-developer/SKILL.md` | Groovy 4 syntax, closures, DSLs, Spock |
| **groovy-developer** | `.agents/skills/groovy-developer/SKILL.md` | Groovy 5 syntax, closures, DSLs, Spock |
| **grails-8-upgrade** | `.agents/skills/grails-8-upgrade/SKILL.md` | Upgrading Grails applications from 7.x to 8 |
| **java-developer** | `.agents/skills/java-developer/SKILL.md` | Java 17 features, Groovy interop |
| **java-developer** | `.agents/skills/java-developer/SKILL.md` | Java 21 features, Groovy interop |
| **hibernate-developer** | `.agents/skills/hibernate-developer/SKILL.md` | Hibernate 7 mapping, binders, generators |
| **violation-fixer** | `.agents/skills/violation-fixer/SKILL.md` | Fix style/analysis violations (CodeNarc, Checkstyle, PMD, SpotBugs) |
| **test-fixer** | `.agents/skills/test-fixer/SKILL.md` | Aggregate and fix test failures |
Expand All @@ -84,11 +84,11 @@ export GRADLE_OPTS="-Xms2G -Xmx5G"
| Component | Version |
|-----------|---------|
| JDK | 21+ (baseline 21) |
| Groovy | 4.0.x |
| Spring Boot | 4.0.x |
| Groovy | 5.0.x |
| Spring Boot | 4.1.x |
| Spring Framework | 7.0.x |
| Spock | 2.4-groovy-4.0 |
| Gradle | 8.14.x |
| Spock | 2.4-groovy-5.0 |
| Gradle | 9.6.x |
| Jakarta EE | 10 |

## Project Structure
Expand Down Expand Up @@ -280,8 +280,8 @@ and known non-findings — before reporting issues.
## Resources

- **Grails Guide**: https://grails.apache.org/docs/latest/guide/single.html
- **Groovy 4 Docs**: https://docs.groovy-lang.org/docs/groovy-4.0.30/html/documentation/
- **Spock 2.3 Docs**: https://spockframework.org/spock/docs/2.3/all_in_one.html
- **Groovy 5 Docs**: https://docs.groovy-lang.org/docs/groovy-5.0.7/html/documentation/
- **Spock 2.4 Docs**: https://spockframework.org/spock/docs/2.4/all_in_one.html
- **GORM Docs**: https://grails.apache.org/docs/latest/grails-data/
- **Issues**: https://github.com/apache/grails-core/issues
- **Slack**: https://grails.slack.com
8 changes: 5 additions & 3 deletions grails-bom/hibernate5-micronaut/build.gradle
Original file line number Diff line number Diff line change
Expand Up @@ -75,9 +75,11 @@ dependencies {
// Re-export the Micronaut platform so consumers inherit Micronaut's managed versions
// transitively. Exclude Groovy since we declare the required version explicitly via
// customBomDependencies. Exclude Spock since we manage that version ourselves.
// Exclude Jackson 3 (tools.jackson) since spring-boot-dependencies manages that version,
// and Micronaut can lag behind Spring Boot's patch bumps (e.g. SB 4.0.6 ships
// jackson-bom 3.1.2 while micronaut-platform 5.0.0-M2 still pins 3.1.0).
// Exclude Jackson 3 (tools.jackson) since spring-boot-dependencies manages that version
// and the two platforms routinely disagree on the patch (e.g. SB 4.0.6 ships
// jackson-bom 3.1.2 while micronaut-platform 5.0.0 pins 3.1.3). Let Spring Boot
// remain the single source of truth so the dependency-version validator does not
// see drift between probe and project resolution.
api(platform("io.micronaut.platform:micronaut-platform:$micronautPlatformVersion")) {
exclude group: 'org.apache.groovy'
exclude group: 'org.spockframework'
Expand Down
8 changes: 5 additions & 3 deletions grails-bom/hibernate7-micronaut/build.gradle
Original file line number Diff line number Diff line change
Expand Up @@ -75,9 +75,11 @@ dependencies {
// Re-export the Micronaut platform so consumers inherit Micronaut's managed versions
// transitively. Exclude Groovy since we declare the required version explicitly via
// customBomDependencies. Exclude Spock since the base BOM manages that version.
// Exclude Jackson 3 (tools.jackson) since spring-boot-dependencies manages that version,
// and Micronaut can lag behind Spring Boot's patch bumps (e.g. SB 4.0.6 ships
// jackson-bom 3.1.2 while micronaut-platform 5.0.0-M2 still pins 3.1.0).
// Exclude Jackson 3 (tools.jackson) since spring-boot-dependencies manages that version
// and the two platforms routinely disagree on the patch (e.g. SB 4.0.6 ships
// jackson-bom 3.1.2 while micronaut-platform 5.0.0 pins 3.1.3). Let Spring Boot
// remain the single source of truth so the dependency-version validator does not
// see drift between probe and project resolution.
api(platform("io.micronaut.platform:micronaut-platform:$micronautPlatformVersion")) {
exclude group: 'org.apache.groovy'
exclude group: 'org.spockframework'
Expand Down
1 change: 0 additions & 1 deletion grails-data-hibernate7/boot-plugin/build.gradle
Original file line number Diff line number Diff line change
Expand Up @@ -39,7 +39,6 @@ ext {
}

dependencies {
// TODO: Clarify and clean up dependencies
implementation platform(project(':grails-hibernate7-bom'))

compileOnly project(':grails-shell-cli'), {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -60,7 +60,7 @@ public class GrailsSessionContext implements CurrentSessionContext {
protected final SessionFactoryImplementor sessionFactory;
protected CurrentSessionContext jtaSessionContext;

// TODO make configurable?
// Match Spring's default: currentSession() must not create a Session outside an active transaction.
protected boolean allowCreate = false;

/**
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -18,8 +18,8 @@
*/
package org.grails.orm.hibernate;

// TODO: Refactor multi-datasource architecture to avoid the parent-child datastore map and anonymous subclasses.
// Consider a single CompositeDatastore approach for the next major release.
// Multi-datasource support currently uses a parent-child datastore map and child datastore instances.
// A future major release can replace this with a single CompositeDatastore approach.

import java.io.Closeable;
import java.io.IOException;
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -74,7 +74,6 @@ import org.grails.orm.hibernate.support.HibernateRuntimeUtils
*/
@Slf4j
@CompileStatic
//TODO Duplication!!
class HibernateGormStaticApi<D> extends GormStaticApi<D> {

protected GrailsHibernateTemplate hibernateTemplate
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -71,7 +71,6 @@
* @author Graeme Rocher
* @since 1.0
*/
//TODO Cleanup
@SuppressWarnings({"rawtypes", "PMD.DataflowAnomalyAnalysis", "PMD.AvoidDuplicateLiterals"})
public class HibernateSession extends AbstractAttributeStoringSession implements QueryAliasAwareSession {

Expand Down Expand Up @@ -288,7 +287,6 @@ public void setSynchronizedWithTransaction(boolean synchronizedWithTransaction)

@Override
@SuppressWarnings("PMD.DataflowAnomalyAnalysis")
//TODO Clean up
public Serializable getObjectIdentifier(Object instance) {
if (instance == null) return null;
if (proxyHandler.isProxy(instance)) {
Expand All @@ -313,7 +311,6 @@ public Serializable getObjectIdentifier(Object instance) {
*/
@Override
@SuppressWarnings("PMD.DataflowAnomalyAnalysis")
//TODO Clean up
public long deleteAll(final QueryableCriteria criteria) {
return getHibernateTemplate().execute((GrailsHibernateTemplate.HibernateCallback<Integer>) session -> {
JpaQueryBuilder builder = new JpaQueryBuilder(criteria);
Expand Down Expand Up @@ -355,7 +352,6 @@ private MutationQuery createMutationQuery(Session session, JpaQueryInfo jpaQuery
*/
@Override
@SuppressWarnings("PMD.DataflowAnomalyAnalysis")
//TODO Cleanup
public long updateAll(final QueryableCriteria criteria, final Map<String, Object> properties) {
return getHibernateTemplate().execute((GrailsHibernateTemplate.HibernateCallback<Integer>) session -> {
JpaQueryBuilder builder = new JpaQueryBuilder(criteria);
Expand Down Expand Up @@ -388,7 +384,6 @@ public long updateAll(final QueryableCriteria criteria, final Map<String, Object

@Override
@SuppressWarnings({"PMD.DataflowAnomalyAnalysis"})
//TODO Cleanup
public List retrieveAll(final Class type, final Iterable keys) {
final GrailsHibernatePersistentEntity persistentEntity = (GrailsHibernatePersistentEntity) getMappingContext().getPersistentEntity(type.getName());
final String entityName = persistentEntity.getName();
Expand Down Expand Up @@ -453,7 +448,6 @@ public void setFlushMode(FlushModeType flushMode) {
}
}

//TODO could be used
protected <D> HibernateGormStaticApi<D> getStaticApi(Class<D> type) {
return new HibernateGormStaticApi<>(
type,
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -31,10 +31,10 @@
import org.grails.orm.hibernate.cfg.domainbinding.hibernate.HibernateEmbeddedProperty;
import org.grails.orm.hibernate.cfg.domainbinding.hibernate.HibernatePersistentProperty;

// TODO (Hibernate 8 refactor): ComponentBinder holds a GrailsPropertyBinder reference set post-construction
// via setGrailsPropertyBinder() to break a circular dependency (ComponentBinder ↔ GrailsPropertyBinder ↔
// CollectionBinder ↔ ComponentBinder). This mutual dependency should be resolved by introducing a shared
// binding context or factory object that all binders receive at construction time.
// ComponentBinder holds a GrailsPropertyBinder reference set post-construction via
// setGrailsPropertyBinder() to break a circular dependency (ComponentBinder ↔ GrailsPropertyBinder ↔
// CollectionBinder ↔ ComponentBinder). A future major release can introduce a shared binding context or
// factory object that all binders receive at construction time.
/**
* Binds embedded components and embedded collection elements to the Hibernate meta-model.
*
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -86,7 +86,6 @@ public Property bindProperty(HibernatePersistentProperty persistentProperty, Val
prop.setPropertyAccessorName(accessorName);

prop.setOptional(persistentProperty.isNullable());
//TODO Change to Hibernate hierarchy
if (persistentProperty instanceof Association<?> association &&
!(persistentProperty instanceof HibernateEnumProperty)) {
prop.setCascade(cascadeBehaviorFetcher.getCascadeBehaviour(association));
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -36,7 +36,6 @@
* @author Graeme Rocher
* @since 7.0
*/
//TODO Hacky implementation
public class GrailsNativeGenerator extends NativeGenerator {

@Serial
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -34,10 +34,10 @@
/**
* Refactored from CollectionBinder to handle collection second pass binding.
*/
// TODO (Hibernate 8 refactor): CollectionSecondPassBinder receives its ComponentBinder reference via
// setComponentBinder() post-construction (mirroring the GrailsPropertyBinder ↔ ComponentBinder circular
// dependency). This should be resolved by introducing a shared binding context or factory that all binders
// receive at construction time, eliminating the need for post-construction wiring.
// CollectionSecondPassBinder receives its ComponentBinder reference via setComponentBinder()
// post-construction, mirroring the GrailsPropertyBinder ↔ ComponentBinder circular dependency. A future
// major release can introduce a shared binding context or factory that all binders receive at construction
// time, eliminating the need for post-construction wiring.
@SuppressWarnings("PMD.DataflowAnomalyAnalysis")
public class CollectionSecondPassBinder {

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -85,7 +85,6 @@ private Object getStrategyInstance(Object strategy, Class<?> strategyClass)
if (strategy instanceof PhysicalNamingStrategy) {
return strategy;
}
//TODO Candidate for SneakyThrow
return strategyClass.newInstance();
}

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -112,7 +112,6 @@ public String calculateTableForMany(HibernatePersistentProperty property) {

// Only proceed with association logic if it's an actual Association and has an associated
// entity
//TODO Use Hibernate hierarchy
if (!(property instanceof Association<?> association)) {
throw new MappingException("Property [" + property.getName() +
"] is not an association and is not a basic type for table calculation.");
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -23,7 +23,7 @@

import org.grails.datastore.gorm.query.criteria.DetachedAssociationCriteria;

/** TODO: Add description. */
/** Maps detached association criteria by association path for alias registration. */
public class AliasMapEntryFunction
implements Function<DetachedAssociationCriteria<?>, Map.Entry<String, DetachedAssociationCriteria<?>>> {

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -36,7 +36,6 @@
* @author graemerocher
* @since 7.0.0
*/
//TODO Cleanup
public class HqlListQueryBuilder {

private final GrailsHibernatePersistentEntity entity;
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -58,7 +58,6 @@
"PMD.AvoidLiteralsInIfCondition",
"PMD.UseLocaleWithCaseConversions"
})
//TODO Cleanup
public record HqlQueryContext(
String hql,
Class<?> targetClass,
Expand Down
Loading
Loading