2010-06-10 8 views
10

Un escenario hipotético:¿Las diferentes actualizaciones JDK producen diferentes códigos de bytes Java?

Tengo un proyecto cuyo nivel de cumplimiento de fuente se especifica en 1.5. Ahora compilo este proyecto con dos JDK diferentes: primero con JDK 6 Update 7 y luego con JDK 6 Update 20.

¿Estos dos JDK diferentes producen código de bytes Java diferente, aunque solo difieren en su versión de actualización?

+0

¿Podemos preguntarnos por qué esto es importante? – polygenelubricants

+1

Pensé en ello cuando tuve problemas con la implementación en caliente de mi JBoss (ver http://stackoverflow.com/questions/3005919/hot-deploy-not-longer-working-on-jboss-scheme-change-not-implemented) –

+1

@polygenelubricants: la compatibilidad binaria se trata de cambios en el código fuente que se permiten manteniendo los archivos de clase compatibles con otros archivos de clase que no se vuelven a compilar. Es un tema útil, pero no creo que se aplique a este problema. –

Respuesta

9

El código generado generalmente solo difiere en caso de correcciones de errores del compilador.

Sin embargo, el JLS no no especifica un mapeo 1: 1 desde el código fuente al código de bytes generado, por lo que no debe confiar en el mismo código de bytes exacto que se generará.

1

¿Por qué demonios alguien se tomaría la molestia de publicar una Actualización de un kit de desarrollo si no llevaba a cambiar el código de bytes en al menos algunos casos? Dudo mucho que alguien lo haga solo por actualizaciones de documentación.

+7

Para responder a su pregunta retórica: Debido a que la interpretación/ejecución del código de bytes así como las bibliotecas pueden haber cambiado. * La mayoría * de los cambios en el JDK entre las actualizaciones son para el tiempo de ejecución y la biblioteca y * no * para el compilador. –

2

Responderemos desde el otro lado: no hay garantía de que dos versiones de jdk produzcan el código de byte idéntico. Entonces puedes esperar diferencias en general.

10

No hay nada que impida que las diferentes versiones generen diferentes códigos de bytes, siempre y cuando cumpla con el comportamiento especificado en el JLS. El JLS deja muchos detalles de implementación para variar de una implementación a otra.

1

El bytecode podría variar ligeramente, pero esto no es nada de lo que preocuparse, ya que seguirá siendo compatible.

Lo que realmente se ejecutará depende de JIT.

0

Como suele ser para diferentes compiladores, también está en el caso de Java: el resultado debe ser el mismo, pero la forma en que se alcanza puede ser (desde el punto de vista de los bytecodes) diferente, p. debido a optimizaciones o similares. La JVM es una máquina V basada en pila; el siguiente es un ejemplo imaginario (no sé mnemónicos JVM para los códigos de operación de instrucciones)

push 10 
push 20 
add
push 19 
push 1 
add 
push 10 
add

Estos producen mismo resultado, pero bytecodes generados son diferentes (el primero es ligeramente optimizadas, el segundo es " totalmente "no optimizado; una tercera opción podría ser push 30 ya que estamos agregando constantes conocidas (probablemente en tiempo de compilación)). Este es un caso simple, pero el caso más complejo se puede construir fácilmente.

1

El compilador de, por ejemplo, JDK 6 Update 7 puede generar un bytecode ligeramente diferente que el compilador de JDK 6 Update 20, pero como ambos son Java 6, los archivos de clase serán totalmente compatibles. Podrá ejecutar código compilado con la Actualización 20 en la Actualización 7 sin ningún problema.

Entre las principales versiones de Java (por ejemplo, Java 5 frente a Java 6) puede haber cambios, por lo que el código compilado en la versión más reciente no se ejecutará en la versión anterior. Por ejemplo, para Java 7 es probable que haya una nueva instrucción, invokedynamic. Los archivos de clase que contienen esa instrucción no serán ejecutables en versiones anteriores de Java.

Sin embargo, estos grandes cambios nunca se realizan entre versiones de actualización.

0

Si compila con diferentes versiones de JDK, le aconsejo usar la opción target para javac. De lo contrario, es posible que no pueda ejecutar el jar con un JDK anterior.

Es posible que desee utilizar la opción fuente en javac, para asegurarse de que el desarrollador no utilice clases/métodos agregados en un JDK más reciente.

Cuestiones relacionadas