You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@grails.apache.org by jd...@apache.org on 2025/07/17 22:37:23 UTC

(grails-core) branch mergedAnnotationsApi updated (e48a54c99f -> 5ded8e84cc)

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

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


 discard e48a54c99f remove old asm & AnnotationMetadataReader supporting classes; adopt Spring's SimpleMetadataReaderFactory instead - see https://github.com/spring-projects/spring-framework/wiki/MergedAnnotation-API-internals?utm_source=chatgpt.com
     new 5ded8e84cc remove old asm & AnnotationMetadataReader supporting classes; adopt Spring's SimpleMetadataReaderFactory instead - see https://github.com/spring-projects/spring-framework/wiki/MergedAnnotation-API-internals

This update added new revisions after undoing existing revisions.
That is to say, some revisions that were in the old version of the
branch are not in the new version.  This situation occurs
when a user --force pushes a change and generates a repository
containing something like this:

 * -- * -- B -- O -- O -- O   (e48a54c99f)
            \
             N -- N -- N   refs/heads/mergedAnnotationsApi (5ded8e84cc)

You should already have received notification emails for all of the O
revisions, and so the following emails describe only the N revisions
from the common base, B.

Any revisions marked "omit" are not gone; other references still
refer to them.  Any revisions marked "discard" are gone forever.

The 1 revisions listed above as "new" are entirely new to this
repository and will be described in separate emails.  The revisions
listed as "add" were already present in the repository and have only
been added to this reference.


Summary of changes:


(grails-core) 01/01: remove old asm & AnnotationMetadataReader supporting classes; adopt Spring's SimpleMetadataReaderFactory instead - see https://github.com/spring-projects/spring-framework/wiki/MergedAnnotation-API-internals

Posted by jd...@apache.org.
This is an automated email from the ASF dual-hosted git repository.

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

commit 5ded8e84cc28adf0006b7319cf03669c10f51013
Author: James Daugherty <jd...@jdresources.net>
AuthorDate: Thu Jul 17 16:36:20 2025 -0600

    remove old asm & AnnotationMetadataReader supporting classes; adopt Spring's SimpleMetadataReaderFactory instead
    - see https://github.com/spring-projects/spring-framework/wiki/MergedAnnotation-API-internals
---
 LICENSE                                            |   29 -
 NOTICE                                             |    9 -
 .../AbstractRecursiveAnnotationVisitor.java        |  108 --
 .../AnnotationAttributesReadingVisitor.java        |  131 ---
 .../AnnotationMetadataReadingVisitor.java          |  207 ----
 .../annotation/AnnotationReadingVisitorUtils.java  |  176 ----
 .../annotation/ClassMetadataReadingVisitor.java    |  246 -----
 .../annotation/MethodMetadataReadingVisitor.java   |  176 ----
 .../RecursiveAnnotationArrayVisitor.java           |  112 ---
 .../RecursiveAnnotationAttributesVisitor.java      |   55 -
 .../compiler/asm/AnnotationMetadataReader.java     |  142 ---
 .../grails/common/compiler/asm/Attribute.java      |  258 -----
 .../grails/common/compiler/asm/ByteVector.java     |  339 -------
 .../grails/common/compiler/asm/ClassReader.java    | 1056 --------------------
 .../apache/grails/common/compiler/asm/Context.java |  146 ---
 .../grails/common/compiler/asm/TypePath.java       |  196 ----
 grails-common/src/main/resources/META-INF/LICENSE  |  233 -----
 grails-common/src/main/resources/META-INF/NOTICE   |   18 -
 .../boot/config/tools/ClassPathScanner.groovy      |    6 +-
 .../utils/AnnotationMetadataReaderFactory.java     |   39 -
 .../gorm/utils/ClasspathEntityScanner.groovy       |    3 +-
 licenses/LICENSE-asm.txt                           |   27 -
 22 files changed, 6 insertions(+), 3706 deletions(-)

diff --git a/LICENSE b/LICENSE
index 06f77ceaab..1e51fd6e2a 100644
--- a/LICENSE
+++ b/LICENSE
@@ -203,20 +203,6 @@
 
 --------------------------------------------------------------------------
 
-BSD License
-
-The following classes within this product:
-
-    org.apache.grails.common.compiler.asm.Attribute
-    org.apache.grails.common.compiler.asm.ByteVector
-    org.apache.grails.common.compiler.asm.ClassReader
-    org.apache.grails.common.compiler.asm.Context
-    org.apache.grails.common.compiler.asm.TypePath
-
-See the LICENSE/licenses-asm.txt file for the ASM license terms.
-
---------------------------------------------------------------------------
-
 Public Domain
 
 The following classes within this product:
@@ -250,21 +236,6 @@ See licenses/LICENSE-CDDL.txt for the full license terms.
 
 --------------------------------------------------------------------------
 
-This product includes the following files from Spring Framework 5.3, developed by Pivotal Software, Inc., licensed under the Apache License 2.0:
-
-    grails-common/src/main/groovy/org/apache/grails/common/annotation/AbstractRecursiveAnnotationVisitor.java
-    grails-common/src/main/groovy/org/apache/grails/common/annotation/AnnotationAttributesReadingVisitor.java
-    grails-common/src/main/groovy/org/apache/grails/common/annotation/AnnotationMetadataReadingVisitor.java
-    grails-common/src/main/groovy/org/apache/grails/common/annotation/AnnotationReadingVisitorUtils.java
-    grails-common/src/main/groovy/org/apache/grails/common/annotation/ClassMetadataReadingVisitor.java
-    grails-common/src/main/groovy/org/apache/grails/common/annotation/MethodMetadataReadingVisitor.java
-    grails-common/src/main/groovy/org/apache/grails/common/annotation/RecursiveAnnotationArrayVisitor.java
-    grails-common/src/main/groovy/org/apache/grails/common/annotation/RecursiveAnnotationAttributesVisitor.java
-
-See the above Apache License 2.0 for the terms governing these files.
-
---------------------------------------------------------------------------
-
 This product includes software developed by the OpenSymphony Group (http://www.opensymphony.com/). It uses Sitemesh2,
 licensed under the OpenSymphony Software License, Version 1.1.
 
diff --git a/NOTICE b/NOTICE
index b78f70d549..d5e4c5dbbf 100644
--- a/NOTICE
+++ b/NOTICE
@@ -8,11 +8,6 @@ The Apache Software Foundation (http://www.apache.org/).
 Additional Licenses
 ------------------
 
-ASM Library
-This product includes software from ASM Library, licensed under BSD License.
-Copyright 2000-2011 INRIA, France Telecom.
-See licenses/LICENSE-asm.txt for the full license terms.
-
 Project Reactor
 This product includes software from Project Reactor, licensed under Apache License, Version 2.0.
 2011-2014 Pivotal Software, Inc.
@@ -23,9 +18,5 @@ The original XML Schemas for Java EE Deployment Descriptors:
 may be obtained from:
 http://www.oracle.com/webfolder/technetwork/jsc/xml/ns/javaee/index.html
 
-This product includes software from Spring Framework 5.3, developed by Pivotal Software, Inc.
-Copyright 2002-2020 the original author or authors.
-See the LICENSE file for the Apache License 2.0 terms.
-
 This product includes software developed by the OpenSymphony Group (http://www.opensymphony.com/). It uses Sitemesh2,
 licensed under the OpenSymphony Software License, Version 1.1. See licenses/LICENSE-opensymphony.txt for the full license terms.
\ No newline at end of file
diff --git a/grails-common/src/main/groovy/org/apache/grails/common/annotation/AbstractRecursiveAnnotationVisitor.java b/grails-common/src/main/groovy/org/apache/grails/common/annotation/AbstractRecursiveAnnotationVisitor.java
deleted file mode 100644
index a810868fd4..0000000000
--- a/grails-common/src/main/groovy/org/apache/grails/common/annotation/AbstractRecursiveAnnotationVisitor.java
+++ /dev/null
@@ -1,108 +0,0 @@
-/*
- * Copyright 2002-2024 the original author or authors.
- *
- * Licensed 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.common.annotation;
-
-import java.lang.reflect.Field;
-import java.security.AccessControlException;
-
-import org.apache.commons.logging.Log;
-import org.apache.commons.logging.LogFactory;
-
-import org.springframework.asm.AnnotationVisitor;
-import org.springframework.asm.SpringAsmInfo;
-import org.springframework.asm.Type;
-import org.springframework.core.annotation.AnnotationAttributes;
-import org.springframework.lang.Nullable;
-import org.springframework.util.ClassUtils;
-import org.springframework.util.ReflectionUtils;
-
-/**
- * {@link AnnotationVisitor} to recursively visit annotations.
-
- * <p>Note: This class was ported to Grails 7 from Spring Framework 5.3 as it was
- * removed in Spring 6 without a public replacement.
- *
- * @author Chris Beams
- * @author Juergen Hoeller
- * @author Phillip Webb
- * @author Sam Brannen
- * @since 3.1.1
- * @deprecated As of Spring Framework 5.2, this class and related classes in this
- * package have been replaced by SimpleAnnotationMetadataReadingVisitor
- * and related classes for internal use within the framework.
- */
-@Deprecated
-abstract class AbstractRecursiveAnnotationVisitor extends AnnotationVisitor {
-
-    protected final Log logger = LogFactory.getLog(getClass());
-
-    protected final AnnotationAttributes attributes;
-
-    @Nullable
-    protected final ClassLoader classLoader;
-
-
-    public AbstractRecursiveAnnotationVisitor(@Nullable ClassLoader classLoader, AnnotationAttributes attributes) {
-        super(SpringAsmInfo.ASM_VERSION);
-        this.classLoader = classLoader;
-        this.attributes = attributes;
-    }
-
-
-    @Override
-    public void visit(String attributeName, Object attributeValue) {
-        this.attributes.put(attributeName, attributeValue);
-    }
-
-    @Override
-    public AnnotationVisitor visitAnnotation(String attributeName, String asmTypeDescriptor) {
-        String annotationType = Type.getType(asmTypeDescriptor).getClassName();
-        AnnotationAttributes nestedAttributes = new AnnotationAttributes(annotationType, this.classLoader);
-        this.attributes.put(attributeName, nestedAttributes);
-        return new RecursiveAnnotationAttributesVisitor(annotationType, nestedAttributes, this.classLoader);
-    }
-
-    @Override
-    public AnnotationVisitor visitArray(String attributeName) {
-        return new RecursiveAnnotationArrayVisitor(attributeName, this.attributes, this.classLoader);
-    }
-
-    @Override
-    public void visitEnum(String attributeName, String asmTypeDescriptor, String attributeValue) {
-        Object newValue = getEnumValue(asmTypeDescriptor, attributeValue);
-        visit(attributeName, newValue);
-    }
-
-    protected Object getEnumValue(String asmTypeDescriptor, String attributeValue) {
-        Object valueToUse = attributeValue;
-        try {
-            Class<?> enumType = ClassUtils.forName(Type.getType(asmTypeDescriptor).getClassName(), this.classLoader);
-            Field enumConstant = ReflectionUtils.findField(enumType, attributeValue);
-            if (enumConstant != null) {
-                ReflectionUtils.makeAccessible(enumConstant);
-                valueToUse = enumConstant.get(null);
-            }
-        }
-        catch (ClassNotFoundException | NoClassDefFoundError ex) {
-            logger.debug("Failed to classload enum type while reading annotation metadata", ex);
-        }
-        catch (IllegalAccessException | AccessControlException ex) {
-            logger.debug("Could not access enum value while reading annotation metadata", ex);
-        }
-        return valueToUse;
-    }
-
-}
diff --git a/grails-common/src/main/groovy/org/apache/grails/common/annotation/AnnotationAttributesReadingVisitor.java b/grails-common/src/main/groovy/org/apache/grails/common/annotation/AnnotationAttributesReadingVisitor.java
deleted file mode 100644
index 91e4bad1d0..0000000000
--- a/grails-common/src/main/groovy/org/apache/grails/common/annotation/AnnotationAttributesReadingVisitor.java
+++ /dev/null
@@ -1,131 +0,0 @@
-/*
- * Copyright 2002-2024 the original author or authors.
- *
- * Licensed 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.common.annotation;
-
-import java.lang.annotation.Annotation;
-import java.lang.reflect.Modifier;
-import java.util.LinkedHashSet;
-import java.util.List;
-import java.util.Map;
-import java.util.Set;
-
-import org.springframework.core.annotation.AnnotationAttributes;
-import org.springframework.core.annotation.AnnotationUtils;
-import org.springframework.lang.Nullable;
-import org.springframework.util.MultiValueMap;
-import org.springframework.util.ObjectUtils;
-
-/**
- * ASM visitor which looks for annotations defined on a class or method,
- * including meta-annotations.
- *
- * <p>This visitor is fully recursive, taking into account any nested
- * annotations or nested annotation arrays.
- *
- * <p>Note: This class was ported to Grails 7 from Spring Framework 5.3 as it was
- * removed in Spring 6 without a public replacement.
- *
- * @author Juergen Hoeller
- * @author Chris Beams
- * @author Phillip Webb
- * @author Sam Brannen
- * @since 3.0
- * @deprecated As of Spring Framework 5.2, this class and related classes in this
- * package have been replaced by SimpleAnnotationMetadataReadingVisitor
- * and related classes for internal use within the framework.
- */
-@Deprecated
-final class AnnotationAttributesReadingVisitor extends RecursiveAnnotationAttributesVisitor {
-
-    private final MultiValueMap<String, AnnotationAttributes> attributesMap;
-
-    private final Map<String, Set<String>> metaAnnotationMap;
-
-
-    public AnnotationAttributesReadingVisitor(String annotationType,
-                                              MultiValueMap<String, AnnotationAttributes> attributesMap, Map<String, Set<String>> metaAnnotationMap,
-                                              @Nullable ClassLoader classLoader) {
-
-        super(annotationType, new AnnotationAttributes(annotationType, classLoader), classLoader);
-        this.attributesMap = attributesMap;
-        this.metaAnnotationMap = metaAnnotationMap;
-    }
-
-
-    @Override
-    public void visitEnd() {
-        super.visitEnd();
-
-        Class<? extends Annotation> annotationClass = this.attributes.annotationType();
-        if (annotationClass != null) {
-            List<AnnotationAttributes> attributeList = this.attributesMap.get(this.annotationType);
-            if (attributeList == null) {
-                this.attributesMap.add(this.annotationType, this.attributes);
-            }
-            else {
-                attributeList.add(0, this.attributes);
-            }
-            if (!AnnotationUtils.isInJavaLangAnnotationPackage(annotationClass.getName())) {
-                try {
-                    Annotation[] metaAnnotations = annotationClass.getAnnotations();
-                    if (!ObjectUtils.isEmpty(metaAnnotations)) {
-                        Set<Annotation> visited = new LinkedHashSet<>();
-                        for (Annotation metaAnnotation : metaAnnotations) {
-                            recursivelyCollectMetaAnnotations(visited, metaAnnotation);
-                        }
-                        if (!visited.isEmpty()) {
-                            Set<String> metaAnnotationTypeNames = new LinkedHashSet<>(visited.size());
-                            for (Annotation ann : visited) {
-                                metaAnnotationTypeNames.add(ann.annotationType().getName());
-                            }
-                            this.metaAnnotationMap.put(annotationClass.getName(), metaAnnotationTypeNames);
-                        }
-                    }
-                }
-                catch (Throwable ex) {
-                    if (logger.isDebugEnabled()) {
-                        logger.debug("Failed to introspect meta-annotations on " + annotationClass + ": " + ex);
-                    }
-                }
-            }
-        }
-    }
-
-    private void recursivelyCollectMetaAnnotations(Set<Annotation> visited, Annotation annotation) {
-        Class<? extends Annotation> annotationType = annotation.annotationType();
-        String annotationName = annotationType.getName();
-        if (!AnnotationUtils.isInJavaLangAnnotationPackage(annotationName) && visited.add(annotation)) {
-            try {
-                // Only do attribute scanning for public annotations; we'd run into
-                // IllegalAccessExceptions otherwise, and we don't want to mess with
-                // accessibility in a SecurityManager environment.
-                if (Modifier.isPublic(annotationType.getModifiers())) {
-                    this.attributesMap.add(annotationName,
-                            AnnotationUtils.getAnnotationAttributes(annotation, false, true));
-                }
-                for (Annotation metaMetaAnnotation : annotationType.getAnnotations()) {
-                    recursivelyCollectMetaAnnotations(visited, metaMetaAnnotation);
-                }
-            }
-            catch (Throwable ex) {
-                if (logger.isDebugEnabled()) {
-                    logger.debug("Failed to introspect meta-annotations on " + annotation + ": " + ex);
-                }
-            }
-        }
-    }
-
-}
diff --git a/grails-common/src/main/groovy/org/apache/grails/common/annotation/AnnotationMetadataReadingVisitor.java b/grails-common/src/main/groovy/org/apache/grails/common/annotation/AnnotationMetadataReadingVisitor.java
deleted file mode 100644
index 664ba4afd2..0000000000
--- a/grails-common/src/main/groovy/org/apache/grails/common/annotation/AnnotationMetadataReadingVisitor.java
+++ /dev/null
@@ -1,207 +0,0 @@
-/*
- * Copyright 2002-2024 the original author or authors.
- *
- * Licensed 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.common.annotation;
-
-import java.util.Collection;
-import java.util.Collections;
-import java.util.LinkedHashMap;
-import java.util.LinkedHashSet;
-import java.util.List;
-import java.util.Map;
-import java.util.Set;
-
-import org.springframework.asm.AnnotationVisitor;
-import org.springframework.asm.MethodVisitor;
-import org.springframework.asm.Opcodes;
-import org.springframework.asm.Type;
-import org.springframework.core.annotation.AnnotationAttributes;
-import org.springframework.core.annotation.AnnotationUtils;
-import org.springframework.core.annotation.MergedAnnotations;
-import org.springframework.core.type.AnnotationMetadata;
-import org.springframework.core.type.MethodMetadata;
-import org.springframework.lang.Nullable;
-import org.springframework.util.LinkedMultiValueMap;
-import org.springframework.util.MultiValueMap;
-
-/**
- * ASM class visitor which looks for the class name and implemented types as
- * well as for the annotations defined on the class, exposing them through
- * the {@link org.springframework.core.type.AnnotationMetadata} interface.
- *
- * <p>Note: This class was ported to Grails 7 from Spring Framework 5.3 as it was
- * removed in Spring 6 without a public replacement.
- *
- * @author Juergen Hoeller
- * @author Mark Fisher
- * @author Costin Leau
- * @author Phillip Webb
- * @author Sam Brannen
- * @since 2.5
- * @deprecated As of Spring Framework 5.2, this class has been replaced by
- * SimpleAnnotationMetadataReadingVisitor for internal use within the
- * framework, but there is no public replacement for
- * {@code AnnotationMetadataReadingVisitor}.
- */
-@Deprecated
-public class AnnotationMetadataReadingVisitor extends ClassMetadataReadingVisitor implements AnnotationMetadata {
-
-    @Nullable
-    protected final ClassLoader classLoader;
-
-    protected final Set<String> annotationSet = new LinkedHashSet<>(4);
-
-    protected final Map<String, Set<String>> metaAnnotationMap = new LinkedHashMap<>(4);
-
-    /**
-     * Declared as a {@link LinkedMultiValueMap} instead of a {@link MultiValueMap}
-     * to ensure that the hierarchical ordering of the entries is preserved.
-     * @see AnnotationReadingVisitorUtils#getMergedAnnotationAttributes
-     */
-    protected final LinkedMultiValueMap<String, AnnotationAttributes> attributesMap = new LinkedMultiValueMap<>(3);
-
-    protected final Set<MethodMetadata> methodMetadataSet = new LinkedHashSet<>(4);
-
-
-    public AnnotationMetadataReadingVisitor(@Nullable ClassLoader classLoader) {
-        this.classLoader = classLoader;
-    }
-
-
-    @Override
-    public MergedAnnotations getAnnotations() {
-        throw new UnsupportedOperationException();
-    }
-
-    @Override
-    public MethodVisitor visitMethod(int access, String name, String desc, String signature, String[] exceptions) {
-        // Skip bridge methods - we're only interested in original annotation-defining user methods.
-        // On JDK 8, we'd otherwise run into double detection of the same annotated method...
-        if ((access & Opcodes.ACC_BRIDGE) != 0) {
-            return super.visitMethod(access, name, desc, signature, exceptions);
-        }
-        return new MethodMetadataReadingVisitor(name, access, getClassName(),
-                Type.getReturnType(desc).getClassName(), this.classLoader, this.methodMetadataSet);
-    }
-
-    @Override
-    @Nullable
-    public AnnotationVisitor visitAnnotation(String desc, boolean visible) {
-        if (!visible) {
-            return null;
-        }
-        String className = Type.getType(desc).getClassName();
-        if (AnnotationUtils.isInJavaLangAnnotationPackage(className)) {
-            return null;
-        }
-        this.annotationSet.add(className);
-        return new AnnotationAttributesReadingVisitor(
-                className, this.attributesMap, this.metaAnnotationMap, this.classLoader);
-    }
-
-
-    @Override
-    public Set<String> getAnnotationTypes() {
-        return this.annotationSet;
-    }
-
-    @Override
-    public Set<String> getMetaAnnotationTypes(String annotationName) {
-        Set<String> metaAnnotationTypes = this.metaAnnotationMap.get(annotationName);
-        return (metaAnnotationTypes != null ? metaAnnotationTypes : Collections.emptySet());
-    }
-
-    @Override
-    public boolean hasMetaAnnotation(String metaAnnotationType) {
-        if (AnnotationUtils.isInJavaLangAnnotationPackage(metaAnnotationType)) {
-            return false;
-        }
-        Collection<Set<String>> allMetaTypes = this.metaAnnotationMap.values();
-        for (Set<String> metaTypes : allMetaTypes) {
-            if (metaTypes.contains(metaAnnotationType)) {
-                return true;
-            }
-        }
-        return false;
-    }
-
-    @Override
-    public boolean isAnnotated(String annotationName) {
-        return (!AnnotationUtils.isInJavaLangAnnotationPackage(annotationName) &&
-                this.attributesMap.containsKey(annotationName));
-    }
-
-    @Override
-    public boolean hasAnnotation(String annotationName) {
-        return getAnnotationTypes().contains(annotationName);
-    }
-
-    @Override
-    @Nullable
-    public AnnotationAttributes getAnnotationAttributes(String annotationName, boolean classValuesAsString) {
-        AnnotationAttributes raw = AnnotationReadingVisitorUtils.getMergedAnnotationAttributes(
-                this.attributesMap, this.metaAnnotationMap, annotationName);
-        if (raw == null) {
-            return null;
-        }
-        return AnnotationReadingVisitorUtils.convertClassValues(
-                "class '" + getClassName() + "'", this.classLoader, raw, classValuesAsString);
-    }
-
-    @Override
-    @Nullable
-    public MultiValueMap<String, Object> getAllAnnotationAttributes(String annotationName, boolean classValuesAsString) {
-        MultiValueMap<String, Object> allAttributes = new LinkedMultiValueMap<>();
-        List<AnnotationAttributes> attributes = this.attributesMap.get(annotationName);
-        if (attributes == null) {
-            return null;
-        }
-        String annotatedElement = "class '" + getClassName() + "'";
-        for (AnnotationAttributes raw : attributes) {
-            for (Map.Entry<String, Object> entry : AnnotationReadingVisitorUtils.convertClassValues(
-                    annotatedElement, this.classLoader, raw, classValuesAsString).entrySet()) {
-                allAttributes.add(entry.getKey(), entry.getValue());
-            }
-        }
-        return allAttributes;
-    }
-
-    @Override
-    public boolean hasAnnotatedMethods(String annotationName) {
-        for (MethodMetadata methodMetadata : this.methodMetadataSet) {
-            if (methodMetadata.isAnnotated(annotationName)) {
-                return true;
-            }
-        }
-        return false;
-    }
-
-    @Override
-    public Set<MethodMetadata> getAnnotatedMethods(String annotationName) {
-        Set<MethodMetadata> annotatedMethods = new LinkedHashSet<>(4);
-        for (MethodMetadata methodMetadata : this.methodMetadataSet) {
-            if (methodMetadata.isAnnotated(annotationName)) {
-                annotatedMethods.add(methodMetadata);
-            }
-        }
-        return annotatedMethods;
-    }
-
-    @Override
-    public Set<MethodMetadata> getDeclaredMethods() {
-        return Set.of();
-    }
-
-}
diff --git a/grails-common/src/main/groovy/org/apache/grails/common/annotation/AnnotationReadingVisitorUtils.java b/grails-common/src/main/groovy/org/apache/grails/common/annotation/AnnotationReadingVisitorUtils.java
deleted file mode 100644
index 7b20f290af..0000000000
--- a/grails-common/src/main/groovy/org/apache/grails/common/annotation/AnnotationReadingVisitorUtils.java
+++ /dev/null
@@ -1,176 +0,0 @@
-/*
- * Copyright 2002-2024 the original author or authors.
- *
- * Licensed 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.common.annotation;
-
-import java.util.ArrayList;
-import java.util.Collections;
-import java.util.HashSet;
-import java.util.List;
-import java.util.Map;
-import java.util.Set;
-
-import org.springframework.asm.Type;
-import org.springframework.core.annotation.AnnotationAttributes;
-import org.springframework.core.annotation.AnnotationUtils;
-import org.springframework.lang.Nullable;
-import org.springframework.util.ClassUtils;
-import org.springframework.util.CollectionUtils;
-import org.springframework.util.LinkedMultiValueMap;
-import org.springframework.util.ObjectUtils;
-
-/**
- * Internal utility class used when reading annotations via ASM.
- *
- * <p>Note: This class was ported to Grails 7 from Spring Framework 5.3 as it was
- * removed in Spring 6 without a public replacement.
- *
- * @author Juergen Hoeller
- * @author Mark Fisher
- * @author Costin Leau
- * @author Phillip Webb
- * @author Sam Brannen
- * @since 4.0
- * @deprecated As of Spring Framework 5.2, this class and related classes in this
- * package have been replaced by SimpleAnnotationMetadataReadingVisitor
- * and related classes for internal use within the framework.
- */
-@Deprecated
-abstract class AnnotationReadingVisitorUtils {
-
-    public static AnnotationAttributes convertClassValues(Object annotatedElement,
-                                                          @Nullable ClassLoader classLoader, AnnotationAttributes original, boolean classValuesAsString) {
-
-        AnnotationAttributes result = new AnnotationAttributes(original);
-        AnnotationUtils.postProcessAnnotationAttributes(annotatedElement, result, classValuesAsString);
-
-        for (Map.Entry<String, Object> entry : result.entrySet()) {
-            try {
-                Object value = entry.getValue();
-                if (value instanceof AnnotationAttributes) {
-                    value = convertClassValues(
-                            annotatedElement, classLoader, (AnnotationAttributes) value, classValuesAsString);
-                }
-                else if (value instanceof AnnotationAttributes[]) {
-                    AnnotationAttributes[] values = (AnnotationAttributes[]) value;
-                    for (int i = 0; i < values.length; i++) {
-                        values[i] = convertClassValues(annotatedElement, classLoader, values[i], classValuesAsString);
-                    }
-                    value = values;
-                }
-                else if (value instanceof Type) {
-                    value = (classValuesAsString ? ((Type) value).getClassName() :
-                            ClassUtils.forName(((Type) value).getClassName(), classLoader));
-                }
-                else if (value instanceof Type[]) {
-                    Type[] array = (Type[]) value;
-                    Object[] convArray =
-                            (classValuesAsString ? new String[array.length] : new Class<?>[array.length]);
-                    for (int i = 0; i < array.length; i++) {
-                        convArray[i] = (classValuesAsString ? array[i].getClassName() :
-                                ClassUtils.forName(array[i].getClassName(), classLoader));
-                    }
-                    value = convArray;
-                }
-                else if (classValuesAsString) {
-                    if (value instanceof Class) {
-                        value = ((Class<?>) value).getName();
-                    }
-                    else if (value instanceof Class[]) {
-                        Class<?>[] clazzArray = (Class<?>[]) value;
-                        String[] newValue = new String[clazzArray.length];
-                        for (int i = 0; i < clazzArray.length; i++) {
-                            newValue[i] = clazzArray[i].getName();
-                        }
-                        value = newValue;
-                    }
-                }
-                entry.setValue(value);
-            }
-            catch (Throwable ex) {
-                // Class not found - can't resolve class reference in annotation attribute.
-                result.put(entry.getKey(), ex);
-            }
-        }
-
-        return result;
-    }
-
-    /**
-     * Retrieve the merged attributes of the annotation of the given type,
-     * if any, from the supplied {@code attributesMap}.
-     * <p>Annotation attribute values appearing <em>lower</em> in the annotation
-     * hierarchy (i.e., closer to the declaring class) will override those
-     * defined <em>higher</em> in the annotation hierarchy.
-     * @param attributesMap the map of annotation attribute lists, keyed by
-     * annotation type name
-     * @param metaAnnotationMap the map of meta annotation relationships,
-     * keyed by annotation type name
-     * @param annotationName the fully qualified class name of the annotation
-     * type to look for
-     * @return the merged annotation attributes, or {@code null} if no
-     * matching annotation is present in the {@code attributesMap}
-     * @since 4.0.3
-     */
-    @Nullable
-    public static AnnotationAttributes getMergedAnnotationAttributes(
-            LinkedMultiValueMap<String, AnnotationAttributes> attributesMap,
-            Map<String, Set<String>> metaAnnotationMap, String annotationName) {
-
-        // Get the unmerged list of attributes for the target annotation.
-        List<AnnotationAttributes> attributesList = attributesMap.get(annotationName);
-        if (CollectionUtils.isEmpty(attributesList)) {
-            return null;
-        }
-
-        // To start with, we populate the result with a copy of all attribute values
-        // from the target annotation. A copy is necessary so that we do not
-        // inadvertently mutate the state of the metadata passed to this method.
-        AnnotationAttributes result = new AnnotationAttributes(attributesList.get(0));
-
-        Set<String> overridableAttributeNames = new HashSet<>(result.keySet());
-        overridableAttributeNames.remove(AnnotationUtils.VALUE);
-
-        // Since the map is a LinkedMultiValueMap, we depend on the ordering of
-        // elements in the map and reverse the order of the keys in order to traverse
-        // "down" the annotation hierarchy.
-        List<String> annotationTypes = new ArrayList<>(attributesMap.keySet());
-        Collections.reverse(annotationTypes);
-
-        // No need to revisit the target annotation type:
-        annotationTypes.remove(annotationName);
-
-        for (String currentAnnotationType : annotationTypes) {
-            List<AnnotationAttributes> currentAttributesList = attributesMap.get(currentAnnotationType);
-            if (!ObjectUtils.isEmpty(currentAttributesList)) {
-                Set<String> metaAnns = metaAnnotationMap.get(currentAnnotationType);
-                if (metaAnns != null && metaAnns.contains(annotationName)) {
-                    AnnotationAttributes currentAttributes = currentAttributesList.get(0);
-                    for (String overridableAttributeName : overridableAttributeNames) {
-                        Object value = currentAttributes.get(overridableAttributeName);
-                        if (value != null) {
-                            // Store the value, potentially overriding a value from an attribute
-                            // of the same name found higher in the annotation hierarchy.
-                            result.put(overridableAttributeName, value);
-                        }
-                    }
-                }
-            }
-        }
-
-        return result;
-    }
-
-}
diff --git a/grails-common/src/main/groovy/org/apache/grails/common/annotation/ClassMetadataReadingVisitor.java b/grails-common/src/main/groovy/org/apache/grails/common/annotation/ClassMetadataReadingVisitor.java
deleted file mode 100644
index c51cf9414e..0000000000
--- a/grails-common/src/main/groovy/org/apache/grails/common/annotation/ClassMetadataReadingVisitor.java
+++ /dev/null
@@ -1,246 +0,0 @@
-/*
- * Copyright 2002-2024 the original author or authors.
- *
- * Licensed 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.common.annotation;
-
-import java.util.LinkedHashSet;
-import java.util.Set;
-
-import org.springframework.asm.AnnotationVisitor;
-import org.springframework.asm.Attribute;
-import org.springframework.asm.ClassVisitor;
-import org.springframework.asm.FieldVisitor;
-import org.springframework.asm.MethodVisitor;
-import org.springframework.asm.Opcodes;
-import org.springframework.asm.SpringAsmInfo;
-import org.springframework.core.type.ClassMetadata;
-import org.springframework.lang.Nullable;
-import org.springframework.util.ClassUtils;
-import org.springframework.util.StringUtils;
-
-/**
- * ASM class visitor which looks only for the class name and implemented types,
- * exposing them through the {@link org.springframework.core.type.ClassMetadata}
- * interface.
- *
- * <p>Note: This class was ported to Grails 7 from Spring Framework 5.3 as it was
- * removed in Spring 6 without a public replacement.
- *
- * @author Rod Johnson
- * @author Costin Leau
- * @author Mark Fisher
- * @author Ramnivas Laddad
- * @author Chris Beams
- * @since 2.5
- * @deprecated As of Spring Framework 5.2, this class and related classes in this
- * package have been replaced by SimpleAnnotationMetadataReadingVisitor
- * and related classes for internal use within the framework.
- */
-@Deprecated
-class ClassMetadataReadingVisitor extends ClassVisitor implements ClassMetadata {
-
-    private String className = "";
-
-    private boolean isInterface;
-
-    private boolean isAnnotation;
-
-    private boolean isAbstract;
-
-    private boolean isFinal;
-
-    @Nullable
-    private String enclosingClassName;
-
-    private boolean independentInnerClass;
-
-    @Nullable
-    private String superClassName;
-
-    private String[] interfaces = new String[0];
-
-    private Set<String> memberClassNames = new LinkedHashSet<>(4);
-
-
-    public ClassMetadataReadingVisitor() {
-        super(SpringAsmInfo.ASM_VERSION);
-    }
-
-
-    @Override
-    public void visit(
-            int version, int access, String name, String signature, @Nullable String supername, String[] interfaces) {
-
-        this.className = ClassUtils.convertResourcePathToClassName(name);
-        this.isInterface = ((access & Opcodes.ACC_INTERFACE) != 0);
-        this.isAnnotation = ((access & Opcodes.ACC_ANNOTATION) != 0);
-        this.isAbstract = ((access & Opcodes.ACC_ABSTRACT) != 0);
-        this.isFinal = ((access & Opcodes.ACC_FINAL) != 0);
-        if (supername != null && !this.isInterface) {
-            this.superClassName = ClassUtils.convertResourcePathToClassName(supername);
-        }
-        this.interfaces = new String[interfaces.length];
-        for (int i = 0; i < interfaces.length; i++) {
-            this.interfaces[i] = ClassUtils.convertResourcePathToClassName(interfaces[i]);
-        }
-    }
-
-    @Override
-    public void visitOuterClass(String owner, String name, String desc) {
-        this.enclosingClassName = ClassUtils.convertResourcePathToClassName(owner);
-    }
-
-    @Override
-    public void visitInnerClass(String name, @Nullable String outerName, String innerName, int access) {
-        if (outerName != null) {
-            String fqName = ClassUtils.convertResourcePathToClassName(name);
-            String fqOuterName = ClassUtils.convertResourcePathToClassName(outerName);
-            if (this.className.equals(fqName)) {
-                this.enclosingClassName = fqOuterName;
-                this.independentInnerClass = ((access & Opcodes.ACC_STATIC) != 0);
-            }
-            else if (this.className.equals(fqOuterName)) {
-                this.memberClassNames.add(fqName);
-            }
-        }
-    }
-
-    @Override
-    public void visitSource(String source, String debug) {
-        // no-op
-    }
-
-    @Override
-    @Nullable
-    public AnnotationVisitor visitAnnotation(String desc, boolean visible) {
-        // no-op
-        return new EmptyAnnotationVisitor();
-    }
-
-    @Override
-    public void visitAttribute(Attribute attr) {
-        // no-op
-    }
-
-    @Override
-    public FieldVisitor visitField(int access, String name, String desc, String signature, Object value) {
-        // no-op
-        return new EmptyFieldVisitor();
-    }
-
-    @Override
-    public MethodVisitor visitMethod(int access, String name, String desc, String signature, String[] exceptions) {
-        // no-op
-        return new EmptyMethodVisitor();
-    }
-
-    @Override
-    public void visitEnd() {
-        // no-op
-    }
-
-
-    @Override
-    public String getClassName() {
-        return this.className;
-    }
-
-    @Override
-    public boolean isInterface() {
-        return this.isInterface;
-    }
-
-    @Override
-    public boolean isAnnotation() {
-        return this.isAnnotation;
-    }
-
-    @Override
-    public boolean isAbstract() {
-        return this.isAbstract;
-    }
-
-    @Override
-    public boolean isFinal() {
-        return this.isFinal;
-    }
-
-    @Override
-    public boolean isIndependent() {
-        return (this.enclosingClassName == null || this.independentInnerClass);
-    }
-
-    @Override
-    public boolean hasEnclosingClass() {
-        return (this.enclosingClassName != null);
-    }
-
-    @Override
-    @Nullable
-    public String getEnclosingClassName() {
-        return this.enclosingClassName;
-    }
-
-    @Override
-    @Nullable
-    public String getSuperClassName() {
-        return this.superClassName;
-    }
-
-    @Override
-    public String[] getInterfaceNames() {
-        return this.interfaces;
-    }
-
-    @Override
-    public String[] getMemberClassNames() {
-        return StringUtils.toStringArray(this.memberClassNames);
-    }
-
-
-    private static class EmptyAnnotationVisitor extends AnnotationVisitor {
-
-        public EmptyAnnotationVisitor() {
-            super(SpringAsmInfo.ASM_VERSION);
-        }
-
-        @Override
-        public AnnotationVisitor visitAnnotation(String name, String desc) {
-            return this;
-        }
-
-        @Override
-        public AnnotationVisitor visitArray(String name) {
-            return this;
-        }
-    }
-
-
-    private static class EmptyMethodVisitor extends MethodVisitor {
-
-        public EmptyMethodVisitor() {
-            super(SpringAsmInfo.ASM_VERSION);
-        }
-    }
-
-
-    private static class EmptyFieldVisitor extends FieldVisitor {
-
-        public EmptyFieldVisitor() {
-            super(SpringAsmInfo.ASM_VERSION);
-        }
-    }
-
-}
diff --git a/grails-common/src/main/groovy/org/apache/grails/common/annotation/MethodMetadataReadingVisitor.java b/grails-common/src/main/groovy/org/apache/grails/common/annotation/MethodMetadataReadingVisitor.java
deleted file mode 100644
index 9e06949c6a..0000000000
--- a/grails-common/src/main/groovy/org/apache/grails/common/annotation/MethodMetadataReadingVisitor.java
+++ /dev/null
@@ -1,176 +0,0 @@
-/*
- * Copyright 2002-2024 the original author or authors.
- *
- * Licensed 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.common.annotation;
-
-import java.util.LinkedHashMap;
-import java.util.List;
-import java.util.Map;
-import java.util.Set;
-
-import org.springframework.asm.AnnotationVisitor;
-import org.springframework.asm.MethodVisitor;
-import org.springframework.asm.Opcodes;
-import org.springframework.asm.SpringAsmInfo;
-import org.springframework.asm.Type;
-import org.springframework.core.annotation.AnnotationAttributes;
-import org.springframework.core.annotation.MergedAnnotations;
-import org.springframework.core.type.MethodMetadata;
-import org.springframework.lang.Nullable;
-import org.springframework.util.LinkedMultiValueMap;
-import org.springframework.util.MultiValueMap;
-
-/**
- * ASM method visitor which looks for the annotations defined on a method,
- * exposing them through the {@link org.springframework.core.type.MethodMetadata}
- * interface.
- *
- * <p>Note: This class was ported to Grails 7 from Spring Framework 5.3 as it was
- * removed in Spring 6 without a public replacement.
- *
- * @author Juergen Hoeller
- * @author Mark Pollack
- * @author Costin Leau
- * @author Chris Beams
- * @author Phillip Webb
- * @since 3.0
- * @deprecated As of Spring Framework 5.2, this class and related classes in this
- * package have been replaced by SimpleAnnotationMetadataReadingVisitor
- * and related classes for internal use within the framework.
- */
-@Deprecated
-public class MethodMetadataReadingVisitor extends MethodVisitor implements MethodMetadata {
-
-    protected final String methodName;
-
-    protected final int access;
-
-    protected final String declaringClassName;
-
-    protected final String returnTypeName;
-
-    @Nullable
-    protected final ClassLoader classLoader;
-
-    protected final Set<MethodMetadata> methodMetadataSet;
-
-    protected final Map<String, Set<String>> metaAnnotationMap = new LinkedHashMap<>(4);
-
-    protected final LinkedMultiValueMap<String, AnnotationAttributes> attributesMap = new LinkedMultiValueMap<>(3);
-
-
-    public MethodMetadataReadingVisitor(String methodName, int access, String declaringClassName,
-                                        String returnTypeName, @Nullable ClassLoader classLoader, Set<MethodMetadata> methodMetadataSet) {
-
-        super(SpringAsmInfo.ASM_VERSION);
-        this.methodName = methodName;
-        this.access = access;
-        this.declaringClassName = declaringClassName;
-        this.returnTypeName = returnTypeName;
-        this.classLoader = classLoader;
-        this.methodMetadataSet = methodMetadataSet;
-    }
-
-
-    @Override
-    public MergedAnnotations getAnnotations() {
-        throw new UnsupportedOperationException();
-    }
-
-    @Override
-    @Nullable
-    public AnnotationVisitor visitAnnotation(final String desc, boolean visible) {
-        if (!visible) {
-            return null;
-        }
-        this.methodMetadataSet.add(this);
-        String className = Type.getType(desc).getClassName();
-        return new AnnotationAttributesReadingVisitor(
-                className, this.attributesMap, this.metaAnnotationMap, this.classLoader);
-    }
-
-
-    @Override
-    public String getMethodName() {
-        return this.methodName;
-    }
-
-    @Override
-    public boolean isAbstract() {
-        return ((this.access & Opcodes.ACC_ABSTRACT) != 0);
-    }
-
-    @Override
-    public boolean isStatic() {
-        return ((this.access & Opcodes.ACC_STATIC) != 0);
-    }
-
-    @Override
-    public boolean isFinal() {
-        return ((this.access & Opcodes.ACC_FINAL) != 0);
-    }
-
-    @Override
-    public boolean isOverridable() {
-        return (!isStatic() && !isFinal() && ((this.access & Opcodes.ACC_PRIVATE) == 0));
-    }
-
-    @Override
-    public boolean isAnnotated(String annotationName) {
-        return this.attributesMap.containsKey(annotationName);
-    }
-
-    @Override
-    @Nullable
-    public AnnotationAttributes getAnnotationAttributes(String annotationName, boolean classValuesAsString) {
-        AnnotationAttributes raw = AnnotationReadingVisitorUtils.getMergedAnnotationAttributes(
-                this.attributesMap, this.metaAnnotationMap, annotationName);
-        if (raw == null) {
-            return null;
-        }
-        return AnnotationReadingVisitorUtils.convertClassValues(
-                "method '" + getMethodName() + "'", this.classLoader, raw, classValuesAsString);
-    }
-
-    @Override
-    @Nullable
-    public MultiValueMap<String, Object> getAllAnnotationAttributes(String annotationName, boolean classValuesAsString) {
-        if (!this.attributesMap.containsKey(annotationName)) {
-            return null;
-        }
-        MultiValueMap<String, Object> allAttributes = new LinkedMultiValueMap<>();
-        List<AnnotationAttributes> attributesList = this.attributesMap.get(annotationName);
-        if (attributesList != null) {
-            String annotatedElement = "method '" + getMethodName() + '\'';
-            for (AnnotationAttributes annotationAttributes : attributesList) {
-                AnnotationAttributes convertedAttributes = AnnotationReadingVisitorUtils.convertClassValues(
-                        annotatedElement, this.classLoader, annotationAttributes, classValuesAsString);
-                convertedAttributes.forEach(allAttributes::add);
-            }
-        }
-        return allAttributes;
-    }
-
-    @Override
-    public String getDeclaringClassName() {
-        return this.declaringClassName;
-    }
-
-    @Override
-    public String getReturnTypeName() {
-        return this.returnTypeName;
-    }
-
-}
diff --git a/grails-common/src/main/groovy/org/apache/grails/common/annotation/RecursiveAnnotationArrayVisitor.java b/grails-common/src/main/groovy/org/apache/grails/common/annotation/RecursiveAnnotationArrayVisitor.java
deleted file mode 100644
index d7ee022739..0000000000
--- a/grails-common/src/main/groovy/org/apache/grails/common/annotation/RecursiveAnnotationArrayVisitor.java
+++ /dev/null
@@ -1,112 +0,0 @@
-/*
- * Copyright 2002-2024 the original author or authors.
- *
- * Licensed 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.common.annotation;
-
-import java.lang.annotation.Annotation;
-import java.lang.reflect.Array;
-import java.util.ArrayList;
-import java.util.List;
-
-import org.springframework.asm.AnnotationVisitor;
-import org.springframework.asm.Type;
-import org.springframework.core.annotation.AnnotationAttributes;
-import org.springframework.lang.Nullable;
-import org.springframework.util.ObjectUtils;
-
-/**
- * {@link AnnotationVisitor} to recursively visit annotation arrays.
- *
- * <p>Note: This class was ported to Grails 7 from Spring Framework 5.3 as it was
- * removed in Spring 6 without a public replacement.
- *
- * @author Chris Beams
- * @author Juergen Hoeller
- * @since 3.1.1
- * @deprecated As of Spring Framework 5.2, this class and related classes in this
- * package have been replaced by SimpleAnnotationMetadataReadingVisitor
- * and related classes for internal use within the framework.
- */
-@Deprecated
-class RecursiveAnnotationArrayVisitor extends AbstractRecursiveAnnotationVisitor {
-
-    private final String attributeName;
-
-    private final List<AnnotationAttributes> allNestedAttributes = new ArrayList<>();
-
-
-    public RecursiveAnnotationArrayVisitor(
-            String attributeName, AnnotationAttributes attributes, @Nullable ClassLoader classLoader) {
-
-        super(classLoader, attributes);
-        this.attributeName = attributeName;
-    }
-
-
-    @Override
-    public void visit(String attributeName, Object attributeValue) {
-        Object newValue = attributeValue;
-        Object existingValue = this.attributes.get(this.attributeName);
-        if (existingValue != null) {
-            newValue = ObjectUtils.addObjectToArray((Object[]) existingValue, newValue);
-        }
-        else {
-            Class<?> arrayClass = newValue.getClass();
-            if (Enum.class.isAssignableFrom(arrayClass)) {
-                while (arrayClass.getSuperclass() != null && !arrayClass.isEnum()) {
-                    arrayClass = arrayClass.getSuperclass();
-                }
-            }
-            Object[] newArray = (Object[]) Array.newInstance(arrayClass, 1);
-            newArray[0] = newValue;
-            newValue = newArray;
-        }
-        this.attributes.put(this.attributeName, newValue);
-    }
-
-    @Override
-    public AnnotationVisitor visitAnnotation(String attributeName, String asmTypeDescriptor) {
-        String annotationType = Type.getType(asmTypeDescriptor).getClassName();
-        AnnotationAttributes nestedAttributes = new AnnotationAttributes(annotationType, this.classLoader);
-        this.allNestedAttributes.add(nestedAttributes);
-        return new RecursiveAnnotationAttributesVisitor(annotationType, nestedAttributes, this.classLoader);
-    }
-
-    @Override
-    public void visitEnd() {
-        if (!this.allNestedAttributes.isEmpty()) {
-            this.attributes.put(this.attributeName, this.allNestedAttributes.toArray(new AnnotationAttributes[0]));
-        }
-        else if (!this.attributes.containsKey(this.attributeName)) {
-            Class<? extends Annotation> annotationType = this.attributes.annotationType();
-            if (annotationType != null) {
-                try {
-                    Class<?> attributeType = annotationType.getMethod(this.attributeName).getReturnType();
-                    if (attributeType.isArray()) {
-                        Class<?> elementType = attributeType.getComponentType();
-                        if (elementType.isAnnotation()) {
-                            elementType = AnnotationAttributes.class;
-                        }
-                        this.attributes.put(this.attributeName, Array.newInstance(elementType, 0));
-                    }
-                }
-                catch (NoSuchMethodException ex) {
-                    // Corresponding attribute method not found: cannot expose empty array.
-                }
-            }
-        }
-    }
-
-}
diff --git a/grails-common/src/main/groovy/org/apache/grails/common/annotation/RecursiveAnnotationAttributesVisitor.java b/grails-common/src/main/groovy/org/apache/grails/common/annotation/RecursiveAnnotationAttributesVisitor.java
deleted file mode 100644
index dc8b935d1a..0000000000
--- a/grails-common/src/main/groovy/org/apache/grails/common/annotation/RecursiveAnnotationAttributesVisitor.java
+++ /dev/null
@@ -1,55 +0,0 @@
-/*
- * Copyright 2002-2024 the original author or authors.
- *
- * Licensed 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.common.annotation;
-
-import org.springframework.asm.AnnotationVisitor;
-import org.springframework.core.annotation.AnnotationAttributes;
-import org.springframework.core.annotation.AnnotationUtils;
-import org.springframework.lang.Nullable;
-
-/**
- * {@link AnnotationVisitor} to recursively visit annotation attributes.
- *
- * <p>Note: This class was ported to Grails 7 from Spring Framework 5.3 as it was
- * removed in Spring 6 without a public replacement.
- *
- * @author Chris Beams
- * @author Juergen Hoeller
- * @since 3.1.1
- * @deprecated As of Spring Framework 5.2, this class and related classes in this
- * package have been replaced by SimpleAnnotationMetadataReadingVisitor
- * and related classes for internal use within the framework.
- */
-@Deprecated
-class RecursiveAnnotationAttributesVisitor extends AbstractRecursiveAnnotationVisitor {
-
-    protected final String annotationType;
-
-
-    public RecursiveAnnotationAttributesVisitor(
-            String annotationType, AnnotationAttributes attributes, @Nullable ClassLoader classLoader) {
-
-        super(classLoader, attributes);
-        this.annotationType = annotationType;
-    }
-
-
-    @Override
-    public void visitEnd() {
-        AnnotationUtils.registerDefaultValues(this.attributes);
-    }
-
-}
diff --git a/grails-common/src/main/groovy/org/apache/grails/common/compiler/asm/AnnotationMetadataReader.java b/grails-common/src/main/groovy/org/apache/grails/common/compiler/asm/AnnotationMetadataReader.java
deleted file mode 100644
index 98a5342bde..0000000000
--- a/grails-common/src/main/groovy/org/apache/grails/common/compiler/asm/AnnotationMetadataReader.java
+++ /dev/null
@@ -1,142 +0,0 @@
-/*
- *  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.common.compiler.asm;
-
-import org.apache.grails.common.annotation.AnnotationMetadataReadingVisitor;
-import org.springframework.asm.AnnotationVisitor;
-import org.springframework.asm.SpringAsmInfo;
-import org.springframework.asm.Type;
-import org.springframework.core.io.Resource;
-import org.springframework.core.type.AnnotationMetadata;
-import org.springframework.core.type.ClassMetadata;
-import org.springframework.core.type.classreading.MetadataReader;
-
-import java.io.BufferedInputStream;
-import java.io.IOException;
-import java.io.InputStream;
-
-/**
- * A more limited version of Spring's annotation reader that only reads annotations on classes
- *
- * @author Graeme Rocher
- * @since 3.1.13
- */
-public class AnnotationMetadataReader implements MetadataReader {
-    private final Resource resource;
-
-    private final ClassMetadata classMetadata;
-
-    private final AnnotationMetadata annotationMetadata;
-
-    /**
-     * Reads only the annotation names from a class resource
-     * @param resource The resource
-     * @param classLoader The classloader
-     * @throws IOException
-     */
-    public AnnotationMetadataReader(Resource resource, ClassLoader classLoader) throws IOException {
-        this(resource, classLoader, false);
-    }
-    /**
-     * Constructs a new annotation metadata reader
-     *
-     * @param resource The resource
-     * @param classLoader The classloader
-     * @param readAttributeValues Whether to read the attributes in addition or just the annotation class names
-     * @throws IOException
-     */
-    public AnnotationMetadataReader(Resource resource, ClassLoader classLoader, boolean readAttributeValues) throws IOException {
-        InputStream is = new BufferedInputStream(resource.getInputStream());
-        ClassReader classReader;
-        try {
-            classReader = new ClassReader(is);
-        }
-        catch (IllegalArgumentException ex) {
-            throw new IOException("ASM ClassReader failed to parse class file - " +
-                    "probably due to a new Java class file version that isn't supported yet: " + resource, ex);
-        }
-        finally {
-            is.close();
-        }
-
-
-        AnnotationMetadataReadingVisitor visitor;
-
-        if(readAttributeValues) {
-            visitor = new AnnotationMetadataReadingVisitor(classLoader);
-        }
-        else {
-            visitor = new AnnotationMetadataReadingVisitor(classLoader) {
-                @Override
-                public AnnotationVisitor visitAnnotation(final String desc, boolean visible) {
-                    String className = Type.getType(desc).getClassName();
-                    this.annotationSet.add(className);
-                    return new EmptyAnnotationVisitor();
-                }
-            };
-        }
-        classReader.accept(visitor, ClassReader.SKIP_DEBUG);
-
-        this.annotationMetadata = visitor;
-        // (since AnnotationMetadataReadingVisitor extends ClassMetadataReadingVisitor)
-        this.classMetadata = visitor;
-        this.resource = resource;
-    }
-
-
-    @Override
-    public Resource getResource() {
-        return this.resource;
-    }
-
-    @Override
-    public ClassMetadata getClassMetadata() {
-        return this.classMetadata;
-    }
-
-    @Override
-    public AnnotationMetadata getAnnotationMetadata() {
-        return this.annotationMetadata;
-    }
-
-    private static class EmptyAnnotationVisitor extends AnnotationVisitor {
-
-        EmptyAnnotationVisitor() {
-            super(loadAsmVersion());
-        }
-
-        private static int loadAsmVersion() {
-            try {
-                // Load the ASM version using reflection to prevent the compiler from replacing the reference
-                // with the value.  This it soupport different verisons of spring.
-                return (int) SpringAsmInfo.class.getField("ASM_VERSION").get(null);
-            } catch (Exception e) {
-                throw new RuntimeException(e);
-            }
-        }
-
-        @Override
-        public AnnotationVisitor visitAnnotation(String name, String desc) {
-            return this;
-        }
-
-        @Override
-        public AnnotationVisitor visitArray(String name) {
-            return this;
-        }
-    }
-}
diff --git a/grails-common/src/main/groovy/org/apache/grails/common/compiler/asm/Attribute.java b/grails-common/src/main/groovy/org/apache/grails/common/compiler/asm/Attribute.java
deleted file mode 100644
index 356d618d19..0000000000
--- a/grails-common/src/main/groovy/org/apache/grails/common/compiler/asm/Attribute.java
+++ /dev/null
@@ -1,258 +0,0 @@
-/***
- * ASM: a very small and fast Java bytecode manipulation framework
- * Copyright (c) 2000-2011 INRIA, France Telecom
- * All rights reserved.
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions
- * are met:
- * 1. Redistributions of source code must retain the above copyright
- *    notice, this list of conditions and the following disclaimer.
- * 2. Redistributions in binary form must reproduce the above copyright
- *    notice, this list of conditions and the following disclaimer in the
- *    documentation and/or other materials provided with the distribution.
- * 3. Neither the name of the copyright holders nor the names of its
- *    contributors may be used to endorse or promote products derived from
- *    this software without specific prior written permission.
- *
- * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
- * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
- * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
- * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE
- * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
- * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
- * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
- * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
- * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
- * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF
- * THE POSSIBILITY OF SUCH DAMAGE.
- */
-package org.apache.grails.common.compiler.asm;
-
-import org.springframework.asm.ClassWriter;
-import org.springframework.asm.Label;
-
-/**
- * A non standard class, field, method or code attribute.
- *
- * @author Eric Bruneton
- * @author Eugene Kuleshov
- */
-class Attribute {
-
-    /**
-     * The type of this attribute.
-     */
-    public final String type;
-
-    /**
-     * The raw value of this attribute, used only for unknown attributes.
-     */
-    byte[] value;
-
-    /**
-     * The next attribute in this attribute list. May be <tt>null</tt>.
-     */
-    Attribute next;
-
-    /**
-     * Constructs a new empty attribute.
-     *
-     * @param type
-     *            the type of the attribute.
-     */
-    protected Attribute(final String type) {
-        this.type = type;
-    }
-
-    /**
-     * Returns <tt>true</tt> if this type of attribute is unknown. The default
-     * implementation of this method always returns <tt>true</tt>.
-     *
-     * @return <tt>true</tt> if this type of attribute is unknown.
-     */
-    public boolean isUnknown() {
-        return true;
-    }
-
-    /**
-     * Returns <tt>true</tt> if this type of attribute is a code attribute.
-     *
-     * @return <tt>true</tt> if this type of attribute is a code attribute.
-     */
-    public boolean isCodeAttribute() {
-        return false;
-    }
-
-    /**
-     * Returns the labels corresponding to this attribute.
-     *
-     * @return the labels corresponding to this attribute, or <tt>null</tt> if
-     *         this attribute is not a code attribute that contains labels.
-     */
-    protected Label[] getLabels() {
-        return null;
-    }
-
-    /**
-     * Reads a {@link #type type} attribute. This method must return a
-     * <i>new</i> {@link Attribute} object, of type {@link #type type},
-     * corresponding to the <tt>len</tt> bytes starting at the given offset, in
-     * the given class reader.
-     *
-     * @param cr
-     *            the class that contains the attribute to be read.
-     * @param off
-     *            index of the first byte of the attribute's content in
-     *            {@link ClassReader#b cr.b}. The 6 attribute header bytes,
-     *            containing the type and the length of the attribute, are not
-     *            taken into account here.
-     * @param len
-     *            the length of the attribute's content.
-     * @param buf
-     *            buffer to be used to call {@link ClassReader#readUTF8
-     *            readUTF8}, {@link ClassReader#readClass(int,char[]) readClass}
-     *            or {@link ClassReader#readConst readConst}.
-     * @param codeOff
-     *            index of the first byte of code's attribute content in
-     *            {@link ClassReader#b cr.b}, or -1 if the attribute to be read
-     *            is not a code attribute. The 6 attribute header bytes,
-     *            containing the type and the length of the attribute, are not
-     *            taken into account here.
-     * @param labels
-     *            the labels of the method's code, or <tt>null</tt> if the
-     *            attribute to be read is not a code attribute.
-     * @return a <i>new</i> {@link Attribute} object corresponding to the given
-     *         bytes.
-     */
-    protected Attribute read(final ClassReader cr, final int off,
-                             final int len, final char[] buf, final int codeOff,
-                             final Label[] labels) {
-        Attribute attr = new Attribute(type);
-        attr.value = new byte[len];
-        System.arraycopy(cr.b, off, attr.value, 0, len);
-        return attr;
-    }
-
-    /**
-     * Returns the byte array form of this attribute.
-     *
-     * @param cw
-     *            the class to which this attribute must be added. This
-     *            parameter can be used to add to the constant pool of this
-     *            class the items that corresponds to this attribute.
-     * @param code
-     *            the bytecode of the method corresponding to this code
-     *            attribute, or <tt>null</tt> if this attribute is not a code
-     *            attributes.
-     * @param len
-     *            the length of the bytecode of the method corresponding to this
-     *            code attribute, or <tt>null</tt> if this attribute is not a
-     *            code attribute.
-     * @param maxStack
-     *            the maximum stack size of the method corresponding to this
-     *            code attribute, or -1 if this attribute is not a code
-     *            attribute.
-     * @param maxLocals
-     *            the maximum number of local variables of the method
-     *            corresponding to this code attribute, or -1 if this attribute
-     *            is not a code attribute.
-     * @return the byte array form of this attribute.
-     */
-    protected ByteVector write(final ClassWriter cw, final byte[] code,
-                               final int len, final int maxStack, final int maxLocals) {
-        ByteVector v = new ByteVector();
-        v.data = value;
-        v.length = value.length;
-        return v;
-    }
-
-    /**
-     * Returns the length of the attribute list that begins with this attribute.
-     *
-     * @return the length of the attribute list that begins with this attribute.
-     */
-    final int getCount() {
-        int count = 0;
-        Attribute attr = this;
-        while (attr != null) {
-            count += 1;
-            attr = attr.next;
-        }
-        return count;
-    }
-
-    /**
-     * Returns the size of all the attributes in this attribute list.
-     *
-     * @param cw
-     *            the class writer to be used to convert the attributes into
-     *            byte arrays, with the {@link #write write} method.
-     * @param code
-     *            the bytecode of the method corresponding to these code
-     *            attributes, or <tt>null</tt> if these attributes are not code
-     *            attributes.
-     * @param len
-     *            the length of the bytecode of the method corresponding to
-     *            these code attributes, or <tt>null</tt> if these attributes
-     *            are not code attributes.
-     * @param maxStack
-     *            the maximum stack size of the method corresponding to these
-     *            code attributes, or -1 if these attributes are not code
-     *            attributes.
-     * @param maxLocals
-     *            the maximum number of local variables of the method
-     *            corresponding to these code attributes, or -1 if these
-     *            attributes are not code attributes.
-     * @return the size of all the attributes in this attribute list. This size
-     *         includes the size of the attribute headers.
-     */
-    final int getSize(final ClassWriter cw, final byte[] code, final int len,
-                      final int maxStack, final int maxLocals) {
-        Attribute attr = this;
-        int size = 0;
-        while (attr != null) {
-            cw.newUTF8(attr.type);
-            size += attr.write(cw, code, len, maxStack, maxLocals).length + 6;
-            attr = attr.next;
-        }
-        return size;
-    }
-
-    /**
-     * Writes all the attributes of this attribute list in the given byte
-     * vector.
-     *
-     * @param cw
-     *            the class writer to be used to convert the attributes into
-     *            byte arrays, with the {@link #write write} method.
-     * @param code
-     *            the bytecode of the method corresponding to these code
-     *            attributes, or <tt>null</tt> if these attributes are not code
-     *            attributes.
-     * @param len
-     *            the length of the bytecode of the method corresponding to
-     *            these code attributes, or <tt>null</tt> if these attributes
-     *            are not code attributes.
-     * @param maxStack
-     *            the maximum stack size of the method corresponding to these
-     *            code attributes, or -1 if these attributes are not code
-     *            attributes.
-     * @param maxLocals
-     *            the maximum number of local variables of the method
-     *            corresponding to these code attributes, or -1 if these
-     *            attributes are not code attributes.
-     * @param out
-     *            where the attributes must be written.
-     */
-    final void put(final ClassWriter cw, final byte[] code, final int len,
-                   final int maxStack, final int maxLocals, final ByteVector out) {
-        Attribute attr = this;
-        while (attr != null) {
-            ByteVector b = attr.write(cw, code, len, maxStack, maxLocals);
-            out.putShort(cw.newUTF8(attr.type)).putInt(b.length);
-            out.putByteArray(b.data, 0, b.length);
-            attr = attr.next;
-        }
-    }
-}
diff --git a/grails-common/src/main/groovy/org/apache/grails/common/compiler/asm/ByteVector.java b/grails-common/src/main/groovy/org/apache/grails/common/compiler/asm/ByteVector.java
deleted file mode 100644
index d3f08fdb14..0000000000
--- a/grails-common/src/main/groovy/org/apache/grails/common/compiler/asm/ByteVector.java
+++ /dev/null
@@ -1,339 +0,0 @@
-/***
- * ASM: a very small and fast Java bytecode manipulation framework
- * Copyright (c) 2000-2011 INRIA, France Telecom
- * All rights reserved.
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions
- * are met:
- * 1. Redistributions of source code must retain the above copyright
- *    notice, this list of conditions and the following disclaimer.
- * 2. Redistributions in binary form must reproduce the above copyright
- *    notice, this list of conditions and the following disclaimer in the
- *    documentation and/or other materials provided with the distribution.
- * 3. Neither the name of the copyright holders nor the names of its
- *    contributors may be used to endorse or promote products derived from
- *    this software without specific prior written permission.
- *
- * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
- * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
- * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
- * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE
- * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
- * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
- * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
- * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
- * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
- * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF
- * THE POSSIBILITY OF SUCH DAMAGE.
- */
-package org.apache.grails.common.compiler.asm;
-
-/**
- * A dynamically extensible vector of bytes. This class is roughly equivalent to
- * a DataOutputStream on top of a ByteArrayOutputStream, but is more efficient.
- *
- * @author Eric Bruneton
- */
-class ByteVector {
-
-    /**
-     * The content of this vector.
-     */
-    byte[] data;
-
-    /**
-     * Actual number of bytes in this vector.
-     */
-    int length;
-
-    /**
-     * Constructs a new {@link ByteVector ByteVector} with a default initial
-     * size.
-     */
-    public ByteVector() {
-        data = new byte[64];
-    }
-
-    /**
-     * Constructs a new {@link ByteVector ByteVector} with the given initial
-     * size.
-     *
-     * @param initialSize
-     *            the initial size of the byte vector to be constructed.
-     */
-    public ByteVector(final int initialSize) {
-        data = new byte[initialSize];
-    }
-
-    /**
-     * Puts a byte into this byte vector. The byte vector is automatically
-     * enlarged if necessary.
-     *
-     * @param b
-     *            a byte.
-     * @return this byte vector.
-     */
-    public ByteVector putByte(final int b) {
-        int length = this.length;
-        if (length + 1 > data.length) {
-            enlarge(1);
-        }
-        data[length++] = (byte) b;
-        this.length = length;
-        return this;
-    }
-
-    /**
-     * Puts two bytes into this byte vector. The byte vector is automatically
-     * enlarged if necessary.
-     *
-     * @param b1
-     *            a byte.
-     * @param b2
-     *            another byte.
-     * @return this byte vector.
-     */
-    ByteVector put11(final int b1, final int b2) {
-        int length = this.length;
-        if (length + 2 > data.length) {
-            enlarge(2);
-        }
-        byte[] data = this.data;
-        data[length++] = (byte) b1;
-        data[length++] = (byte) b2;
-        this.length = length;
-        return this;
-    }
-
-    /**
-     * Puts a short into this byte vector. The byte vector is automatically
-     * enlarged if necessary.
-     *
-     * @param s
-     *            a short.
-     * @return this byte vector.
-     */
-    public ByteVector putShort(final int s) {
-        int length = this.length;
-        if (length + 2 > data.length) {
-            enlarge(2);
-        }
-        byte[] data = this.data;
-        data[length++] = (byte) (s >>> 8);
-        data[length++] = (byte) s;
-        this.length = length;
-        return this;
-    }
-
-    /**
-     * Puts a byte and a short into this byte vector. The byte vector is
-     * automatically enlarged if necessary.
-     *
-     * @param b
-     *            a byte.
-     * @param s
-     *            a short.
-     * @return this byte vector.
-     */
-    ByteVector put12(final int b, final int s) {
-        int length = this.length;
-        if (length + 3 > data.length) {
-            enlarge(3);
-        }
-        byte[] data = this.data;
-        data[length++] = (byte) b;
-        data[length++] = (byte) (s >>> 8);
-        data[length++] = (byte) s;
-        this.length = length;
-        return this;
-    }
-
-    /**
-     * Puts an int into this byte vector. The byte vector is automatically
-     * enlarged if necessary.
-     *
-     * @param i
-     *            an int.
-     * @return this byte vector.
-     */
-    public ByteVector putInt(final int i) {
-        int length = this.length;
-        if (length + 4 > data.length) {
-            enlarge(4);
-        }
-        byte[] data = this.data;
-        data[length++] = (byte) (i >>> 24);
-        data[length++] = (byte) (i >>> 16);
-        data[length++] = (byte) (i >>> 8);
-        data[length++] = (byte) i;
-        this.length = length;
-        return this;
-    }
-
-    /**
-     * Puts a long into this byte vector. The byte vector is automatically
-     * enlarged if necessary.
-     *
-     * @param l
-     *            a long.
-     * @return this byte vector.
-     */
-    public ByteVector putLong(final long l) {
-        int length = this.length;
-        if (length + 8 > data.length) {
-            enlarge(8);
-        }
-        byte[] data = this.data;
-        int i = (int) (l >>> 32);
-        data[length++] = (byte) (i >>> 24);
-        data[length++] = (byte) (i >>> 16);
-        data[length++] = (byte) (i >>> 8);
-        data[length++] = (byte) i;
-        i = (int) l;
-        data[length++] = (byte) (i >>> 24);
-        data[length++] = (byte) (i >>> 16);
-        data[length++] = (byte) (i >>> 8);
-        data[length++] = (byte) i;
-        this.length = length;
-        return this;
-    }
-
-    /**
-     * Puts an UTF8 string into this byte vector. The byte vector is
-     * automatically enlarged if necessary.
-     *
-     * @param s
-     *            a String whose UTF8 encoded length must be less than 65536.
-     * @return this byte vector.
-     */
-    public ByteVector putUTF8(final String s) {
-        int charLength = s.length();
-        if (charLength > 65535) {
-            throw new IllegalArgumentException();
-        }
-        int len = length;
-        if (len + 2 + charLength > data.length) {
-            enlarge(2 + charLength);
-        }
-        byte[] data = this.data;
-        // optimistic algorithm: instead of computing the byte length and then
-        // serializing the string (which requires two loops), we assume the byte
-        // length is equal to char length (which is the most frequent case), and
-        // we start serializing the string right away. During the serialization,
-        // if we find that this assumption is wrong, we continue with the
-        // general method.
-        data[len++] = (byte) (charLength >>> 8);
-        data[len++] = (byte) charLength;
-        for (int i = 0; i < charLength; ++i) {
-            char c = s.charAt(i);
-            if (c >= '\001' && c <= '\177') {
-                data[len++] = (byte) c;
-            } else {
-                length = len;
-                return encodeUTF8(s, i, 65535);
-            }
-        }
-        length = len;
-        return this;
-    }
-
-    /**
-     * Puts an UTF8 string into this byte vector. The byte vector is
-     * automatically enlarged if necessary. The string length is encoded in two
-     * bytes before the encoded characters, if there is space for that (i.e. if
-     * this.length - i - 2 >= 0).
-     *
-     * @param s
-     *            the String to encode.
-     * @param i
-     *            the index of the first character to encode. The previous
-     *            characters are supposed to have already been encoded, using
-     *            only one byte per character.
-     * @param maxByteLength
-     *            the maximum byte length of the encoded string, including the
-     *            already encoded characters.
-     * @return this byte vector.
-     */
-    ByteVector encodeUTF8(final String s, int i, int maxByteLength) {
-        int charLength = s.length();
-        int byteLength = i;
-        char c;
-        for (int j = i; j < charLength; ++j) {
-            c = s.charAt(j);
-            if (c >= '\001' && c <= '\177') {
-                byteLength++;
-            } else if (c > '\u07FF') {
-                byteLength += 3;
-            } else {
-                byteLength += 2;
-            }
-        }
-        if (byteLength > maxByteLength) {
-            throw new IllegalArgumentException();
-        }
-        int start = length - i - 2;
-        if (start >= 0) {
-            data[start] = (byte) (byteLength >>> 8);
-            data[start + 1] = (byte) byteLength;
-        }
-        if (length + byteLength - i > data.length) {
-            enlarge(byteLength - i);
-        }
-        int len = length;
-        for (int j = i; j < charLength; ++j) {
-            c = s.charAt(j);
-            if (c >= '\001' && c <= '\177') {
-                data[len++] = (byte) c;
-            } else if (c > '\u07FF') {
-                data[len++] = (byte) (0xE0 | c >> 12 & 0xF);
-                data[len++] = (byte) (0x80 | c >> 6 & 0x3F);
-                data[len++] = (byte) (0x80 | c & 0x3F);
-            } else {
-                data[len++] = (byte) (0xC0 | c >> 6 & 0x1F);
-                data[len++] = (byte) (0x80 | c & 0x3F);
-            }
-        }
-        length = len;
-        return this;
-    }
-
-    /**
-     * Puts an array of bytes into this byte vector. The byte vector is
-     * automatically enlarged if necessary.
-     *
-     * @param b
-     *            an array of bytes. May be <tt>null</tt> to put <tt>len</tt>
-     *            null bytes into this byte vector.
-     * @param off
-     *            index of the fist byte of b that must be copied.
-     * @param len
-     *            number of bytes of b that must be copied.
-     * @return this byte vector.
-     */
-    public ByteVector putByteArray(final byte[] b, final int off, final int len) {
-        if (length + len > data.length) {
-            enlarge(len);
-        }
-        if (b != null) {
-            System.arraycopy(b, off, data, length, len);
-        }
-        length += len;
-        return this;
-    }
-
-    /**
-     * Enlarge this byte vector so that it can receive n more bytes.
-     *
-     * @param size
-     *            number of additional bytes that this byte vector should be
-     *            able to receive.
-     */
-    private void enlarge(final int size) {
-        int length1 = 2 * data.length;
-        int length2 = length + size;
-        byte[] newData = new byte[length1 > length2 ? length1 : length2];
-        System.arraycopy(data, 0, newData, 0, length);
-        data = newData;
-    }
-}
diff --git a/grails-common/src/main/groovy/org/apache/grails/common/compiler/asm/ClassReader.java b/grails-common/src/main/groovy/org/apache/grails/common/compiler/asm/ClassReader.java
deleted file mode 100644
index e7afd73883..0000000000
--- a/grails-common/src/main/groovy/org/apache/grails/common/compiler/asm/ClassReader.java
+++ /dev/null
@@ -1,1056 +0,0 @@
-/***
- * ASM: a very small and fast Java bytecode manipulation framework
- * Copyright (c) 2000-2011 INRIA, France Telecom
- * All rights reserved.
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions
- * are met:
- * 1. Redistributions of source code must retain the above copyright
- *    notice, this list of conditions and the following disclaimer.
- * 2. Redistributions in binary form must reproduce the above copyright
- *    notice, this list of conditions and the following disclaimer in the
- *    documentation and/or other materials provided with the distribution.
- * 3. Neither the name of the copyright holders nor the names of its
- *    contributors may be used to endorse or promote products derived from
- *    this software without specific prior written permission.
- *
- * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
- * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
- * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
- * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE
- * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
- * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
- * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
- * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
- * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
- * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF
- * THE POSSIBILITY OF SUCH DAMAGE.
- */
-package org.apache.grails.common.compiler.asm;
-
-import org.springframework.asm.*;
-import java.io.IOException;
-import java.io.InputStream;
-
-/**
- * A Java class parser to make a {@link org.springframework.asm.ClassVisitor} visit an existing class.
- * This class parses a byte array conforming to the Java class file format and
- * calls the appropriate visit methods of a given class visitor for each field,
- * method and bytecode instruction encountered.
- *
- * @author Eric Bruneton
- * @author Eugene Kuleshov
- */
-class ClassReader {
-    /**
-     * Pseudo access flag to distinguish between the synthetic attribute and the
-     * synthetic access flag.
-     */
-    static final int ACC_SYNTHETIC_ATTRIBUTE = 0x40000;
-
-
-    /**
-     * The type of CONSTANT_Class constant pool items.
-     */
-    static final int CLASS = 7;
-
-    /**
-     * The type of CONSTANT_Fieldref constant pool items.
-     */
-    static final int FIELD = 9;
-
-    /**
-     * The type of CONSTANT_Methodref constant pool items.
-     */
-    static final int METH = 10;
-
-    /**
-     * The type of CONSTANT_InterfaceMethodref constant pool items.
-     */
-    static final int IMETH = 11;
-
-    /**
-     * The type of CONSTANT_String constant pool items.
-     */
-    static final int STR = 8;
-
-    /**
-     * The type of CONSTANT_Integer constant pool items.
-     */
-    static final int INT = 3;
-
-    /**
-     * The type of CONSTANT_Float constant pool items.
-     */
-    static final int FLOAT = 4;
-
-    /**
-     * The type of CONSTANT_Long constant pool items.
-     */
-    static final int LONG = 5;
-
-    /**
-     * The type of CONSTANT_Double constant pool items.
-     */
-    static final int DOUBLE = 6;
-
-    /**
-     * The type of CONSTANT_NameAndType constant pool items.
-     */
-    static final int NAME_TYPE = 12;
-
-    /**
-     * The type of CONSTANT_Utf8 constant pool items.
-     */
-    static final int UTF8 = 1;
-
-    /**
-     * The type of CONSTANT_MethodType constant pool items.
-     */
-    static final int MTYPE = 16;
-
-    /**
-     * The type of CONSTANT_MethodHandle constant pool items.
-     */
-    static final int HANDLE = 15;
-
-    /**
-     * The type of CONSTANT_InvokeDynamic constant pool items.
-     */
-    static final int INDY = 18;
-
-    /**
-     * True to enable signatures support.
-     */
-    static final boolean SIGNATURES = true;
-
-    /**
-     * True to enable annotations support.
-     */
-    static final boolean ANNOTATIONS = true;
-
-
-    /**
-     * Flag to skip the debug information in the class. If this flag is set the
-     * debug information of the class is not visited, i.e. the
-     * {@link MethodVisitor#visitLocalVariable visitLocalVariable} and
-     * {@link MethodVisitor#visitLineNumber visitLineNumber} methods will not be
-     * called.
-     */
-    public static final int SKIP_DEBUG = 2;
-
-    /**
-     * The class to be parsed. <i>The content of this array must not be
-     * modified. This field is intended for {@link Attribute} sub classes, and
-     * is normally not needed by class generators or adapters.</i>
-     */
-    public final byte[] b;
-
-    /**
-     * The start index of each constant pool item in {@link #b b}, plus one. The
-     * one byte offset skips the constant pool item tag that indicates its type.
-     */
-    private final int[] items;
-
-    /**
-     * The String objects corresponding to the CONSTANT_Utf8 items. This cache
-     * avoids multiple parsing of a given CONSTANT_Utf8 constant pool item,
-     * which GREATLY improves performances (by a factor 2 to 3). This caching
-     * strategy could be extended to all constant pool items, but its benefit
-     * would not be so great for these items (because they are much less
-     * expensive to parse than CONSTANT_Utf8 items).
-     */
-    private final String[] strings;
-
-    /**
-     * Maximum length of the strings contained in the constant pool of the
-     * class.
-     */
-    private final int maxStringLength;
-
-    /**
-     * Start index of the class header information (access, name...) in
-     * {@link #b b}.
-     */
-    public final int header;
-
-    // ------------------------------------------------------------------------
-    // Constructors
-    // ------------------------------------------------------------------------
-
-    /**
-     * Constructs a new {@link ClassReader} object.
-     *
-     * @param b
-     *            the bytecode of the class to be read.
-     */
-    private ClassReader(final byte[] b) {
-        this(b, 0, b.length);
-    }
-
-    /**
-     * Constructs a new {@link ClassReader} object.
-     *
-     * @param b
-     *            the bytecode of the class to be read.
-     * @param off
-     *            the start offset of the class data.
-     * @param len
-     *            the length of the class data.
-     */
-    public ClassReader(final byte[] b, final int off, final int len) {
-        this.b = b;
-        // checks the class version
-		/* SPRING PATCH: REMOVED FOR FORWARD COMPATIBILITY WITH JDK 9
-        if (readShort(off + 6) > Opcodes.V1_8) {
-            throw new IllegalArgumentException();
-        }
-		*/
-        // parses the constant pool
-        items = new int[readUnsignedShort(off + 8)];
-        int n = items.length;
-        strings = new String[n];
-        int max = 0;
-        int index = off + 10;
-        for (int i = 1; i < n; ++i) {
-            items[i] = index + 1;
-            int size;
-            switch (b[index]) {
-                case FIELD:
-                case METH:
-                case IMETH:
-                case INT:
-                case FLOAT:
-                case NAME_TYPE:
-                case INDY:
-                    size = 5;
-                    break;
-                case LONG:
-                case DOUBLE:
-                    size = 9;
-                    ++i;
-                    break;
-                case UTF8:
-                    size = 3 + readUnsignedShort(index + 1);
-                    if (size > max) {
-                        max = size;
-                    }
-                    break;
-                case HANDLE:
-                    size = 4;
-                    break;
-                // case ClassWriter.CLASS:
-                // case ClassWriter.STR:
-                // case ClassWriter.MTYPE
-                default:
-                    size = 3;
-                    break;
-            }
-            index += size;
-        }
-        maxStringLength = max;
-        // the class header information starts just after the constant pool
-        header = index;
-    }
-
-    /**
-     * Returns the class's access flags (see {@link Opcodes}). This value may
-     * not reflect Deprecated and Synthetic flags when bytecode is before 1.5
-     * and those flags are represented by attributes.
-     *
-     * @return the class access flags
-     *
-     * @see ClassVisitor#visit(int, int, String, String, String, String[])
-     */
-    public int getAccess() {
-        return readUnsignedShort(header);
-    }
-
-    /**
-     * Returns the internal name of the class (see
-     * {@link Type#getInternalName() getInternalName}).
-     *
-     * @return the internal class name
-     *
-     * @see ClassVisitor#visit(int, int, String, String, String, String[])
-     */
-    public String getClassName() {
-        return readClass(header + 2, new char[maxStringLength]);
-    }
-
-    /**
-     * Returns the internal of name of the super class (see
-     * {@link Type#getInternalName() getInternalName}). For interfaces, the
-     * super class is {@link Object}.
-     *
-     * @return the internal name of super class, or <tt>null</tt> for
-     *         {@link Object} class.
-     *
-     * @see ClassVisitor#visit(int, int, String, String, String, String[])
-     */
-    public String getSuperName() {
-        return readClass(header + 4, new char[maxStringLength]);
-    }
-
-    /**
-     * Returns the internal names of the class's interfaces (see
-     * {@link Type#getInternalName() getInternalName}).
-     *
-     * @return the array of internal names for all implemented interfaces or
-     *         <tt>null</tt>.
-     *
-     * @see ClassVisitor#visit(int, int, String, String, String, String[])
-     */
-    public String[] getInterfaces() {
-        int index = header + 6;
-        int n = readUnsignedShort(index);
-        String[] interfaces = new String[n];
-        if (n > 0) {
-            char[] buf = new char[maxStringLength];
-            for (int i = 0; i < n; ++i) {
-                index += 2;
-                interfaces[i] = readClass(index, buf);
-            }
-        }
-        return interfaces;
-    }
-
-
-
-
-
-    /**
-     * Constructs a new {@link ClassReader} object.
-     *
-     * @param is
-     *            an input stream from which to read the class.
-     * @throws IOException
-     *             if a problem occurs during reading.
-     */
-    public ClassReader(final InputStream is) throws IOException {
-        this(readClass(is, false));
-    }
-
-    /**
-     * Constructs a new {@link ClassReader} object.
-     *
-     * @param name
-     *            the binary qualified name of the class to be read.
-     * @throws IOException
-     *             if an exception occurs during reading.
-     */
-    public ClassReader(final String name) throws IOException {
-        this(readClass(
-                ClassLoader.getSystemResourceAsStream(name.replace('.', '/')
-                        + ".class"), true));
-    }
-
-    /**
-     * Reads the bytecode of a class.
-     *
-     * @param is
-     *            an input stream from which to read the class.
-     * @param close
-     *            true to close the input stream after reading.
-     * @return the bytecode read from the given input stream.
-     * @throws IOException
-     *             if a problem occurs during reading.
-     */
-    private static byte[] readClass(final InputStream is, boolean close)
-            throws IOException {
-        if (is == null) {
-            throw new IOException("Class not found");
-        }
-        try {
-            byte[] b = new byte[is.available()];
-            int len = 0;
-            while (true) {
-                int n = is.read(b, len, b.length - len);
-                if (n == -1) {
-                    if (len < b.length) {
-                        byte[] c = new byte[len];
-                        System.arraycopy(b, 0, c, 0, len);
-                        b = c;
-                    }
-                    return b;
-                }
-                len += n;
-                if (len == b.length) {
-                    int last = is.read();
-                    if (last < 0) {
-                        return b;
-                    }
-                    byte[] c = new byte[b.length + 1000];
-                    System.arraycopy(b, 0, c, 0, len);
-                    c[len++] = (byte) last;
-                    b = c;
-                }
-            }
-        } finally {
-            if (close) {
-                is.close();
-            }
-        }
-    }
-
-    // ------------------------------------------------------------------------
-    // Public methods
-    // ------------------------------------------------------------------------
-
-    /**
-     * Makes the given visitor visit the Java class of this {@link ClassReader}
-     * . This class is the one specified in the constructor (see
-     * {@link #ClassReader(byte[]) ClassReader}).
-     *
-     * @param classVisitor
-     *            the visitor that must visit this class.
-     */
-    public void accept(final ClassVisitor classVisitor, final int flags) {
-        accept(classVisitor, new Attribute[0], flags);
-    }
-
-    /**
-     * Makes the given visitor visit the Java class of this {@link ClassReader}.
-     * This class is the one specified in the constructor (see
-     * {@link #ClassReader(byte[]) ClassReader}).
-     *
-     * @param classVisitor
-     *            the visitor that must visit this class.
-     * @param attrs
-     *            prototypes of the attributes that must be parsed during the
-     *            visit of the class. Any attribute whose type is not equal to
-     *            the type of one the prototypes will not be parsed: its byte
-     *            array value will be passed unchanged to the ClassWriter.
-     *            <i>This may corrupt it if this value contains references to
-     *            the constant pool, or has syntactic or semantic links with a
-     *            class element that has been transformed by a class adapter
-     *            between the reader and the writer</i>.
-     */
-    public void accept(final ClassVisitor classVisitor,
-                       final Attribute[] attrs, final int flags) {
-        int u = header; // current offset in the class file
-        char[] c = new char[maxStringLength]; // buffer used to read strings
-
-        Context context = new Context();
-        context.attrs = attrs;
-        context.flags = flags;
-        context.buffer = c;
-
-        // reads the class declaration
-        int access = readUnsignedShort(u);
-        String name = readClass(u + 2, c);
-        String superClass = readClass(u + 4, c);
-        String[] interfaces = new String[readUnsignedShort(u + 6)];
-        u += 8;
-        for (int i = 0; i < interfaces.length; ++i) {
-            interfaces[i] = readClass(u, c);
-            u += 2;
-        }
-
-        // reads the class attributes
-        String signature = null;
-        String sourceFile = null;
-        String sourceDebug = null;
-        String enclosingOwner = null;
-        String enclosingName = null;
-        String enclosingDesc = null;
-        int anns = 0;
-        int ianns = 0;
-        int tanns = 0;
-        int itanns = 0;
-        int innerClasses = 0;
-        Attribute attributes = null;
-
-        u = getAttributes();
-        for (int i = readUnsignedShort(u); i > 0; --i) {
-            String attrName = readUTF8(u + 2, c);
-            // tests are sorted in decreasing frequency order
-            // (based on frequencies observed on typical classes)
-            if ("SourceFile".equals(attrName)) {
-                sourceFile = readUTF8(u + 8, c);
-            } else if ("InnerClasses".equals(attrName)) {
-                innerClasses = u + 8;
-            } else if ("EnclosingMethod".equals(attrName)) {
-                enclosingOwner = readClass(u + 8, c);
-                int item = readUnsignedShort(u + 10);
-                if (item != 0) {
-                    enclosingName = readUTF8(items[item], c);
-                    enclosingDesc = readUTF8(items[item] + 2, c);
-                }
-            } else if (SIGNATURES && "Signature".equals(attrName)) {
-                signature = readUTF8(u + 8, c);
-            } else if (ANNOTATIONS
-                    && "RuntimeVisibleAnnotations".equals(attrName)) {
-                anns = u + 8;
-            } else if (ANNOTATIONS
-                    && "RuntimeVisibleTypeAnnotations".equals(attrName)) {
-                tanns = u + 8;
-            } else if ("Deprecated".equals(attrName)) {
-                access |= Opcodes.ACC_DEPRECATED;
-            } else if ("Synthetic".equals(attrName)) {
-                access |= Opcodes.ACC_SYNTHETIC
-                        | ACC_SYNTHETIC_ATTRIBUTE;
-            } else if ("SourceDebugExtension".equals(attrName)) {
-                int len = readInt(u + 4);
-                sourceDebug = readUTF(u + 8, len, new char[len]);
-            } else if (ANNOTATIONS
-                    && "RuntimeInvisibleAnnotations".equals(attrName)) {
-                ianns = u + 8;
-            } else if (ANNOTATIONS
-                    && "RuntimeInvisibleTypeAnnotations".equals(attrName)) {
-                itanns = u + 8;
-            } else if ("BootstrapMethods".equals(attrName)) {
-                int[] bootstrapMethods = new int[readUnsignedShort(u + 8)];
-                for (int j = 0, v = u + 10; j < bootstrapMethods.length; j++) {
-                    bootstrapMethods[j] = v;
-                    v += 2 + readUnsignedShort(v + 2) << 1;
-                }
-                context.bootstrapMethods = bootstrapMethods;
-            } else {
-                Attribute attr = readAttribute(attrs, attrName, u + 8,
-                        readInt(u + 4), c, -1, null);
-                if (attr != null) {
-                    attr.next = attributes;
-                    attributes = attr;
-                }
-            }
-            u += 6 + readInt(u + 4);
-        }
-
-        // visits the class declaration
-        classVisitor.visit(readInt(items[1] - 7), access, name, signature,
-                superClass, interfaces);
-
-        // visits the source and debug info
-        if ((flags & SKIP_DEBUG) == 0
-                && (sourceFile != null || sourceDebug != null)) {
-            classVisitor.visitSource(sourceFile, sourceDebug);
-        }
-
-        // visits the outer class
-        if (enclosingOwner != null) {
-            classVisitor.visitOuterClass(enclosingOwner, enclosingName,
-                    enclosingDesc);
-        }
-
-        // visits the class annotations and type annotations
-        if (ANNOTATIONS && anns != 0) {
-            for (int i = readUnsignedShort(anns), v = anns + 2; i > 0; --i) {
-                v = readAnnotationValues(v + 2, c, true,
-                        classVisitor.visitAnnotation(readUTF8(v, c), true));
-            }
-        }
-        if (ANNOTATIONS && ianns != 0) {
-            for (int i = readUnsignedShort(ianns), v = ianns + 2; i > 0; --i) {
-                v = readAnnotationValues(v + 2, c, true,
-                        classVisitor.visitAnnotation(readUTF8(v, c), false));
-            }
-        }
-
-        // visits the end of the class
-        classVisitor.visitEnd();
-    }
-
-    /**
-     * Reads the values of an annotation and makes the given visitor visit them.
-     *
-     * @param v
-     *            the start offset in {@link #b b} of the values to be read
-     *            (including the unsigned short that gives the number of
-     *            values).
-     * @param buf
-     *            buffer to be used to call {@link #readUTF8 readUTF8},
-     *            {@link #readClass(int,char[]) readClass} or {@link #readConst
-     *            readConst}.
-     * @param named
-     *            if the annotation values are named or not.
-     * @param av
-     *            the visitor that must visit the values.
-     * @return the end offset of the annotation values.
-     */
-    private int readAnnotationValues(int v, final char[] buf,
-                                     final boolean named, final AnnotationVisitor av) {
-        int i = readUnsignedShort(v);
-        v += 2;
-        if (named) {
-            for (; i > 0; --i) {
-                v = readAnnotationValue(v + 2, buf, readUTF8(v, buf), av);
-            }
-        } else {
-            for (; i > 0; --i) {
-                v = readAnnotationValue(v, buf, null, av);
-            }
-        }
-        if (av != null) {
-            av.visitEnd();
-        }
-        return v;
-    }
-
-    /**
-     * Reads a value of an annotation and makes the given visitor visit it.
-     *
-     * @param v
-     *            the start offset in {@link #b b} of the value to be read
-     *            (<i>not including the value name constant pool index</i>).
-     * @param buf
-     *            buffer to be used to call {@link #readUTF8 readUTF8},
-     *            {@link #readClass(int,char[]) readClass} or {@link #readConst
-     *            readConst}.
-     * @param name
-     *            the name of the value to be read.
-     * @param av
-     *            the visitor that must visit the value.
-     * @return the end offset of the annotation value.
-     */
-    private int readAnnotationValue(int v, final char[] buf, final String name,
-                                    final AnnotationVisitor av) {
-        int i;
-        if (av == null) {
-            switch (b[v] & 0xFF) {
-                case 'e': // enum_const_value
-                    return v + 5;
-                case '@': // annotation_value
-                    return readAnnotationValues(v + 3, buf, true, null);
-                case '[': // array_value
-                    return readAnnotationValues(v + 1, buf, false, null);
-                default:
-                    return v + 3;
-            }
-        }
-        switch (b[v++] & 0xFF) {
-            case 'I': // pointer to CONSTANT_Integer
-            case 'J': // pointer to CONSTANT_Long
-            case 'F': // pointer to CONSTANT_Float
-            case 'D': // pointer to CONSTANT_Double
-                av.visit(name, readConst(readUnsignedShort(v), buf));
-                v += 2;
-                break;
-            case 'B': // pointer to CONSTANT_Byte
-                av.visit(name, (byte) readInt(items[readUnsignedShort(v)]));
-                v += 2;
-                break;
-            case 'Z': // pointer to CONSTANT_Boolean
-                av.visit(name, readInt(items[readUnsignedShort(v)]) == 0 ? Boolean.FALSE : Boolean.TRUE);
-                v += 2;
-                break;
-            case 'S': // pointer to CONSTANT_Short
-                av.visit(name, (short) readInt(items[readUnsignedShort(v)]));
-                v += 2;
-                break;
-            case 'C': // pointer to CONSTANT_Char
-                av.visit(name, (char) readInt(items[readUnsignedShort(v)]));
-                v += 2;
-                break;
-            case 's': // pointer to CONSTANT_Utf8
-                av.visit(name, readUTF8(v, buf));
-                v += 2;
-                break;
-            case 'e': // enum_const_value
-                av.visitEnum(name, readUTF8(v, buf), readUTF8(v + 2, buf));
-                v += 4;
-                break;
-            case 'c': // class_info
-                av.visit(name, Type.getType(readUTF8(v, buf)));
-                v += 2;
-                break;
-            case '@': // annotation_value
-                v = readAnnotationValues(v + 2, buf, true,
-                        av.visitAnnotation(name, readUTF8(v, buf)));
-                break;
-            case '[': // array_value
-                int size = readUnsignedShort(v);
-                v += 2;
-                if (size == 0) {
-                    return readAnnotationValues(v - 2, buf, false,
-                            av.visitArray(name));
-                }
-                switch (this.b[v++] & 0xFF) {
-                    case 'B':
-                        byte[] bv = new byte[size];
-                        for (i = 0; i < size; i++) {
-                            bv[i] = (byte) readInt(items[readUnsignedShort(v)]);
-                            v += 3;
-                        }
-                        av.visit(name, bv);
-                        --v;
-                        break;
-                    case 'Z':
-                        boolean[] zv = new boolean[size];
-                        for (i = 0; i < size; i++) {
-                            zv[i] = readInt(items[readUnsignedShort(v)]) != 0;
-                            v += 3;
-                        }
-                        av.visit(name, zv);
-                        --v;
-                        break;
-                    case 'S':
-                        short[] sv = new short[size];
-                        for (i = 0; i < size; i++) {
-                            sv[i] = (short) readInt(items[readUnsignedShort(v)]);
-                            v += 3;
-                        }
-                        av.visit(name, sv);
-                        --v;
-                        break;
-                    case 'C':
-                        char[] cv = new char[size];
-                        for (i = 0; i < size; i++) {
-                            cv[i] = (char) readInt(items[readUnsignedShort(v)]);
-                            v += 3;
-                        }
-                        av.visit(name, cv);
-                        --v;
-                        break;
-                    case 'I':
-                        int[] iv = new int[size];
-                        for (i = 0; i < size; i++) {
-                            iv[i] = readInt(items[readUnsignedShort(v)]);
-                            v += 3;
-                        }
-                        av.visit(name, iv);
-                        --v;
-                        break;
-                    case 'J':
-                        long[] lv = new long[size];
-                        for (i = 0; i < size; i++) {
-                            lv[i] = readLong(items[readUnsignedShort(v)]);
-                            v += 3;
-                        }
-                        av.visit(name, lv);
-                        --v;
-                        break;
-                    case 'F':
-                        float[] fv = new float[size];
-                        for (i = 0; i < size; i++) {
-                            fv[i] = Float
-                                    .intBitsToFloat(readInt(items[readUnsignedShort(v)]));
-                            v += 3;
-                        }
-                        av.visit(name, fv);
-                        --v;
-                        break;
-                    case 'D':
-                        double[] dv = new double[size];
-                        for (i = 0; i < size; i++) {
-                            dv[i] = Double
-                                    .longBitsToDouble(readLong(items[readUnsignedShort(v)]));
-                            v += 3;
-                        }
-                        av.visit(name, dv);
-                        --v;
-                        break;
-                    default:
-                        v = readAnnotationValues(v - 3, buf, false, av.visitArray(name));
-                }
-        }
-        return v;
-    }
-
-
-    /**
-     * Returns the label corresponding to the given offset. The default
-     * implementation of this method creates a label for the given offset if it
-     * has not been already created.
-     *
-     * @param offset
-     *            a bytecode offset in a method.
-     * @param labels
-     *            the already created labels, indexed by their offset. If a
-     *            label already exists for offset this method must not create a
-     *            new one. Otherwise it must store the new label in this array.
-     * @return a non null Label, which must be equal to labels[offset].
-     */
-    protected Label readLabel(int offset, Label[] labels) {
-        // SPRING PATCH: leniently handle offset mismatch
-        if (offset >= labels.length) {
-            return new Label();
-        }
-        // END OF PATCH
-        if (labels[offset] == null) {
-            labels[offset] = new Label();
-        }
-        return labels[offset];
-    }
-
-    /**
-     * Returns the start index of the attribute_info structure of this class.
-     *
-     * @return the start index of the attribute_info structure of this class.
-     */
-    private int getAttributes() {
-        // skips the header
-        int u = header + 8 + readUnsignedShort(header + 6) * 2;
-        // skips fields and methods
-        for (int i = readUnsignedShort(u); i > 0; --i) {
-            for (int j = readUnsignedShort(u + 8); j > 0; --j) {
-                u += 6 + readInt(u + 12);
-            }
-            u += 8;
-        }
-        u += 2;
-        for (int i = readUnsignedShort(u); i > 0; --i) {
-            for (int j = readUnsignedShort(u + 8); j > 0; --j) {
-                u += 6 + readInt(u + 12);
-            }
-            u += 8;
-        }
-        // the attribute_info structure starts just after the methods
-        return u + 2;
-    }
-
-    /**
-     * Reads an attribute in {@link #b b}.
-     *
-     * @param attrs
-     *            prototypes of the attributes that must be parsed during the
-     *            visit of the class. Any attribute whose type is not equal to
-     *            the type of one the prototypes is ignored (i.e. an empty
-     *            {@link Attribute} instance is returned).
-     * @param type
-     *            the type of the attribute.
-     * @param off
-     *            index of the first byte of the attribute's content in
-     *            {@link #b b}. The 6 attribute header bytes, containing the
-     *            type and the length of the attribute, are not taken into
-     *            account here (they have already been read).
-     * @param len
-     *            the length of the attribute's content.
-     * @param buf
-     *            buffer to be used to call {@link #readUTF8 readUTF8},
-     *            {@link #readClass(int,char[]) readClass} or {@link #readConst
-     *            readConst}.
-     * @param codeOff
-     *            index of the first byte of code's attribute content in
-     *            {@link #b b}, or -1 if the attribute to be read is not a code
-     *            attribute. The 6 attribute header bytes, containing the type
-     *            and the length of the attribute, are not taken into account
-     *            here.
-     * @param labels
-     *            the labels of the method's code, or <tt>null</tt> if the
-     *            attribute to be read is not a code attribute.
-     * @return the attribute that has been read, or <tt>null</tt> to skip this
-     *         attribute.
-     */
-    private Attribute readAttribute(final Attribute[] attrs, final String type,
-                                    final int off, final int len, final char[] buf, final int codeOff,
-                                    final Label[] labels) {
-        for (int i = 0; i < attrs.length; ++i) {
-            if (attrs[i].type.equals(type)) {
-                return attrs[i].read(this, off, len, buf, codeOff, labels);
-            }
-        }
-        return new Attribute(type).read(this, off, len, null, -1, null);
-    }
-
-
-    /**
-     * Reads a byte value in {@link #b b}. <i>This method is intended for
-     * {@link Attribute} sub classes, and is normally not needed by class
-     * generators or adapters.</i>
-     *
-     * @param index
-     *            the start index of the value to be read in {@link #b b}.
-     * @return the read value.
-     */
-    public int readByte(final int index) {
-        return b[index] & 0xFF;
-    }
-
-    /**
-     * Reads an unsigned short value in {@link #b b}. <i>This method is intended
-     * for {@link Attribute} sub classes, and is normally not needed by class
-     * generators or adapters.</i>
-     *
-     * @param index
-     *            the start index of the value to be read in {@link #b b}.
-     * @return the read value.
-     */
-    public int readUnsignedShort(final int index) {
-        byte[] b = this.b;
-        return ((b[index] & 0xFF) << 8) | (b[index + 1] & 0xFF);
-    }
-
-    /**
-     * Reads a signed short value in {@link #b b}. <i>This method is intended
-     * for {@link Attribute} sub classes, and is normally not needed by class
-     * generators or adapters.</i>
-     *
-     * @param index
-     *            the start index of the value to be read in {@link #b b}.
-     * @return the read value.
-     */
-    public short readShort(final int index) {
-        byte[] b = this.b;
-        return (short) (((b[index] & 0xFF) << 8) | (b[index + 1] & 0xFF));
-    }
-
-    /**
-     * Reads a signed int value in {@link #b b}. <i>This method is intended for
-     * {@link Attribute} sub classes, and is normally not needed by class
-     * generators or adapters.</i>
-     *
-     * @param index
-     *            the start index of the value to be read in {@link #b b}.
-     * @return the read value.
-     */
-    public int readInt(final int index) {
-        byte[] b = this.b;
-        return ((b[index] & 0xFF) << 24) | ((b[index + 1] & 0xFF) << 16)
-                | ((b[index + 2] & 0xFF) << 8) | (b[index + 3] & 0xFF);
-    }
-
-    /**
-     * Reads a signed long value in {@link #b b}. <i>This method is intended for
-     * {@link Attribute} sub classes, and is normally not needed by class
-     * generators or adapters.</i>
-     *
-     * @param index
-     *            the start index of the value to be read in {@link #b b}.
-     * @return the read value.
-     */
-    public long readLong(final int index) {
-        long l1 = readInt(index);
-        long l0 = readInt(index + 4) & 0xFFFFFFFFL;
-        return (l1 << 32) | l0;
-    }
-
-    /**
-     * Reads an UTF8 string constant pool item in {@link #b b}. <i>This method
-     * is intended for {@link Attribute} sub classes, and is normally not needed
-     * by class generators or adapters.</i>
-     *
-     * @param index
-     *            the start index of an unsigned short value in {@link #b b},
-     *            whose value is the index of an UTF8 constant pool item.
-     * @param buf
-     *            buffer to be used to read the item. This buffer must be
-     *            sufficiently large. It is not automatically resized.
-     * @return the String corresponding to the specified UTF8 item.
-     */
-    public String readUTF8(int index, final char[] buf) {
-        int item = readUnsignedShort(index);
-        if (index == 0 || item == 0) {
-            return null;
-        }
-        String s = strings[item];
-        if (s != null) {
-            return s;
-        }
-        index = items[item];
-        return strings[item] = readUTF(index + 2, readUnsignedShort(index), buf);
-    }
-
-    /**
-     * Reads UTF8 string in {@link #b b}.
-     *
-     * @param index
-     *            start offset of the UTF8 string to be read.
-     * @param utfLen
-     *            length of the UTF8 string to be read.
-     * @param buf
-     *            buffer to be used to read the string. This buffer must be
-     *            sufficiently large. It is not automatically resized.
-     * @return the String corresponding to the specified UTF8 string.
-     */
-    private String readUTF(int index, final int utfLen, final char[] buf) {
-        int endIndex = index + utfLen;
-        byte[] b = this.b;
-        int strLen = 0;
-        int c;
-        int st = 0;
-        char cc = 0;
-        while (index < endIndex) {
-            c = b[index++];
-            switch (st) {
-                case 0:
-                    c = c & 0xFF;
-                    if (c < 0x80) { // 0xxxxxxx
-                        buf[strLen++] = (char) c;
-                    } else if (c < 0xE0 && c > 0xBF) { // 110x xxxx 10xx xxxx
-                        cc = (char) (c & 0x1F);
-                        st = 1;
-                    } else { // 1110 xxxx 10xx xxxx 10xx xxxx
-                        cc = (char) (c & 0x0F);
-                        st = 2;
-                    }
-                    break;
-
-                case 1: // byte 2 of 2-byte char or byte 3 of 3-byte char
-                    buf[strLen++] = (char) ((cc << 6) | (c & 0x3F));
-                    st = 0;
-                    break;
-
-                case 2: // byte 2 of 3-byte char
-                    cc = (char) ((cc << 6) | (c & 0x3F));
-                    st = 1;
-                    break;
-            }
-        }
-        return new String(buf, 0, strLen);
-    }
-
-    /**
-     * Reads a class constant pool item in {@link #b b}. <i>This method is
-     * intended for {@link Attribute} sub classes, and is normally not needed by
-     * class generators or adapters.</i>
-     *
-     * @param index
-     *            the start index of an unsigned short value in {@link #b b},
-     *            whose value is the index of a class constant pool item.
-     * @param buf
-     *            buffer to be used to read the item. This buffer must be
-     *            sufficiently large. It is not automatically resized.
-     * @return the String corresponding to the specified class item.
-     */
-    public String readClass(final int index, final char[] buf) {
-        // computes the start index of the CONSTANT_Class item in b
-        // and reads the CONSTANT_Utf8 item designated by
-        // the first two bytes of this CONSTANT_Class item
-        return readUTF8(items[readUnsignedShort(index)], buf);
-    }
-
-    /**
-     * Reads a numeric or string constant pool item in {@link #b b}. <i>This
-     * method is intended for {@link Attribute} sub classes, and is normally not
-     * needed by class generators or adapters.</i>
-     *
-     * @param item
-     *            the index of a constant pool item.
-     * @param buf
-     *            buffer to be used to read the item. This buffer must be
-     *            sufficiently large. It is not automatically resized.
-     * @return the {@link Integer}, {@link Float}, {@link Long}, {@link Double},
-     *         {@link String}, {@link Type} or {@link Handle} corresponding to
-     *         the given constant pool item.
-     */
-    public Object readConst(final int item, final char[] buf) {
-        int index = items[item];
-        switch (b[index - 1]) {
-            case INT:
-                return readInt(index);
-            case FLOAT:
-                return Float.intBitsToFloat(readInt(index));
-            case LONG:
-                return readLong(index);
-            case DOUBLE:
-                return Double.longBitsToDouble(readLong(index));
-            case CLASS:
-                return Type.getObjectType(readUTF8(index, buf));
-            case STR:
-                return readUTF8(index, buf);
-            case MTYPE:
-                return Type.getMethodType(readUTF8(index, buf));
-            default: // case ClassWriter.HANDLE_BASE + [1..9]:
-                int tag = readByte(index);
-                int[] items = this.items;
-                int cpIndex = items[readUnsignedShort(index + 1)];
-                String owner = readClass(cpIndex, buf);
-                cpIndex = items[readUnsignedShort(cpIndex + 2)];
-                String name = readUTF8(cpIndex, buf);
-                String desc = readUTF8(cpIndex + 2, buf);
-                return new Handle(tag, owner, name, desc, tag == Opcodes.H_INVOKEINTERFACE);
-        }
-    }
-}
diff --git a/grails-common/src/main/groovy/org/apache/grails/common/compiler/asm/Context.java b/grails-common/src/main/groovy/org/apache/grails/common/compiler/asm/Context.java
deleted file mode 100644
index 2ad9692aa0..0000000000
--- a/grails-common/src/main/groovy/org/apache/grails/common/compiler/asm/Context.java
+++ /dev/null
@@ -1,146 +0,0 @@
-/***
- * ASM: a very small and fast Java bytecode manipulation framework
- * Copyright (c) 2000-2011 INRIA, France Telecom
- * All rights reserved.
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions
- * are met:
- * 1. Redistributions of source code must retain the above copyright
- *    notice, this list of conditions and the following disclaimer.
- * 2. Redistributions in binary form must reproduce the above copyright
- *    notice, this list of conditions and the following disclaimer in the
- *    documentation and/or other materials provided with the distribution.
- * 3. Neither the name of the copyright holders nor the names of its
- *    contributors may be used to endorse or promote products derived from
- *    this software without specific prior written permission.
- *
- * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
- * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
- * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
- * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE
- * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
- * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
- * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
- * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
- * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
- * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF
- * THE POSSIBILITY OF SUCH DAMAGE.
- */
-package org.apache.grails.common.compiler.asm;
-
-import org.springframework.asm.Label;
-
-/**
- * Information about a class being parsed in a {@link ClassReader}.
- *
- * @author Eric Bruneton
- */
-class Context {
-
-    /**
-     * Prototypes of the attributes that must be parsed for this class.
-     */
-    Attribute[] attrs;
-
-    /**
-     * The {@link ClassReader} option flags for the parsing of this class.
-     */
-    int flags;
-
-    /**
-     * The buffer used to read strings.
-     */
-    char[] buffer;
-
-    /**
-     * The start index of each bootstrap method.
-     */
-    int[] bootstrapMethods;
-
-    /**
-     * The access flags of the method currently being parsed.
-     */
-    int access;
-
-    /**
-     * The name of the method currently being parsed.
-     */
-    String name;
-
-    /**
-     * The descriptor of the method currently being parsed.
-     */
-    String desc;
-
-    /**
-     * The label objects, indexed by bytecode offset, of the method currently
-     * being parsed (only bytecode offsets for which a label is needed have a
-     * non null associated Label object).
-     */
-    Label[] labels;
-
-    /**
-     * The target of the type annotation currently being parsed.
-     */
-    int typeRef;
-
-    /**
-     * The path of the type annotation currently being parsed.
-     */
-    TypePath typePath;
-
-    /**
-     * The offset of the latest stack map frame that has been parsed.
-     */
-    int offset;
-
-    /**
-     * The labels corresponding to the start of the local variable ranges in the
-     * local variable type annotation currently being parsed.
-     */
-    Label[] start;
-
-    /**
-     * The labels corresponding to the end of the local variable ranges in the
-     * local variable type annotation currently being parsed.
-     */
-    Label[] end;
-
-    /**
-     * The local variable indices for each local variable range in the local
-     * variable type annotation currently being parsed.
-     */
-    int[] index;
-
-    /**
-     * The encoding of the latest stack map frame that has been parsed.
-     */
-    int mode;
-
-    /**
-     * The number of locals in the latest stack map frame that has been parsed.
-     */
-    int localCount;
-
-    /**
-     * The number locals in the latest stack map frame that has been parsed,
-     * minus the number of locals in the previous frame.
-     */
-    int localDiff;
-
-    /**
-     * The local values of the latest stack map frame that has been parsed.
-     */
-    Object[] local;
-
-    /**
-     * The stack size of the latest stack map frame that has been parsed.
-     */
-    int stackCount;
-
-    /**
-     * The stack values of the latest stack map frame that has been parsed.
-     */
-    Object[] stack;
-}
\ No newline at end of file
diff --git a/grails-common/src/main/groovy/org/apache/grails/common/compiler/asm/TypePath.java b/grails-common/src/main/groovy/org/apache/grails/common/compiler/asm/TypePath.java
deleted file mode 100644
index f2510b12aa..0000000000
--- a/grails-common/src/main/groovy/org/apache/grails/common/compiler/asm/TypePath.java
+++ /dev/null
@@ -1,196 +0,0 @@
-/***
- * ASM: a very small and fast Java bytecode manipulation framework
- * Copyright (c) 2000-2011 INRIA, France Telecom
- * All rights reserved.
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions
- * are met:
- * 1. Redistributions of source code must retain the above copyright
- *    notice, this list of conditions and the following disclaimer.
- * 2. Redistributions in binary form must reproduce the above copyright
- *    notice, this list of conditions and the following disclaimer in the
- *    documentation and/or other materials provided with the distribution.
- * 3. Neither the name of the copyright holders nor the names of its
- *    contributors may be used to endorse or promote products derived from
- *    this software without specific prior written permission.
- *
- * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
- * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
- * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
- * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE
- * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
- * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
- * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
- * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
- * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
- * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF
- * THE POSSIBILITY OF SUCH DAMAGE.
- */
-package org.apache.grails.common.compiler.asm;
-
-
-/**
- * The path to a type argument, wildcard bound, array element type, or static
- * inner type within an enclosing type.
- *
- * @author Eric Bruneton
- */
-class TypePath {
-
-    /**
-     * A type path step that steps into the element type of an array type. See
-     * {@link #getStep getStep}.
-     */
-    public final static int ARRAY_ELEMENT = 0;
-
-    /**
-     * A type path step that steps into the nested type of a class type. See
-     * {@link #getStep getStep}.
-     */
-    public final static int INNER_TYPE = 1;
-
-    /**
-     * A type path step that steps into the bound of a wildcard type. See
-     * {@link #getStep getStep}.
-     */
-    public final static int WILDCARD_BOUND = 2;
-
-    /**
-     * A type path step that steps into a type argument of a generic type. See
-     * {@link #getStep getStep}.
-     */
-    public final static int TYPE_ARGUMENT = 3;
-
-    /**
-     * The byte array where the path is stored, in Java class file format.
-     */
-    byte[] b;
-
-    /**
-     * The offset of the first byte of the type path in 'b'.
-     */
-    int offset;
-
-    /**
-     * Creates a new type path.
-     *
-     * @param b
-     *            the byte array containing the type path in Java class file
-     *            format.
-     * @param offset
-     *            the offset of the first byte of the type path in 'b'.
-     */
-    TypePath(byte[] b, int offset) {
-        this.b = b;
-        this.offset = offset;
-    }
-
-    /**
-     * Returns the length of this path.
-     *
-     * @return the length of this path.
-     */
-    public int getLength() {
-        return b[offset];
-    }
-
-    /**
-     * Returns the value of the given step of this path.
-     *
-     * @param index
-     *            an index between 0 and {@link #getLength()}, exclusive.
-     * @return {@link #ARRAY_ELEMENT ARRAY_ELEMENT}, {@link #INNER_TYPE
-     *         INNER_TYPE}, {@link #WILDCARD_BOUND WILDCARD_BOUND}, or
-     *         {@link #TYPE_ARGUMENT TYPE_ARGUMENT}.
-     */
-    public int getStep(int index) {
-        return b[offset + 2 * index + 1];
-    }
-
-    /**
-     * Returns the index of the type argument that the given step is stepping
-     * into. This method should only be used for steps whose value is
-     * {@link #TYPE_ARGUMENT TYPE_ARGUMENT}.
-     *
-     * @param index
-     *            an index between 0 and {@link #getLength()}, exclusive.
-     * @return the index of the type argument that the given step is stepping
-     *         into.
-     */
-    public int getStepArgument(int index) {
-        return b[offset + 2 * index + 2];
-    }
-
-    /**
-     * Converts a type path in string form, in the format used by
-     * {@link #toString()}, into a TypePath object.
-     *
-     * @param typePath
-     *            a type path in string form, in the format used by
-     *            {@link #toString()}. May be null or empty.
-     * @return the corresponding TypePath object, or null if the path is empty.
-     */
-    public static TypePath fromString(final String typePath) {
-        if (typePath == null || typePath.length() == 0) {
-            return null;
-        }
-        int n = typePath.length();
-        ByteVector out = new ByteVector(n);
-        out.putByte(0);
-        for (int i = 0; i < n;) {
-            char c = typePath.charAt(i++);
-            if (c == '[') {
-                out.put11(ARRAY_ELEMENT, 0);
-            } else if (c == '.') {
-                out.put11(INNER_TYPE, 0);
-            } else if (c == '*') {
-                out.put11(WILDCARD_BOUND, 0);
-            } else if (c >= '0' && c <= '9') {
-                int typeArg = c - '0';
-                while (i < n && (c = typePath.charAt(i)) >= '0' && c <= '9') {
-                    typeArg = typeArg * 10 + c - '0';
-                    i += 1;
-                }
-                if (i < n && typePath.charAt(i) == ';') {
-                    i += 1;
-                }
-                out.put11(TYPE_ARGUMENT, typeArg);
-            }
-        }
-        out.data[0] = (byte) (out.length / 2);
-        return new TypePath(out.data, 0);
-    }
-
-    /**
-     * Returns a string representation of this type path. {@link #ARRAY_ELEMENT
-     * ARRAY_ELEMENT} steps are represented with '[', {@link #INNER_TYPE
-     * INNER_TYPE} steps with '.', {@link #WILDCARD_BOUND WILDCARD_BOUND} steps
-     * with '*' and {@link #TYPE_ARGUMENT TYPE_ARGUMENT} steps with their type
-     * argument index in decimal form followed by ';'.
-     */
-    @Override
-    public String toString() {
-        int length = getLength();
-        StringBuilder result = new StringBuilder(length * 2);
-        for (int i = 0; i < length; ++i) {
-            switch (getStep(i)) {
-                case ARRAY_ELEMENT:
-                    result.append('[');
-                    break;
-                case INNER_TYPE:
-                    result.append('.');
-                    break;
-                case WILDCARD_BOUND:
-                    result.append('*');
-                    break;
-                case TYPE_ARGUMENT:
-                    result.append(getStepArgument(i)).append(';');
-                    break;
-                default:
-                    result.append('_');
-            }
-        }
-        return result.toString();
-    }
-}
diff --git a/grails-common/src/main/resources/META-INF/LICENSE b/grails-common/src/main/resources/META-INF/LICENSE
deleted file mode 100644
index 9f2db4a21e..0000000000
--- a/grails-common/src/main/resources/META-INF/LICENSE
+++ /dev/null
@@ -1,233 +0,0 @@
-
-                                 Apache License
-                           Version 2.0, January 2004
-                        http://www.apache.org/licenses/
-
-   TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION
-
-   1. Definitions.
-
-      "License" shall mean the terms and conditions for use, reproduction,
-      and distribution as defined by Sections 1 through 9 of this document.
-
-      "Licensor" shall mean the copyright owner or entity authorized by
-      the copyright owner that is granting the License.
-
-      "Legal Entity" shall mean the union of the acting entity and all
-      other entities that control, are controlled by, or are under common
-      control with that entity. For the purposes of this definition,
-      "control" means (i) the power, direct or indirect, to cause the
-      direction or management of such entity, whether by contract or
-      otherwise, or (ii) ownership of fifty percent (50%) or more of the
-      outstanding shares, or (iii) beneficial ownership of such entity.
-
-      "You" (or "Your") shall mean an individual or Legal Entity
-      exercising permissions granted by this License.
-
-      "Source" form shall mean the preferred form for making modifications,
-      including but not limited to software source code, documentation
-      source, and configuration files.
-
-      "Object" form shall mean any form resulting from mechanical
-      transformation or translation of a Source form, including but
-      not limited to compiled object code, generated documentation,
-      and conversions to other media types.
-
-      "Work" shall mean the work of authorship, whether in Source or
-      Object form, made available under the License, as indicated by a
-      copyright notice that is included in or attached to the work
-      (an example is provided in the Appendix below).
-
-      "Derivative Works" shall mean any work, whether in Source or Object
-      form, that is based on (or derived from) the Work and for which the
-      editorial revisions, annotations, elaborations, or other modifications
-      represent, as a whole, an original work of authorship. For the purposes
-      of this License, Derivative Works shall not include works that remain
-      separable from, or merely link (or bind by name) to the interfaces of,
-      the Work and Derivative Works thereof.
-
-      "Contribution" shall mean any work of authorship, including
-      the original version of the Work and any modifications or additions
-      to that Work or Derivative Works thereof, that is intentionally
-      submitted to Licensor for inclusion in the Work by the copyright owner
-      or by an individual or Legal Entity authorized to submit on behalf of
-      the copyright owner. For the purposes of this definition, "submitted"
-      means any form of electronic, verbal, or written communication sent
-      to the Licensor or its representatives, including but not limited to
-      communication on electronic mailing lists, source code control systems,
-      and issue tracking systems that are managed by, or on behalf of, the
-      Licensor for the purpose of discussing and improving the Work, but
-      excluding communication that is conspicuously marked or otherwise
-      designated in writing by the copyright owner as "Not a Contribution."
-
-      "Contributor" shall mean Licensor and any individual or Legal Entity
-      on behalf of whom a Contribution has been received by Licensor and
-      subsequently incorporated within the Work.
-
-   2. Grant of Copyright License. Subject to the terms and conditions of
-      this License, each Contributor hereby grants to You a perpetual,
-      worldwide, non-exclusive, no-charge, royalty-free, irrevocable
-      copyright license to reproduce, prepare Derivative Works of,
-      publicly display, publicly perform, sublicense, and distribute the
-      Work and such Derivative Works in Source or Object form.
-
-   3. Grant of Patent License. Subject to the terms and conditions of
-      this License, each Contributor hereby grants to You a perpetual,
-      worldwide, non-exclusive, no-charge, royalty-free, irrevocable
-      (except as stated in this section) patent license to make, have made,
-      use, offer to sell, sell, import, and otherwise transfer the Work,
-      where such license applies only to those patent claims licensable
-      by such Contributor that are necessarily infringed by their
-      Contribution(s) alone or by combination of their Contribution(s)
-      with the Work to which such Contribution(s) was submitted. If You
-      institute patent litigation against any entity (including a
-      cross-claim or counterclaim in a lawsuit) alleging that the Work
-      or a Contribution incorporated within the Work constitutes direct
-      or contributory patent infringement, then any patent licenses
-      granted to You under this License for that Work shall terminate
-      as of the date such litigation is filed.
-
-   4. Redistribution. You may reproduce and distribute copies of the
-      Work or Derivative Works thereof in any medium, with or without
-      modifications, and in Source or Object form, provided that You
-      meet the following conditions:
-
-      (a) You must give any other recipients of the Work or
-          Derivative Works a copy of this License; and
-
-      (b) You must cause any modified files to carry prominent notices
-          stating that You changed the files; and
-
-      (c) You must retain, in the Source form of any Derivative Works
-          that You distribute, all copyright, patent, trademark, and
-          attribution notices from the Source form of the Work,
-          excluding those notices that do not pertain to any part of
-          the Derivative Works; and
-
-      (d) If the Work includes a "NOTICE" text file as part of its
-          distribution, then any Derivative Works that You distribute must
-          include a readable copy of the attribution notices contained
-          within such NOTICE file, excluding those notices that do not
-          pertain to any part of the Derivative Works, in at least one
-          of the following places: within a NOTICE text file distributed
-          as part of the Derivative Works; within the Source form or
-          documentation, if provided along with the Derivative Works; or,
-          within a display generated by the Derivative Works, if and
-          wherever such third-party notices normally appear. The contents
-          of the NOTICE file are for informational purposes only and
-          do not modify the License. You may add Your own attribution
-          notices within Derivative Works that You distribute, alongside
-          or as an addendum to the NOTICE text from the Work, provided
-          that such additional attribution notices cannot be construed
-          as modifying the License.
-
-      You may add Your own copyright statement to Your modifications and
-      may provide additional or different license terms and conditions
-      for use, reproduction, or distribution of Your modifications, or
-      for any such Derivative Works as a whole, provided Your use,
-      reproduction, and distribution of the Work otherwise complies with
-      the conditions stated in this License.
-
-   5. Submission of Contributions. Unless You explicitly state otherwise,
-      any Contribution intentionally submitted for inclusion in the Work
-      by You to the Licensor shall be under the terms and conditions of
-      this License, without any additional terms or conditions.
-      Notwithstanding the above, nothing herein shall supersede or modify
-      the terms of any separate license agreement you may have executed
-      with Licensor regarding such Contributions.
-
-   6. Trademarks. This License does not grant permission to use the trade
-      names, trademarks, service marks, or product names of the Licensor,
-      except as required for reasonable and customary use in describing the
-      origin of the Work and reproducing the content of the NOTICE file.
-
-   7. Disclaimer of Warranty. Unless required by applicable law or
-      agreed to in writing, Licensor provides the Work (and each
-      Contributor provides its Contributions) on an "AS IS" BASIS,
-      WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or
-      implied, including, without limitation, any warranties or conditions
-      of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A
-      PARTICULAR PURPOSE. You are solely responsible for determining the
-      appropriateness of using or redistributing the Work and assume any
-      risks associated with Your exercise of permissions under this License.
-
-   8. Limitation of Liability. In no event and under no legal theory,
-      whether in tort (including negligence), contract, or otherwise,
-      unless required by applicable law (such as deliberate and grossly
-      negligent acts) or agreed to in writing, shall any Contributor be
-      liable to You for damages, including any direct, indirect, special,
-      incidental, or consequential damages of any character arising as a
-      result of this License or out of the use or inability to use the
-      Work (including but not limited to damages for loss of goodwill,
-      work stoppage, computer failure or malfunction, or any and all
-      other commercial damages or losses), even if such Contributor
-      has been advised of the possibility of such damages.
-
-   9. Accepting Warranty or Additional Liability. While redistributing
-      the Work or Derivative Works thereof, You may choose to offer,
-      and charge a fee for, acceptance of support, warranty, indemnity,
-      or other liability obligations and/or rights consistent with this
-      License. However, in accepting such obligations, You may act only
-      on Your own behalf and on Your sole responsibility, not on behalf
-      of any other Contributor, and only if You agree to indemnify,
-      defend, and hold each Contributor harmless for any liability
-      incurred by, or claims asserted against, such Contributor by reason
-      of your accepting any such warranty or additional liability.
-
-   END OF TERMS AND CONDITIONS
-
-   APPENDIX: How to apply the Apache License to your work.
-
-      To apply the Apache License to your work, attach the following
-      boilerplate notice, with the fields enclosed by brackets "[]"
-      replaced with your own identifying information. (Don't include
-      the brackets!)  The text should be enclosed in the appropriate
-      comment syntax for the file format. We also recommend that a
-      file or class name and description of purpose be included on the
-      same "printed page" as the copyright notice for easier
-      identification within third-party archives.
-
-   Copyright [yyyy] [name of copyright owner]
-
-   Licensed 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.
-
---------------------------------------------------------------------------
-
-BSD License
-
-The following classes within this product:
-
-    org.apache.grails.common.compiler.asm.Attribute
-    org.apache.grails.common.compiler.asm.ByteVector
-    org.apache.grails.common.compiler.asm.ClassReader
-    org.apache.grails.common.compiler.asm.Context
-    org.apache.grails.common.compiler.asm.TypePath
-
-See the LICENSE/licenses-asm.txt file for the ASM license terms.
-
---------------------------------------------------------------------------
-
-This product includes the following classes from Spring Framework 5.3, developed by Pivotal Software, Inc., licensed under the Apache License 2.0:
-
-    org.apache.grails.common.annotation.AbstractRecursiveAnnotationVisitor
-    org.apache.grails.common.annotation.AnnotationAttributesReadingVisitor
-    org.apache.grails.common.annotation.AnnotationMetadataReadingVisitor
-    org.apache.grails.common.annotation.AnnotationReadingVisitorUtils
-    org.apache.grails.common.annotation.ClassMetadataReadingVisitor
-    org.apache.grails.common.annotation.MethodMetadataReadingVisitor
-    org.apache.grails.common.annotation.RecursiveAnnotationArrayVisitor
-    org.apache.grails.common.annotation.RecursiveAnnotationAttributesVisitor
-
-See the above Apache License 2.0 for the terms governing these files.
-
---------------------------------------------------------------------------
\ No newline at end of file
diff --git a/grails-common/src/main/resources/META-INF/NOTICE b/grails-common/src/main/resources/META-INF/NOTICE
deleted file mode 100644
index d524ab7e3e..0000000000
--- a/grails-common/src/main/resources/META-INF/NOTICE
+++ /dev/null
@@ -1,18 +0,0 @@
-Apache Grails
-Copyright 2005-2025 The Apache Software Foundation
-
-This product includes software developed at
-The Apache Software Foundation (http://www.apache.org/).
-
-
-Additional Licenses
-------------------
-
-ASM Library
-This product includes software from ASM Library, licensed under BSD License.
-Copyright 2000-2011 INRIA, France Telecom.
-See licenses/LICENSE-asm.txt for the full license terms.
-
-This product includes software from Spring Framework 5.3, developed by Pivotal Software, Inc.
-Copyright 2002-2020 the original author or authors.
-See the LICENSE file for the Apache License 2.0 terms.
\ No newline at end of file
diff --git a/grails-core/src/main/groovy/grails/boot/config/tools/ClassPathScanner.groovy b/grails-core/src/main/groovy/grails/boot/config/tools/ClassPathScanner.groovy
index 88fc29a66b..8691eaf698 100644
--- a/grails-core/src/main/groovy/grails/boot/config/tools/ClassPathScanner.groovy
+++ b/grails-core/src/main/groovy/grails/boot/config/tools/ClassPathScanner.groovy
@@ -22,11 +22,11 @@ import groovy.transform.CompileStatic
 import groovy.transform.InheritConstructors
 import groovy.transform.Memoized
 import groovy.util.logging.Slf4j
-import org.apache.grails.common.compiler.asm.AnnotationMetadataReader
 import org.springframework.core.io.DefaultResourceLoader
 import org.springframework.core.io.Resource
 import org.springframework.core.io.support.PathMatchingResourcePatternResolver
 import org.springframework.core.io.support.ResourcePatternResolver
+import org.springframework.core.type.classreading.SimpleMetadataReaderFactory
 import org.springframework.util.ClassUtils
 
 import java.lang.annotation.Annotation
@@ -173,10 +173,12 @@ class ClassPathScanner {
 
     private void scanUsingPattern(ResourcePatternResolver resourcePatternResolver, String pattern, ClassLoader classLoader, Closure<Boolean> annotationFilter, Set<Class> classes) {
         def resources = resourcePatternResolver.getResources(pattern)
+
+        def factory = new SimpleMetadataReaderFactory(classLoader)
         for (Resource res in resources) {
             // ignore closures / inner classes
             if (!isExcluded(res)) {
-                def reader = new AnnotationMetadataReader(res, classLoader)
+                def reader = factory.getMetadataReader(res)
                 def metadata = reader.annotationMetadata
                 if (metadata.annotationTypes.any(annotationFilter)) {
                     classes << classLoader.loadClass(reader.classMetadata.className)
diff --git a/grails-datamapping-core/src/main/groovy/org/grails/datastore/gorm/utils/AnnotationMetadataReaderFactory.java b/grails-datamapping-core/src/main/groovy/org/grails/datastore/gorm/utils/AnnotationMetadataReaderFactory.java
deleted file mode 100644
index 78b29ec529..0000000000
--- a/grails-datamapping-core/src/main/groovy/org/grails/datastore/gorm/utils/AnnotationMetadataReaderFactory.java
+++ /dev/null
@@ -1,39 +0,0 @@
-/*
- *  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.grails.datastore.gorm.utils;
-
-import org.apache.grails.common.compiler.asm.AnnotationMetadataReader;
-import org.springframework.core.io.Resource;
-import org.springframework.core.type.classreading.CachingMetadataReaderFactory;
-import org.springframework.core.type.classreading.MetadataReader;
-
-import java.io.IOException;
-
-/**
- * A {@link CachingMetadataReaderFactory} that only reads annotations and not the whole class body
- */
-class AnnotationMetadataReaderFactory extends CachingMetadataReaderFactory {
-    public AnnotationMetadataReaderFactory(ClassLoader classLoader) {
-        super(classLoader);
-    }
-
-    @Override
-    public MetadataReader getMetadataReader(Resource resource) throws IOException {
-        return new AnnotationMetadataReader(resource, getResourceLoader().getClassLoader(), false);
-    }
-}
diff --git a/grails-datamapping-core/src/main/groovy/org/grails/datastore/gorm/utils/ClasspathEntityScanner.groovy b/grails-datamapping-core/src/main/groovy/org/grails/datastore/gorm/utils/ClasspathEntityScanner.groovy
index c39a25c10d..b180ea815d 100644
--- a/grails-datamapping-core/src/main/groovy/org/grails/datastore/gorm/utils/ClasspathEntityScanner.groovy
+++ b/grails-datamapping-core/src/main/groovy/org/grails/datastore/gorm/utils/ClasspathEntityScanner.groovy
@@ -24,6 +24,7 @@ import groovy.util.logging.Slf4j
 import org.grails.datastore.mapping.reflect.ClassUtils
 import org.springframework.beans.factory.config.BeanDefinition
 import org.springframework.context.annotation.ClassPathScanningCandidateComponentProvider
+import org.springframework.core.type.classreading.SimpleMetadataReaderFactory
 import org.springframework.core.type.filter.AnnotationTypeFilter
 
 import java.lang.annotation.Annotation
@@ -70,7 +71,7 @@ class ClasspathEntityScanner {
      */
     Class[] scan(Package... packages) {
         ClassPathScanningCandidateComponentProvider componentProvider = new ClassPathScanningCandidateComponentProvider(false)
-        componentProvider.setMetadataReaderFactory(new AnnotationMetadataReaderFactory(classLoader))
+        componentProvider.setMetadataReaderFactory(new SimpleMetadataReaderFactory(classLoader))
         for(ann in annotations) {
             componentProvider.addIncludeFilter(new AnnotationTypeFilter(ann))
         }
diff --git a/licenses/LICENSE-asm.txt b/licenses/LICENSE-asm.txt
deleted file mode 100644
index 1a71c4ce46..0000000000
--- a/licenses/LICENSE-asm.txt
+++ /dev/null
@@ -1,27 +0,0 @@
-ASM: a very small and fast Java bytecode manipulation framework
-Copyright (c) 2000-2011 INRIA, France Telecom
-All rights reserved.
-
-Redistribution and use in source and binary forms, with or without
-modification, are permitted provided that the following conditions
-are met:
-1. Redistributions of source code must retain the above copyright
-   notice, this list of conditions and the following disclaimer.
-2. Redistributions in binary form must reproduce the above copyright
-   notice, this list of conditions and the following disclaimer in the
-   documentation and/or other materials provided with the distribution.
-3. Neither the name of the copyright holders nor the names of its
-   contributors may be used to endorse or promote products derived from
-   this software without specific prior written permission.
-
-THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
-AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
-IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
-ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE
-LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
-CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
-SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
-INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
-CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
-ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF
-THE POSSIBILITY OF SUCH DAMAGE.