Command-line options in a jar file

Discussion in 'Java' started by Hiram Hunt, Apr 21, 2012.

  1. Hiram Hunt

    Hiram Hunt Guest

    Hello,

    Is there a way to pass command-line options to java.exe
    with an executable jar file? The "Jar tool reference
    page for Windows" seems to say that the -J option should
    do it, but when I try it out, the option is sent to the
    java virtual machine when I run the jar command, not when
    I run the executable jar file. I want to send -Xmxn and
    -Dthis=that options to java.exe.

    Trying things out with a simple HelloWorld program, when I
    use -J-showversion or -J-verbose, the extra output comes
    when the jar file is being created, not when it is being
    run. I was using Windows SP3 and Java 7u3. I also tried
    under Windows 7 a program that prints system properties
    (retrieved with System.getProperties()) under Windows 7
    and a -J-Dthis=that option, but the property did not appear
    in the output.

    Specifically, with Windows SP3 and the command prompt:

    #javac hi\HelloWorld.java

    #jar cfe hi.jar hi.HelloWorld hi\HelloWorld.class -J-showversion
    java version "1.7.0_03"
    Java(TM) SE Runtime Environment (build 1.7.0_03-b05)
    Java HotSpot(TM) Client VM (build 22.1-b02, mixed mode, sharing)


    #ftype jarfile
    jarfile="C:\Program Files\Java\jre7\bin\java.exe" -jar "%1%" %*

    #hi.jar
    Hello, world

    #

    Is there a way to (in this example) get the version information
    to show up when running hi.jar instead of when running jar itself?

    -- Hiram Hunt
     
    Hiram Hunt, Apr 21, 2012
    #1
    1. Advertisements

  2. Hiram Hunt

    Lew Guest

    Pass them on the command line with the "java" command.
    Please don't use backslashes as path separators, at least not here. It's very
    disconcerting as they have special meaning for Java and non-Windows shells.
    Windows handles forward slashes as path separators, so there's no reason not
    to use them in Usenet posts.
    Version of what? Java itself, as you show here? What's wrong with using the
    "java" command for that?

    <http://docs.oracle.com/javase/7/docs/>

    Does Windows 7 let you specify command options with the file association? I
    never invoke JARs without an explicit invocation of the "java" command; I
    suggest you follow that practice.

    You can put the invocation in a shell script and pass all the options your
    little heart desires to the "java" command. That seems like the obvious
    approach, yes?
     
    Lew, Apr 21, 2012
    #2
    1. Advertisements

  3. Use the "Main-Class: full.class.name" directive in the jarfile's manifest
    to select the program to be executed and then run it with the command:

    java -jar jarfile_absolute_name arguments...

    which passes the argument list to "static void main(String[] args) in
    full.class.name via args. If you need to pass options to the JVM, they
    are put in front of the -jar option.

    If I want to be able to choose one candidate program out of several in
    the jar file, I use the Main-Class to run a simple launcher program and
    pass it the program name as its first argument. The launcher program uses
    Class.forName() to load the required program and then starts it by
    calling a method, which must not have the "static void main(String[])"
    signature. I typically use via a method with the "void run(String[] args)"
    signature and pass it all the command line arguments except the first via
    args.
     
    Martin Gregorie, Apr 21, 2012
    #3
  4. Hiram Hunt

    Hiram Hunt Guest

    I have done that, but that is not what I am trying to do now.
    This was actual cut and paste of a Windows session. In this case, forward
    slashes would work with javac, but it is unnatural when using the Windows
    command prompt because they are not generally accepted there. For
    example, they will not work in the ftype file association shown below.
    I used -version to demonstrate the problem I was having getting a
    command-line option to be saved in a jar file for use when the
    jar file is executed. The specific option I used for the demonstration
    was just a convenient example, because the results can easily be
    seen. As I said before, the options I actually care about (today, anyway)
    are -Xmxn and -Dthis=that (with appropriate values to be substituted
    for "n" and "this=that").
    I could (I think) add the command line options to the file association (I
    have
    already changed it from javaw.exe to java.exe), but then the options would
    apply to each jar file I execute.
    Very obvious, so yes I had already thought of it and used it, though mainly
    with .class files that were not in a jar file, but I am asking whether
    there is
    a way to pass the options in a jar file. Alternatively, I think I can set
    the
    property in the executable with System.setProperty(), but I am not sure
    what command could be used to set the memory option (-Xmxn) from
    within the program.

    -- Hiram Hunt
     
    Hiram Hunt, Apr 21, 2012
    #4
  5. Hiram Hunt

    Hiram Hunt Guest

    Thanks. Yes, I know I can put options before the -jar option, but I would
    like to be able to just run the program as "MyProgram.jar" by using the
    ftype association in my original post. Thus, my question is about passing
    arguments for java.exe in the jar file. My guess at this point is that it
    is
    not possible.

    -- Hiram Hunt
     
    Hiram Hunt, Apr 21, 2012
    #5
  6. Hiram Hunt

    Jan Burse Guest

    Hi,

    The syntax the java command line in case of a .jar is:

    java [ options ] -jar file.jar [ argument ... ]

    The -X and the -D option can be placed before the -jar.
    But I also did not find a method to place it into a
    manifest. Definition for:

    -Dproperty=value

    Is that it will set a system property value. So right,
    this can be done inside your .jar. And arguments are
    passed to main() this can be also done inside your .jar.
    But for the -X options I don't see a way, since:

    Options that begin with -X are non-standard
    (not guaranteed to be supported on all VM
    implementations), and are subject to change
    without notice in subsequent releases of
    the JDK.

    To modify a -X option inside your .jar seems hope
    less. Not because they are non standard. But because
    most of them are immutable and take effect when the
    JVM is initialized. So when your main() is invoked
    it is already too late.

    I was once hoping that I can for example change the
    heap size via a management bean. But I didn't find
    an appropriate method here:

    Package java.lang.management
    http://docs.oracle.com/javase/7/docs/api/java/lang/management/package-summary.html

    So I guess what some tools do is that they fork
    a Process and pass the parameters they want. This
    can be done inside a jar.

    Class ProcessBuilder

    http://docs.oracle.com/javase/1.5.0/docs/api/java/lang/ProcessBuilder.html

    But this seems also risky and ugly, same as writing
    small scripts. The following stack overflow answer
    additionally lists launch4j and JavaWeb Start as
    an alternative:

    http://stackoverflow.com/questions/1018217/can-i-set-java-max-heap-size-for-running-from-a-jar-file

    Didn't try either...

    Bye
     
    Jan Burse, Apr 21, 2012
    #6
  7. I don't think the -J option does what you think it does. It does not
    appear to cause the launcher, java.exe, to use the option you specified
    with the -J when you compiled it or jar'd it. I think it passes that to
    the runtime that does the compiling and jar'ing. To be specific in your
    example above, I think the -showversion option was passed to the java
    runtime that was used to by the jar.exe program to create your jar file.
    And that is why it shows up when you run it as above.

    If you want a command line option when you run your program, you will
    have to pass the arguments on the command line or by Patricia's method
    in a call to the main() method.
     
    Knute Johnson, Apr 21, 2012
    #7
  8. Hiram Hunt

    Hiram Hunt Guest

    Thanks, but those are not the arguments I am trying to
    work with. I am trying to pass arguments to the java
    virtual machine, not to main(). I want to use -Xmxn and
    -Dthis=that (with appropriate substitutions for "n" and
    "this=that"). Java.exe needs to see them. Alternatively,
    I think I could use "System.setProperty()" first in main(),
    but I don't know what I could call in main() to produce
    the same effect as -Xmxn. The -Dthis=that is to prevent
    a conflict that might only occur _rarely_ in a library I
    am using, so I would have a hard time checking directly
    whether setting it in main() is really soon enough.
    The actual option is -Dsun.java2d.noddraw=true .

    I am hoping to be able to run the program in a "pretty"
    way -- just type MyProgram.jar without having to give
    certain fixed, mandatory arguments every time and without
    resorting to a batch file. In the end, I don't think
    it will be possible. It is not a show stopper, just an
    annoyance.

    -- Hiram Hunt
     
    Hiram Hunt, Apr 21, 2012
    #8
  9. Hiram Hunt

    Hiram Hunt Guest

    Thanks. Actually, I already had figured out what -J was doing.
    I showed in my original post what it was doing in hopes that people
    who had not tried it would not reply that -J was the answer to my
    problem.

    -- Hiram Hunt
     
    Hiram Hunt, Apr 22, 2012
    #9
  10. Hiram Hunt

    Hiram Hunt Guest

    Thanks. The stackoverflow link gets at the sort of thing I am
    trying to do. I don't see in the ProcessBuilder documentation
    a way to set memory size, though it does let one set system
    properties. I think I should just settle for running things in
    a less pretty way (batch file, e.g.) than I would like. Maybe
    someday a new option will be added for jar files to do this.

    -- Hiram Hunt
     
    Hiram Hunt, Apr 22, 2012
    #10
  11. Hiram Hunt

    Jan Burse Guest

    Jan Burse, Apr 22, 2012
    #11
  12. Hiram Hunt

    Hiram Hunt Guest

    Hiram Hunt, Apr 22, 2012
    #12
  13. Hiram Hunt

    Arne Vajhøj Guest

    Executable jar files does not support JVM args in manifest.

    You options are:
    1) specify the JVM args in the command line (does not work with
    double click)
    2) write a startup script (this is very common)
    3) write your own startup executable that create the JVM with
    the args you want (requires a build per supported platform)

    Arne
     
    Arne Vajhøj, Apr 22, 2012
    #13
  14. Hiram Hunt

    Roedy Green Guest

    There is no way to put command line arguments destined for java.exe
    inside the jar in the manifest. However, if you use JWS, you can put
    them in the JNLP file which lives outside the jar. The reason for this
    is, by the time the java.exe JVM (Java Virtual Machine) gets around to
    looking inside jars, it has already cast in stone everything it
    learned from the command line.

    ~ http://mindprod.com/jgloss/jar.html#MANIFEST
    --
    Roedy Green Canadian Mind Products
    http://mindprod.com
    When you were a child, if you did your own experiment
    to see if it was better to put to cocoa into your cup first
    or the hot milk first, then you likely have the programmer gene..
     
    Roedy Green, Apr 22, 2012
    #14
  15. Hiram Hunt

    Hiram Hunt Guest

    Thanks.

    -- Hiram Hunt
     
    Hiram Hunt, Apr 22, 2012
    #15
  16. Hiram Hunt

    Hiram Hunt Guest

    Thanks.

    -- Hiram Hunt
     
    Hiram Hunt, Apr 22, 2012
    #16
  17. See also this gui.Launcher:

    <http://groups.google.com/group/comp.lang.java.programmer/msg/c81f8c5f269e22e5>
     
    John B. Matthews, Apr 22, 2012
    #17
  18. Hiram Hunt

    Hiram Hunt Guest

    Hiram Hunt, Apr 22, 2012
    #18
    1. Advertisements

Ask a Question

Want to reply to this thread or ask your own question?

You'll need to choose a username for the site, which only take a couple of moments (here). After that, you can post your question and our members will help you out.