ADDITIONAL SYSTEM INFORMATION :
Linux
Property settings:
file.encoding = UTF-8
file.separator = /
java.class.path =
java.class.version = 69.0
java.home = /usr/lib/jvm/java-25-openjdk-amd64
java.io.tmpdir = /tmp
java.library.path = /usr/java/packages/lib
/usr/lib/x86_64-linux-gnu/jni
/lib/x86_64-linux-gnu
/usr/lib/x86_64-linux-gnu
/usr/lib/jni
/lib
/usr/lib
java.runtime.name = OpenJDK Runtime Environment
java.runtime.version = 25.0.2+10-Ubuntu-124.04
java.specification.name = Java Platform API Specification
java.specification.vendor = Oracle Corporation
java.specification.version = 25
java.vendor = Ubuntu
java.vendor.url = https://ubuntu.com/
java.vendor.url.bug = https://bugs.launchpad.net/ubuntu/+source/openjdk-25
java.version = 25.0.2
java.version.date = 2026-01-20
java.vm.compressedOopsMode = Zero based
java.vm.info = mixed mode, sharing
java.vm.name = OpenJDK 64-Bit Server VM
java.vm.specification.name = Java Virtual Machine Specification
java.vm.specification.vendor = Oracle Corporation
java.vm.specification.version = 25
java.vm.vendor = Ubuntu
java.vm.version = 25.0.2+10-Ubuntu-124.04
jdk.debug = release
line.separator = \n
native.encoding = UTF-8
os.arch = amd64
os.name = Linux
os.version = 6.17.0-14-generic
path.separator = :
stderr.encoding = UTF-8
stdin.encoding = UTF-8
stdout.encoding = UTF-8
sun.arch.data.model = 64
sun.boot.library.path = /usr/lib/jvm/java-25-openjdk-amd64/lib
sun.cpu.endian = little
sun.io.unicode.encoding = UnicodeLittle
sun.java.launcher = SUN_STANDARD
sun.jnu.encoding = UTF-8
sun.management.compiler = HotSpot 64-Bit Tiered Compilers
user.country = DE
user.dir = /tmp/canonical-path-test
openjdk version "25.0.2" 2026-01-20
OpenJDK Runtime Environment (build 25.0.2+10-Ubuntu-124.04)
OpenJDK 64-Bit Server VM (build 25.0.2+10-Ubuntu-124.04, mixed mode, sharing)
Windows
Property settings:
file.encoding = UTF-8
file.separator = \
java.class.path =
java.class.version = 69.0
java.home = c:\Program Files\Eclipse Adoptium\jdk-25.0.2.10-hotspot
java.io.tmpdir = C:\Users\bodewig\AppData\Local\Temp\
java.library.path = c:\Program Files\Eclipse Adoptium\jdk-25.0.2.10-hotspot\bin
C:\WINDOWS\Sun\Java\bin
C:\WINDOWS\system32
C:\WINDOWS
C:\Program Files\Eclipse Adoptium\jdk-21.0.10.7-hotspot\bin
C:\Program Files\Eclipse Adoptium\jdk-25.0.2.10-hotspot\bin
C:\WINDOWS\system32
C:\WINDOWS
C:\WINDOWS\System32\Wbem
C:\WINDOWS\System32\WindowsPowerShell\v1.0\
C:\Program Files\dotnet\
C:\WINDOWS\System32\OpenSSH\
C:\Program Files\PowerShell\7\
C:\Program Files\Git\cmd
C:\Users\bodewig\.dotnet\tools
C:\Windows\Microsoft.NET\Framework\v4.0.30319
C:\Users\bodewig\AppData\Local\Microsoft\WindowsApps
C:\Users\bodewig\.dotnet\tools
C:\xmlunit
.
java.runtime.name = OpenJDK Runtime Environment
java.runtime.version = 25.0.2+10-LTS
java.specification.name = Java Platform API Specification
java.specification.vendor = Oracle Corporation
java.specification.version = 25
java.vendor = Eclipse Adoptium
java.vendor.url = https://adoptium.net/
java.vendor.url.bug = https://github.com/adoptium/adoptium-support/issues
java.vendor.version = Temurin-25.0.2+10
java.version = 25.0.2
java.version.date = 2026-01-20
java.vm.compressedOopsMode = Zero based
java.vm.info = mixed mode, sharing
java.vm.name = OpenJDK 64-Bit Server VM
java.vm.specification.name = Java Virtual Machine Specification
java.vm.specification.vendor = Oracle Corporation
java.vm.specification.version = 25
java.vm.vendor = Eclipse Adoptium
java.vm.version = 25.0.2+10-LTS
jdk.debug = release
line.separator = \r \n
native.encoding = Cp1252
os.arch = amd64
os.name = Windows 11
os.version = 10.0
path.separator = ;
stderr.encoding = cp437
stdin.encoding = cp437
stdout.encoding = cp437
sun.arch.data.model = 64
sun.boot.library.path = c:\Program Files\Eclipse Adoptium\jdk-25.0.2.10-hotspot\bin
sun.cpu.endian = little
sun.cpu.isalist = amd64
sun.io.unicode.encoding = UnicodeLittle
sun.java.launcher = SUN_STANDARD
sun.jnu.encoding = Cp1252
sun.management.compiler = HotSpot 64-Bit Tiered Compilers
sun.os.patch.level =
user.country = US
user.dir = C:\temp\canonical-path-test
user.home = C:\Users\bodewig
user.language = en
user.script =
user.variant =
openjdk version "25.0.2" 2026-01-20 LTS
OpenJDK Runtime Environment Temurin-25.0.2+10 (build 25.0.2+10-LTS)
OpenJDK 64-Bit Server VM Temurin-25.0.2+10 (build 25.0.2+10-LTS, mixed mode, sharing)
A DESCRIPTION OF THE PROBLEM :
When running java from within a directory that is a symbolic link the current working directory as reflected by the File constructor or the user.dir system property resolves the symlink on Linux but does not on Windows.
STEPS TO FOLLOW TO REPRODUCE THE PROBLEM :
on Linux
$ mkdir -p /tmp/cwd-test/normal
/tmp/canonical-path-test$ cd /tmp/cwd-test
/tmp/cwd-test$ ln -s normal symlink
# copy WhereAmI to /tmp/cwd-test
$ /usr/lib/jvm/java-25-openjdk-amd64/bin/javac WhereAmI.java
$ cd symlink
# run WhereAmI
On Windows
Windows:
>cd \Temp
C:\temp>mkdir cwd-test
C:\temp>cd cwd-test
C:\temp\cwd-test>mkdir normal
C:\temp\cwd-test>mklink /D symlink c:\temp\cwd-test\normal
symbolic link created for symlink <<===>> c:\temp\cwd-test\normal
C:\temp\cwd-test>mklink /J junction c:\temp\cwd-test\normal
Junction created for junction <<===>> c:\temp\cwd-test\normal
# copy WhereAmI to C:\temp\cwd-test
C:\temp\cwd-test>"c:\Program Files\Eclipse Adoptium\jdk-25.0.2.10-hotspot\bin\javac.exe" WhereAmI.java
C:\temp\cwd-test> cd symlink
# run WhereAmI
C:\temp\cwd-test\symlink> cd ..\junction
# run WhereAmI
---------- BEGIN SOURCE ----------
import java.io.*;
public class WhereAmI {
public static void main(String[] args) {
System.err.println("user.dir is " + System.getProperty("user.dir"));
System.err.println("Current dir is " + new File(".").getAbsolutePath());
}
}
---------- END SOURCE ----------
CUSTOMER SUBMITTED WORKAROUND :
never trust user.dir or use the single-String arg File constructor but rather invoke getCanonicalPath on whatever user.dir returns and specify it as base directory explicitly, I guess.
Linux
Property settings:
file.encoding = UTF-8
file.separator = /
java.class.path =
java.class.version = 69.0
java.home = /usr/lib/jvm/java-25-openjdk-amd64
java.io.tmpdir = /tmp
java.library.path = /usr/java/packages/lib
/usr/lib/x86_64-linux-gnu/jni
/lib/x86_64-linux-gnu
/usr/lib/x86_64-linux-gnu
/usr/lib/jni
/lib
/usr/lib
java.runtime.name = OpenJDK Runtime Environment
java.runtime.version = 25.0.2+10-Ubuntu-124.04
java.specification.name = Java Platform API Specification
java.specification.vendor = Oracle Corporation
java.specification.version = 25
java.vendor = Ubuntu
java.vendor.url = https://ubuntu.com/
java.vendor.url.bug = https://bugs.launchpad.net/ubuntu/+source/openjdk-25
java.version = 25.0.2
java.version.date = 2026-01-20
java.vm.compressedOopsMode = Zero based
java.vm.info = mixed mode, sharing
java.vm.name = OpenJDK 64-Bit Server VM
java.vm.specification.name = Java Virtual Machine Specification
java.vm.specification.vendor = Oracle Corporation
java.vm.specification.version = 25
java.vm.vendor = Ubuntu
java.vm.version = 25.0.2+10-Ubuntu-124.04
jdk.debug = release
line.separator = \n
native.encoding = UTF-8
os.arch = amd64
os.name = Linux
os.version = 6.17.0-14-generic
path.separator = :
stderr.encoding = UTF-8
stdin.encoding = UTF-8
stdout.encoding = UTF-8
sun.arch.data.model = 64
sun.boot.library.path = /usr/lib/jvm/java-25-openjdk-amd64/lib
sun.cpu.endian = little
sun.io.unicode.encoding = UnicodeLittle
sun.java.launcher = SUN_STANDARD
sun.jnu.encoding = UTF-8
sun.management.compiler = HotSpot 64-Bit Tiered Compilers
user.country = DE
user.dir = /tmp/canonical-path-test
openjdk version "25.0.2" 2026-01-20
OpenJDK Runtime Environment (build 25.0.2+10-Ubuntu-124.04)
OpenJDK 64-Bit Server VM (build 25.0.2+10-Ubuntu-124.04, mixed mode, sharing)
Windows
Property settings:
file.encoding = UTF-8
file.separator = \
java.class.path =
java.class.version = 69.0
java.home = c:\Program Files\Eclipse Adoptium\jdk-25.0.2.10-hotspot
java.io.tmpdir = C:\Users\bodewig\AppData\Local\Temp\
java.library.path = c:\Program Files\Eclipse Adoptium\jdk-25.0.2.10-hotspot\bin
C:\WINDOWS\Sun\Java\bin
C:\WINDOWS\system32
C:\WINDOWS
C:\Program Files\Eclipse Adoptium\jdk-21.0.10.7-hotspot\bin
C:\Program Files\Eclipse Adoptium\jdk-25.0.2.10-hotspot\bin
C:\WINDOWS\system32
C:\WINDOWS
C:\WINDOWS\System32\Wbem
C:\WINDOWS\System32\WindowsPowerShell\v1.0\
C:\Program Files\dotnet\
C:\WINDOWS\System32\OpenSSH\
C:\Program Files\PowerShell\7\
C:\Program Files\Git\cmd
C:\Users\bodewig\.dotnet\tools
C:\Windows\Microsoft.NET\Framework\v4.0.30319
C:\Users\bodewig\AppData\Local\Microsoft\WindowsApps
C:\Users\bodewig\.dotnet\tools
C:\xmlunit
.
java.runtime.name = OpenJDK Runtime Environment
java.runtime.version = 25.0.2+10-LTS
java.specification.name = Java Platform API Specification
java.specification.vendor = Oracle Corporation
java.specification.version = 25
java.vendor = Eclipse Adoptium
java.vendor.url = https://adoptium.net/
java.vendor.url.bug = https://github.com/adoptium/adoptium-support/issues
java.vendor.version = Temurin-25.0.2+10
java.version = 25.0.2
java.version.date = 2026-01-20
java.vm.compressedOopsMode = Zero based
java.vm.info = mixed mode, sharing
java.vm.name = OpenJDK 64-Bit Server VM
java.vm.specification.name = Java Virtual Machine Specification
java.vm.specification.vendor = Oracle Corporation
java.vm.specification.version = 25
java.vm.vendor = Eclipse Adoptium
java.vm.version = 25.0.2+10-LTS
jdk.debug = release
line.separator = \r \n
native.encoding = Cp1252
os.arch = amd64
os.name = Windows 11
os.version = 10.0
path.separator = ;
stderr.encoding = cp437
stdin.encoding = cp437
stdout.encoding = cp437
sun.arch.data.model = 64
sun.boot.library.path = c:\Program Files\Eclipse Adoptium\jdk-25.0.2.10-hotspot\bin
sun.cpu.endian = little
sun.cpu.isalist = amd64
sun.io.unicode.encoding = UnicodeLittle
sun.java.launcher = SUN_STANDARD
sun.jnu.encoding = Cp1252
sun.management.compiler = HotSpot 64-Bit Tiered Compilers
sun.os.patch.level =
user.country = US
user.dir = C:\temp\canonical-path-test
user.home = C:\Users\bodewig
user.language = en
user.script =
user.variant =
openjdk version "25.0.2" 2026-01-20 LTS
OpenJDK Runtime Environment Temurin-25.0.2+10 (build 25.0.2+10-LTS)
OpenJDK 64-Bit Server VM Temurin-25.0.2+10 (build 25.0.2+10-LTS, mixed mode, sharing)
A DESCRIPTION OF THE PROBLEM :
When running java from within a directory that is a symbolic link the current working directory as reflected by the File constructor or the user.dir system property resolves the symlink on Linux but does not on Windows.
STEPS TO FOLLOW TO REPRODUCE THE PROBLEM :
on Linux
$ mkdir -p /tmp/cwd-test/normal
/tmp/canonical-path-test$ cd /tmp/cwd-test
/tmp/cwd-test$ ln -s normal symlink
# copy WhereAmI to /tmp/cwd-test
$ /usr/lib/jvm/java-25-openjdk-amd64/bin/javac WhereAmI.java
$ cd symlink
# run WhereAmI
On Windows
Windows:
>cd \Temp
C:\temp>mkdir cwd-test
C:\temp>cd cwd-test
C:\temp\cwd-test>mkdir normal
C:\temp\cwd-test>mklink /D symlink c:\temp\cwd-test\normal
symbolic link created for symlink <<===>> c:\temp\cwd-test\normal
C:\temp\cwd-test>mklink /J junction c:\temp\cwd-test\normal
Junction created for junction <<===>> c:\temp\cwd-test\normal
# copy WhereAmI to C:\temp\cwd-test
C:\temp\cwd-test>"c:\Program Files\Eclipse Adoptium\jdk-25.0.2.10-hotspot\bin\javac.exe" WhereAmI.java
C:\temp\cwd-test> cd symlink
# run WhereAmI
C:\temp\cwd-test\symlink> cd ..\junction
# run WhereAmI
---------- BEGIN SOURCE ----------
import java.io.*;
public class WhereAmI {
public static void main(String[] args) {
System.err.println("user.dir is " + System.getProperty("user.dir"));
System.err.println("Current dir is " + new File(".").getAbsolutePath());
}
}
---------- END SOURCE ----------
CUSTOMER SUBMITTED WORKAROUND :
never trust user.dir or use the single-String arg File constructor but rather invoke getCanonicalPath on whatever user.dir returns and specify it as base directory explicitly, I guess.
- relates to
-
JDK-8366102 Clarification Needed: Symbolic Link Handling in File API Specifications
-
- Resolved
-