Frage

Kennt jemand von euch ein Tool, das nach .class-Dateien sucht und dann deren kompilierte Versionen anzeigt?

Ich weiß, dass Sie sie einzeln in einem Hex-Editor betrachten können, aber ich muss viele Klassendateien durchsehen (irgendetwas in meiner riesigen Anwendung kompiliert aus irgendeinem Grund nach Java6).

War es hilfreich?

Lösung

Benutzen Sie die Javap Tool, das mit dem JDK geliefert wird.Der -verbose Option gibt die Versionsnummer der Klassendatei aus.

> javap -verbose MyClass
Compiled from "MyClass.java"
public class MyClass
  SourceFile: "MyClass.java"
  minor version: 0
  major version: 46
...

Um nur die Version anzuzeigen:

WINDOWS> javap -verbose MyClass | find "version"
LINUX  > javap -verbose MyClass | grep version

Andere Tipps

Es ist leicht zu lesen Signatur der Klassendatei und erhalten Sie diese Werte ohne eine Drittanbieter-API.Sie müssen lediglich die ersten 8 Bytes lesen.

ClassFile {
    u4 magic;
    u2 minor_version;
    u2 major_version;

Für die Klassendateiversion 51.0 (Java 7) lauten die Anfangsbytes:

CA FE BA BE 00 00 00 33

...wobei 0xCAFEBABE die magischen Bytes sind, 0x0000 die Nebenversion und 0x0033 die Hauptversion ist.

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);
    }
  }
}

Wanderverzeichnisse (Datei) und Archive (JarFile) Die Suche nach Klassendateien ist trivial.

Oracles Joe Darcys Blog listet die auf Zuordnungen von Klassenversionen zu JDK-Versionen bis 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

Auf Unix-ähnlich

file /path/to/Thing.class

Gibt auch den Dateityp und die Version an.So sieht die Ausgabe aus:

kompilierte Java-Klassendaten, Version 49.0

Wenn Sie auf einem Unix-System arbeiten, können Sie einfach Folgendes tun:

find /target-folder -name \*.class | xargs file | grep "version 50\.0"

(Meine Version der Datei sagt „kompilierte Java-Klassendaten, Version 50.0“ für Java6-Klassen).

Noch eine Java-Versionsprüfung

od -t d -j 7 -N 1 ApplicationContextProvider.class | head -1 | awk '{print "Java", $2 - 44}'

In Eclipse, wenn Sie keine Quellen angehängt haben.Beachten Sie die erste Zeile nach der Schaltfläche „Quelle anhängen“.

// Kompiliert aus CDestinoLog.java (Version 1.5:49,0, Superbit)

enter image description here

Vielleicht hilft das auch jemandem.Es scheint, dass es eine einfachere Möglichkeit gibt, die JAVA-Version zum Kompilieren/Erstellen von .class zu verwenden.Diese Methode ist nützlich für die Selbstprüfung von Anwendungen/Klassen in der JAVA-Version.

Ich habe die JDK-Bibliothek durchgesehen und diese nützliche Konstante gefunden:com.sun.deploy.config.BuiltInProperties.CURRENT_VERSION.Ich weiß nicht, seit wann es in JAVA JDK ist.

Wenn ich diesen Code für mehrere Versionskonstanten ausprobiere, erhalte ich das folgende Ergebnis:

Quelle:

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() );

Ausgabe:

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

Im Klassenbytecode ist tatsächlich eine Konstante gespeichert – siehe rot markierter Teil von Main.call – Konstante, gespeichert im .class-Bytecode

Die Konstante wird in der Klasse verwendet, um zu überprüfen, ob die JAVA-Version veraltet ist (siehe Wie Java prüft, ob es veraltet ist)...

Lizenziert unter: CC-BY-SA mit Zuschreibung
Nicht verbunden mit StackOverflow
scroll top