This is an automated email from the ASF dual-hosted git repository. markt pushed a commit to branch main in repository https://gitbox.apache.org/repos/asf/tomcat.git
commit a2384804c527c64290cfae1fa988f1f394890e91 Author: Mark Thomas <ma...@apache.org> AuthorDate: Wed Jul 24 17:51:24 2024 +0100 Add JreCompat support for Subject.callAs() With the changes coming in Java 23 we need to move away from Subject.doAs() but the replacement isn't available in Java 17. Hence use JreCompat. --- .../org/apache/tomcat/util/compat/Jre18Compat.java | 71 ++++++++++++++++++++++ .../org/apache/tomcat/util/compat/Jre19Compat.java | 2 +- java/org/apache/tomcat/util/compat/JreCompat.java | 39 ++++++++++++ .../tomcat/util/compat/LocalStrings.properties | 1 + 4 files changed, 112 insertions(+), 1 deletion(-) diff --git a/java/org/apache/tomcat/util/compat/Jre18Compat.java b/java/org/apache/tomcat/util/compat/Jre18Compat.java new file mode 100644 index 0000000000..b83999f179 --- /dev/null +++ b/java/org/apache/tomcat/util/compat/Jre18Compat.java @@ -0,0 +1,71 @@ +/* + * 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.apache.tomcat.util.compat; + +import java.lang.reflect.InvocationTargetException; +import java.lang.reflect.Method; +import java.util.concurrent.Callable; +import java.util.concurrent.CompletionException; + +import javax.security.auth.Subject; + +import org.apache.juli.logging.Log; +import org.apache.juli.logging.LogFactory; +import org.apache.tomcat.util.res.StringManager; + +public class Jre18Compat extends JreCompat { + + private static final Log log = LogFactory.getLog(Jre18Compat.class); + private static final StringManager sm = StringManager.getManager(Jre18Compat.class); + + private static final Method callAsMethod; + + static { + Method m1 = null; + + try { + m1 = Subject.class.getMethod("classAS", Subject.class, Callable.class); + } catch (NoSuchMethodException e) { + // Must before-Java 18 + log.debug(sm.getString("jre18Compat.javaPre18"), e); + } + + callAsMethod = m1; + } + + + static boolean isSupported() { + return callAsMethod != null; + } + + + @SuppressWarnings("unchecked") + @Override + public <T> T callAs(Subject subject, Callable<T> action) throws CompletionException { + try { + return (T) callAsMethod.invoke(null, subject, action); + } catch (IllegalAccessException e) { + throw new CompletionException(e); + } catch (InvocationTargetException e) { + Throwable cause = e.getCause(); + if (cause instanceof CompletionException) { + throw (CompletionException) cause; + } + throw new CompletionException(e); + } + } +} diff --git a/java/org/apache/tomcat/util/compat/Jre19Compat.java b/java/org/apache/tomcat/util/compat/Jre19Compat.java index 60ee0c2dc1..fd9b85c515 100644 --- a/java/org/apache/tomcat/util/compat/Jre19Compat.java +++ b/java/org/apache/tomcat/util/compat/Jre19Compat.java @@ -22,7 +22,7 @@ import org.apache.juli.logging.Log; import org.apache.juli.logging.LogFactory; import org.apache.tomcat.util.res.StringManager; -public class Jre19Compat extends JreCompat { +public class Jre19Compat extends Jre18Compat { private static final Log log = LogFactory.getLog(Jre19Compat.class); private static final StringManager sm = StringManager.getManager(Jre19Compat.class); diff --git a/java/org/apache/tomcat/util/compat/JreCompat.java b/java/org/apache/tomcat/util/compat/JreCompat.java index 743f76e64f..9227c2deac 100644 --- a/java/org/apache/tomcat/util/compat/JreCompat.java +++ b/java/org/apache/tomcat/util/compat/JreCompat.java @@ -17,6 +17,11 @@ package org.apache.tomcat.util.compat; import java.lang.reflect.Field; +import java.security.PrivilegedExceptionAction; +import java.util.concurrent.Callable; +import java.util.concurrent.CompletionException; + +import javax.security.auth.Subject; import org.apache.tomcat.util.res.StringManager; @@ -29,6 +34,7 @@ public class JreCompat { private static final JreCompat instance; private static final boolean graalAvailable; + private static final boolean jre18Available; private static final boolean jre19Available; private static final boolean jre21Available; private static final boolean jre22Available; @@ -53,21 +59,31 @@ public class JreCompat { jre22Available = true; jre21Available = true; jre19Available = true; + jre18Available = true; } else if (Jre21Compat.isSupported()) { instance = new Jre21Compat(); jre22Available = false; jre21Available = true; jre19Available = true; + jre18Available = true; } else if (Jre19Compat.isSupported()) { instance = new Jre19Compat(); jre22Available = false; jre21Available = false; jre19Available = true; + jre18Available = true; + } else if (Jre18Compat.isSupported()) { + instance = new Jre19Compat(); + jre22Available = false; + jre21Available = false; + jre19Available = false; + jre18Available = true; } else { instance = new JreCompat(); jre22Available = false; jre21Available = false; jre19Available = false; + jre18Available = false; } } @@ -82,6 +98,11 @@ public class JreCompat { } + public static boolean isJre18Available() { + return jre18Available; + } + + public static boolean isJre19Available() { return jre19Available; } @@ -97,6 +118,24 @@ public class JreCompat { } + // Java 17 implementations of Java 18 methods + + @SuppressWarnings("removal") + public <T> T callAs(Subject subject, Callable<T> action) throws CompletionException { + try { + return Subject.doAs(subject, new PrivilegedExceptionAction<T>() { + + @Override + public T run() throws Exception { + return action.call(); + } + }); + } catch (Exception e) { + throw new CompletionException(e); + } + } + + // Java 17 implementations of Java 19 methods /** diff --git a/java/org/apache/tomcat/util/compat/LocalStrings.properties b/java/org/apache/tomcat/util/compat/LocalStrings.properties index e3bbf2b43b..40184d95ab 100644 --- a/java/org/apache/tomcat/util/compat/LocalStrings.properties +++ b/java/org/apache/tomcat/util/compat/LocalStrings.properties @@ -13,5 +13,6 @@ # See the License for the specific language governing permissions and # limitations under the License. +jre18Compat.javaPre18=Method not found so assuming code is running on a pre-Java 18 JVM jre22Compat.javaPre22=Class not found so assuming code is running on a pre-Java 22 JVM jre22Compat.unexpected=Failed to create references to Java 22 classes and methods --------------------------------------------------------------------- To unsubscribe, e-mail: dev-unsubscr...@tomcat.apache.org For additional commands, e-mail: dev-h...@tomcat.apache.org