JDK-8323811 : Setting java.io.tmpdir programatically does not work since Java 20
  • Type: Bug
  • Component: core-libs
  • Sub-Component: java.io
  • Affected Version: 20
  • Priority: P3
  • Status: Resolved
  • Resolution: Not an Issue
  • OS: generic
  • CPU: generic
  • Submitted: 2024-01-15
  • Updated: 2024-01-19
  • Resolved: 2024-01-16
Related Reports
Relates :  
Relates :  
Description
ADDITIONAL SYSTEM INFORMATION :
tested on linux and windows

A DESCRIPTION OF THE PROBLEM :
java.io.File.createTempFile("xyz", ".tmp") uses default temp-dir event if 
System.setProperty("java.io.tmpdir", ...); was set before.

It seems that this was changed between java 19 and 20

One possible change was in java.nio.file.TempFileHelper
from
private static final Path tmpdir = Paths.get(doPrivileged(new GetPropertyAction("java.io.tmpdir")));
to
private static final Path tmpdir = Path.of(StaticProperty.javaIoTmpDir());

StaticProperty is loaded very very early and therefore jdk.internal.util.StaticProperty.JAVA_IO_TMPDIR contains the default temp-dir.
-> I know that java.io.tmpdir has to be set early in application but currently even a simple main-method is not able to change the java.io.tmpdir (see steps to reproduce)

REGRESSION : Last worked in version 19

STEPS TO FOLLOW TO REPRODUCE THE PROBLEM :
call System.setProperty("java.io.tmpdir", ...) on application start, create temp-file and check the directory.

EXPECTED VERSUS ACTUAL BEHAVIOR :
EXPECTED -
no exception 
ACTUAL -
exception beginning with java 20

docker run -it --rm -v $PWD:/test -w /test eclipse-temurin:11-jdk sh -c "javac Test.java && java -cp . Test"
11.0.21
/tmpfoobar
/tmpfoobar/xyz12142257841535750632.tmp

docker run -it --rm -v $PWD:/test -w /test eclipse-temurin:17-jdk sh -c "javac Test.java && java -cp . Test"
17.0.9
/tmpfoobar
/tmpfoobar/xyz3659998787174078425.tmp

docker run -it --rm -v $PWD:/test -w /test eclipse-temurin:19-jdk sh -c "javac Test.java && java -cp . Test"
19.0.2
/tmpfoobar
/tmpfoobar/xyz16800814432785594764.tmp

docker run -it --rm -v $PWD:/test -w /test eclipse-temurin:20-jdk sh -c "javac Test.java && java -cp . Test"
20.0.2
/tmpfoobar
/tmp/xyz7255378145959570555.tmp
Exception in thread "main" java.lang.IllegalStateException: actual: /tmp, expected: /tmpfoobar
        at Test.main(Test.java:14)

docker run -it --rm -v $PWD:/test -w /test eclipse-temurin:21-jdk sh -c "javac Test.java && java -cp . Test"
21.0.1
/tmpfoobar
/tmp/xyz1465904699981539377.tmp
Exception in thread "main" java.lang.IllegalStateException: actual: /tmp, expected: /tmpfoobar
        at Test.main(Test.java:14)


---------- BEGIN SOURCE ----------
public class Test {
  public static void main(String[] args)
   throws Exception
  {
    final java.io.File tmp = new java.io.File("/tmpfoobar");
    tmp.mkdirs();
    System.setProperty("java.io.tmpdir", tmp.getAbsolutePath());
    java.io.File testFile = java.io.File.createTempFile("xyz", ".tmp");
    System.out.println(System.getProperty("java.version"));
    System.out.println(tmp.getAbsolutePath());
    System.out.println(testFile);

    if (!tmp.getAbsolutePath().equals(testFile.getParent()))
      throw new IllegalStateException("actual: " + testFile.getParent() + ", expected: " + tmp.getAbsolutePath());
  }
}

---------- END SOURCE ----------

FREQUENCY : always



Comments
The changes for JEP 380 added the needed infrastructure for this in JDK 16. The changes in JDK 20 via 8290313 made use of it. It was just an oversight that a release note didn't document the change in JDK 20.
19-01-2024

The test cases are reproducible and were tested for the below JDK versions on Linux and Windows. Observations 1. For JDK versions before JDK 20 - The 'tmp' directory is set according to System.setProperty("java.io.tmpdir", ...) Tested on jdk- 11.0.21, jdk-17.0.2, jdk-19. 2. For JDK versions after JDK 20 - The 'tmp' directory is set to the default and doesn't consider the path given in System.setProperty() Tested on jdk-20.0.2 and jdk-21.0.1 Possible cause Changes related to https://bugs.openjdk.org/browse/JDK-8290313 The JDK 20 RN only mentions the 'Print Warning to Standard Error If Bad java.io.tmpdir Setting Is Detected' and nothing related to the change to java.io.tmpdir.
16-01-2024

I think this can be closed as not a bug but we should create a RN for JDK 20.
16-01-2024

See API note in System.getProperties where it explains that changing the value of standard system properties leads to unpredictable results. The JDK has been gradually moving to read the standard system properties at startup. Probably should have been a release note for the change to java.io.tmpdir.
15-01-2024