gcj -C -ftarget 1.1 produces output that doesn't work in Sun JDK 1.1.8, as tested under Wine. The problem is that the bytecode produced for a synchronized() block is not accepted by the VM. Upon encountering this bytecode, the VM either (1) prints "nonfatal internal JIT (3.00.078(x)) error 'chgTarg: Conditional' has occurred ... Interpreting method" or (2) fails to synchronize correctly and instead throws java.lang.IllegalMonitorStateException in an infinite loop.
While this is clearly not ideal behavior for the VM, this VM defines the 1.1 target, so -ftarget 1.1 should produce bytecode that actually works.
Sun introduced a similar bug into their javac starting in JDK 1.4, and has failed to fix it, leaving no good way to produce backwards-compatible bytecode. See: