2012-03-29 9 views
6

Actualmente estamos en el proceso de reescribir todo nuestro sistema de compilación para un proyecto grande (alrededor de 2000 archivos fuente) y se ha hablado de hacer una comparación binaria en los archivos para asegurar que todo sea correcto lo que conduce al siguiente pregunta: ¿Se garantiza que la salida de javac sea la misma en todas las compilaciones o podría estar sujeta a cambios?¿El archivo de clase generado por javac es siempre el mismo?

Another question a entender que la piscina constante podría tener un orden diferente, pero asumiendo que son capaces de controlar el orden de los archivos de entrar en la llamada javac ¿Existe todavía un potencial de diferencias? Estamos usando Ant y Maven como parte de la construcción si eso también puede influir en las cosas.

+2

No garantizado. En la práctica, probablemente sería idéntico si utiliza el compilador idéntico y la estructura JAR en tiempo de compilación, pero incluso cambios menores en el orden JAR, etc., podrían alterar el carro de manzanas. –

+0

¿No garantizarían sus pruebas la equivalencia * funcional *, que es lo que realmente le preocupa? En cualquier caso, ¿por qué no probarlo y ver qué pasa? Si encuentra que las cosas se han reordenado, tendrá que entrar y hacer un análisis de código de bytes para ver si de todas maneras son equivalentes al código byte. –

+0

Realmente me pregunto por qué tendrías que hacer una comparación binaria de las clases creadas? –

Respuesta

3

El bytecode es absolutamente no garantiza que es el mismo; Por un lado, los compiladores pueden realizar optimizaciones que no afectan a ningún comportamiento garantizado. La Especificación del lenguaje Java incluso menciona, en algunos lugares, las optimizaciones que un compilador podría realizar; por ejemplo, del operador de concatenación de cadenas +, observa que:

Una implementación puede elegir para llevar a cabo la conversión y la concatenación en un solo paso para evitar la creación y después de descartar un String objeto intermedio. Para aumentar el rendimiento de la concatenación repetida de cadenas, un compilador Java puede usar la clase StringBuffer o una técnica similar para reducir el número de objetos intermedios String que se crean mediante la evaluación de una expresión.

[link]

0

No soy un experto en el compilador, pero tiendo a creer que las otras respuestas dicen que la comparación binaria no es 100% confiable.

Consideraría otra alternativa: debería poder inspeccionar los artefactos que crea su sistema de compilación (.jars & .wars, etc.) y asegurarse de que cada uno tenga el contenido esperado, e incluso el tamaño de cada archivo está dentro de una tolerancia bastante ajustada.

Si su script de compilación genera fuente y la compila, entonces debería poder hacer comparaciones con la fuente generada, que espero que sea sea 100% estable de una compilación a otra. (O al menos predecible).

Espero que esto ayude!

0

La única manera de asegurar la equivalencia es conseguir uno de los varios programas de análisis del archivo de clase, analizar los archivos, y luego hacer el trabajo pesado de averiguar las diferencias debidas a cambios de orden de la piscina constantes, etc. El principal problema es que al reordenar el conjunto constante se cambiarán los valores numéricos que hacen referencia a las constantes, algunos de los cuales están en elementos de tabla, algunos de los cuales están en códigos de bytes. Puede hacerlo, pero definitivamente no es trivial, y probablemente no sea práctico a menos que ya tenga la mayor parte del marco en su lugar por alguna otra razón (como la modificación del código de bytes).

Cuestiones relacionadas