Uploaded image for project: 'JDK'
  1. JDK
  2. JDK-5082706

File constructor and methods don't consistently resolve relative paths against user.dir


    • Type: Bug
    • Status: Closed
    • Priority: P4
    • Resolution: Duplicate
    • Affects Version/s: 5.0
    • Fix Version/s: None
    • Component/s: core-libs
    • Labels:
    • Subcomponent:
    • CPU:
    • OS:


      Name: gm110360 Date: 08/04/2004

      java version "1.5.0-beta2"
      Java(TM) 2 Runtime Environment, Standard Edition (build 1.5.0-beta2-b51)
      Java HotSpot(TM) Client VM (build 1.5.0-beta2-b51, mixed mode, sharing)

      Windows 2000 Service Pack 4 (probably fails on all Operating Systems)

      The java.io.File class has behaviour which is contrary to the documentation. Relative paths are sometimes resolved against the directory named by System.getProperty("user.dir"), which is the expected behaviour from the JavaDoc for this class. Sometimes however, relative names are resolved against the directory in the Java Virtual Machine was originally invoked (this behaviour is of no use to anyone!!!! eg. if you are developing in NetBeans [which starts the JVM] you cannot use relative paths with java.io.File as it sometimes ignores the directory you set as "user.dir").

      The java.io.File documentation states (emphasis added by me):
             "By default the classes in the java.io package ALWAYS resolve relative
              pathnames against the current user directory. This directory is named
              by the system property user.dir, and is TYPICALLY the directory in
              which the Java virtual machine was invoked."

      Yes, the JavaDoc also indicates that relative to absolute path resolution is also system dependent - which invalidates bot user expectation and the quote above.

      This was originally reported as related bugs 4117557 as 4483097 and was *incorrectly* closed by the responsible engineer. All the client/user comments (below the main text of the 4483097 bug report state this). The engineer's comments were:
        " Not a bug. If you need to resolve a filename against the value of
      the "user.dir" system property then you must use getAbsolutePath (or
      getAbsoluteFile, or getCanonicalPath, or getCanonicalFile). Simpler
      operations such as exists() always resolve against the directory in
      which the Java virtual machine was originally invoked (and no, there
      is no way to change that).

      -- xxxxx@xxxxx 2001/7/23"

      However, this clearly contravenes both the JavaDoc for java.io.File, but also (and this is far worse) results in behaviour which users cannot control.

        Suggested fixes:

      a) Fix the java.io.File class so that *ALL* relative names are resolved against the value of "user.dir". This is the behaviour that all user comments have requested (it was the behaviour they expected). The users that have looked at the Java source code believe it is possible to do from the publically available source code they have seen. It would fufil the user expected behaviour and the specified semantics given in the java.io.File JavaDoc documentation. Yes I know that this solution takes time the maintainers have too little of, but this is also the "right solution".
      b) Change the java.io.File JavaDoc to indicate which methods ignore the user-specified "user.dir". This is a quick and easy fix for the maintainers, but pretty much renders relative paths unusable in java.io.File as the user has no way to consistently control the base path that relative files are resolved against.

      In conclusion
      I think Java is great, but this bug should have been fixed years ago (saying it isn't a bug defies reality, all your users and the documentation unamimously think it is). No wonder so many people have become disillusioned with Java and are turning the the (vile) C#.NET - at least in C# the users control over relative directory resolution.

      See the example code below.

      EXPECTED -
      The printout from the example code should be:

      relativeFileExists = true, absoluteFileExists = true

      ie. relative file paths should always be resolved against the System property "user.dir".
      ACTUAL -
      The printout from the example code is:

      relativeFileExists = false, absoluteFileExists = true

      ie. relative file paths are only sometimes resolved against the System property "user.dir" and are sometimes resolved against a path in an undocumented manner.

      This bug can be reproduced always.

      ---------- BEGIN SOURCE ----------
       * TestFile.java
       * Created on 29 July 2004, 14:47
      * NOTE: since relative paths don't work consistently in java.io.File
      * you will have to set the variable workingDirectory (within the
      * main() method of this class) to name the location where you
      * placed this java file.

      import java.io.File;

      public class TestFile
        public static void main(String args[])
           String filename = "TestFile.java";

           // Change this path to name the absolute directory path where
           // this Java file is located.
           String workingDirectory = "H:\\source\\bi\\installer";
            // Run the test.
           TestFile test = new TestFile(filename, workingDirectory);
          /** Creates a new instance of TestFile */
          public TestFile (String filename, String workingDirectory)
            // Set the system property "user.dir" to a known state.
            System.setProperty("user.dir", workingDirectory);
            File relativeFile = new File(filename);
            File absoluteFile = new File(relativeFile.getAbsolutePath());
            // The following code returns false, as the relative path ignores the
            // "user.dir" property and resolves the file against the initial directory
            // that the JVM was invoked in. This contravenes the JavaDoc for
            // java.io.File which states:
            // "By default the classes in the java.io package always resolve relative
            // pathnames against the current user directory. This directory is named
            // by the system property user.dir, and is typically the directory in
            // which the Java virtual machine was invoked."
            boolean relativeFileExists = relativeFile.exists(); // ERROR: is false!
            // This returns true, as expected.
            boolean absoluteFileExists = absoluteFile.exists(); // is true.
            System.out.println("relativeFileExists = " + relativeFileExists + ", absoluteFileExists = " + absoluteFileExists);
      ---------- END SOURCE ----------

        From bug 4483097:

        An ugly work-around is using getAbsoluteFile() on all File objects that came
        from "unknown" sources, and may therefore contain a relative path (e.g. user-
        supplied strings, as opposed to JFileChooser.)

      However, this workaround is simply saying that relative paths can't be used in Java (which is pretty bad!!!!).
      (Incident Review ID: 290252)


          Issue Links



              • Assignee:
                alanb Alan Bateman
                gmanwanisunw Girish Manwani (Inactive)
              • Votes:
                0 Vote for this issue
                0 Start watching this issue


                • Created: