diff --git a/manual/Types/permissions.html b/manual/Types/permissions.html
index d0db0e3272..b0c7e892de 100644
--- a/manual/Types/permissions.html
+++ b/manual/Types/permissions.html
@@ -25,11 +25,17 @@
Permissions
-Note Permissions
requires the use of Java SecurityManager.
- Java version 17 deprecated SecurityManager for removal and Java 18 by default disallowed
- setting SecurityManager at runtime. Permissions
is thus no longer supported
- when used in Java 18 or higher versions. Using it in such Java runtime versions won't provide the
- functionality that it originally provided.
+Note: Permissions
requires the use of Java SecurityManager.
+ Java version 17 deprecated SecurityManager for removal and Java 18 and higher versions, by
+ default, disallow setting SecurityManager at runtime. Permissions
is thus no longer
+ supported when used in Java 18 or higher versions. Using it in those Java runtime versions
+ will throw a org.apache.tools.ant.BuildException
. Throwing of
+ BuildException
can be relaxed by setting the
+ ant.securitymanager.usage.warn
system or Ant property to true
,
+ which will then cause a warning to be logged instead of the exception being thrown. Even when
+ ant.securitymanager.usage.warn
is set to true
,
+ SecurityManager usage will still be disabled and no security checks will be performed.
+ It is recommended to no longer use <permissions>
Permissions represents a set of security permissions granted or revoked to a specific part
code executed in the JVM where Apache Ant is running in. The actual Permissions are specified
diff --git a/src/main/org/apache/tools/ant/MagicNames.java b/src/main/org/apache/tools/ant/MagicNames.java
index 12fbcf7316..4e3b8735e7 100644
--- a/src/main/org/apache/tools/ant/MagicNames.java
+++ b/src/main/org/apache/tools/ant/MagicNames.java
@@ -359,5 +359,16 @@ private MagicNames() {
*/
public static final String DISABLE_NASHORN_COMPAT = "ant.disable.graal.nashorn.compat";
+ /**
+ * When running on Java 18 or higher runtime, Ant will throw a {@link BuildException}
+ * if the {@linkplain org.apache.tools.ant.types.Permissions } type is used.
+ * Set this property to {@code true} to disable throwing an exception and instead just log a
+ * warning message.
+ *
+ * Value: {@value}
+ * @since Ant 1.10.14
+ */
+ public static final String WARN_SECURITY_MANAGER_USAGE = "ant.securitymanager.usage.warn";
+
}
diff --git a/src/main/org/apache/tools/ant/taskdefs/ExecuteJava.java b/src/main/org/apache/tools/ant/taskdefs/ExecuteJava.java
index 0964c91329..cb0d1250fc 100644
--- a/src/main/org/apache/tools/ant/taskdefs/ExecuteJava.java
+++ b/src/main/org/apache/tools/ant/taskdefs/ExecuteJava.java
@@ -211,9 +211,11 @@ public void execute(Project project) throws BuildException {
@Override
public void run() {
final Object[] argument = {javaCommand.getArguments()};
+ boolean restoreSecMgr = false;
try {
if (perm != null) {
perm.setSecurityManager();
+ restoreSecMgr = true;
}
main.invoke(null, argument);
} catch (InvocationTargetException e) {
@@ -224,7 +226,7 @@ public void run() {
} catch (Throwable t) {
caught = t;
} finally {
- if (perm != null) {
+ if (perm != null && restoreSecMgr) {
perm.restoreSecurityManager();
}
synchronized (this) {
diff --git a/src/main/org/apache/tools/ant/types/Permissions.java b/src/main/org/apache/tools/ant/types/Permissions.java
index 703c8acc86..35144acf13 100644
--- a/src/main/org/apache/tools/ant/types/Permissions.java
+++ b/src/main/org/apache/tools/ant/types/Permissions.java
@@ -30,13 +30,13 @@
import org.apache.tools.ant.BuildException;
import org.apache.tools.ant.ExitException;
+import org.apache.tools.ant.Project;
+import org.apache.tools.ant.ProjectComponent;
import org.apache.tools.ant.util.SecurityManagerUtil;
/**
* This class implements a security manager meant for usage by tasks that run inside the
* Ant VM. An examples are the Java Task and JUnitTask.
- *
- * Note: This class doesn't provide any functionality for Java 18 and higher
*
*
* The basic functionality is that nothing (except for a base set of permissions) is allowed, unless
@@ -46,9 +46,13 @@
* It is not permissible to add permissions (either granted or revoked) while the Security Manager
* is active (after calling setSecurityManager() but before calling restoreSecurityManager()).
*
+ *
+ * Note: This class isn't supported in Java 18 and higher where {@link SecurityManager} has been
+ * deprecated for removal.
+ *
* @since Ant 1.6
*/
-public class Permissions {
+public class Permissions extends ProjectComponent {
private final List grantedPermissions = new LinkedList<>();
private final List revokedPermissions = new LinkedList<>();
@@ -99,11 +103,24 @@ public void addConfiguredRevoke(final Permissions.Permission perm) {
* subject to these Permissions. Note that setting the SecurityManager too early may
* prevent your part from starting, as for instance changing classloaders may be prohibited.
* The classloader for the new situation is supposed to be present.
+ *
+ * This method is no longer supported in Java 18 and higher versions and throws a
+ * {@link BuildException}. {@link org.apache.tools.ant.MagicNames#WARN_SECURITY_MANAGER_USAGE}
+ * property can be set to {@code true} to log a warning message instead of throwing the exception.
+ *
* @throws BuildException on error
*/
public synchronized void setSecurityManager() throws BuildException {
if (!SecurityManagerUtil.isSetSecurityManagerAllowed()) {
- return;
+ final String msg = "Use of or " + Permissions.class.getName()
+ + " is disallowed in current Java runtime version";
+ if (SecurityManagerUtil.warnOnSecurityManagerUsage(getProject())) {
+ // just log a warning
+ log("Security checks are disabled - " + msg, Project.MSG_WARN);
+ return;
+ } else {
+ throw new BuildException(msg);
+ }
}
origSm = System.getSecurityManager();
init();
@@ -174,10 +191,22 @@ private java.security.Permission createPermission(
/**
* To be used by tasks that just finished executing the parts subject to these permissions.
+ *
+ * This method is no longer supported in Java 18 and higher versions and throws a
+ * {@link BuildException}. {@link org.apache.tools.ant.MagicNames#WARN_SECURITY_MANAGER_USAGE}
+ * property can be set to {@code true} to log a warning message instead of throwing the exception.
*/
- public synchronized void restoreSecurityManager() {
+ public synchronized void restoreSecurityManager() throws BuildException {
if (!SecurityManagerUtil.isSetSecurityManagerAllowed()) {
- return;
+ final String msg = "Use of or " + Permissions.class.getName()
+ + " is disallowed in current Java runtime version";
+ if (SecurityManagerUtil.warnOnSecurityManagerUsage(getProject())) {
+ // just log a warning
+ log("Security checks are disabled - " + msg, Project.MSG_WARN);
+ return;
+ } else {
+ throw new BuildException(msg);
+ }
}
active = false;
System.setSecurityManager(origSm);
diff --git a/src/main/org/apache/tools/ant/util/SecurityManagerUtil.java b/src/main/org/apache/tools/ant/util/SecurityManagerUtil.java
index e27b14efb5..836a7b872b 100644
--- a/src/main/org/apache/tools/ant/util/SecurityManagerUtil.java
+++ b/src/main/org/apache/tools/ant/util/SecurityManagerUtil.java
@@ -17,14 +17,41 @@
*/
package org.apache.tools.ant.util;
+import org.apache.tools.ant.MagicNames;
+import org.apache.tools.ant.Project;
+
+/**
+ * @since Ant 1.10.14
+ */
public final class SecurityManagerUtil {
private static final boolean isJava18OrHigher = JavaEnvUtils.isAtLeastJavaVersion("18");
+ private static final boolean sysPropWarnOnSecMgrUsage =
+ Boolean.getBoolean(MagicNames.WARN_SECURITY_MANAGER_USAGE);
+ /**
+ * {@return true if {@code SecurityManager} usage is allowed in current Java runtime. false
+ * otherwise}
+ */
public static boolean isSetSecurityManagerAllowed() {
if (isJava18OrHigher) {
return false;
}
return true;
}
+
+ /**
+ * {@return true if {@code SecurityManager} usage should only be logged as a warning. false
+ * otherwise}
+ */
+ public static boolean warnOnSecurityManagerUsage(final Project project) {
+ if (project == null) {
+ return sysPropWarnOnSecMgrUsage;
+ }
+ final String val = project.getProperty(MagicNames.WARN_SECURITY_MANAGER_USAGE);
+ if (val == null) {
+ return sysPropWarnOnSecMgrUsage;
+ }
+ return Boolean.parseBoolean(val);
+ }
}
diff --git a/src/main/org/apache/tools/ant/util/optional/NoExitSecurityManager.java b/src/main/org/apache/tools/ant/util/optional/NoExitSecurityManager.java
index 4df8ef099f..f1559e9abe 100644
--- a/src/main/org/apache/tools/ant/util/optional/NoExitSecurityManager.java
+++ b/src/main/org/apache/tools/ant/util/optional/NoExitSecurityManager.java
@@ -26,6 +26,8 @@
* The goal is to intercept System.exit calls and make it throw an
* exception instead so that a System.exit in a task does not
* fully terminate Ant.
+ *
+ * This class is no longer supported in Java runtime versions 18 and higher.
*
* @see ExitException
*/