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).

¿Fue útil?

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}'

En eclipse si no tienes fuentes adjuntas.Tenga en cuenta la primera línea después del botón adjuntar fuente.

// Compilado desde CDestinoLog.java (versión 1.5:49.0, súper bit)

enter image description here

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)...

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