0

Given the following verified working directory structure:

    /Users/me/Projects/DSS_Server/target/universal/stage/

And a higher directory containing some data:

    /Users/me/Projects/DSS_Server/data/

My question is this:

How is it possible for just the following Java code to be able to access and read data from the data directory given the above verified working directory?

    File input = new File("./data/rasterData.dat");
    FileInputStream fis = new FileInputStream(input);

To clarify, the data really does exist here:

    /Users/me/Projects/DSS_Server/data/rasterData.dat

And it does not exist here:

    /Users/me/Projects/DSS_Server/target/universal/stage/data/rasterData.dat

The observed behavior suggests (but does not prove) that there can be a path resolution happening behind-the-scenes when using a relative path.

Note: this example is not something I am deliberately trying to or wanting do, rather, this scenario came about in an accidental way and was not noticed for a while because the server data still loads as expected. i.e., it wasn't immediately obvious that anything was broken.

JDischler
  • 191
  • 17
  • What is the actual working directory? "…DSS_Server/"? Are you sure that "…DSS_Server/data/rasterData.dat" does not exist? Hope my question don't seem dump but my notion of "directory structure" does not necessary need to state the presence or not of regular (non-directory) files. – Valentin Ruano Jan 23 '14 at 19:00
  • The working directory depends on where you started the JVM from, not where the Java code lives. – Samhain Jan 23 '14 at 19:01
  • 1
    If you execute System.err.println(new File(".").getAbsoluteFile()) you will get the working directory. Similarly System.err.println(new File("./data/rasterData.dat").getAbsoluteFile()) would give you the actual location of that mysterious file. Please try. – Valentin Ruano Jan 23 '14 at 19:03
  • @Valentin: Indeed, that returns this: /Users/me/Projects/DSS_Server/target/universal/stage/ – JDischler Jan 23 '14 at 19:05
  • @JDischler and System.err.println(new File("./data/rasterData.dat").getAbsoluteFile())? Can you check that file is not existent in the machine you are running the program on? – Valentin Ruano Jan 23 '14 at 19:06
  • That returns this: /Users/me/Projects/DSS_Server/target/universal/stage/data/rasterData.dat Problem is the data is really at: /Users/me/Projects/DSS_Server/data/rasterData.dat And it somehow loads even though no one at my work can explain how or why. – JDischler Jan 23 '14 at 19:10
  • what do you get if you do "ls -ld /Users/me/Projects/DSS_Server/target/universal/stage/data"? is that symbolic link to the other directory? – Valentin Ruano Jan 23 '14 at 19:10
  • There's nothing there: "ls: /Users/me/Projects/DSS_Server/target/universal/stage/data: No such file or directory" The data is really at: "/Users/me/Projects/DSS_Server/dat" It's almost like the JVM is somehow resolving the location but I've never heard of that happening. – JDischler Jan 23 '14 at 19:14
  • Also is FileInputStream actually coming from java.io or another package? by the javadoc it should not work unless there is such a file. I wondering whether /Users/me/Projects/DSS_Server/ happens to be in the classpath and somehow it try to locate file relative to any entry in the classpath. – Valentin Ruano Jan 23 '14 at 19:15
  • Also are you running this from the command line or from some IDE? – Valentin Ruano Jan 23 '14 at 19:16
  • And of course, code downstream from the one listed is successfully processing some contents from rasterData.dat…? E.g. output the first few lines. Perhaps new FileInputStream is raising an exception but might actually get muffle by a surrounding try-catch (inside the same method or the calling code) – Valentin Ruano Jan 23 '14 at 19:20
  • Coming from java.io. The application is started via a batch file generated by the framework we are using. I should re-investigate that to see if there's anything odd in there. And yes, the data does load - our server pulls in roughly 6 GB of data through this method and all processes using that data are working normally. – JDischler Jan 23 '14 at 19:26
  • All of of the logic for the FileInputStream constructors are native methods (specifically FileInputStream.open(string)). As such, we need to know your OS version in order to find the actual implementation of FileInputStream that you're using. – Mark W Jan 23 '14 at 19:29
  • I run my own version of the server on mac OS X 10.9.1 (build 13B42) for development though identical behavior happens on our production server. I don't know the specifics of that system other than it's not mac based and is running some variant of linux (vague, I know - I could get that info if really needed). – JDischler Jan 23 '14 at 19:35
  • What if you to query that file within the same VM but without using FIS or any pure-java approach ? Say… try to output the file's inode using Runtime.getRuntime().exec("ls -i ./data/rasterData.dat") Does it succeed? I am afraid that the code is a bit more involved: http://stackoverflow.com/questions/792024/how-to-execute-system-commands-linux-bsd-using-java – Valentin Ruano Jan 23 '14 at 19:43
  • I wont be able to go through the native source for the FileInputStream. I dont have, or want an apple ID. You on the other hand probably can. I suggest you follow this guide: http://www.mkyong.com/mac/how-to-download-jdk-source-code-for-mac-os-x/ Get the source code for your version of java, and check out the implementation of this class. The implementation is going to be OS specific, clearly as it operates on the file system. It may be that the parent tree is traversed when a File object with a relative path is given to the stream, and can resolve it when it hits ./DSS_Server. – Mark W Jan 23 '14 at 19:51
  • @MarkW, the behavior does suggest that there is some kind of behind-the-scenes path resolution happening here with a relative path. I guess the details of how or why aren't super important because we need to refactor our code for other reasons. I think we mostly were hoping for some confirmation that this kind of behavior can happen (for our own sanity), though regardless of it indeed being platform specific or something in the Java specification, it doesn't seem wise to rely on this sort of behavior because has caused quite a bit of confusion here. – JDischler Jan 23 '14 at 20:02
  • I dont know if the standard JRE operates in the same way, but Open JDK spec says that it operates on the system property user.dir when attempting to use relative path operators. You could just quick check that property's value by getting it System.getProperty("user.dir") and comparing it with the absolute path from new File("").getAbsolutePath(). If one of them returns the /DSS_Server directory, I would think its safe to assume your implementation is using that system property with relative paths. http://docs.oracle.com/javase/tutorial/essential/environment/sysprop.html ps. Wisconsinites! – Mark W Jan 23 '14 at 20:05

0 Answers0