This is an automated email from the ASF dual-hosted git repository.
paulk pushed a commit to branch master
in repository https://gitbox.apache.org/repos/asf/groovy.git
The following commit(s) were added to refs/heads/master by this push:
new 3b4d02f5ae GROOVY-10581: Prepare for deprecation of security manager
(additional refactoring)
3b4d02f5ae is described below
commit 3b4d02f5aeaecb8eda64e5243047af1376c88e74
Author: Paul King <[email protected]>
AuthorDate: Sun Mar 29 20:46:54 2026 +1000
GROOVY-10581: Prepare for deprecation of security manager (additional
refactoring)
---
.../groovy/reflection/AccessPermissionChecker.java | 95 ----------------------
.../groovy/reflection/CachedConstructor.java | 6 +-
.../codehaus/groovy/reflection/CachedField.java | 1 -
.../codehaus/groovy/reflection/CachedMethod.java | 14 +---
.../groovy/reflection/ReflectionUtils.java | 5 +-
.../org/codehaus/groovy/vmplugin/v8/Java8.java | 4 +-
.../org/codehaus/groovy/vmplugin/v9/Java9.java | 46 +----------
.../swing/binding/ClosureTriggerBinding.java | 12 +--
8 files changed, 8 insertions(+), 175 deletions(-)
diff --git
a/src/main/java/org/codehaus/groovy/reflection/AccessPermissionChecker.java
b/src/main/java/org/codehaus/groovy/reflection/AccessPermissionChecker.java
deleted file mode 100644
index 55656b77f9..0000000000
--- a/src/main/java/org/codehaus/groovy/reflection/AccessPermissionChecker.java
+++ /dev/null
@@ -1,95 +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
- *
- * http://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.codehaus.groovy.reflection;
-
-import groovy.lang.GroovyObject;
-
-import java.lang.reflect.Constructor;
-import java.lang.reflect.Field;
-import java.lang.reflect.Method;
-import java.lang.reflect.Modifier;
-import java.lang.reflect.ReflectPermission;
-
-@SuppressWarnings("removal") // TODO future Groovy versions should deprecate
then remove this class
-final class AccessPermissionChecker {
-
- private static final ReflectPermission REFLECT_PERMISSION = new
ReflectPermission("suppressAccessChecks");
-
- private AccessPermissionChecker() {
- }
-
- private static void checkAccessPermission(final Class<?> declaringClass,
final int modifiers, final boolean accessible) {
- SecurityManager securityManager;
- if (accessible && (securityManager = System.getSecurityManager()) !=
null) {
- if (((modifiers & Modifier.PRIVATE) != 0
- || ((modifiers & (Modifier.PUBLIC |
Modifier.PROTECTED)) == 0 && declaringClass.getName().startsWith("java.")))
- && !GroovyObject.class.isAssignableFrom(declaringClass)) {
- securityManager.checkPermission(REFLECT_PERMISSION);
- } else if ((modifiers & (Modifier.PROTECTED)) != 0 &&
declaringClass.equals(ClassLoader.class)) {
- securityManager.checkCreateClassLoader();
- }
- }
- }
-
- static void checkAccessPermission(Method method) {
- try {
- checkAccessPermission(method.getDeclaringClass(),
method.getModifiers(), method.isAccessible());
- } catch (java.security.AccessControlException e) {
- throw createCacheAccessControlExceptionOf(method, e);
- }
- }
-
- static void checkAccessPermission(Constructor constructor) {
- try {
- checkAccessPermission(constructor.getDeclaringClass(),
constructor.getModifiers(), constructor.isAccessible());
- } catch (java.security.AccessControlException e) {
- throw createCacheAccessControlExceptionOf(constructor, e);
- }
- }
-
- private static CacheAccessControlException
createCacheAccessControlExceptionOf(Method method,
java.security.AccessControlException e) {
- return new CacheAccessControlException(
- "Groovy object can not access method " + method.getName()
- + " cacheAccessControlExceptionOf class " +
method.getDeclaringClass().getName()
- + " with modifiers \"" +
Modifier.toString(method.getModifiers()) + "\"", e);
- }
-
- private static CacheAccessControlException
createCacheAccessControlExceptionOf(Constructor constructor,
java.security.AccessControlException e) {
- return new CacheAccessControlException(
- "Groovy object can not access constructor " +
constructor.getName()
- + " cacheAccessControlExceptionOf class " +
constructor.getDeclaringClass().getName()
- + " with modifiers \"" +
Modifier.toString(constructor.getModifiers()) + "\"", e);
- }
-
- static void checkAccessPermission(Field field) {
- try {
- checkAccessPermission(field.getDeclaringClass(),
field.getModifiers(), field.isAccessible());
- } catch (java.security.AccessControlException e) {
- throw createCacheAccessControlExceptionOf(field, e);
- }
- }
-
- private static CacheAccessControlException
createCacheAccessControlExceptionOf(Field field,
java.security.AccessControlException e) {
- return new CacheAccessControlException(
- "Groovy object can not access field " + field.getName()
- + " cacheAccessControlExceptionOf class " +
field.getDeclaringClass().getName()
- + " with modifiers \"" +
Modifier.toString(field.getModifiers()) + "\"", e);
- }
-
-}
diff --git
a/src/main/java/org/codehaus/groovy/reflection/CachedConstructor.java
b/src/main/java/org/codehaus/groovy/reflection/CachedConstructor.java
index 25ac75a516..6d23d52394 100644
--- a/src/main/java/org/codehaus/groovy/reflection/CachedConstructor.java
+++ b/src/main/java/org/codehaus/groovy/reflection/CachedConstructor.java
@@ -128,10 +128,6 @@ public class CachedConstructor extends ParameterTypes
implements MetaMember {
public Constructor getCachedConstructor() {
makeAccessibleIfNecessary();
- if (!accessAllowed) {
- AccessPermissionChecker.checkAccessPermission(cachedConstructor);
- accessAllowed = true;
- }
return cachedConstructor;
}
@@ -147,5 +143,5 @@ public class CachedConstructor extends ParameterTypes
implements MetaMember {
return
Modifier.isAbstract(cachedConstructor.getDeclaringClass().getModifiers());
}
- private boolean accessAllowed = false;
+
}
diff --git a/src/main/java/org/codehaus/groovy/reflection/CachedField.java
b/src/main/java/org/codehaus/groovy/reflection/CachedField.java
index 86cbb75d0b..d8ee24da4c 100644
--- a/src/main/java/org/codehaus/groovy/reflection/CachedField.java
+++ b/src/main/java/org/codehaus/groovy/reflection/CachedField.java
@@ -38,7 +38,6 @@ public class CachedField extends MetaProperty {
private boolean madeAccessible;
private void makeAccessible() {
ReflectionUtils.makeAccessibleInPrivilegedAction(field);
- AccessPermissionChecker.checkAccessPermission(field);
madeAccessible = true;
}
diff --git a/src/main/java/org/codehaus/groovy/reflection/CachedMethod.java
b/src/main/java/org/codehaus/groovy/reflection/CachedMethod.java
index d0cb91e451..9f1527a1a5 100644
--- a/src/main/java/org/codehaus/groovy/reflection/CachedMethod.java
+++ b/src/main/java/org/codehaus/groovy/reflection/CachedMethod.java
@@ -62,7 +62,7 @@ public class CachedMethod extends MetaMethod implements
Comparable {
private int hashCode;
private boolean skipCompiled;
- private boolean accessAllowed;
+
private boolean makeAccessibleDone;
private CachedMethod transformedMethod;
private SoftReference<Constructor<CallSite>> pogoCallSiteConstructor,
pojoCallSiteConstructor, staticCallSiteConstructor;
@@ -169,10 +169,6 @@ public class CachedMethod extends MetaMethod implements
Comparable {
public Method getCachedMethod() {
makeAccessibleIfNecessary();
- if (!accessAllowed) {
- AccessPermissionChecker.checkAccessPermission(cachedMethod);
- accessAllowed = true;
- }
return cachedMethod;
}
@@ -325,14 +321,6 @@ public class CachedMethod extends MetaMethod implements
Comparable {
@Override
public final Object invoke(final Object object, final Object[] arguments) {
makeAccessibleIfNecessary();
- if (!accessAllowed) {
- try {
- AccessPermissionChecker.checkAccessPermission(cachedMethod);
- accessAllowed = true;
- } catch (CacheAccessControlException ex) {
- throw new InvokerInvocationException(ex);
- }
- }
try {
return cachedMethod.invoke(object, arguments);
diff --git a/src/main/java/org/codehaus/groovy/reflection/ReflectionUtils.java
b/src/main/java/org/codehaus/groovy/reflection/ReflectionUtils.java
index 7f3aeb791a..0bccdec6d4 100644
--- a/src/main/java/org/codehaus/groovy/reflection/ReflectionUtils.java
+++ b/src/main/java/org/codehaus/groovy/reflection/ReflectionUtils.java
@@ -201,14 +201,13 @@ public class ReflectionUtils {
}
// to be run in PrivilegedAction!
- @SuppressWarnings("deprecation") // replace isAccessible with canAccess
once min JDK version >= 9
public static Optional<AccessibleObject> makeAccessible(final
AccessibleObject ao) {
try {
- if (ao.isAccessible() || trySetAccessible(ao)) {
+ if (trySetAccessible(ao)) {
return Optional.of(ao);
}
} catch (Throwable ignore) {
- // swallow for strict security managers, module systems, android,
etc.
+ // swallow for module systems, android, etc.
}
return Optional.empty();
}
diff --git a/src/main/java/org/codehaus/groovy/vmplugin/v8/Java8.java
b/src/main/java/org/codehaus/groovy/vmplugin/v8/Java8.java
index d009f6a448..5da3938fcf 100644
--- a/src/main/java/org/codehaus/groovy/vmplugin/v8/Java8.java
+++ b/src/main/java/org/codehaus/groovy/vmplugin/v8/Java8.java
@@ -587,9 +587,7 @@ public class Java8 implements VMPlugin {
try {
return newLookup(receiverClass).unreflectSpecial(method,
receiverClass).bindTo(receiver);
} catch (ReflectiveOperationException e1) {
- if (!method.isAccessible()) {
- ReflectionUtils.trySetAccessible(method);
- }
+ ReflectionUtils.trySetAccessible(method);
final Class<?> declaringClass = method.getDeclaringClass();
try {
return newLookup(declaringClass).unreflectSpecial(method,
declaringClass).bindTo(receiver);
diff --git a/src/main/java/org/codehaus/groovy/vmplugin/v9/Java9.java
b/src/main/java/org/codehaus/groovy/vmplugin/v9/Java9.java
index 2f0af57de4..cf213d0690 100644
--- a/src/main/java/org/codehaus/groovy/vmplugin/v9/Java9.java
+++ b/src/main/java/org/codehaus/groovy/vmplugin/v9/Java9.java
@@ -19,7 +19,6 @@
package org.codehaus.groovy.vmplugin.v9;
import groovy.lang.GroovyClassLoader;
-import groovy.lang.GroovyRuntimeException;
import groovy.lang.MetaClass;
import groovy.lang.MetaMethod;
import org.codehaus.groovy.GroovyBugError;
@@ -35,8 +34,6 @@ import java.lang.module.ModuleDescriptor;
import java.lang.module.ModuleFinder;
import java.lang.module.ModuleReference;
import java.lang.reflect.AccessibleObject;
-import java.lang.reflect.Constructor;
-import java.lang.reflect.InvocationTargetException;
import java.lang.reflect.Member;
import java.lang.reflect.Method;
import java.lang.reflect.Modifier;
@@ -136,48 +133,9 @@ public class Java9 extends Java8 {
@Override
protected MethodHandles.Lookup newLookup(final Class<?> targetClass) {
try {
- var privateLookup = getPrivateLookup();
- if (privateLookup != null) {
- return (MethodHandles.Lookup) privateLookup.invoke(null,
targetClass, MethodHandles.lookup());
- }
- return getLookupConstructor().newInstance(targetClass,
MethodHandles.Lookup.PRIVATE).in(targetClass);
-
- } catch (final IllegalAccessException | InstantiationException e) {
+ return MethodHandles.privateLookupIn(targetClass,
MethodHandles.lookup());
+ } catch (final IllegalAccessException e) {
throw new IllegalArgumentException(e);
- } catch (final InvocationTargetException e) {
- throw new GroovyRuntimeException(e);
- }
- }
-
- protected static Constructor<MethodHandles.Lookup> getLookupConstructor() {
- return LookupHolder.LOOKUP_Constructor;
- }
-
- protected static Method getPrivateLookup() {
- return LookupHolder.PRIVATE_LOOKUP;
- }
-
- private static class LookupHolder {
- private static final Method PRIVATE_LOOKUP;
- private static final Constructor<MethodHandles.Lookup>
LOOKUP_Constructor;
-
- static {
- Constructor<MethodHandles.Lookup> lookup = null;
- Method privateLookup = null;
- try { // java 9
- privateLookup =
MethodHandles.class.getMethod("privateLookupIn", Class.class,
MethodHandles.Lookup.class);
- } catch (final NoSuchMethodException | RuntimeException e) { //
java 8 or fallback if anything else goes wrong
- try {
- lookup =
MethodHandles.Lookup.class.getDeclaredConstructor(Class.class, Integer.TYPE);
- if (!lookup.isAccessible()) {
- ReflectionUtils.trySetAccessible(lookup);
- }
- } catch (final NoSuchMethodException ex) {
- throw new IllegalStateException("Incompatible JVM", e);
- }
- }
- PRIVATE_LOOKUP = privateLookup;
- LOOKUP_Constructor = lookup;
}
}
diff --git
a/subprojects/groovy-swing/src/main/java/org/apache/groovy/swing/binding/ClosureTriggerBinding.java
b/subprojects/groovy-swing/src/main/java/org/apache/groovy/swing/binding/ClosureTriggerBinding.java
index 159ab9c727..c753a4fdb5 100644
---
a/subprojects/groovy-swing/src/main/java/org/apache/groovy/swing/binding/ClosureTriggerBinding.java
+++
b/subprojects/groovy-swing/src/main/java/org/apache/groovy/swing/binding/ClosureTriggerBinding.java
@@ -23,7 +23,7 @@ import groovy.lang.GroovyObjectSupport;
import groovy.lang.Reference;
import org.codehaus.groovy.reflection.ReflectionUtils;
-import java.lang.reflect.AccessibleObject;
+
import java.lang.reflect.Constructor;
import java.lang.reflect.Field;
import java.util.ArrayList;
@@ -80,19 +80,15 @@ public class ClosureTriggerBinding implements
TriggerBinding, SourceBinding {
}
Closure closureLocalCopy;
try {
- boolean acc = isAccessible(constructor);
ReflectionUtils.trySetAccessible(constructor);
closureLocalCopy = (Closure) constructor.newInstance(args);
- if (!acc) { constructor.setAccessible(false); }
closureLocalCopy.setResolveStrategy(Closure.DELEGATE_ONLY);
for (Field f:closureClass.getDeclaredFields()) {
- acc = isAccessible(f);
ReflectionUtils.trySetAccessible(f);
if (f.getType() == Reference.class) {
delegate.fields.put(f.getName(),
(BindPathSnooper) ((Reference)
f.get(closureLocalCopy)).get());
}
- if (!acc) { f.setAccessible(false); }
}
} catch (Exception e) {
throw new RuntimeException("Error snooping closure", e);
@@ -124,12 +120,6 @@ public class ClosureTriggerBinding implements
TriggerBinding, SourceBinding {
return fb;
}
- // TODO when JDK9+ is minimum, use canAccess and remove suppression
- @SuppressWarnings("deprecation")
- private boolean isAccessible(AccessibleObject accessibleObject) {
- return accessibleObject.isAccessible();
- }
-
@Override
public Object getSourceValue() {
return closure.call();