En primer lugar, vale la pena señalar que JVM de Sun fue escrito en C. C es un lenguaje muy popular cuando se necesita portabilidad.
El lenguaje C es portátil a pesar de que muchos programas C no lo son. Esto se debe a que C no impone tantas restricciones al programador ni hace tantas suposiciones. Si un programador C quiere que sus programas sean portátiles, debe imponerse esas restricciones.
En la práctica, eso realmente no es mucho más difícil que vivir con las restricciones que Java te impone. Es principalmente una cuestión de ser consciente de su endianness y tamaños primitivos, y usar bibliotecas portátiles como GTK + en lugar de bibliotecas específicas de la plataforma.
Podría hacer un compilador de GTK + y C que admitiera una máquina virtual, incluso probablemente la JVM, y obtener el código existente para trabajar con muy pocos cambios. De hecho, sin la recolección de basura, una máquina virtual en C probablemente sería mucho más simple. ¿Pero por qué querrías hacerlo?
Lo contrario, compilar Java en código nativo, también es factible. Eso es básicamente lo que hace el JIT. ¿Pero por qué querrías hacerlo? Estoy seguro de que hay proyectos favoritos para hacerlo "solo porque", pero no están en uso serio.