Skip to content

Conversation

@jdaugherty
Copy link
Contributor

Fixes #15048 , but I think the AclIdentityObject in spring security will still differ after this change. From local testing, the closures are generated in the same order - we can confirm this as part of the next release.

@jdaugherty jdaugherty force-pushed the reproducibleGormServices branch from 392872f to c282f70 Compare September 24, 2025 19:33
@jdaugherty jdaugherty merged commit 93a0aeb into 7.0.x Sep 24, 2025
36 checks passed

}

propertiesFields.sort(true) { it.name } // ensure a consistent order of processing fields
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Can be removed if we use a sorted set.

boolean isInterface = classNode.isInterface()
boolean isAbstractClass = !isInterface && Modifier.isAbstract(classNode.modifiers)

List<FieldNode> propertiesFields = []
Copy link
Contributor

@matrei matrei Sep 25, 2025

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

  • Use a sorted set from the start? Would eliminate the need to sort after the loop.
// Use sorted set to ensure consistent ordering for build reproducibility
def propertiesFields = new TreeSet<FieldNode>({ FieldNode a, FieldNode b -> a.name <=> b.name })

Comment on lines 264 to +266
List<MethodNode> abstractMethods = findAllUnimplementedAbstractMethods(classNode)
abstractMethods.sort(true) { it.name } // ensure a consistent order of processing methods

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Sort inline? Simplify?

// Sort to ensure consistent ordering for build reproducibility
def abstractMethods = findAllUnimplementedAbstractMethods(classNode)
        .sort { it.name }

Comment on lines +271 to +272
def sortedMethods = classNode.methods.sort(true) { it.name }
for (MethodNode existing in (sortedMethods)) {
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

  • Add comment why we are sorting?
  • Why mutate?
  • Simplify?
// Sort to ensure consistent ordering for build reproducibility
def sortedMethods = classNode.methods.sort { it.name }
for (MethodNode existing in sortedMethods) {

List<FieldNode> propertiesFields = []
if (isAbstractClass) {
List<PropertyNode> properties = classNode.getProperties()
List<PropertyNode> properties = classNode.getProperties().sort { it.name }
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

  • Add comment why we are sorting?
  • Simplify?
// Sort to ensure consistent ordering for build reproducibility
def properties = classNode.properties.sort { it.name }


Iterable<ServiceImplementerAdapter> adapters = load(ServiceImplementerAdapter)
List<ServiceImplementerAdapter> finalAdapters = adapters.toList()
List<ServiceImplementerAdapter> finalAdapters = adapters.toList().sort { it.class.name }
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

  • Add comment why we are sorting?
  • Simplify?
// Sort to ensure consistent ordering for build reproducibility
def finalAdapters = adapters.sort { it.class.name }

@jdaugherty jdaugherty deleted the reproducibleGormServices branch October 3, 2025 15:38
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Projects

None yet

Development

Successfully merging this pull request may close these issues.

Ordering with Closures generated for Gorm Services

3 participants