Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Java 11 breaks chdir() for JavaPOSIX #131

Open
ickzon opened this issue Mar 26, 2019 · 5 comments
Open

Java 11 breaks chdir() for JavaPOSIX #131

ickzon opened this issue Mar 26, 2019 · 5 comments

Comments

@ickzon
Copy link

ickzon commented Mar 26, 2019

In Java 11 setting system property "user.dir" doesn't have any effect JDK-8066709.

Now file handling is messed up after changing the working directory:

new File("c:/foo").mkdirs();

jnr.posix.POSIXFactory.getJavaPOSIX().chdir("c:/foo");
jnr.posix.POSIXFactory.getNativePOSIX().chdir("c:/foo");

File f = new File("file");

// correctly creates file in "c:/foo"
f.createNewFile();
f.delete();

// creates file in the old working dir
f.getAbsoluteFile().createNewFile();
f.getAbsoluteFile().delete();

// creates file in the old working dir
f.getCanonicalFile().createNewFile();
f.getCanonicalFile().delete();

// correctly creates file in "c:/foo"
new FileOutputStream(f).close();
f.delete();

// correctly creates file in "c:/foo"
new FileOutputStream("file").close();
f.delete();

// creates file in the old working dir
Files.writeString(f.toPath(), "");
Files.delete(f.toPath());

I'm not sure if there even is a way to get this working again. Maybe I should report that as a bug in the Java specs itself? Oracle will of course close this as "don't change the working directory of a running JVM"...

I'm so pissed how they are currently destroying the Java ecosystem...

@ickzon
Copy link
Author

ickzon commented Mar 26, 2019

After reading through JDK 4045688 (again) I'm quite sure that switching the current working directory of a running JVM is considered inherently insecure (and okay, it really is under certain circumstances) and will never be officially supported again in any way. The previously working solution (switch working directory and set "user.dir" accordingly) will no longer work with Java 11 and above, so maybe the "solution" is to let JavaPOSIX return an error code or throw an exception if called (if Java version is > 10).

@Melab
Copy link

Melab commented Mar 5, 2022

After reading through JDK 4045688 (again) I'm quite sure that switching the current working directory of a running JVM is considered inherently insecure (and okay, it really is under certain circumstances) and will never be officially supported again in any way. The previously working solution (switch working directory and set "user.dir" accordingly) will no longer work with Java 11 and above, so maybe the "solution" is to let JavaPOSIX return an error code or throw an exception if called (if Java version is > 10).

Is there any reason JNR can't access the corresponding system call, instead? It is Java Native Runtime.

@headius
Copy link
Member

headius commented Mar 10, 2022

@Melab This is in the pure-Java emulation part of jnr-posix. The native logic does actually do a process-level chdir but previously the best we could do is change the user.dir property. Now it seems we can't even do that and have it be reflected by the rest of the JDK in any meaninful way.

@ickzon Setting user.dir was never a particularly useful change, since as JDK-4045688 points out, it is usually read once at boot and cached by all the JDK classes that use it. Making it read-only just removes our ability to update it but does not really impact functionality much (since the functionality we did have was very limited).

It probably would be worth raising a better error for JavaPOSIX.chdir but since it's an error either way on Java 11 it's just moving the error around a bit. Perhaps we can raise something more like an EACCES to mimic the similar situation when a target path is not searchable (and therefore we can't enter it) but it won't make your example code work.

We deal with this in JRuby by always maintaining a per-instance representation of the current directory, and adding logic to all filesystem-related calls to appropriately use that current directory. JDK-4045688 discusses a similar possible change for OpenJDK as being too big of a job (and it is certainly not easy) but it can be done externally by other users of jnr-posix (such as yourself) if you need to simulate a "virtual" CWD.

Integrating virtual CWD support into jnr-posix's pure-Java support is probably out of scope since it would require us to provide JDK-equivalent File and Path APIs that know about the virtual CWD.

@Melab
Copy link

Melab commented Mar 14, 2022

@Melab This is in the pure-Java emulation part of jnr-posix. The native logic does actually do a process-level chdir but previously the best we could do is change the user.dir property. Now it seems we can't even do that and have it be reflected by the rest of the JDK in any meaninful way.

@ickzon Setting user.dir was never a particularly useful change, since as JDK-4045688 points out, it is usually read once at boot and cached by all the JDK classes that use it. Making it read-only just removes our ability to update it but does not really impact functionality much (since the functionality we did have was very limited).

It probably would be worth raising a better error for JavaPOSIX.chdir but since it's an error either way on Java 11 it's just moving the error around a bit. Perhaps we can raise something more like an EACCES to mimic the similar situation when a target path is not searchable (and therefore we can't enter it) but it won't make your example code work.

We deal with this in JRuby by always maintaining a per-instance representation of the current directory, and adding logic to all filesystem-related calls to appropriately use that current directory. JDK-4045688 discusses a similar possible change for OpenJDK as being too big of a job (and it is certainly not easy) but it can be done externally by other users of jnr-posix (such as yourself) if you need to simulate a "virtual" CWD.

Integrating virtual CWD support into jnr-posix's pure-Java support is probably out of scope since it would require us to provide JDK-equivalent File and Path APIs that know about the virtual CWD.

@headius Considering I can't even get native POSIX support loaded without Java whining about an unsatisfied link or a missing class definition, I think this project's lack of chdir support is bigger than all of that.

@headius
Copy link
Member

headius commented Mar 14, 2022

@Melab Without loading the native library, there's no way to force the JVM to do a real chdir. When native support loads, chdir works fine.

I'll try to help you in the other issue.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

3 participants