We always want our dev/test environment to be production like, but often we can be caught in the trap of using JDK functions that are not exposing environment dependency very explicit (like required method parameter) or can be subtle to detect and be aware. For example:
public String(byte bytes[])
uses default encodingnew Date()/Instant.now()
uses sytem timezoneSystem.out.printf("%n")
uses platform line endingsSome of them can be driven by JVM parameters like -Dfile.encoding=UTF-8
.
But how to find all of such gotchas?
The type of gotchas depends on the type of your application.
For an almost complete list you can run this check, which lists both your operating system environment variables and the java system properties:
import java.awt.GraphicsEnvironment;
import java.util.Map;
import java.util.Properties;
public class Sof39189179 {
public static void main(String[] args) {
Map<String, String> sysenv = System.getenv();
for(String key: sysenv.keySet())
System.out.println( key + ": " + sysenv.get(key));
Properties properties = System.getProperties();
for(Object key: properties.keySet())
System.out.println(key + ": " + properties.get(key));
GraphicsEnvironment ge = GraphicsEnvironment.getLocalGraphicsEnvironment();
System.out.println("headless: " + ge.isHeadless());
}
}
On my computer, I get the following output (I have left out some lines):
M2: $M2_HOME/bin
JAVA_HOME: /opt/local/jdk-1.8.0_51
LANG: en_US.UTF-8
CATALINA_HOME: /opt/local/tomcat-8.0.24
...
---------------------
java.runtime.name: Java(TM) SE Runtime Environment
sun.boot.library.path: /opt/local/jdk-1.8.0_51/jre/lib/amd64
java.vm.version: 25.51-b03
java.vm.vendor: Oracle Corporation
java.vendor.url: http://java.oracle.com/
path.separator: :
java.vm.name: Java HotSpot(TM) 64-Bit Server VM
file.encoding.pkg: sun.io
user.country: US
sun.java.launcher: SUN_STANDARD
sun.os.patch.level: unknown
java.vm.specification.name: Java Virtual Machine Specification
user.dir: /home/rudolf/workspace/neon/sof39189179
java.runtime.version: 1.8.0_51-b16
java.awt.graphicsenv: sun.awt.X11GraphicsEnvironment
java.endorsed.dirs: /opt/local/jdk-1.8.0_51/jre/lib/endorsed
os.arch: amd64
java.io.tmpdir: /tmp
line.separator:
java.vm.specification.vendor: Oracle Corporation
os.name: Linux
...
java.awt.printerjob: sun.print.PSPrinterJob
file.encoding: UTF-8
java.specification.version: 1.8
java.class.path: /home/rudolf/workspace/neon/sof39189179/bin
user.name: rudolf
java.vm.specification.version: 1.8
java.home: /opt/local/jdk-1.8.0_51/jre
sun.arch.data.model: 64
user.language: en
java.specification.vendor: Oracle Corporation
awt.toolkit: sun.awt.X11.XToolkit
java.vm.info: mixed mode
java.version: 1.8.0_51
java.ext.dirs: /opt/local/jdk-1.8.0_51/jre/lib/ext:/usr/java/packages/lib/ext
sun.boot.class.path: /opt/local/jdk-1.8.0_51/jre/lib/resources.jar:/opt/local/jdk-1.8.0_51/jre/lib/rt.jar:/opt/local/jdk-1.8.0_51/jre/lib/sunrsasign.jar:/opt/local/jdk-1.8.0_51/jre/lib/jsse.jar:/opt/local/jdk-1.8.0_51/jre/lib/jce.jar:/opt/local/jdk-1.8.0_51/jre/lib/charsets.jar:/opt/local/jdk-1.8.0_51/jre/lib/jfr.jar:/opt/local/jdk-1.8.0_51/jre/classes
java.vendor: Oracle Corporation
file.separator: /
java.vendor.url.bug: http://bugreport.sun.com/bugreport/
sun.io.unicode.encoding: UnicodeLittle
sun.cpu.endian: little
sun.cpu.isalist:
headless: false
You can determine from this list what properties are relevant in your case and check your code for it. Or, better, code with those properties in mind.
System.out.printf("%n") uses platform line endings
I prefer using the properties listed above, i.e. for printing out a newline, I use something like:
String newline = (String) System.getProperties().get("line.separator");
System.out.println("newline: " + newline);
Since you're asking for a complete list: Every time you interact with the operating system or native libraries.
Every time you don't do pure computationlet's ignore strict math there can be differences. Sometimes they are minor and only occur in edge-cases and sometimes they're explicitly part of the API.
As general advise: Read the docs of the APIs you're using and know what OS features underpin them
Not the direct answer to your question, but -XX:+PrintFlagsFinal
and -XshowSettings:all
helps a lot in comparing different environments. These flags will show default (hardware/os dependent) jvm settings and env/system properties.
You will also need to compare os settings like environment variables, os limits/quotas, security settings, file system settings etc.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With