This is a hack misusing the fact that Properties extends Map, an old unfortunate design decision.
public final class JvmWideSingleton
{
    private static final JvmWideSingleton INSTANCE;
    static {
        // There should be just one system class loader object in the whole JVM.
        synchronized(ClassLoader.getSystemClassLoader()) {
            Properties sysProps = System.getProperties();
            // The key is a String, because the .class object would be different across classloaders.
            JvmWideSingleton singleton = (JvmWideSingleton) sysProps.get(JvmWideSingleton.class.getName());
            // Some other class loader loaded JvmWideSingleton earlier.
            if (singleton != null) {
                INSTANCE = singleton;
            }
            else {
                // Otherwise this classloader is the first one, let's create a singleton.
                // Make sure not to do any locking within this.
                INSTANCE = new JvmWideSingleton();
                System.getProperties().put(JvmWideSingleton.class.getName(), INSTANCE);
            }
        }
    }
    public static JvmWideSingleton getSingleton() {
        return INSTANCE;
    }
}
This could be made parametrized, but then the initialization would be lazy and go to getSingleton().
Properties is Hashtable-based, so it is thread safe (as per the documentation). So one could use props.computeIfAbsent(). But I like it this way more.
Also read here: Scope of the Java System Properties
I just wrote it and there is a chance there's something I overlooked that would prevent this from working.