Bagaimana saya tahu versi Java compiler apa yang digunakan untuk membuat toples? Saya punya file jar, dan itu bisa dibangun di salah satu dari tiga JDK. Kami perlu tahu persis yang mana, sehingga kami dapat memeriksa kompatibilitasnya. Apakah versi kompiler tertanam di suatu tempat di file kelas atau toples?
212
Created-By: 1.7.0_13 (Oracle Corporation)
Created-By: Apache Maven
danBuild-Jdk: 1.8.0_25
Jawaban:
Anda tidak bisa membedakannya dari file JAR itu sendiri.
Unduh hex editor dan buka salah satu file kelas di dalam JAR dan lihat byte offset 4 hingga 7. Informasi versi sudah ada di dalamnya.
http://en.wikipedia.org/wiki/Java_class_file
Catatan: Seperti disebutkan dalam komentar di bawah,
sumber
A
jar
hanyalah sebuah wadah. Ini adalah arsip file ā latar
. Meskipunjar
mungkin memiliki informasi menarik yang terkandung dalam hierarki META-INF itu, ia tidak memiliki kewajiban untuk menentukan vintage kelas di dalamnya. Untuk itu, seseorang harus memeriksaclass
file - file di dalamnya.Seperti yang disebutkan oleh Peter Lawrey dalam komentar terhadap pertanyaan awal, Anda tidak dapat selalu mengetahui rilis JDK mana yang membangun
class
file yang diberikan , tetapi Anda dapat mengetahui versi kelas kode byte dariclass
file yang terkandung dalam ajar
.Ya, ini agak menyebalkan, tetapi langkah pertama adalah mengekstraksi satu atau lebih kelas dari
jar
. Sebagai contoh:Di Linux, Mac OS X atau Windows dengan Cygwin terinstal, perintah file (1) tahu versi kelasnya.
Atau sebagai alternatif, menggunakan
javap
dari JDK sebagai @ jikes.thunderbolt dengan tepat menunjukkan:Dan jika Anda terdegradasi ke
Windows
lingkungan tanpa salah satufile
ataugrep
FWIW, saya akan setuju bahwa
javap
akan memberi tahu lebih banyak tentangclass
file yang diberikan daripada pertanyaan asli yang diajukan.Bagaimanapun, versi kelas yang berbeda, misalnya:
Nomor utama versi kelas sesuai dengan versi Java JDK berikut:
sumber
file
tidak menunjukkan itu, tapi saya bisa memeriksa kelas manual dengan perintah ini:hexdump ~/bin/classes/P.class | head
. Lihat saja byte kedelapan dan konversikan ke desimal.JAR=something.jar ; unzip -p $JAR `unzip -l $JAR | grep '\.class$' | head -1` | file -
file file.class
(5.22-1) pada awalnya tidak menunjukkan target kelas java: "file.class: [architecture = 6909806] [architecture = 6845039]". Namunfile -k file.class
melakukan itu: "file.class: [architecture = 6909806] [architecture = 6845039] menyusun data kelas Java, versi 50.0 (Java 1.6)". Sepertinyafile
hanya ada pertandingan pertama di magicfiles db tanpa-k
.Berikut adalah cara Java untuk menemukan informasi ini.
Windows:
javap -v <class> | findstr major
Unix:
javap -v <class> | grep major
Sebagai contoh:
> javap -v Application | findstr major major version: 51
sumber
<class>
parameter untuk?Application.class
file dan ternyata dikompilasi untuk Java 7 (major version: 51
).javac
versi yang mengkompilasi file .class, yang diminta.Tidak perlu membongkar JAR (jika salah satu nama kelas diketahui atau dicari misalnya menggunakan 7zip), maka pada Windows berikut ini sudah cukup:
sumber
javac
versi yang mengkompilasi file .class, yang diminta.Java compiler (
javac
) tidak membuat toples, ia menerjemahkan file Java ke file kelas. Alat Jar (jar
) membuat toples yang sebenarnya. Jika tidak ada manifes khusus yang ditentukan, manifes default akan menentukan versi JDK mana yang digunakan untuk membuat toples.sumber
Karena saya perlu menganalisis guci gemuk saya tertarik pada versi setiap kelas individu dalam file jar. Karenanya saya mengambil pendekatan Joe Liversedge https://stackoverflow.com/a/27877215/1497139 dan menggabungkannya dengan https://stackoverflow.com/a/3313839/1497139 tabel versi nomor kelas David untuk membuat skrip bash jarv untuk menampilkan versi semua file kelas dalam file jar.
pemakaian
Contoh
Bash script jarv
sumber
head -1
dapat digunakan bersamaan dengan skrip: biasanya, cukup untuk melihat versi kelas pertama dalam file jar.Anda dapat menemukan versi kompiler Java dari file .class menggunakan Hex Editor.
Langkah 1: Ekstrak file .class dari file jar menggunakan zip extractor
langkah 2: buka file .class dengan hex editor. (Saya telah menggunakan notepad ++ hex editor plugin. Plugin ini membaca file sebagai biner dan menunjukkannya dalam hex) Anda dapat melihat di bawah ini.
Indeks 6 dan 7 memberikan nomor versi utama dari format file kelas yang digunakan. https://en.wikipedia.org/wiki/Java_class_file
Java SE 11 = 55 (0x37 hex)
Java SE 10 = 54 (hex 0x36)
Java SE 9 = 53 (hex 0x35)
Java SE 8 = 52 (hex 0x34),
Java SE 7 = 51 (0x33 hex),
Java SE 6.0 = 50 (hex 0x32),
Java SE 5.0 = 49 (0x31 hex),
JDK 1.4 = 48 (hex 0x30),
JDK 1.3 = 47 (hex 0x2F),
JDK 1.2 = 46 (hex 0x2E),
JDK 1.1 = 45 (hex 0x2D).
sumber
Anda dapat memberi tahu versi biner Java dengan memeriksa 8 byte pertama (atau menggunakan aplikasi yang bisa).
Kompiler itu sendiri, setahu saya, tidak memasukkan tanda tangan pengenal apa pun. Saya tidak dapat menemukan hal seperti itu dalam format file spesifikasi kelas VM .
sumber
javac
versi yang mengkompilasi file .class, yang diminta.The kode diposting oleh Owen dapat memberitahu Anda informasi yang disebutkan oleh sejumlah jawaban lain di sini:
Lihat juga ini dan situs ini . Saya akhirnya memodifikasi kode Produk Pikiran dengan cepat untuk memeriksa untuk apa masing-masing dependensi saya dikompilasi.
sumber
javac
versi yang mengkompilasi file .class, yang diminta.Pengembang dan administrator yang menjalankan Bash mungkin menemukan fungsi kenyamanan ini bermanfaat:
Anda dapat menempelkannya untuk penggunaan satu kali atau menambahkannya ke
~/.bash_aliases
atau~/.bashrc
. Hasilnya terlihat seperti:dan
EDIT Seperti yang ditunjukkan oleh jackrabbit , Anda tidak dapat 100% mengandalkan manifes untuk memberi tahu Anda sesuatu yang bermanfaat. Jika ya, maka Anda bisa mengeluarkannya di shell UNIX favorit Anda dengan
unzip
:.Jar ini tidak memiliki apa pun yang berguna dalam manifes tentang kelas yang ada.
sumber
javac
versi yang mengkompilasi file .class, yang diminta.One liner (Linux)
unzip -p mylib.jar META-INF/MANIFEST.MF
Ini mencetak konten
MANIFEST.MF
file ke stdout (mudah-mudahan ada satu di file jar Anda :)Bergantung pada apa yang membangun paket Anda, Anda akan menemukan versi
Created-By
atauBuild-Jdk
kunci JDK .sumber
MANIFEST.MF
, serta tidak ada kewajiban untuk nilai-nilai yang benar (Ya, saya pernah mengalami di.jar
mana nilainya palsu).javac
versi yang mengkompilasi file .class, yang diminta.Setiap file kelas memiliki nomor versi yang disematkan untuk level kode byte yang digunakan JVM untuk melihat apakah itu suka potongan kode byte tertentu atau tidak. Ini adalah 48 untuk Java 1.4, 49 untuk Java 1.5 dan 50 untuk Java 6.
Ada banyak kompiler yang dapat menghasilkan kode byte di setiap level, javac menggunakan opsi "-target" untuk menunjukkan level kode byte mana yang akan dihasilkan, dan Java 6 javac dapat menghasilkan kode byte setidaknya 1,4, 1,5 dan 6. Saya tidak percaya bahwa kompiler memasukkan apa pun yang dapat mengidentifikasi kompiler itu sendiri yang saya pikir Anda minta. Kompiler Eclipse juga semakin banyak digunakan, karena ini adalah satu toples yang dapat dijalankan dengan JRE saja.
Dalam file jar biasanya ada banyak kelas, dan masing-masingnya independen, jadi Anda perlu menyelidiki semua kelas di jar untuk memastikan tentang karakteristik konten.
sumber
Menindaklanjuti jawaban @ David J. Liszewski, saya menjalankan perintah berikut untuk mengekstrak manifes file jar di Ubuntu:
sumber
unzip -p LiceneSearch.jar META-INF/MANIFEST.MF
javac
versi yang mengkompilasi file .class, yang diminta.Banyak kali, Anda mungkin melihat file jar keseluruhan, atau file perang yang berisi banyak file jar selain diri mereka sendiri.
Karena saya tidak ingin memeriksa setiap kelas dengan tangan, saya menulis program java untuk melakukannya:
https://github.com/Nthalk/WhatJDK
Meskipun ini tidak mengatakan apa yang dikompilasi dengan kelas, itu menentukan apa JDK akan dapat memuat kelas, yang mungkin adalah apa yang Anda ingin mulai dengan.
sumber
Untuk memperluas jawaban Jonathon Faust dan McDowell : Jika Anda menggunakan sistem berbasis * nix, Anda dapat menggunakan
od
(salah satu program Unix 1 yang paling awal yang seharusnya tersedia secara praktis di mana saja) untuk meminta.class
file pada tingkat biner:Ini akan menampilkan nilai integer yang sudah dikenal, misalnya
50
untukJava 5
,51
untuk ,Java 6
dan seterusnya.1 Kutipan dari https://en.wikipedia.org/wiki/Od_(Unix)
sumber
javac
versi yang mengkompilasi file .class, yang diminta.Saya juga menulis skrip bash saya sendiri untuk membuang versi Java yang diperlukan oleh semua stoples yang dilewati di baris perintah ... Tambang saya agak kasar, tetapi bekerja untuk saya ;-)
contoh penggunaan
jar_dump_version_of_jvm_required.sh
sumber
Anda dapat dengan mudah melakukan ini di baris perintah menggunakan proses berikut:
Jika Anda tahu salah satu nama kelas dalam toples, Anda dapat menggunakan perintah berikut:
contoh:
Output:
Referensi cepat :
sumber
Anda memeriksa di file Manifest toples:
Manifest-Version: 1.0 Created-By: 1.6.0 (IBM Corporation)
sumber
Di Windows lakukan hal berikut:
Sekarang Eclipse akan menampilkan versi utama dan minor yang tepat.
sumber
Saya membuat skrip bash kecil (di github) berdasarkan saran Davids menggunakan
file
perintahsumber