According to Oracle, the only way to set system properties is through command line -D parameters like that :
java -Dmy.prop=value com.package.MyClass
Is it really the only way ? Isn't it possible to create some system.properties file that will contain all these properties, and that would be automagically read when the JVM starts ?
I precise I can have no use of the System.setProperty(String,String) function.[1]
Setting this file through a command line parameter would be fine as well :
java -Fsystem.properties com.package.MyClass
I have searched where I know (and found there is a way with IBM's JVM), but I'm still empty-handed...
[1] : The goal is to set the default Charset, and this is primarily done through the file.encoding property, but only at the VM startup phase. Setting this property in runtime doesn't change the default Charset, and there is also no way to change it 'programmatically'.
Related
Java -XshowSettings dump the information such as VM setting. Where in the box/system this information configured or what is the source of the setting? Is there any property file ?
java -XshowSettings:all
The information comes from various sources; e.g. command line options, environment variables, values derived from the result of syscalls, default values hard-wired into the JVM executable, and so on.
Is there any property file ?
There are some system properties that are defined by property files in the $JAVA_HOME/cfg tree, but the majority of the properties and other settings come from other places.
My Java Webstart application runs in a controlled trusted environment. This is a closed internal network where I have some control on how the application is started.
How can I pass JVM arguments to the application, even if they are considered 'unsecure' for use by webstart by the JVM?
There are several options to pass JVM arguments to webstart.
Through JNLP file.
Through the JAVA_TOOL_OPTIONS environment variable.
Through the deployment settings on the local computer.
Through the javaws command (I was unable to get this to work).
Note that I have included links to the java 8 version of this documentation. All of these ideas are supported and documented in other Java versions, however sometimes they work a tiny bit different, or have slightly changed restrictions.
Through JNLP file.
The JNLP supports many JVM arguments through the JNLP file. Some can be done though direct settings, such as initial-heap-size and max-heap-size. For other settings java-vm-args can be used.
The JNLP File Syntax documentation lists some supported java-vm-args for 'this version' however it is unsure if that is the version 1.4+ of the example, or JRE 8. I know some unlisted settings are actually supported, such as -XX:MaxGCPauseMillis and activating the G1 garbage collector. You can make a JNLP and then use jinfo -flag MaxGCPauseMillis <pid> to test if a setting has been correctly propagated.
This is the preferred method, because it does not require any direct control of the JVM. The down-side is that only supports specific parameters that are considered 'safe'.
Through the JAVA_TOOL_OPTIONS environment variable
When you start Java Webstart by using the javaws command, you can use the JAVA_TOOL_OPTIONS to set any parameter you want on all JVM started from that environment.
So in Linux you can do to set an unsupported parameter:
export JAVA_TOOL_OPTIONS=-XX:SoftRefLRUPolicyMSPerMB=2000
javaws <my jnlp>
Note that this will affect all java applications ran with this system variable. So setting this for all users, or a specific user should be done with great care. Setting this only for a single application as the example above is much safer.
The advantage of this solution is that you can pass any parameter you want. The downside is that it requires a specific way of launching the application, or a very broad setting. It also requires control over the client system.
Through the deployment settings on the local computer
You can also pass JVM arguments by changing the deployment settings of the JVM. This can be done through the Java Control Panel, which allows you to set default runtime settings.
If you want to automate these settings you can use the deployment properties file. Unfortunately the JRE specific section of this file is undocumented. Manually it is very easy to adapt this file:
deployment.javaws.jre.0.args=-XX\:SoftRefLRUPolicyMSPerMB\=2000
When automating this file, you have to watch very carefully that it contains these settings for all detected JVMs, so you have to be sure to change the correct one. Also this will be used for all Webstart and applets on your system.
Through the javaws command (I was unable to get this to work)
There should be another way (besides the JAVA_TOOL_OPTIONS method) to change the parameters using the command line. The javaws documentation lists the -J option to pass arguments to the JVM, for example by running your JNLP as follows:
javaws -J-XX:SoftRefLRUPolicyMSPerMB=2000 <my jnlp>
However I have not been able to get this to actually set the JVM parameters.
I'm trying to get code coverage data from a remote server, so I added a JVM argument:
-javaagent:/opt/jacocoagent.jar=output=tcpserver,port=6300,includes="a pretty long list"
but unfortunately the includes list is too long, that the java command has exceeded the maximum length of our system limits.
Is there any way to specify a external property file so I can put the long "includes list” there?
I've read the jacoco document, it seems when running in "Offline Instrumentation", the jacoco agent will read properties from jacoco-agent.properties if it appears in classpath. But I don't want to use this mode.
Found a solution myself.
When oracle JVM startup, it picks an environment variable JAVA_TOOL_OPTIONS and
the JNI_CreateJavaVM function (in the JNI Invocation API) prepends the
value of the environment variable to the options supplied in its
JavaVMInitArgs argument.
So in my case, I defined:
JAVA_TOOL_OPTIONS=-javaagent:/path/to/jacocoagent.jar=output=tcpserver,address=*,port=6300,includes="a pretty long list"
For details, you can refer to:
https://docs.oracle.com/javase/8/docs/technotes/guides/troubleshoot/envvars002.html
Currently, I am trying to pass a system property to an executable in the following format: ./executable -Dvar="value" other parameters, since this is what I've seen people do for java files. I keep getting an error in the executable saying that -Dvar="value" doesn't exist as a parameter. Where am I going wrong? Are system properties exclusive to Java or something?
The -D parameter sets a system property. The system properties can be accessed through System.getProperty("<your parametername>");
A tutorial is given here https://docs.oracle.com/javase/tutorial/essential/environment/sysprop.html
The -D is consumed by the java runtime (java.exe) and will be invisible to your application on the commandline.
Currently my ant output is colorized by AnsiColorLogger. It works as expected, and now I want to customize the colors (default ones are too dim). I created a color file as specified, but have no idea how to pass the file name through. The documentation says
This file must be specified as the value of a system variable named ant.logger.defaults and passed as an argument using the -D option to the java command that invokes the Ant application.
How to pass an argument to the java command if I just run on terminal with ant? I tried to pass
-Dant.logger.defaults=<my file path>
to ant but no luck. I also tried setting environment variable
ANT_OPTS='-Dant.logger.defaults=<my file path>'
but it didn't work either. In case it matters, I am with
OS X 10.10.5
Apache Ant(TM) version 1.9.6
Java 1.8.0_65
I found my bug: my path to the file was ~/my-file but ~ in single quotes is not expanded. That simple.
(I forgot the fact that when I use ~ in terminal, it is expanded by the shell before passed to the program.)
Typical setup for ant:
export ANT_HOME="${HOME}/opt/apache-ant"
export ANT_ARGS="-logger org.apache.tools.ant.listener.AnsiColorLogger"
export ANT_OPTS="-Dant.logger.defaults=${HOME}/etc/ant-colors.properties"
export PATH="${ANT_HOME}/bin:${PATH}"
In this case I have ant installed in my home directory under opt/, while it's color configuration is similarly in the home directory under etc/. This can be customized to whatever it needs to be. Use of ${HOME} avoids issues with ~, as long as I also use double quotes as in the example instead of single quotes.
My initial error was that I thought the -D could be added with ANT_ARGS, but we need both ANT_ARGS and ANT_OPTS as above.
This is the ant-colors.properties I am using on macOs:
AnsiColorLogger.ERROR_COLOR=31
AnsiColorLogger.WARNING_COLOR=35
AnsiColorLogger.INFO_COLOR=36
AnsiColorLogger.VERBOSE_COLOR=32
AnsiColorLogger.DEBUG_COLOR=34
Note that I leave out the attribute prefix "2;", as that would but the output in Bold. I also do not use "1;", as then the output is way to light. Instead I leave it at the default which has ideal visibility to me.
Note the syntax is as follows:
AnsiColorLogger.*=Attribute;Foreground;Background