Có bất kỳ API Java nào để tìm phiên bản JDK mà một tệp lớp được biên dịch không? Tất nhiên có công cụ javap để tìm ra phiên bản chính như đã đề cập trong here. Tuy nhiên tôi muốn làm điều đó theo chương trình để tôi có thể cảnh báo người dùng biên dịch nó cho JDKJava API để tìm phiên bản JDK một tệp lớp được biên dịch?
Trả lời
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();
}
}
Các giá trị có thể là:
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
JavaP hiện có API, nhưng nó cụ thể đối với JDK của Mặt trời.
Nó được tìm thấy trong tools.jar
, dưới sun/tools/javap/Main.class
.
này giúp bạn các nội dung của tập tin lớp:
MysteryClass.class.getResourceAsStream("MysteryClass.class")
Sau đó nhìn vào byte 5-8 để có được trẻ vị thành niên và phiên bản chính. Một bản đồ giữa các số đó và các bản phát hành JDK có thể được tìm thấy here.
Đối số chuỗi có cần phải đủ điều kiện không? getResourceAsStream ("org/apache/foobar/Whatever.class")? –
Không, vì bạn đang sử dụng chính lớp đó làm cơ sở để nhận tài nguyên. Bạn cần tên đầy đủ nếu bạn có thể lấy các phương thức nguồn của ClassLoader thay vì một lớp. –
Chỉ cần đọc trực tiếp tệp lớp học. Nó rất dễ dàng để tìm ra phiên bản. Hãy xem spec và wiki rồi thử mã. Gói mã này và làm cho hữu ích hơn/khá là trái như một bài tập. Ngoài ra, bạn có thể sử dụng một thư viện như BCEL, ASM, hoặc 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();
}
}
}
Thao tác này có hoạt động đối với các tệp lớp trong một cái lọ không? –
Như những người khác đã chỉ ra, nó là đủ dễ dàng để làm bằng cách đọc số tám byte đầu tiên của một tập tin lớp. Nếu bạn muốn có một thư viện nhị phân dựng sẵn, bạn có thể tải xuống một here.
Apache BCEL cung cấp API này:
JavaClass c = Repository.lookupClass("com.x.MyClass")
c.getMinor();
c.getMajor();
cách tiếp cận basszero có thể được thực hiện thông qua các dòng lệnh UNIX, và "od (1)" lệnh:
% 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" là magic number. "0000 3100" là 0x31, đại diện cho J2SE 5.0.
Trên Linux, bạn có thể sử dụng lệnh file
trên tệp lớp mà tôi thấy dễ dàng nhất cho trường hợp sử dụng của mình. Ví dụ:
$ file Foo.class
Foo.class: compiled Java class data, version 50.0 (Java 1.6)
- 1. Phiên bản JDK sẽ được trình biên dịch Maven sử dụng ở đâu?
- 2. làm thế nào để kiểm tra phiên bản jdk sử dụng để biên dịch một file .class
- 3. Biên dịch một tệp Java ... bằng một chương trình Java
- 4. JDK, JRE, Java: Phiên bản Lẫn lộn!
- 5. Bắt Java JDK để biên dịch trên ubuntu
- 6. biên dịch xuống một phiên bản - nhật thực, maven
- 7. Trình biên dịch java tìm các tệp lớp trong khi đường dẫn lớp không được đặt thành đường dẫn jdk như thế nào?
- 8. Thay đổi Phiên bản Phiên bản trong một assembly được biên dịch .NET
- 9. Sử dụng Java Compiler API để biên dịch nhiều tệp java
- 10. Làm thế nào để tôi tìm ra phiên bản JDK Eclipse đang sử dụng?
- 11. Cách thay đổi phiên bản JDK cho dự án Eclipse
- 12. Phiên bản API dịch vụ web
- 13. Biên dịch với libc cũ hơn (phiên bản 'GLIBC_2.14' không được tìm thấy)
- 14. Làm cách nào để biên dịch tệp .java với hỗ trợ cho các phiên bản Java cũ hơn?
- 15. Làm cách nào để kiểm tra phiên bản của python API tại thời gian biên dịch?
- 16. Java - Cách biên dịch một tệp với Java Eclipse
- 17. Trình biên dịch java nào được NetBeans sử dụng?
- 18. Thêm lớp java đã biên dịch vào dự án maven
- 19. Làm cách nào để tìm phiên bản của mô-đun hạt nhân đã biên dịch?
- 20. Đặt classpath java: -cp vs -classpath trong các phiên bản JDK 1.0 đến 1.8?
- 21. Các tệp JSP Java (* __ jsp.java) được biên dịch ở đâu?
- 22. CoffeeScript biên dịch API
- 23. Cách truy xuất phiên bản GCC được sử dụng để biên dịch một tệp ELF đã cho?
- 24. Plugin phát hành Maven: chỉ định phiên bản trình biên dịch java
- 25. Cách chọn phiên bản .NET để biên dịch dự án?
- 26. Có API dịch vụ web để tìm phiên bản mới nhất của trình duyệt web không?
- 27. Làm cách nào để sử dụng thư viện được biên dịch cho Java 7 trong Java 6?
- 28. Tại sao đơn vị của tôi "được biên dịch bằng một phiên bản khác" của các tệp của riêng tôi?
- 29. Thay đổi sang phiên bản JDK mới?
- 30. Flex: Tìm ra khi swf đang được biên dịch?
Câu trả lời liên quan đến việc đọc byte từ một tệp có vẻ khá không được giải thích với tôi. Có phải là một cách để có được thông tin này bằng cách sử dụng Reflection, chẳng hạn như Foobar.class.getTargetVersion(). –