Could inconsistent JIT optimization be the culprit? Twenty minutes' Googling was unable to produce for me any better answer than... maybe.
Possibly, but I'm not sure. The weird thing is, the inconsistencies persist even once JIT compilations stop (you can watch them with -XX:+PrintCompilation), so whatever non-determinism is happening, it's happening within the same compiled code, at least I think it is (unless the JVM is switching between compiled versions of code? I dunno...). Also have not been able to find much info on this online.
It does sound like the strictfp keyword could indeed somewhat easily be used to quash the problem, anyway... though in that case one would need two whole versions of one's program.
Apparently this is the case: http://zetsgames.com/deterministic-physics/
seems to have tried that, and it worked.
Sucks that strictfp has to be added as a modifier, there's no way to turn it on and off for a whole codebase with a single flag, at least without adding a preprocessing step.
However, at least this tells us that it's not something wrong with the way the engine is coded, it's actually just an issue with the way floating point is handled in Java. And if strictfp works, that should actually give cross-platform
consistency in Java, which is vastly more difficult to obtain in any other language, including C++. This could actually be the "killer feature" of the Java port if we were to add strictfp, though I'd want to measure the performance hit before going for it...
I think you're mistaken about the nondeterminism you're seeing on a single machine. Java is "deterministic", even without strictfp.
I suspect you're seeing the effects of these unseeded calls to Random() in jbox2d:
By default, "new Random()" is seeded with the time, which will cause two runs of jbox2d to differ. I added a static seed to the random() calls (e.g., new Random(5)) and now every run is the same.