Hello Stefan,

One additional thing to consider is whether we can completely get rid of this field from the JavaEnvUtils class. As far as I can see, FileUtils.getFileUtils() already returns a single instance of FileUtils. So it might be easier and would avoid using this class in the static initialization of JavaEnvUtils if we just called FileUtils.getFileUtils() in the couple of methods where we use it. If you however prefer retaining the current fix, that's fine too. Here's what I was thinking of:

diff --git a/src/main/org/apache/tools/ant/util/JavaEnvUtils.java b/src/main/org/apache/tools/ant/util/JavaEnvUtils.java
--- a/src/main/org/apache/tools/ant/util/JavaEnvUtils.java
+++ b/src/main/org/apache/tools/ant/util/JavaEnvUtils.java
@@ -47,9 +47,6 @@ public final class JavaEnvUtils {
     /** shortcut for System.getProperty("java.home") */
     private static final String JAVA_HOME = System.getProperty("java.home");

-    /** FileUtils instance for path normalization */
-    private static final FileUtils FILE_UTILS = FileUtils.getFileUtils();
-
     /** Version of currently running VM. */
     private static String javaVersion;

@@ -448,7 +445,7 @@ public final class JavaEnvUtils {
      * @return null if the executable cannot be found.
      */
     private static File findInDir(String dirName, String commandName) {
-        File dir = FILE_UTILS.normalize(dirName);
+        File dir = FileUtils.getFileUtils().normalize(dirName);
         File executable = null;
         if (dir.exists()) {
             executable = new File(dir, addExtension(commandName));
@@ -542,7 +539,7 @@ public final class JavaEnvUtils {
      */
     public static File createVmsJavaOptionFile(String[] cmds)
             throws IOException {
-        File script = FILE_UTILS.createTempFile(null, "ANT", ".JAVA_OPTS", null, false, true); +        File script = FileUtils.getFileUtils().createTempFile(null, "ANT", ".JAVA_OPTS", null, false, true);          try (BufferedWriter out = new BufferedWriter(new FileWriter(script))) {
             for (String cmd : cmds) {
                 out.write(cmd);

-Jaikiran


On 03/04/26 1:16 pm, [email protected] wrote:
This is an automated email from the ASF dual-hosted git repository.

bodewig pushed a commit to branch master
in repository https://gitbox.apache.org/repos/asf/ant.git


The following commit(s) were added to refs/heads/master by this push:
      new 8b82aa501 allow JavaEnvUtils class to be loaded without loading 
FileUtils explicitly
8b82aa501 is described below

commit 8b82aa501391738fec9ba0f2788f39982e1edb22
Author: Stefan Bodewig <[email protected]>
AuthorDate: Fri Apr 3 09:45:15 2026 +0200

     allow JavaEnvUtils class to be loaded without loading FileUtils explicitly
https://bz.apache.org/bugzilla/show_bug.cgi?id=69992
---
  WHATSNEW                                           | 10 +++++
  .../org/apache/tools/ant/util/JavaEnvUtils.java    |  4 +-
  src/tests/antunit/util/java-env-test.xml           | 52 ++++++++++++++++++++++
  3 files changed, 65 insertions(+), 1 deletion(-)

diff --git a/WHATSNEW b/WHATSNEW
index 96b78b6b6..627cf4adf 100644
--- a/WHATSNEW
+++ b/WHATSNEW
@@ -1,6 +1,16 @@
  Changes from Ant 1.10.16 TO Ant 1.10.17
  =======================================
+Fixed bugs:
+-----------
+
+ * The JavaEnvUtils and FileUtils classes statically depend on each
+   other since Ant 1.10.16 making it impossible to load JavaEnvUtils
+   without loading FileUtils first causing NullPointerException for
+   programmatic use on Windows. This affected Eclipse and may also
+   affect other projects using Ant as a library.
+   Bugzilla Report 69992
+
  Changes from Ant 1.10.15 TO Ant 1.10.16
  =======================================
diff --git a/src/main/org/apache/tools/ant/util/JavaEnvUtils.java b/src/main/org/apache/tools/ant/util/JavaEnvUtils.java
index 899c714a9..e38002905 100644
--- a/src/main/org/apache/tools/ant/util/JavaEnvUtils.java
+++ b/src/main/org/apache/tools/ant/util/JavaEnvUtils.java
@@ -48,7 +48,7 @@ public final class JavaEnvUtils {
      private static final String JAVA_HOME = System.getProperty("java.home");
/** FileUtils instance for path normalization */
-    private static final FileUtils FILE_UTILS = FileUtils.getFileUtils();
+    private static final FileUtils FILE_UTILS;
/** Version of currently running VM. */
      private static String javaVersion;
@@ -230,6 +230,8 @@ public final class JavaEnvUtils {
          } catch (Throwable t) {
              // swallow as this simply doesn't seem to be Apache Harmony
          }
+
+        FILE_UTILS = FileUtils.getFileUtils();
      }
/**
diff --git a/src/tests/antunit/util/java-env-test.xml 
b/src/tests/antunit/util/java-env-test.xml
new file mode 100644
index 000000000..3d75e4668
--- /dev/null
+++ b/src/tests/antunit/util/java-env-test.xml
@@ -0,0 +1,52 @@
+<?xml version="1.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.
+-->
+<project xmlns:au="antlib:org.apache.ant.antunit"
+         name="firstmatch-test"
+         default="antunit">
+
+  <import file="../antunit-base.xml" />
+
+  <target name="setUp">
+    <mkdir dir="${input}"/>
+    <mkdir dir="${output}"/>
+  </target>
+
+  <target name="testLoadJavaEnvUtils" depends="setUp">
+    <echo file="${input}/JavaEnvUtilsTest.java">
+import org.apache.tools.ant.util.JavaEnvUtils;
+
+public class JavaEnvUtilsTest {
+
+    public static void main(String[] args) {
+        JavaEnvUtils.isClasspathBased();
+    }
+}
+    </echo>
+    <javac srcdir="${input}" destDir="${output}" includeantruntime="true"/>
+    <java classname="JavaEnvUtilsTest"
+          fork="true" failonerror="false" resultproperty="result">
+      <classpath>
+        <pathelement location="${output}"/>
+        <fileset dir="${ant.home}/lib" includes="ant.jar"/>
+      </classpath>
+    </java>
+    <au:assertFalse>
+      <isfailure code="${result}"/>
+    </au:assertFalse>
+  </target>
+</project>


---------------------------------------------------------------------
To unsubscribe, e-mail: [email protected]
For additional commands, e-mail: [email protected]

Reply via email to