How to get VM arguments from inside of Java application?
Asked Answered
B

5

198

I need to check if some option that can be passed to JVM is explicitly set or has its default value.

To be more specific: I need to create one specific thread with higher native stack size than the default one, but in case the user wants to take care of such things by himself by specifying the -Xss option I want to create all threads with default stack size (which will be specified by user in -Xss option).

I've checked classes like java.lang.System and java.lang.Runtime, but these aren't giving me any useful information about VM arguments.

Is there any way to get the information I need?

Baty answered 29/9, 2009 at 6:22 Comment(0)
G
229

With this code you can get the JVM arguments:

import java.lang.management.ManagementFactory;
import java.lang.management.RuntimeMXBean;
...
RuntimeMXBean runtimeMxBean = ManagementFactory.getRuntimeMXBean();
List<String> arguments = runtimeMxBean.getInputArguments();
Glioma answered 7/10, 2009 at 14:32 Comment(7)
Sadly you cannot get the Name of the main class if it is given on the command line.Bokbokhara
@Daniel, this should get you the name of the main class: final StackTraceElement[] stackTrace = Thread.currentThread().getStackTrace(); final String mainClassName = stackTrace[stackTrace.length - 1].getClassName());Pontificate
If you are guaranteed to be running on Oracle's JVM and have the code to parse the arguments that can be useful.Pontificate
@Vulcan That does not get VM arguments. It contains the main class name, and the args array to the main method.Fushih
@Fushih Never did I imply that VM arguments are located in the sun.java.command system property; I said that property can be used to acquire main class name (although I did not mention, as @Pontificate pointed out, that property is only present on Oracle's JVM).Buyers
Just for the record, I had problems with Java 1.6.0_25 and JVM arguments with space characters in the value, this method was returning multiple entries for only one of these JVM args, problem didn't appeared in Java 1.7.0_21Urbanna
@Pontificate that assumes you are in the main threadHelfant
K
230

At startup pass this -Dname=value

and then in your code you should use

value=System.getProperty("name");

to get that value

Kei answered 22/11, 2010 at 15:34 Comment(9)
I cannot use this to get -XdebugCook
Not sure why this answer has been so upvoted, this only retrieves application parameters (specified with -D), not VM parameters (those specified with -X). The question is specifically about -X params.Arturoartus
I came here because I believed parameters of type -Dname=value are JVM arguments and that there is no intrinsic difference to -X arguments. Actually, they are both passed to java and not the application at the command line and as evidence by example, in maven you can pass both as -Drun.jvmArguments=.... I believe that is why it is upvoted.Vachil
This doesn't answer the original posters needs at all.Trismus
Might be ! but it googles on tops when searching for "how to read VM options in code" and that's why it's relevant )Dilute
A little more context: via IDEA Run/Debug Configuration for tests, it's not possible to set "program arguments", but it's fine to set VM options using "-Dname=value" formDilute
In a regular Java application, -Dname=value goes in the VM Arguments (Run Configurations...=>select the application=>Arguments tab=>VM Arguments).Armond
I was searching for -Dname=value and I came here from google with searching "java get vm arguments" and this was the first post @Arturoartus thats why I voted up .Selie
@Vachil Hits the nail on its head.Rebuild
G
229

With this code you can get the JVM arguments:

import java.lang.management.ManagementFactory;
import java.lang.management.RuntimeMXBean;
...
RuntimeMXBean runtimeMxBean = ManagementFactory.getRuntimeMXBean();
List<String> arguments = runtimeMxBean.getInputArguments();
Glioma answered 7/10, 2009 at 14:32 Comment(7)
Sadly you cannot get the Name of the main class if it is given on the command line.Bokbokhara
@Daniel, this should get you the name of the main class: final StackTraceElement[] stackTrace = Thread.currentThread().getStackTrace(); final String mainClassName = stackTrace[stackTrace.length - 1].getClassName());Pontificate
If you are guaranteed to be running on Oracle's JVM and have the code to parse the arguments that can be useful.Pontificate
@Vulcan That does not get VM arguments. It contains the main class name, and the args array to the main method.Fushih
@Fushih Never did I imply that VM arguments are located in the sun.java.command system property; I said that property can be used to acquire main class name (although I did not mention, as @Pontificate pointed out, that property is only present on Oracle's JVM).Buyers
Just for the record, I had problems with Java 1.6.0_25 and JVM arguments with space characters in the value, this method was returning multiple entries for only one of these JVM args, problem didn't appeared in Java 1.7.0_21Urbanna
@Pontificate that assumes you are in the main threadHelfant
A
7

I found that HotSpot lists all the VM arguments in the management bean except for -client and -server. Thus, if you infer the -client/-server argument from the VM name and add this to the runtime management bean's list, you get the full list of arguments.

Here's the SSCCE:

import java.util.*;
import java.lang.management.ManagementFactory;

class main {
  public static void main(final String[] args) {
    System.out.println(fullVMArguments());
  }

  static String fullVMArguments() {
    String name = javaVmName();
    return (contains(name, "Server") ? "-server "
      : contains(name, "Client") ? "-client " : "")
      + joinWithSpace(vmArguments());
  }

  static List<String> vmArguments() {
    return ManagementFactory.getRuntimeMXBean().getInputArguments();
  }

  static boolean contains(String s, String b) {
    return s != null && s.indexOf(b) >= 0;
  }

  static String javaVmName() {
    return System.getProperty("java.vm.name");
  }

  static String joinWithSpace(Collection<String> c) {
    return join(" ", c);
  }

  public static String join(String glue, Iterable<String> strings) {
    if (strings == null) return "";
    StringBuilder buf = new StringBuilder();
    Iterator<String> i = strings.iterator();
    if (i.hasNext()) {
      buf.append(i.next());
      while (i.hasNext())
        buf.append(glue).append(i.next());
    }
    return buf.toString();
  }
}

Could be made shorter if you want the arguments in a List<String>.

Final note: We might also want to extend this to handle the rare case of having spaces within command line arguments.

Advertent answered 29/11, 2017 at 12:44 Comment(1)
Yup, just did. Cheers :)Advertent
C
3

I haven't tried specifically getting the VM settings, but there is a wealth of information in the JMX utilities specifically the MXBean utilities. This would be where I would start. Hopefully you find something there to help you.

The sun website has a bunch on the technology:

http://java.sun.com/javase/6/docs/technotes/guides/management/mxbeans.html

Cyclades answered 2/10, 2009 at 3:2 Comment(0)
I
2

If you want the entire command line of your java process, you can use: JvmArguments.java (uses a combination of JNA + /proc to cover most unix implementations)

Injury answered 20/9, 2017 at 14:2 Comment(0)

© 2022 - 2024 — McMap. All rights reserved.