giovedì 30 maggio 2013

Capire dal .class la java version

I compilati Java, con estensione .class, hanno una struttura iniziale che ci consente di capire con quale java version sono stati compilati.
Tutti i .class iniziano con la sequenza 0xCAFEBABE, detto magic number, il numero esadecimale che consente di capire il formato del file.
Sulla storia di questo magic number sono raccontate in rete storie divertenti, secondo Wikipedia inglese pare che tutto venga da un caffè frequentato dai Grateful Dead (http://en.wikipedia.org/wiki/Java_class_file).
Dopo il magic number c'è l'identificativo di versione major e minor.
I valori del major identificano la versione e sono i seguenti:
46 -> java 1.2
47-> java 1.3
48-> java 1.4
49-> java 1.5
50 -> java 1.6
51-> java 1.7

Di seguito incollo il testo di una classe Java che dato un file .class restituisce la versione Java.


package it.test;
import java.io.DataInputStream;
import java.io.FileInputStream;
import java.io.IOException;
import java.util.*;
public class CheckCompiledVersion {
 static Map myMap=null;
 private static CheckCompiledVersion istanza;
 private CheckCompiledVersion(){
  
 }
 public static CheckCompiledVersion getInstance(){
  if(istanza==null){
   istanza=new CheckCompiledVersion();
  }
  return istanza;
 }
 static
 {

      myMap=new HashMap();
      myMap.put(46, "Java 1.2");
      myMap.put(47, "Java 1.3");
      myMap.put(48, "Java 1.4");
      myMap.put(49, "Java 1.5");
      myMap.put(50, "Java 1.6");
      myMap.put(51, "Java 1.7");
 }
 public static void main(String[] args) throws IOException {
  System.out.println(CheckCompiledVersion.getInstance().checkClassVersion("out/Myfile.class"));
 }

 public String checkClassVersion(String filename)
         throws IOException
     {
         DataInputStream in = new DataInputStream(new FileInputStream(filename));
         int magic = in.readInt();
         if(magic != 0xcafebabe) {
           return filename + " non è un .class";
         }
         int minor = in.readUnsignedShort();
         int major = in.readUnsignedShort();
         System.out.println(filename + ": " + major + " . " + minor);
         in.close();
         return myMap.get(major);
     }
}


Nessun commento:

Posta un commento