Существуют ли какие-либо Java-API для поиска версии JDK для компиляции файла класса? Конечно, есть инструмент javap, чтобы узнать основную версию, как указано в здесь. Однако я хочу сделать это программно, чтобы я мог предупредить пользователя о его компиляции для соответствующего JDK
Java API, чтобы узнать версию JDK для файла класса?
Ответ 1
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();
}
}
Возможные значения:
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
55 0 11
Ответ 2
basszero подход может быть выполнен через командную строку UNIX, а команда "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" - это магический номер. "0000 3100" равен 0x31, что представляет собой J2SE 5.0.
Ответ 3
Это дает вам содержимое файла класса:
MysteryClass.class.getResourceAsStream("MysteryClass.class")
Затем посмотрите байты 5-8, чтобы получить младшую и основную версию. Отображение между этими числами и версиями JDK можно найти здесь.
Ответ 4
Apache BCEL предоставляет этот API:
JavaClass c = Repository.lookupClass("com.x.MyClass")
c.getMinor();
c.getMajor();
Ответ 5
Просто прочитайте файл класса напрямую. ОЧЕНЬ легко понять версию. Ознакомьтесь с спецификацией и wiki, а затем попробуйте код. Обернуть этот код и сделать более полезным/красивым остается в качестве упражнения. Кроме того, вы можете использовать библиотеку, например BCEL, ASM, или 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();
}
}
}
Ответ 6
В Linux вы можете использовать команду file
в файле класса, который я нашел наиболее простым для моего варианта использования. Например:
$ file Foo.class
Foo.class: compiled Java class data, version 50.0 (Java 1.6)
Ответ 7
Как показали другие, это легко сделать, читая первые восемь байтов файла класса. Если вы хотите создать встроенную двоичную библиотеку, вы можете загрузить здесь здесь.
Ответ 8
JavaP имеет API, но он специфичен для Sun JDK.
Он найден в tools.jar
, под sun/tools/javap/Main.class
.