Home > Root > Log book > Java hack to deal with Windows file paths in Linux - 2023 version

Java hack to deal with Windows file paths in Linux - 2023 version

Sunday 2 April 2023, by Mathieu Brèthes

All the versions of this article: [Deutsch] [English] [français]

So sometimes I geek. This is stored here for posterity.

So you have this super cool Java binary code, that you want to run on Linux. The source code is long lost. You eagerly run the program, because Java is multiplatform it should just work, right?

Exception in thread "main" java.io.FileNotFoundException: c:\hello.txt (No such file or directory.)

Right, human stupidity. How to get this to run: start Windows? No way. Use Wine? Hmm...

What if, in all simplicity, we could just modify the JVM so that it converts Windows paths into Linux paths?

It turns out Chase Siebert, engineering directory at Dropbox, just wrote how to do this in his blog post. Thanks to the way the standard library is made, it is possible to do this by modifying a single file of the JDK: File.java. Great! So you follow the instructions, install the source code of the JVM (sudo apt-get install openjdk-src), look for the archive in the installation folder /usr/lib/jvm/openjdk-11/lib/src.zip, unzip it, look for File.java which is in java.base/java/io, modify and compile it (with which parameters? This takes a short while). Then create a jar, and run your Java program with a special parameter described in the blog. You eagerly press enter and then:

-Xbootclasspath/p is no longer a supported option.

That’s right, this used to work 13 years ago with Java 8. Now, we’re using Java 11. It’s a little bit more complicated...

Step 1: organize your project

Create a build directory for your build of the "patch" of the, a "run" directory for your program with hard-coded windows paths, and a sdk directory to hold the unzipped files of the sdk.

./build
./run
./sdk

Step 2: compile File.java with the right options

Modify File.java like indicated in the above blog post. Then add on top of the file import java.util.regex.Pattern; which is necessary to get the file to compile.

Go to the sdk’s root directory (the one containing java.base and others) and run the following line:

javac -XDstringConcat=inline -d ../build/java.base --patch-module java.base=. java.base/java/io/File.java

This will build your "patch" ofe File.java in the folder build/java.base . -XDstringConcat=inline is necessary to avoid an error at run-time (this documents why, and it took me ages to find the source of this bug...).

Step 3. Run the darn thing!

Go in the run directory and start your program with the following command:

java --patch-module java.base=../build/java.base myprogram

And now c:\hello.txt is converted into /hello.txt, which is a Linux path. Great!

A last link as a conclusion, I found the syntax of --patch-module correctly explained here (at the bottom of the page).

Now, finally, two websites talk about this problem!


View online : Java hack to deal with Windows file paths in Linux