Apakah ada cara untuk memasukkan semua jar file dalam sebuah direktori dalam classpath?
I'm mencoba java -classpath lib/*.jar:. saya.paket.Program
dan tidak dapat menemukan file kelas yang pasti di dalam toples itu. Apakah saya perlu untuk menambahkan masing-masing file jar ke classpath secara terpisah?
Menggunakan Java 6 atau yang lebih baru, classpath pilihan mendukung wildcard. Perhatikan hal berikut:
"
)*
, bukan *.jar
Windows
java -cp "Test.jar;lib/*" saya.paket.MainClass
Unix
java -cp "Tes.jar:lib/*" saya.paket.MainClass
Hal ini mirip dengan Windows, tetapi menggunakan :
bukan ;
. Jika anda tidak dapat menggunakan wildcard, bash
yang memungkinkan sintaks berikut (di mana lib
adalah direktori yang berisi semua Java file arsip):
java -cp $(echo lib/*.jar | tr ' ' ':')
(Perhatikan bahwa menggunakan classpath adalah tidak sesuai dengan jar
pilihan. Lihat juga: https://stackoverflow.com/questions/13018100/execute-jar-file-with-multiple-classpath-libraries-from-command-prompt)
Pengertian Wildcard
Dari Classpath dokumen:
Kelas jalan entri dapat mengandung nama dasar karakter wildcard
*
, yang dianggap setara untuk menentukan daftar semua file dalam direktori dengan ekstensi.jar
atau.JAR
. Misalnya, kelas jalan masukfoo/*
menetapkan semua file JAR di direktori bernama foo. Sebuah classpath masuk hanya terdiri dari*
mengembang untuk daftar semua jar file dalam direktori saat ini.kelas jalan masuk yang berisi
*
tidak akan cocok dengan file kelas. Untuk pertandingan kedua kelas dan JAR file dalam sebuah direktori tunggal foo, gunakan salahfoo;foo/*
ataufoo/*;foo
. Urutan yang dipilih menentukan apakah kelas dan sumber daya difoo
yang dimuat sebelum file JAR difoo
, atau sebaliknya.Subdirektori yang tidak dicari secara rekursif. Misalnya,
foo/*
terlihat untuk file JAR hanya difoo
, bukanfoo/bar
,foo/baz
, dll.urutan JAR file dalam direktori yang disebutkan di diperluas kelas jalan yang tidak ditentukan dan dapat bervariasi dari platform ke platform dan bahkan dari waktu ke waktu pada mesin yang sama. A dibangun dengan aplikasi tidak harus bergantung pada perangkat tertentu order. Jika urutan tertentu diperlukan maka file JAR dapat disebutkan secara eksplisit dalam kelas jalan.
Perluasan wildcard dilakukan lebih awal, sebelum doa dari program's metode utama, daripada terlambat, selama kelas-loading proses itu sendiri. Setiap elemen input kelas jalan yang berisi wildcard digantikan oleh (mungkin kosong) urutan elemen yang dihasilkan oleh enumerasi JAR file dalam direktori yang diberi nama. Untuk contoh, jika direktori
foo
berisia.jar
,b.jar
, danc.jar
, kemudian kelas jalanfoo/*
diperluas menjadifoo/a.jar;foo/b.jar;foo/c.jar
, dan string yang akan menjadi nilai sistem propertijawa.kelas.jalan
.
CLASSPATH
variabel lingkungan ini tidak diobati dengan cara yang berbeda dari- classpath
(atau-cp
) opsi baris perintah. Artinya, wildcard dihormati dalam semua kasus ini. Namun, kelas jalan wildcard tidak terhormat di Kelas-Jalan jar-nyata` header.
Catatan: karena bug yang dikenal dalam java 8, windows contoh harus menggunakan backslash sebelumnya entri dengan tanda asterisk: https://bugs.openjdk.java.net/browse/JDK-8131329
Di dalam windows ini bekerja:
java -cp "Test.jar;lib/*" my.package.MainClass
dan ini tidak bekerja:
java -cp "Test.jar;lib/*.jar" my.package.MainClass
perhatikan *.jar, *jadi wildcard harus digunakan sendiri**.
Di Linux, karya-karya berikut:
java -cp "Test.jar:lib/*" my.package.MainClass
Dengan pemisah titik, bukan tanda koma.
Kami mendapatkan sekitar masalah ini dengan mengerahkan utama file jar myapp.jar
yang berisi nyata (Terwujud.mf
) file menentukan classpath dengan lainnya yang diperlukan dalam botol, yang kemudian disebarkan di samping itu. Dalam hal ini, anda hanya perlu untuk menyatakan java -jar myapp.jar
ketika menjalankan kode.
Jadi jika anda menyebarkan utama jar
ke beberapa direktori, dan kemudian menempatkan tergantung guci menjadi lib
folder di bawahnya, nyata terlihat seperti:
Manifest-Version: 1.0
Implementation-Title: myapp
Implementation-Version: 1.0.1
Class-Path: lib/dep1.jar lib/dep2.jar
NB: ini adalah platform-independen - kita dapat menggunakan guci yang sama untuk peluncuran pada server UNIX atau Windows PC.
Solusi saya di Ubuntu 10.04 menggunakan java-matahari 1.6.0_24 memiliki semua botol dalam "lib" direktori:
java -cp .:lib/* saya.utama.Kelas
Jika ini gagal, berikut perintah yang harus bekerja (mencetak semua *.guci di lib direktori untuk classpath param)
java -cp $(untuk saya di lib/*.jar ; do echo -n $i: ; dilakukan). saya.utama.Kelas
Jawaban singkat: java -classpath lib/*:. saya.paket.Program
Oracle menyediakan dokumentasi menggunakan wildcard di classpaths di sini untuk Jawa 6 dan di sini untuk Jawa 7, di bawah judul bagian Pengertian kelas jalan wildcard. (Saat saya menulis ini, dua halaman berisi informasi yang sama.) Berikut ini's ikhtisar highlights:
Secara umum, untuk mencakup semua Botol dalam direktori tertentu, anda dapat menggunakan wildcard *
(tidak *.jar
).
Wildcard hanya pertandingan Guci, bukan file kelas; untuk mendapatkan semua kelas dalam sebuah direktori, hanya akhir classpath masuk pada direktori nama.
Dua pilihan di atas dapat dikombinasikan untuk mencakup semua BOTOL dan kelas file dalam sebuah direktori, dan biasa classpath didahulukan aturan yang berlaku. E. g. -cp /kelas;/botol/*
Wildcard akan tidak mencari Botol di subdirektori.
Di atas poin-poin yang benar jika anda menggunakan CLASSPATH
sistem properti atau -cp
atau -classpath
command line bendera. Namun, jika anda menggunakan Class-Path
JAR mewujudkan header (seperti yang mungkin anda lakukan dengan semut membangun file), wildcard akan tidak dihormati.
Yes, pertama saya link adalah salah satu yang sama yang diberikan di atas skor jawaban (yang saya tidak memiliki harapan untuk menyalip), tapi jawaban itu doesn't memberikan banyak penjelasan di luar link. Karena perilaku semacam itu adalah discouraged pada Stack Overflow hari ini, saya pikir saya'd memperluas di atasnya.
Windows:
lang-bash java -cp file.jar;dir/* saya.aplikasi.ClassName
Linux:
lang-bash java -cp file.jar:dir/* saya.aplikasi.ClassName
Mengingatkan:
;
:
Anda dapat mencoba java -Djava.ext.dirs=jarDirectory
http://docs.oracle.com/javase/6/docs/technotes/guides/extensions/spec.html
Direktori eksternal guci ketika menjalankan jawa
Benar:
java -classpath "lib/*:." my.package.Program
Salah:
java -classpath "lib/a*.jar:." my.package.Program
java -classpath "lib/a*:." my.package.Program
java -classpath "lib/*.jar:." my.package.Program
java -classpath lib/*:. my.package.Program
Jika anda benar-benar perlu untuk menentukan semua .jar file secara dinamis anda bisa menggunakan shell script, atau Apache Ant. Ada's commons proyek yang disebut Commons Launcher yang pada dasarnya memungkinkan anda menentukan anda skrip startup seperti semut membangun file (jika anda melihat apa yang saya maksud).
Kemudian, anda dapat menentukan sesuatu seperti:
<path id="base.class.path">
<pathelement path="${resources.dir}"/>
<Fileset dir="${extensions.dir}" includes="*.jar" />
<Fileset dir="${lib.dir}" includes="*.jar"/>
</path>
Dalam peluncuran membangun file, yang akan meluncurkan aplikasi anda dengan benar classpath.
Jika anda menggunakan Java 6, maka anda dapat menggunakan wildcard dalam classpath.
Sekarang adalah mungkin untuk menggunakan wildcard di classpath definisi:
javac -cp libs/* -verbose -encoding UTF-8 src/mypackage/*.java -d build/classes
Harap dicatat bahwa wildcard ekspansi rusak Java 7 pada Windows.
Check out ini StackOverflow issue untuk informasi lebih lanjut.
Pemecahan masalah adalah untuk menempatkan tanda titik koma setelah wildcard. java -cp "di suatu tempat/*;,"
Untuk siapa ini mei kepedulian,
Saya menemukan ini perilaku aneh pada Windows di bawah MSYS/MinGW shell.
Karya:
$ javac -cp '.;c:\Programs\COMSOL44\plugins\*' Reclaim.java
Doesn't bekerja:
$ javac -cp 'c:\Programs\COMSOL44\plugins\*' Reclaim.java
javac: invalid flag: c:\Programs\COMSOL44\plugins\com.comsol.aco_1.0.0.jar
Usage: javac <options> <source files>
use -help for a list of possible options
Saya cukup yakin bahwa wildcard tidak diperluas oleh shell, karena misalnya
$ echo './*'
./*
(Mencoba dengan program lain juga, daripada built-in echo
, dengan hasil yang sama.)
Saya percaya bahwa itu's javac
yang berusaha untuk memperluas, dan berperilaku berbeda apakah ada tanda titik koma dalam argumen atau tidak. Pertama, mungkin akan mencoba untuk memperluas semua argumen yang terlihat seperti jalan. Dan hanya kemudian akan mengurai mereka, dengan -cp
hanya mengambil berikut token. (Perhatikan bahwa com.comsol.aco_1.0.0.jar
kedua JAR di direktori tersebut.) Yang's semua menebak.
Ini adalah
$ javac -version
javac 1.7.0
Semua solusi di atas bekerja dengan baik jika anda mengembangkan dan menjalankan aplikasi Java di luar IDE seperti Eclipse atau Netbeans.
Jika anda berada di Windows 7 dan menggunakan IDE Eclipse untuk Pengembangan di pulau Jawa, anda mungkin mengalami masalah jika menggunakan Command Prompt untuk menjalankan file kelas yang dibangun di dalam Eclipse.
E. g. Kode sumber anda dalam Gerhana ini memiliki paket berikut hirarki: edu.sjsu.myapp.Main.java
Anda telah json.jar sebagai eksternal ketergantungan untuk Main.java
Ketika anda mencoba menjalankan Main.java dari dalam Eclipse, itu akan berjalan tanpa masalah apapun.
Tetapi ketika anda mencoba menjalankan ini menggunakan Command Prompt setelah kompilasi Main.java di Eclipse, itu akan menembak beberapa aneh kesalahan dengan mengatakan "ClassNotDef Error bla bla".
Saya asumsikan anda di direktori kode sumber anda !!
Gunakan sintaks berikut untuk menjalankannya dari command prompt:
javac -cp ".;json.jar" Main.java
java -cp ".;json.jar" edu.sjsu.myapp.Utama
[Don't lewatkan . di atas]
Hal ini karena anda telah menempatkan Main.java di dalam paket edu.sjsu.myapp dan java.exe akan mencari pola yang tepat.
Semoga membantu !!
Bentuk pendek: Jika anda utama adalah dalam botol, anda'll mungkin perlu tambahan '-jar pathTo/yourJar/YourJarsName.jar ' menyatakan secara eksplisit untuk membuatnya bekerja (meskipun 'YourJarsName.jar' pada classpath) (atau, menyatakan untuk menjawab pertanyaan awal yang diajukan 5 tahun yang lalu: anda don't perlu redeclare masing-masing botol secara eksplisit, tetapi tidak tampak, bahkan dengan java6 yang anda butuhkan untuk redeclare anda sendiri jar ...)
Bentuk Panjang: (Saya've ini dibuat eksplisit ke titik bahwa aku bahkan berharap penyusup ke jawa bisa menggunakan ini)
Seperti banyak di sini saya'm menggunakan eclipse untuk ekspor botol: (File>Ekspor-->'Runnable JAR File'). Ada tiga pilihan pada 'Perpustakaan penanganan' gerhana (Juno) menawarkan:
opt1: "Extract required libraries into generated JAR"
opt2: "Package required libraries into generated JAR"
opt3: "Copy required libraries into a sub-folder next to the generated JAR"
Biasanya saya'd gunakan opt2 (dan opt1 pasti melanggar), namun kode asli di salah satu stoples I'm menggunakan saya menemukan istirahat dengan handy "jarinjar" trik yang gerhana memanfaatkan ketika anda memilih pilihan itu. Bahkan setelah menyadari aku yang dibutuhkan opt3, dan kemudian menemukan ini StackOverflow masuk, masih butuh beberapa waktu untuk mencari tahu bagaimana untuk memulai utama saya di luar eclipse, jadi di sini's apa yang bekerja untuk saya, karena itu's berguna bagi orang lain...
Jika anda bernama jar anda: "fooBarTheJarFile.jar" dan semua diatur untuk ekspor ke dir: "/theFully/qualifiedPath/toYourChosenDir".
(yang berarti 'tujuan Ekspor' bidang akan membaca: '/theFully/qualifiedPath/toYourChosenDir/fooBarTheJarFile.jar' )
Setelah anda tekan finish, anda'll menemukan eclipse kemudian menempatkan semua perpustakaan menjadi sebuah folder yang bernama 'fooBarTheJarFile_lib' hanya yang mengekspor direktori, memberikan anda sesuatu seperti:
/theFully/qualifiedPath/toYourChosenDir/fooBarTheJarFile.jar
/theFully/qualifiedPath/toYourChosenDir/fooBarTheJarFile_lib/SomeOtherJar01.jar
/theFully/qualifiedPath/toYourChosenDir/fooBarTheJarFile_lib/SomeOtherJar02.jar
/theFully/qualifiedPath/toYourChosenDir/fooBarTheJarFile_lib/SomeOtherJar03.jar
/theFully/qualifiedPath/toYourChosenDir/fooBarTheJarFile_lib/SomeOtherJar04.jar
Anda kemudian dapat memulai dari mana saja di sistem anda dengan:
java -classpath "/theFully/qualifiedPath/toYourChosenDir/fooBarTheJarFile_lib/*" -jar /theFully/qualifiedPath/toYourChosenDir/fooBarTheJarFile.jar package.path_to.the_class_with.your_main.TheClassWithYourMain
(Untuk Jawa Pemula: 'paket.path_to.the_class_with.your_main' yang menyatakan paket-jalan yang kau'll menemukan di bagian atas 'TheClassWithYourMain.jawa' file yang berisi 'main(String[] args){...}' bahwa anda ingin menjalankan dari luar jawa)
Perangkap untuk melihat: adalah yang memiliki 'fooBarTheJarFile.jar' dalam daftar guci pada anda menyatakan classpath tidak cukup. Anda harus secara eksplisit menyatakan '-jar', dan redeclare lokasi yang jar.
misalnya istirahat ini:
java -classpath "/theFully/qualifiedPath/toYourChosenDir/fooBarTheJarFile.jar;/theFully/qualifiedPath/toYourChosenDir/fooBarTheJarFile_lib/*" somepackages.inside.yourJar.leadingToTheMain.TheClassWithYourMain
disajikan kembali dengan path relatif:
cd /theFully/qualifiedPath/toYourChosenDir/;
BREAKS: java -cp "fooBarTheJarFile_lib/*" package.path_to.the_class_with.your_main.TheClassWithYourMain
BREAKS: java -cp ".;fooBarTheJarFile_lib/*" package.path_to.the_class_with.your_main.TheClassWithYourMain
BREAKS: java -cp ".;fooBarTheJarFile_lib/*" -jar package.path_to.the_class_with.your_main.TheClassWithYourMain
WORKS: java -cp ".;fooBarTheJarFile_lib/*" -jar fooBarTheJarFile.jar package.path_to.the_class_with.your_main.TheClassWithYourMain
(menggunakan java versi "1.6.0_27"; via OpenJDK 64-Bit VM Server pada ubuntu 12.04)
Bukan solusi langsung untuk mampu mengatur /* untuk -cp tapi saya harap anda dapat menggunakan script berikut untuk meredakan situasi sedikit untuk dinamis kelas-jalan dan direktori lib.
libDir2Scan4jars="../test";cp=""; for j in `ls ${libDir2Scan4jars}/*.jar`; do if [ "$j" != "" ]; then cp=$cp:$j; fi; done; echo $cp| cut -c2-${#cp} > .tmpCP.tmp; export tmpCLASSPATH=`cat .tmpCP.tmp`; if [ "$tmpCLASSPATH" != "" ]; then echo .; echo "classpath set, you can now use ~> java -cp \$tmpCLASSPATH"; echo .; else echo .; echo "Error please check libDir2Scan4jars path"; echo .; fi;
Scripted untuk Linux, bisa mirip satu untuk windows juga. Jika direktori yang tepat diberikan sebagai masukan untuk "libDir2Scan4jars"; script ini akan memindai semua botol dan membuat classpath string dan ekspor ke env variabel "tmpCLASSPATH".
Anda perlu menambahkan mereka semua secara terpisah. Atau, jika anda benar-benar ** hanya perlu menentukan direktori, anda dapat unjar semuanya ke dalam satu dir dan menambahkan bahwa ke classpath anda. Saya don't merekomendasikan pendekatan ini namun karena anda berisiko aneh masalah dalam classpath versi dan unmanagability.