1 2 3 Previous Next 66 Replies Latest reply: Dec 16, 2010 5:38 AM by JoachimSauer RSS

    How to get the jar file without knowing its name and any class inside it?

    809259
      Hello, everybody!

      I would like to know if there's a way to get a reference programatically to the initial jar without knowing its name and any class contained in it. By "initial jar" I mean the jar that was called in the prompt, like this:
      java -jar jarfile.jar
      or in another way, in a graphical system. To be sincere what I really want is to get a reference to the jar's manifest, but I know if I can get a reference to the jar I can get a reference to its manifest file. Or if you know a way to get the manifest directly, it would also help. So, is there a way to do this?

      Thank you.

      Marcos
        • 1. Re: How to get the jar file without knowing its name and any class inside it?
          abillconsl
          What do you want the reference for? You can execute a jarfile like this:
          java -jar *.jar
          ... if it's the only jarfile in the folder.

          Or you can "find" a jar using a FileChooser or using the File methods available.

          Can you be more specific - IOW, can you cite a specific case?
          • 2. Re: How to get the jar file without knowing its name and any class inside it?
            baftos
            Class.getResourceAsStream() gives you access to 'files' inside the jar or anywhere in the classpath.
            MANIFEST.MF is just such a file, but...

            ... normal applications should not make assumptions on how they are packaged (1 JAR, multiple JARs, classes outside JARs or a combination).
            Why do you need access to your own application manifest?
            • 3. Re: How to get the jar file without knowing its name and any class inside it?
              809259
              abillconsl wrote:
              Can you be more specific - IOW, can you cite a specific case?
              Absolutely. I want to access the jar in source code with the java.util.zip.JarFile class, for example. With this class I can use its getManifest method. Or in any other way you find more appropriate.

              Marcos
              • 4. Re: How to get the jar file without knowing its name and any class inside it?
                809259
                baftos wrote:
                Why do you need access to your own application manifest?
                I want to get the system name and version from it. Of course I could provide strings in source code for this, but I would be duplicating things. I want a single point of access. If I change the manifest, the system changes. I would like to do this without using Class , because the code that will read the manifest will be called from another util jar, not the application jar that started. I know I could pass to this code some class reference that exist in the application jar, but I would like to avoid it.

                Marcos
                • 5. Re: How to get the jar file without knowing its name and any class inside it?
                  796440
                  marcos_aps wrote:
                  abillconsl wrote:
                  Can you be more specific - IOW, can you cite a specific case?
                  Absolutely. I want to access the jar in source code with the java.util.zip.JarFile class, for example.
                  But why? You still haven't provided a use case or explained what you're trying to accomplish. As already pointed out, whatever you're trying to do, this is a brittle solution. If you explain what you're trying to accomplish with this, somebody may be able to suggest a better approach.
                  • 6. Re: How to get the jar file without knowing its name and any class inside it?
                    809259
                    jverd wrote:
                    marcos_aps wrote:
                    abillconsl wrote:
                    Can you be more specific - IOW, can you cite a specific case?
                    Absolutely. I want to access the jar in source code with the java.util.zip.JarFile class, for example.
                    But why? You still haven't provided a use case or explained what you're trying to accomplish. As already pointed out, whatever you're trying to do, this is a brittle solution. If you explain what you're trying to accomplish with this, somebody may be able to suggest a better approach.
                    jverd, I explained for baftos. Anyway, I will try to be more specific. I start my sytem like this, from, say, for example, jar1.jar:
                    import br.product.System;
                    
                    public static void main(String[] args)
                    {
                        System.start("NameOfTheSystem");
                    }
                    The System class is in util.jar, for example. This jar is used by all systems. I wouldn't like to pass in the name of the system, as above. I would like that the System class could read it from jar1.jar's manifest file. I just would like to have this:
                    import br.product.System;
                    
                    public static void main(String[] args)
                    {
                        System.start();
                    }
                    It is more elegant and I don't have the name of the system in two places: code and manifest file.

                    Marcos
                    • 7. Re: How to get the jar file without knowing its name and any class inside it?
                      DrClap
                      Except that now your so-called "elegant" solution is forcing you into an inelegant implementation.

                      A solution which is a tiny bit less elegant would be to put your version number into a resource in the META-INF directory in the jar, but not actually into the manifest itself. Then you just search for the resource named (e.g.) META-INF/marcos_aps_version using a class which you know to be in the jar, or using the classloader which loaded the jar, and you're done. Personally I would find that preferable to an elegant solution which can't be implemented, or which requires ugly hacks to do it.
                      • 8. Re: How to get the jar file without knowing its name and any class inside it?
                        809259
                        DrClap wrote:
                        Except that now your so-called "elegant" solution is forcing you into an inelegant implementation.

                        A solution which is a tiny bit less elegant would be to put your version number into a resource in the META-INF directory in the jar, but not actually into the manifest itself. Then you just search for the resource named (e.g.) META-INF/marcos_aps_version using a class which you know to be in the jar, or using the classloader which loaded the jar, and you're done. Personally I would find that preferable to an elegant solution which can't be implemented, or which requires ugly hacks to do it.
                        Yes, this is possible and I know how to implement it, but now I have one more resource in the META-INF folder for an information that would be better placed in the manifest file. Don't get me wrong, but I think this sounds more like a hack than reading from the manifest file. And for education purposes, if what I want is possible, it would be great for everyone to know. I think that reading the name of the system and the version from the manifest is the right thing.

                        Marcos
                        • 9. Re: How to get the jar file without knowing its name and any class inside it?
                          baftos
                          import br.product.System;
                          
                          public static void main(String[] args)
                          {
                          System.start();
                          }
                          In System.start() you can find out who is calling you by examining the stack (Thread.getStackTrace()). From there you have the calling class name and from there you can load the MANIFEST.MF resource. Do I like it? I don't know. It requires discipline. System.start() must be first call in main() and, God forbid, if someone puts it in another method called by main.
                          • 10. Re: How to get the jar file without knowing its name and any class inside it?
                            abillconsl
                            I know I could pass to this code some class reference that exist in the application jar, but I would like to avoid it.
                            How would YOU do this? ... and why would you like to avoid it?
                            • 11. Re: How to get the jar file without knowing its name and any class inside it?
                              809259
                              abillconsl wrote:
                              I know I could pass to this code some class reference that exist in the application jar, but I would like to avoid it.
                              How would YOU do this? ... and why would you like to avoid it?
                              Very simple. I would do it like this:
                              import br.product.System;
                               
                              public static void main(String[] args)
                              {
                                  System.start(SomeClassInThisJar.class);
                              }
                              I would like to avoid because I'm seeking a better solution, without having to pass the class reference.

                              Marcos
                              • 12. Re: How to get the jar file without knowing its name and any class inside it?
                                809259
                                baftos wrote:
                                import br.product.System;
                                
                                public static void main(String[] args)
                                {
                                System.start();
                                }
                                In System.start() you can find out who is calling you by examining the stack (Thread.getStackTrace()). From there you have the calling class name and from there you can load the MANIFEST.MF resource. Do I like it? I don't know. It requires discipline. System.start() must be first call in main() and, God forbid, if someone puts it in another method called by main.
                                Hey, baftos, I didn't know about Thread.getStackTrace(). When I saw your post I almost laugh. I was thinking about raising an exception just to get the exception stack trace to see what was the previous class. In my system, System.start() is the first call in main() and I don't see any reason to change this.

                                Marcos
                                • 13. Re: How to get the jar file without knowing its name and any class inside it?
                                  DrClap
                                  marcos_aps wrote:
                                  I would like to avoid because I'm seeking a better solution, without having to pass the class reference.
                                  Such as mine, where you can use any class as long as the resource containing the version is in the classpath.
                                  • 14. Re: How to get the jar file without knowing its name and any class inside it?
                                    796440
                                    marcos_aps wrote:
                                    baftos wrote:
                                    import br.product.System;
                                    
                                    public static void main(String[] args)
                                    {
                                    System.start();
                                    }
                                    In System.start() you can find out who is calling you by examining the stack (Thread.getStackTrace()). From there you have the calling class name and from there you can load the MANIFEST.MF resource. Do I like it? I don't know. It requires discipline. System.start() must be first call in main() and, God forbid, if someone puts it in another method called by main.
                                    Hey, baftos, I didn't know about Thread.getStackTrace().
                                    Personally, I consider using getStackTrace() to be the biggest hack yet.

                                    I find it rather surprising that you consider mentioning one key piece of data twice to be a bigger hack than requiring your app to be packaged and started one particular way.

                                    I still don't understand what piece of information you're trying to get either.

                                    Edited by: jverd on Dec 14, 2010 1:48 PM
                                    1 2 3 Previous Next