¿Qué ajustes afectan el diseño de los archivos compilados de Java .class? ¿Cómo puede saber si dos clases compiladas son iguales?

StackOverflow https://stackoverflow.com/questions/644320

Pregunta

Tengo una aplicación que se compiló con el Eclipse integrado "Compilar" tarea. Luego decidí mover el procedimiento de compilación al javac de Ant, y el resultado terminó siendo archivos más pequeños.

Más tarde descubrí que ajustando el nivel de depuración a " vars, lines, source " podría incrustar la misma información de depuración que Eclipse, y en muchos casos los archivos permanecían exactamente del mismo tamaño pero El diseño interno era diferente. Y como consecuencia, no pude usar las firmas md5sum para determinar si eran exactamente la misma versión.

Además de la información de depuración, ¿cuál puede ser la razón por la que 2 archivos supuestamente iguales obtienen un diseño o tamaño interno diferente?

¿Y cómo puede comparar archivos compilados .class?

¿Fue útil?

Solución

No hay un orden requerido para cosas como el orden de las entradas constantes del grupo (esencialmente toda la información del símbolo), así como los atributos para cada campo / método / clase. Los diferentes compiladores son libres de escribir en el orden que deseen.

Puede comparar clases compiladas, pero necesitaría profundizar en la estructura del archivo de clase y analizarla. Existen bibliotecas para hacerlo, como BCEL o ASM , pero no estoy 100% seguro de que te ayudarán con lo que quieres hacer.

Otros consejos

El ASM Eclipse plugin tiene un comparador de bytecode. Selecciona dos clases, haz clic derecho y compara Bytecode / Each Other.

Una cosa importante a tener en cuenta es que Eclipse no usa javac. Eclipse tiene su propio compilador, el JDT , y así las diferencias en el resultado. Los archivos de clase no me sorprenden. Esperaría que no fueran textuales, porque son compiladores diferentes.

Debido a sus diferencias, existe un código que se compila con javac pero no con JDT, y viceversa. Por lo general, he visto que las diferencias en los dos se hacen evidentes en casos de uso intensivo de genéricos

Lo más importante, las ranuras de pila para variables locales se pueden organizar de forma arbitraria sin cambiar la semántica del código. Básicamente, no se pueden comparar archivos de clase compilados sin analizarlos y normalizarlos, un gran esfuerzo.

¿Por qué quieres hacer eso de todos modos?

como dijo Michale B, puede ser arbitrario.

Trabajo en sistemas que utilizan tamaños de archivo como seguridad. Si los archivos .class cambian de tamaño, la clase no tendrá ciertos permisos.

Normalmente eso sería fácil de manejar, pero tenemos un control bastante completo sobre el entorno, por lo que en realidad es bastante funcional.

De todos modos, cada vez que las clases que se ven se vuelven a compilar, parece que tenemos que volver a calcular el tamaño.

Otra cosa: se genera un número de clave especial cuando se compila el archivo. No sé mucho sobre esto, pero a menudo impide que las clases trabajen juntas. Creo que el procedimiento es compilar la clase A y guardarla (llámela a1). compile la clase a de nuevo (a2). Compile la clase b contra la clase a2. Intenta ejecutar b contra a1. Creo que en este caso fallará en tiempo de ejecución.

Si pudiera obtener más información sobre ese número clave, podría darle la información que busca.

Para la comparación, puede descompilar sus archivos de clase y jugar con las fuentes generadas. Consulte esto .

¿Eclipse está haciendo alguna instrumentación para ayudar con la ejecución del depurador?

En última instancia, las configuraciones que se utilizan probablemente marcan la diferencia. Suponiendo que están utilizando las mismas versiones de Java, hay una gran cantidad de opciones disponibles para la configuración de compilación (cumplimiento de JDK, compatibilidad de archivos de clase y una gran cantidad de opciones de información de depuración).

Licenciado bajo: CC-BY-SA con atribución
No afiliado a StackOverflow
scroll top