10 Replies Latest reply: Feb 24, 2012 3:03 PM by jtahlborn RSS

    Why does java.nio.files.Path require implementations to be immutable?

    919532
      The javadocs for Path (http://docs.oracle.com/javase/7/docs/api/java/nio/file/Path.html) state that "implementations of this interface are immutable and safe for use by multiple concurrent threads.". However, the interface also defines a getFileSystem() method that needs to return a reference to the FileSystem that created the Path object. FileSystems can be closed, and therefore as far as I can figure are not immutable. This means that a simple implementation sketch like this one doesn't meet the criteria in the javadoc:

      public class MyPath implements Path {
      private final FileSystem fileSystem;

      public MyPath(FileSystem fileSystem) {
      this.fileSystem = fileSystem;
      }

      @Override
      public FileSystem getFileSystem() {
      return fileSystem;
      }
      }

      (I'd love to be able to format the code above better, but I can't figure out how to do that)

      Instead, the only option I can think of would be to do some kind of lookup in some global state, which feels absolutely awful. I wonder if the existing Path implementations in the Sun-private packages actually are properly immutable and how that's done - does anybody know?
        • 1. Re: Why does java.nio.files.Path require implementations to be immutable?
          gimbal2
          916529 wrote:
          (I'd love to be able to format the code above better, but I can't figure out how to do that)
          With \
           tags. 
          
          >
          
          Instead, the only option I can think of would be to do some kind of lookup in some global state, which feels absolutely awful.
          Feelings and programming do not mix. As a human you are often wrong and the state of being wrong often stems from an emotional state. Think more about what is sensible and logical. In this case, I would hesitate to say that there is only one instance of a given FileSystem implementation at a given time, which means you can reference it as a Singleton and not store a reference to it inside the Path object. Still, you pose an interesting design question here. Because quote "implementations of this interface are immutable and safe for use by multiple concurrent threads." -> I call shenanigans. If a thread closed the FileSystem, that is certainly going to influence the other threads.
          I wonder if the existing Path implementations in the Sun-private packages actually are properly immutable and how that's done - does anybody know?
          You can always download and check the source code of OpenJDK. It might even be in that src.zip you will find in your JDK directory.                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                       
          • 2. Re: Why does java.nio.files.Path require implementations to be immutable?
            jtahlborn
            I think you are misinterpreting the javadocs. it says the Path instance is immutable, it doesn't say anything about the FileSystem instance referenced by the Path. i would say that your simple implementation would be perfectly valid. (as a side note, i would not use a singleton reference to a FileSystem as gimbal2 suggested, as that will restrict the usefulness of your code and is generally a code smell).
            • 3. Re: Why does java.nio.files.Path require implementations to be immutable?
              gimbal2
              jtahlborn wrote:
              I think you are misinterpreting the javadocs. it says the Path instance is immutable, it doesn't say anything about the FileSystem instance referenced by the Path. i would say that your simple implementation would be perfectly valid.
              Yes, but Path must be able to return a reference to it. So how would you do that while maintaining complete immutability?
              (as a side note, i would not use a singleton reference to a FileSystem as gimbal2 suggested, as that will restrict the usefulness of your code and is generally a code smell).
              It does not and it is not. Not NECESSARILY, at least, like you are trying to pass off without any argument or reason.

              Even the cleanest piece of code can be made smelly. It is not an argument to throw around. I am a decent engineer, I know how to properly use the tools available to me - including singleton objects. My code certainly does not "restrict usefulness", or whatever the heck that means.
              • 4. Re: Why does java.nio.files.Path require implementations to be immutable?
                EJP
                I would do it by having the FileSystem construct the Path, with a back pointer, rather than have the Path go get a new one, or a singleton one.

                Agree your other comment. The statement about a singleton reference is unmotivated and also a misquotation. You didn't say that.
                • 5. Re: Why does java.nio.files.Path require implementations to be immutable?
                  jtahlborn
                  gimbal2 wrote:
                  jtahlborn wrote:
                  I think you are misinterpreting the javadocs. it says the Path instance is immutable, it doesn't say anything about the FileSystem instance referenced by the Path. i would say that your simple implementation would be perfectly valid.
                  Yes, but Path must be able to return a reference to it. So how would you do that while maintaining complete immutability?
                  the OP included an example implementation which has a Path instance with a final reference to a FileSystem instance. this makes the Path instance immutable (it can never have a different FileSystem reference).
                  (as a side note, i would not use a singleton reference to a FileSystem as gimbal2 suggested, as that will restrict the usefulness of your code and is generally a code smell).
                  It does not and it is not. Not NECESSARILY, at least, like you are trying to pass off without any argument or reason.
                  if the Path instance makes a call to some singleton instance to retrieve the FileSystem, you are restricting your FileSystem implementation to living as a singleton (for no reason that i can see). the arguments against singletons (aka global variables) are many and varied and i'm not going to repeat them all here, but obvious arguments like "it's harder to test" and "you may have to rewrite a bunch of your code when you realize you actually want to support having more than one instance at a time" come to mind. i consider avoiding singletons a coding best practice and i'm pretty sure many other developers will agree with that.
                  Even the cleanest piece of code can be made smelly. It is not an argument to throw around. I am a decent engineer, I know how to properly use the tools available to me - including singleton objects. My code certainly does not "restrict usefulness", or whatever the heck that means.
                  i'm sorry you were offended by that comment (it wasn't meant as a personal attack on you as a programmer), but i stand by my argument that avoiding singletons is generally a best practice. and yes, it does restrict the usefulness of the implementation as you can never have more than one instance of that particular FileSystem implementation.

                  Edited by: jtahlborn on Feb 24, 2012 2:07 PM
                  • 6. Re: Why does java.nio.files.Path require implementations to be immutable?
                    jtahlborn
                    EJP wrote:
                    Agree your other comment. The statement about a singleton reference is unmotivated and also a misquotation. You didn't say that.
                    what did i misquote? did the quote i referenced not recommend using a singleton reference to the FileSystem? if it did not, then you are correct, i misquoted. if it did, then...?
                    • 7. Re: Why does java.nio.files.Path require implementations to be immutable?
                      EJP
                      No it didn't. "Singleton reference" is your invention. He just said "singleton". I don't even know what "singleton reference" means, let alone why you think it smelly.
                      • 8. Re: Why does java.nio.files.Path require implementations to be immutable?
                        jtahlborn
                        EJP wrote:
                        No it didn't. "Singleton reference" is your invention. He just said "singleton". I don't even know what "singleton reference" means, let alone why you think it smelly.
                        i don't understand your distinction. he is referring to maintaining the specific FileSystem implementation as a single, global reference (aka a singleton). the singleton pattern, aka global variables, are generally limiting in terms of overall program design, of which i'm sure you are already aware, and often a sign of poor program design, aka code smell.
                        • 9. Re: Why does java.nio.files.Path require implementations to be immutable?
                          EJP
                          If there is no difference, you didn't need to introduce one by adding the word 'reference', which I still dont understand. Singletons are single instances, but you can have as many references as you like. And if it is a 'code smell' you need to say why, rather than just use unexplained perjorative terms. I don't use Singletons much myself, but when you need one, you need one. Configurations are a good example.

                          And this:
                          this makes the Path instance immutable (it can never have a different FileSystem reference)
                          Doesn't sound like a real problem to me. Why would a Path need more than one FileSystem over its lifetime? It is a path in that file system.
                          • 10. Re: Why does java.nio.files.Path require implementations to be immutable?
                            jtahlborn
                            EJP wrote:
                            And this:
                            this makes the Path instance immutable (it can never have a different FileSystem reference)
                            Doesn't sound like a real problem to me. Why would a Path need more than one FileSystem over its lifetime? It is a path in that file system.
                            you are confusing different arguments. a given Path instance would never need a separate FileSystem instance, i never argued that it would.

                            however, if you implement your Path like so:
                            public class MyPath implements Path {
                            
                              public FileSystem getFileSystem() {
                                return MyFileSystem.getInstance();
                              }
                            }
                            you are limiting your MyFileSystem implementation to only one instance ever. if, however, you followed the OP's example and had the Path maintain a reference to its owner FileSystem (as both you and I have already recommended in this thread), you could maintain multiple FileSystem instances with their own collection of Path instances.