This discussion is archived
1 2 Previous Next 18 Replies Latest reply: Mar 17, 2008 4:56 AM by jwenting RSS

Get the name of the executed jar file at runtime

807591 Newbie
Currently Being Moderated
In order to print the help of my application I need to obtain the name of the executed jar file or class:
public String getApplicationName()  {
  /* TODO return the name of the executing jar file,
          or return the name of the executing main class if not executed from jar file */
  return "???";
}

public void printHelp()  {
  System.out.println("Usage: " + getApplicationName() + " args");
}
Does anybody knows a way how to implement the method getApplicationName() ?
  • 1. Re: Get the name of the executed jar file at runtime
    807591 Newbie
    Currently Being Moderated
    One idea that may work
    use
    new File(".").listFiles()
    to get the list of files in the current working directory then look for .class or .jar files
    If you only have one then it is the executed one.

    Regards,
  • 2. Re: Get the name of the executed jar file at runtime
    807591 Newbie
    Currently Being Moderated
    I could load all jar files from the application directory and seek for a class that implements a main method, but if there are multiple jar files with a main method, or one jar file contains some other classes with a main method, I will get an incorrect answer.

    It is required to get an exact answer from the method, any other ideas?
  • 3. Re: Get the name of the executed jar file at runtime
    jwenting Journeyer
    Currently Being Moderated
    you might be able to get the information from the ClassLoader of the class in question.
    If it's available at all, that would be the place.
  • 4. Re: Get the name of the executed jar file at runtime
    800322 Newbie
    Currently Being Moderated
    @NightMan150: the present working directory and the JAR's location have nothing to do with each other. Your method will not work in many cases.

    @Ryiden: load the .class as resource
    URL u = ...getClassLoader().getResource("\" + package + "." + classname + ".class")

    The resulting URL will be like
    file:///C/mypath/myjar.jar!my.package.MyClass.class

    You can grab the info from the String (substring before the '!'), create a URI from it and fill that URI into a File object.

    Problem: you will never know which class or JAR originally started your program. Just the location of the JAR the current class is in. So the problem as you posted it is not solvable.
  • 5. Re: Get the name of the executed jar file at runtime
    807591 Newbie
    Currently Being Moderated
         public String getMainClass(){
              String mainClass = "";
              String paramType = "";
              Method[] declaredMethods = this.getClass().getDeclaredMethods();
              for(int i=0; i<declaredMethods.length; i++){
                   
                   for(int j=0; j<declaredMethods.getParameterTypes().length; j++){
                        if(declaredMethods[i].getParameterTypes()[j].isArray()){
                             paramType = declaredMethods[i].getParameterTypes()[j].getComponentType().toString();
                        }
                        else{
                             paramType = declaredMethods[i].getParameterTypes()[j].toString();
                        }
                   }
                   
                   if(declaredMethods[i].getName().equals("main") && declaredMethods[i].getModifiers()==9
                        && declaredMethods[i].getReturnType().toString().equals("void")
                        && paramType.equals("class java.lang.String")
                        && declaredMethods[i].getExceptionTypes().length==0){
                             System.out.println("The main class::: "+declaredMethods[i].getDeclaringClass());
                             mainClass = declaredMethods[i].getDeclaringClass().toString();
                   }
                   

                   paramType = "";
              }
              return mainClass;
              
         }
    This should give the mainclass. If you are facing any issue, please let us know.
    
    Edited by: AnishThomas on Mar 17, 2008 12:13 PM
    
    Edited by: AnishThomas on Mar 17, 2008 12:15 PM                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                    
  • 6. Re: Get the name of the executed jar file at runtime
    807591 Newbie
    Currently Being Moderated
    AnishThomas wrote:
         public String getMainClass(){
              String mainClass = "";
              String paramType = "";
              Method[] declaredMethods = this.getClass().getDeclaredMethods();
              for(int i=0; i<declaredMethods.length; i++){
                   
                   for(int j=0; j<declaredMethods.getParameterTypes().length; j++){
                        if(declaredMethods[i].getParameterTypes()[j].isArray()){
                             paramType = declaredMethods[i].getParameterTypes()[j].getComponentType().toString();
                        }
                        else{
                             paramType = declaredMethods[i].getParameterTypes()[j].toString();
                        }
                   }
                   
                   if(declaredMethods[i].getName().equals("main") && declaredMethods[i].getModifiers()==9
                        && declaredMethods[i].getReturnType().toString().equals("void")
                        && paramType.equals("class java.lang.String")
                        && declaredMethods[i].getExceptionTypes().length==0){
                             System.out.println("The main class::: "+declaredMethods[i].getDeclaringClass());
                             mainClass = declaredMethods[i].getDeclaringClass().toString();
                   }
                   

                   paramType = "";
              }
              return mainClass;
              
         }
    This should give the mainclass. If you are facing any issue, please let us know.
    
    Edited by: AnishThomas on Mar 17, 2008 12:13 PM
    
    Edited by: AnishThomas on Mar 17, 2008 12:15 PM
    Erm, what??
  • 7. Re: Get the name of the executed jar file at runtime
    800322 Newbie
    Currently Being Moderated
    WTF!?
  • 8. Re: Get the name of the executed jar file at runtime
    807591 Newbie
    Currently Being Moderated
    CeciNEstPasUnProgrammeur wrote:
    WTF!?
    That's what happens when someone prematurely discovers the reflection API, I guess
  • 9. Re: Get the name of the executed jar file at runtime
    807591 Newbie
    Currently Being Moderated
    sorry.. my mistake..
  • 10. Re: Get the name of the executed jar file at runtime
    807591 Newbie
    Currently Being Moderated
    AnishThomas wrote:
    sorry.. my mistake..
    You understand why it's a mistake, I take it?
  • 11. Re: Get the name of the executed jar file at runtime
    807591 Newbie
    Currently Being Moderated
    The following will find the source of the .class file for the current class:
    URL codeBase = getClass().getProtectionDomain().getCodeSource().getLocation();
    If codebase.getProtocol() is "file" you can then get the file path from it (which will either be a .jar or a directory, if running from an unpacked class tree).

    If it's a jar and you also want the main class you can simply open it using JarFile and read the manifest.

    Edited by: malcolmmc on Mar 17, 2008 1:13 PM
  • 12. Re: Get the name of the executed jar file at runtime
    807591 Newbie
    Currently Being Moderated
    Your method helps for class files, for jar files I have to try.

    I think you have to remove the else statement from the following code.
    if(declaredMethods.getParameterTypes()[j].isArray()){
    paramType = declaredMethods[i].getParameterTypes()[j].getComponentType().toString();
    }
    else{
    paramType = declaredMethods[i].getParameterTypes()[j].toString();
    }
    Otherwise, the following method will match:
    public static void main(String args) {
    System.out.println("this is not an entry point");
    }
    Furthermore I prefer to use symbolic names for the modifiers:
    ... && declaredMethods[i].getModifiers() == (Modifier.PUBLIC | Modifier.STATIC)
    You should also check for 
    ... && declaredMethods[i].getParameterTypes().length == 1
     to avoid a match for such a main method:
    public static void main(String[] args, String[] args2) {
    System.out.println("this is not an entry point");
    }
                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                        
  • 13. Re: Get the name of the executed jar file at runtime
    800322 Newbie
    Currently Being Moderated
    ... and if you have
    public static void main(String[] args) {
      TheOriginalClass.main(args);
    }
    you're still lost. There is no way to intercept that. Unless maybe you grab the bottom of the stack trace and try to find the JAR that that class is from...
  • 14. Re: Get the name of the executed jar file at runtime
    807591 Newbie
    Currently Being Moderated
    ... and if you have something like this:
    public class Application
    {
      public static void main(String[] args)
      {
        SystemInfo info = new SystemInfo();
        System.out.println(info.getMainClassName());
      }
    }
    
    public class SystemInfo
    {
      public String getMainClassName()
      {
         .... // the posted algorithm
         return mainClassName;
      }
    }
    you are also lost, because the algorithm only seeks for a main method in the SystemInfo class.
1 2 Previous Next