Setting wrapper.working.dir does not affect the NIO2 filesystem API. This is a JVM-dependent issue. I am using Oracle 8u20, but this could also affect non-Oracle/OpenJDK JVMs.
Suppose YAJSW's working directory is "C:/foo". If you set wrapper.working.dir to "C:/bar", then try running a Java application that does something like
Path p = Paths.get("relative").toAbsolutePath();
p will point to C:/foo/relative, not C:/bar/relative
It looks like the problem stems from how the NIO2 API is implemented in OpenJDK/Oracle JVMs. The default filesystem is created when FileSystems is referenced by another class that needs to be loaded. The constructors for both sun.nio.fs.UnixFileSystem and WindowsFileSystem take a path parameter that is used as the "default directory". The value passed is the value of the "user.dir" system property. Because the default filesystem is cached for later use, any change to user.dir after the default filesystem is created will not affect the NIO2 APIs.
I managed to engineer a hack to "fix" this, by recreating the default filesystem after user.dir has been changed:
try { Class<?> fsClass = Class.forName("java.nio.file.FileSystems$DefaultFileSystemHolder"); Method defaultFsMethod = fsClass.getDeclaredMethod("defaultFileSystem"); defaultFsMethod.setAccessible(true); Field defaultFsField = fsClass.getDeclaredField("defaultFileSystem"); defaultFsField.setAccessible(true); FieldUtils.removeFinalModifier(defaultFsField); defaultFsField.set(null, defaultFsMethod.invoke(null)); } catch (Exception e) { System.err.println("Failed to apply NIO2 Path hackfix"); e.printStackTrace(); }
FieldUtils is from Apache Commons-Lang 3. This solution is not perfect. Any Path created before the default filesystem is replaced will still refer to the wrong working directory because Path objects retain a reference to the FileSystem that created them, but this does at least fix any Path objects created after the replacement. Also, this presumably does not work on JVMs not derived from OpenJDK, such as the IBM JVM. But then again, the IBM JVM may not have this problem to begin with.
hello,
thanks for your feedback.
i tried to reproduce the issue but could not.
yajsw: 12.00, jdk: 1.7
in the configuration i set wrapper.working.dir
in the main method of the wrapped application i invoke:
System.out.println(Paths.get(".").toAbsolutePath());
i installed the application as windows service and run it.
it logs the same path as the one set for wrapper.working.dir.
The method WindowsXPProcess.changeWorkingDir(String) also sets the system property user.dir.
Could you pls provide some more input how to reproduce the issue.
-- Ron
I am using YAJSW 11.11, since 12.00 is still in alpha.
Which JVM are you using? Oracle? This is a JVM-specific issue and I don't know if it occurs in Oracle/OpenJDK 1.7. I am currently using Oracle 8u20.
seems to work with release 12.04