version - tengo - verificar java instalado
API de Java para averiguar la versiĆ³n de JDK para la que se compila un archivo de clase (8)
¿Hay alguna API de Java para averiguar la versión de JDK para la que se compila un archivo de clase? Por supuesto, existe la herramienta javap para averiguar la versión principal tal como se menciona here . Sin embargo, quiero hacerlo programáticamente para que yo pueda advertir al usuario que lo compile para el JDK apropiado.
Como otros han demostrado, es bastante fácil hacerlo al leer los primeros ocho bytes de un archivo de clase. Si desea una biblioteca binaria preconstruida, puede descargar una here .
El enfoque de basszero se puede hacer a través de la línea de comando de UNIX y el comando "od (1)":
% od -x HelloWorldJava.class |head -2
0000000 feca beba 0000 3100 dc00 0007 0102 2a00
0000020 6f63 2f6d 6e65 6564 6163 642f 6d65 2f6f
"feca beba" es el número mágico . El "0000 3100" es 0x31, que representa J2SE 5.0.
En Linux, puede usar el comando de file
en un archivo de clase, que encontré más fácil para mi caso de uso. Por ejemplo:
$ file Foo.class
Foo.class: compiled Java class data, version 50.0 (Java 1.6)
Esto te proporciona el contenido del archivo de clase:
MysteryClass.class.getResourceAsStream("MysteryClass.class")
Luego mira los bytes 5-8 para obtener la versión menor y mayor. here puede encontrar un mapeo entre esos números y los lanzamientos de JDK.
JavaP tiene una API , pero es específica de Sun JDK.
Se encuentra en tools.jar
, en sun/tools/javap/Main.class
.
Solo lea el archivo de clase directamente. Es muy fácil descubrir la versión. Verifique las spec y la wiki y luego pruebe el código. Envolver este código y hacer es más útil / bonito se deja como un ejercicio. Alternativamente, puede usar una biblioteca como BCEL , ASM o JavaAssist
import java.io.DataInputStream;
import java.io.FileInputStream;
import java.io.FileNotFoundException;
import java.io.IOException;
public class ClassVersionTest
{
private static final int JAVA_CLASS_MAGIC = 0xCAFEBABE;
public static void main(String[] args)
{
try
{
DataInputStream dis = new DataInputStream(new FileInputStream("Test.class"));
int magic = dis.readInt();
if(magic == JAVA_CLASS_MAGIC)
{
int minorVersion = dis.readUnsignedShort();
int majorVersion = dis.readUnsignedShort();
/**
* majorVersion is ...
* J2SE 6.0 = 50 (0x32 hex),
* J2SE 5.0 = 49 (0x31 hex),
* JDK 1.4 = 48 (0x30 hex),
* JDK 1.3 = 47 (0x2F hex),
* JDK 1.2 = 46 (0x2E hex),
* JDK 1.1 = 45 (0x2D hex).
*/
System.out.println("ClassVersionTest.main() " + majorVersion + "." + minorVersion);
}
else
{
// not a class file
}
}
catch (FileNotFoundException e)
{
// TODO Auto-generated catch block
e.printStackTrace();
}
catch (IOException e)
{
// TODO Auto-generated catch block
e.printStackTrace();
}
}
}
Apache BCEL proporciona esta API:
JavaClass c = Repository.lookupClass("com.x.MyClass")
c.getMinor();
c.getMajor();
import java.io.*;
public class ClassVersionChecker {
public static void main(String[] args) throws IOException {
for (int i = 0; i < args.length; i++)
checkClassVersion(args[i]);
}
private static void checkClassVersion(String filename)
throws IOException
{
DataInputStream in = new DataInputStream
(new FileInputStream(filename));
int magic = in.readInt();
if(magic != 0xcafebabe) {
System.out.println(filename + " is not a valid class!");;
}
int minor = in.readUnsignedShort();
int major = in.readUnsignedShort();
System.out.println(filename + ": " + major + " . " + minor);
in.close();
}
}
Los valores posibles son:
major minor Java platform version
45 3 1.0
45 3 1.1
46 0 1.2
47 0 1.3
48 0 1.4
49 0 5
50 0 6
51 0 7
52 0 8
53 0 9
54 0 10