Herramienta para leer y mostrar versiones Java .class
-
09-06-2019 - |
Pregunta
¿Alguno de ustedes conoce una herramienta que busque archivos .class y luego muestre sus versiones compiladas?
Sé que puedes verlos individualmente en un editor hexadecimal, pero tengo muchos archivos de clase que revisar (algo en mi aplicación gigante se está compilando en Java6 por alguna razón).
Solución
Utilizar el javap herramienta que viene con el JDK.El -verbose
La opción imprimirá el número de versión del archivo de clase.
> javap -verbose MyClass
Compiled from "MyClass.java"
public class MyClass
SourceFile: "MyClass.java"
minor version: 0
major version: 46
...
Para mostrar solo la versión:
WINDOWS> javap -verbose MyClass | find "version"
LINUX > javap -verbose MyClass | grep version
Otros consejos
Es bastante fácil leer el firma del archivo de clase y obtenga estos valores sin una API de terceros.Todo lo que necesitas hacer es leer los primeros 8 bytes.
ClassFile {
u4 magic;
u2 minor_version;
u2 major_version;
Para el archivo de clase versión 51.0 (Java 7), los bytes de apertura son:
CA FE BA BE 00 00 00 33
...donde 0xCAFEBABE son los bytes mágicos, 0x0000 es la versión menor y 0x0033 es la versión principal.
import java.io.*;
public class Demo {
public static void main(String[] args) throws IOException {
ClassLoader loader = Demo.class.getClassLoader();
try (InputStream in = loader.getResourceAsStream("Demo.class");
DataInputStream data = new DataInputStream(in)) {
if (0xCAFEBABE != data.readInt()) {
throw new IOException("invalid header");
}
int minor = data.readUnsignedShort();
int major = data.readUnsignedShort();
System.out.println(major + "." + minor);
}
}
}
Directorios ambulantes (Archivo) y archivos (Archivo Jar) buscar archivos de clase es trivial.
oráculo El blog de Joe Darcy. enumera el Asignaciones de versión de clase a versión JDK hasta Java 7:
Target Major.minor Hex
1.1 45.3 0x2D
1.2 46.0 0x2E
1.3 47.0 0x2F
1.4 48.0 0x30
5 (1.5) 49.0 0x31
6 (1.6) 50.0 0x32
7 (1.7) 51.0 0x33
8 (1.8) 52.0 0x34
9 53.0 0x35
En estilo Unix
file /path/to/Thing.class
También proporcionará el tipo de archivo y la versión.Así es como se ve el resultado:
datos de clase Java compilados, versión 49.0
Si estás en un sistema Unix, puedes simplemente hacer un
find /target-folder -name \*.class | xargs file | grep "version 50\.0"
(mi versión del archivo dice "datos de clase Java compilados, versión 50.0" para clases java6).
Otra verificación más de la versión de Java
od -t d -j 7 -N 1 ApplicationContextProvider.class | head -1 | awk '{print "Java", $2 - 44}'
Quizás esto también ayude a alguien.Parece que hay una forma más sencilla de utilizar la versión JAVA para compilar/construir .class.De esta manera es útil para la autoverificación de aplicaciones/clases en la versión JAVA.
Revisé la biblioteca JDK y encontré esta constante útil:com.sun.deploy.config.BuiltInProperties.CURRENT_VERSION.No sé desde cuando está en JAVA JDK.
Al probar este fragmento de código para varias constantes de versión, obtengo el siguiente resultado:
origen:
System.out.println("JAVA DEV ver.: " + com.sun.deploy.config.BuiltInProperties.CURRENT_VERSION);
System.out.println("JAVA RUN v. X.Y: " + System.getProperty("java.specification.version") );
System.out.println("JAVA RUN v. W.X.Y.Z: " + com.sun.deploy.config.Config.getJavaVersion() ); //_javaVersionProperty
System.out.println("JAVA RUN full ver.: " + System.getProperty("java.runtime.version") + " (may return unknown)" );
System.out.println("JAVA RUN type: " + com.sun.deploy.config.Config.getJavaRuntimeNameProperty() );
producción:
JAVA DEV ver.: 1.8.0_77
JAVA RUN v. X.Y: 1.8
JAVA RUN v. W.X.Y.Z: 1.8.0_91
JAVA RUN full ver.: 1.8.0_91-b14 (may return unknown)
JAVA RUN type: Java(TM) SE Runtime Environment
En el código de bytes de la clase realmente hay una constante almacenada; consulte la parte marcada en rojo de Main.call. constante almacenada en código de bytes .class
La constante está en la clase que se usa para verificar si la versión de JAVA está desactualizada (consulte Cómo comprueba Java que está desactualizado)...