2008-08-25 13 views
103

Qualcuno di voi sa di uno strumento che cercherà i file .class e quindi visualizzerà le loro versioni compilate?Strumento per leggere e visualizzare le versioni .class Java

So che puoi visualizzarli singolarmente in un editor esadecimale, ma ho un sacco di file di classe da esaminare (qualcosa nella mia gigantesca applicazione si sta compilando su Java6 per qualche motivo).

+0

duplicato più popolare http://stackoverflow.com/questions/1096148/how-to-check-the -jdk-version-used-to-compile-a-class-file ha in risposta alcuni utili strumenti non menzionati qui. – Vadzim

risposta

129

Utilizzare lo strumento javap che viene fornito con il JDK. L'opzione -verbose stamperà il numero di versione del file di classe.

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

per mostrare solo la versione:

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

È sufficiente leggere lo class file signature e ottenere questi valori senza un'API di terze parti. Tutto ciò che devi fare è leggere i primi 8 byte.

ClassFile { 
    u4 magic; 
    u2 minor_version; 
    u2 major_version; 

Per file di classe versione 51.0 (Java 7), i byte di apertura sono:

CA FE BA BE 00 00 00 33 

... dove 0xCAFEBABE sono i byte magici, 0x0000 è la versione minore e 0x0033 è la versione principale .

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

directory piedi (File) e archivi (JarFile) in cerca di file di classe è banale.

di Oracle Joe Darcy's blog liste del class version to JDK version mappings fino a 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 
+0

Ricorda inoltre che l'assert viene eseguito solo se è abilitato all'avvio di java in modo da poter leggere i file indesiderati se non si utilizza IllegalArgumentException (ad esempio) – jontejj

9

Se siete su un sistema Unix si può solo fare un

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

(la mia versione di file di dice "compilato dati di classe

Java , versione 50.0 "per le classi java6).

+0

Su macOS (almeno 10.12.6), l'output è ancora più utile: 'file * .class' produce: ' ClassName.class: i dati della classe Java compilato, versione 50.0 (Java 1.6) ' – Gary

17

On Unix-like

file /path/to/Thing.class

darà il tipo di file e versione. Ecco ciò che il risultato è simile:

dati della classe Java compilati, versione 49,0

+0

(semplificato dalla risposta di WMR) – phunehehe

+0

questo è il modo più semplice rispetto alle altre soluzioni – mmuller

5

Ancora un'altra versione Java Mostra

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

in Eclipse, se non si dispone di fonti allegate. Presta attenzione alla prima riga dopo il pulsante "Collega fonte".

// compilato da CDestinoLog.java (versione 1.5: 49.0, super po)

enter image description here

2

Forse questo aiuta qualcuno, anche. Sembra che ci sia un modo più semplice per ottenere la versione di JAVA usata per compilare/compilare .class.In questo modo è utile per l'autovalutazione applicazione/classe sulla versione di JAVA.

Ho passato con biblioteca JDK e ho trovato questa costante utile: com.sun.deploy.config.BuiltInProperties.CURRENT_VERSION. Non so da quando è in JAVA JDK.

Cercando questo pezzo di codice per diverse costanti versione ottengo risultato qui sotto:

src:

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

uscita:

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 

In classe bytecode c'è davvero memorizzato costante - vedi parte contrassegnata in rosso di Main.call - constant stored in .class bytecode

costante è in classe utilizzato per verificare se la versione JAVA non è aggiornato (vedi How Java checks that is out of date) ...

Problemi correlati