JAR dahilinde JAR dahil sınıf yolu


134

Başka classpathbir JAR dosyasında bulunan bir JAR dosyası içeren bir Java belirtmek mümkün müdür ?

Yanıtlar:


94

Uygulamanızı ve gerekli kitaplıklarını içeren tek bir kavanoz oluşturmaya çalışıyorsanız, bunu yapmanın iki yolu vardır (bildiğim). Birincisi , kavanozların yuvalanmasına izin vermek için özel bir sınıf yükleyici kullanan One-Jar . İkincisi, içerilen kütüphaneleri patlatan ve tüm sınıfları üst düzey kavanoza koyan UberJar (veya Shade ).

UberJar ve Shade'nin sırasıyla Maven1 ve Maven2 için eklentiler olduğunu da belirtmeliyim. Aşağıda belirtildiği gibi, montaj eklentisini de kullanabilirsiniz (gerçekte çok daha güçlü, ancak düzgün bir şekilde yapılandırılması çok daha zordur).


81
İşte buradayız, 5 yıl sonra. Bu hala doğru gibi görünüyor. Çok üzücü :(
T3rm1

3
Günümüzde bildiğim en iyi yol IntelliJ kavanoz yapısını kullanmak. Tüm sınıfları bağımlı kavanozlardan çıkarır ve onları bir kavanoza koyar.
enl8enmentnow

2
İmzalanması gereken BouncyCastle gibi JCE uygulamalarını kullandığınızda olduğu gibi bazı durumlarda mümkün değildir
debuti

1
@ BrainSlugs83 ... Ne yapmaya çalışıyorsun? One-Jar'un sınıf yükleyicisinin ve paketleyicisinin hala bir Jar (Java SE için) projelerine bir Kavanoz dahil etmenin cevabı olduğunu düşünüyorum. UberJar kullanmak Jar'nize sınıf dosyalarını ayıklayarak sorunu ortadan kaldırır.
Steve Moyer

1
UberJar bağlantısının oturum açma kimlik bilgilerine ihtiyacı var. Ardıl web sayfası var mı?
Thomas Weller

50

Bu "JAR içeriğini patlat" çözümlerini kullanmak istemezsiniz. Kesinlikle bir şeyler görmeyi zorlaştırıyorlar (çünkü her şey aynı seviyede patlıyor). Ayrıca, adlandırma çakışmaları olabilir (insanlar uygun paketleri kullanırsa olmamalıdır, ancak bunu her zaman kontrol edemezsiniz).

İstediğiniz özellik, en önemli 25 Sun RFE'sinden biri : Sun'ın sonsuz bilgeliğinde düşük öncelikli olarak belirlediği RFE 4648386 . Sadece Sun'ın uyanmasını umut edebiliriz ...

Bu arada, karşılaştığım en iyi çözüm (Sun'ın JDK'da kopyalamasını diliyorum) özel sınıf yükleyici JarClassLoader kullanmaktır .


4
Adlandırma çakışmaları, log4j yapılandırması ve lisans metinleri gibi şeylerle neredeyse gerçekleşir.
Michael Borgwardt

1
Ne yazık ki JarClassLoader GPLv3 / ticari, bu yüzden muhtemelen "güneş tarafından kopyalandı (şimdi oracle)" almayacak ve iç siyasi nüfuz ve bir şey satın almak için zaman yoksa ticari olarak kullanılamaz. Ancak geçerli dizindeki barf kavanozları kötü bir şey olduğunu kabul ediyorum.
Gus

Bu yanıttaki fikir için +1 (ancak cevabın kendisini + 1'lemeyeceğim): imzalı herhangi bir JAR dosyasını yeniden paketleyemezsiniz, bu nedenle bu teknik birçok durumda kullanılamaz (örneğin Java'nın activation.jar).
Christopher Schultz

31

Bazı araştırmalardan sonra maven veya herhangi bir 3. taraf uzantısı / programı gerektirmeyen bir yöntem buldum.

Manifest dosyanızda "Class-Path" kullanabilirsiniz.

Örneğin:

Manifest dosyası MANIFEST.MF oluştur

Manifest-Version: 1.0
Created-By: Bundle
Class-Path: ./custom_lib.jar
Main-Class: YourMainClass

Tüm sınıflarınızı derleyin ve çalıştırın jar cfm Testing.jar MANIFEST.MF *.class custom_lib.jar

carşiv oluştur anlamına gelir fdosya belirtmek istediğinizi belirtmek viçin ayrıntılı girdi mözel manifest dosyasını geçireceğimiz anlamına gelir

Lib paketini lib paketine eklediğinizden emin olun. Kavanozu normal şekilde çalıştırabilmelisiniz.

dayalı: http://www.ibm.com/developerworks/library/j-5things6/

sınıf yolu hakkında ihtiyacınız olan diğer tüm bilgileri burada bulabilirsiniz


19
Bu cevap vermez değil çalışır. oracle doc'den (yukarıdaki banana bağlı): "Class-Path başlığı yerel ağdaki JAR dosyalarını değil, sınıfları veya JAR dosyalarını işaret eder"
sebnukem

Bunun bir Android ayarında da kullanılıp kullanılamayacağı bilinen her şey.
Mostowski Collapse

2
Yürütülebilir kavanoz senaryosu için çalışır (test edilmiştir), ancak kitaplık kavanozuna bir kavanoz eklemek istediğinizde çalışmayabilir.
Cychih

5
Oh hayır çalışmıyor, taşındıktan custom_lib.jarsonra kavanoz artık idam edilemez :(
Cychih

Sınıf Yolunda birden çok kavanoz nasıl belirtilebilir?
Abhishek Tiwari

22

Zipgroupfileset etiketini kullanın ( dosya kümesi etiketiyle aynı nitelikleri kullanır ); dizindeki tüm dosyaları açar ve yeni arşiv dosyanıza ekler. Daha fazla bilgi: http://ant.apache.org/manual/Tasks/zip.html

Bu bir kavanoz kavanoza sorununu çözmek için çok yararlı bir yol - biliyorum çünkü ne yapacağımı anlamaya çalışırken bu tam StackOverflow soru googled. Ant ile inşa edilmiş bir kavanozunuza bir kavanoz veya kavanoz klasörü paketlemek istiyorsanız, tüm bu sınıf yolu veya üçüncü taraf eklenti şeylerini unutun, yapmanız gereken tek şey (Ant'de):

<jar destfile="your.jar" basedir="java/dir">
  ...
  <zipgroupfileset dir="dir/of/jars" />
</jar>

8

Eğer karınca ile inşa ediyorsanız (Tutulmadan karınca kullanıyorum), sadece karıncaya ekleyerek ekstra kavanoz dosyalarını ekleyebilirsiniz ... Birden fazla kişi tarafından tutulan bir projeniz varsa mutlaka en iyi yöntem değil ama işe yarıyor bir kişi projesi için ve kolaydır.

Örneğin .jar dosyasını oluşturan hedefim şuydu:

<jar destfile="${plugin.jar}" basedir="${plugin.build.dir}">
    <manifest>
        <attribute name="Author" value="ntg"/>
        ................................
        <attribute name="Plugin-Version" value="${version.entry.commit.revision}"/>
    </manifest>
</jar>

Bunu yapmak için sadece bir satır ekledim:

<jar ....">
    <zipgroupfileset dir="${external-lib-dir}" includes="*.jar"/>
    <manifest>
        ................................
    </manifest>
</jar>

nerede

<property name="external-lib-dir" 
          value="C:\...\eclipseWorkspace\Filter\external\...\lib" />

dış kavanozlara sahip dir. Ve bu kadar...


6

Kendi sınıf yükleyicinizi yazmadan olmaz. Kavanozun sınıfyoluna kavanoz ekleyebilirsiniz, ancak ana kavanozda bulunmayan, birlikte yerleştirilmelidirler.


2

Bunu yapmak için özel bir sınıf yükleyici veya bunu destekleyen bir üçüncü taraf kitaplığı oluşturmanız gerekir. En iyi seçeneğiniz kavanozu çalışma zamanından çıkarmak ve bunları sınıfyoluna eklemek (veya zaten sınıf yoluna eklemelerini sağlamak).


2

Javen derleme eklentisi adı verilen bir eklentiye sahip java sürümlerim için maven kullanıyorum .

Sorduğunuz şeyi yapar, ancak diğer önerilerin bazıları gibi - tüm bağımlı kavanozları patlatıp tek bir kavanoza tekrar birleştirin


Maven montaj eklentisi kullanmak oldukça acı verici ... UberJar ve Shade Maven1 ve Maven2 eklentileri (yukarıda bahsetmiş olmalıyım ve şimdi yapacağım bir gerçek)
Steve Moyer

2

Eclpise IDE'niz varsa, sadece JAR'ınızı dışa aktarmanız ve "Gerekli kütüphaneleri oluşturulan JAR'a paketlemeniz" yeterlidir. eclipse, gerekli JAR'ları oluşturulan JAR'a otomatik olarak ekleyecek ve bu JAR'ları otomatik olarak yükleyen bazı eclipse özel sınıf yükleyici üretecektir.


1

Tüm dosyaları aynı seviyede çıkarmanızı ve ardından sonuçtan bir kavanoz çıkarmayı önermek üzereydim, çünkü paket sistemi onları düzgün bir şekilde ayırmalıdır. El ile yol bu olurdu, Steve tarafından belirtilen araçları güzel yapacağını varsayalım.



1

Eclipse kullanıyorsanız çok kolay bir yol var.

Projenizi "Çalıştırılabilir" Jar dosyası olarak dışa aktarın (Eclipse içinden proje klasörünü sağ tıklayın, "Dışa aktar ..." seçeneğini seçin). Dışa aktarma ayarlarını yapılandırırken, "Gerekli kitaplıkları oluşturulan Jar'a çıkart" ı seçtiğinizden emin olun. Unutmayın, "Gerekli kütüphaneleri paketle ..." değil " Çıkar ..." seçeneğini belirleyin .

Ayrıca : Dışa aktarma ayarlarınızda bir çalıştırma yapılandırması seçmelisiniz. Böylece, bazı sınıflarda her zaman boş bir main () oluşturabilir ve bunu çalışma yapılandırmanız için kullanabilirsiniz.

Her neyse, zamanın% 100'ünün çalışması garanti edilmez - çünkü içerdiğiniz Jar dosyalarının lisanslarını ve imza dosyalarını kopyalamama hakkında bir şey kontrol ettiğinizden emin olmanızı söyleyen bir açılır mesaj göreceksiniz. Ancak, ben bu yapıyor yıllar ve bir sorunla karşılaştı hiç.


0

Hepimiz root: \ java kullanmalı ve sürüm kodlu paketlerde çıkış koduna sahip olmamız gerektiği için bir Uber-dir'e ayıklamak benim için çalışıyor. Yani ca.tecreations-1.0.0. İmzalama tamam çünkü kavanozlar indirildikleri yerden bozulmamış. 3. taraf imzaları bozulmamış, c: \ java dizinine ayıklayın. İşte benim proje dir. başlatıcıdan çalıştır java -cp c: \ java Launcher


Yani c: \ java \ jars içindeki kavanozlar. Kaynak, ikili dosyalar ve c: \ java içindeki kaynaklar. Yedekleri, özellikleri, anahtar deposu_gizli'yi hariç tutun. C: \ java paketini açın ve sınıf yolu oluşturma aracıyla çalıştırın, bu nedenle belki ca.tecreations.system.tools.SystemTool veya karşılaştırılabilir java sınıfı olabilir. Bunu yürütün.
Tim de Vries
Sitemizi kullandığınızda şunları okuyup anladığınızı kabul etmiş olursunuz: Çerez Politikası ve Gizlilik Politikası.
Licensed under cc by-sa 3.0 with attribution required.