เป็นไปได้หรือไม่ที่จะระบุ Java classpath
ที่มีไฟล์ JAR ที่อยู่ในไฟล์ JAR อื่น
เป็นไปได้หรือไม่ที่จะระบุ Java classpath
ที่มีไฟล์ JAR ที่อยู่ในไฟล์ JAR อื่น
คำตอบ:
หากคุณกำลังพยายามสร้าง jar เดียวที่มีแอปพลิเคชันของคุณและไลบรารีที่จำเป็นมีสองวิธี (ที่ฉันรู้) ในการทำเช่นนั้น อย่างแรกคือOne-Jarซึ่งใช้ classloader พิเศษเพื่อให้สามารถซ้อนไหได้ อย่างที่สองคือUberJar (หรือShade ) ซึ่งจะระเบิดไลบรารีที่รวมอยู่และทำให้คลาสทั้งหมดอยู่ในโถระดับบนสุด
ฉันควรพูดถึงว่า UberJar และ Shade เป็นปลั๊กอินสำหรับ Maven1 และ Maven2 ตามลำดับ ดังที่ได้กล่าวไว้ด้านล่างคุณยังสามารถใช้ปลั๊กอินแอสเซมบลี (ซึ่งในความเป็นจริงมีประสิทธิภาพมากกว่ามาก แต่จะกำหนดค่าได้ยากกว่ามาก)
คุณไม่ต้องการใช้โซลูชัน "ระเบิดเนื้อหา JAR" เหล่านั้น พวกเขาทำให้ยากต่อการมองเห็นสิ่งต่างๆ (เนื่องจากทุกอย่างระเบิดในระดับเดียวกัน) นอกจากนี้อาจมีข้อขัดแย้งในการตั้งชื่อ (ไม่ควรเกิดขึ้นหากผู้คนใช้แพ็กเกจที่เหมาะสม แต่คุณไม่สามารถควบคุมได้ตลอดเวลา)
คุณลักษณะที่คุณต้องการคือหนึ่งใน25 อันดับแรกของ Sun RFE : RFE 4648386ซึ่ง Sun ในภูมิปัญญาที่ไม่มีที่สิ้นสุดของพวกเขาได้กำหนดให้มีความสำคัญต่ำ เราได้ แต่หวังว่าอาทิตย์จะตื่น ...
ในขณะเดียวกันการแก้ปัญหาที่ดีที่สุดที่ฉันได้เจอ (ซึ่งผมหวังว่าดวงอาทิตย์จะคัดลอกใน JDK) คือการใช้รถตักดินชั้นเองJarClassLoader
activation.jar
).
หลังจากการวิจัยบางส่วนฉันได้พบวิธีการที่ไม่ต้องใช้ maven หรือส่วนขยาย / โปรแกรมของบุคคลที่สาม
คุณสามารถใช้ "Class-Path" ในไฟล์ Manifest ของคุณ
ตัวอย่างเช่น:
สร้างไฟล์ Manifest.MF
Manifest-Version: 1.0
Created-By: Bundle
Class-Path: ./custom_lib.jar
Main-Class: YourMainClass
รวบรวมชั้นเรียนทั้งหมดของคุณและเรียกใช้ jar cfm Testing.jar MANIFEST.MF *.class custom_lib.jar
c
ย่อมาจาก create archive
f
บ่งชี้ว่าคุณต้องการระบุไฟล์
v
สำหรับอินพุต verbose
m
หมายความว่าเราจะส่งไฟล์ manifest ที่กำหนดเอง
ตรวจสอบให้แน่ใจว่าคุณรวม lib ไว้ในแพ็คเกจ jar คุณควรจะสามารถเรียกใช้ jar ด้วยวิธีปกติ
อ้างอิงจาก: http://www.ibm.com/developerworks/library/j-5things6/
ข้อมูลอื่น ๆ ทั้งหมดที่คุณต้องการเกี่ยวกับ class-path คุณพบได้ที่นี่
custom_lib.jar
ออกไปโถจะไม่สามารถใช้งานได้อีกต่อไป :(
ใช้แท็กzipgroupfileset (ใช้แอตทริบิวต์เดียวกันกับแท็กfileset ) มันจะแตกไฟล์ทั้งหมดในไดเร็กทอรีและเพิ่มลงในไฟล์เก็บถาวรใหม่ของคุณ ข้อมูลเพิ่มเติม: http://ant.apache.org/manual/Tasks/zip.html
นี่เป็นวิธีที่มีประโยชน์มากในการแก้ไขปัญหา jar-in-a-jar - ฉันรู้เพราะฉันได้ googled คำถาม StackOverflow ที่แน่นอนนี้ในขณะที่พยายามคิดว่าจะทำอย่างไร หากคุณต้องการบรรจุ jar หรือโฟลเดอร์ jar ไว้ใน jar ที่สร้างขึ้นด้วย Ant ให้ลืมเกี่ยวกับ classpath หรือสิ่งที่ปลั๊กอินของบุคคลที่สามทั้งหมดที่คุณต้องทำก็คือ (ใน Ant):
<jar destfile="your.jar" basedir="java/dir">
...
<zipgroupfileset dir="dir/of/jars" />
</jar>
หากคุณกำลังสร้างด้วย ant (ฉันใช้ ant จาก eclipse) คุณสามารถเพิ่มไฟล์ jar พิเศษโดยบอกให้ ant เพิ่มได้ ... ไม่จำเป็นต้องเป็นวิธีที่ดีที่สุดหากคุณมีโครงการที่ดูแลโดยคนหลายคน แต่ใช้ได้ผล สำหรับโครงการคนเดียวและเป็นเรื่องง่าย
ตัวอย่างเช่นเป้าหมายของฉันที่สร้างไฟล์. jar คือ:
<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>
ฉันเพิ่งเพิ่มหนึ่งบรรทัดเพื่อให้:
<jar ....">
<zipgroupfileset dir="${external-lib-dir}" includes="*.jar"/>
<manifest>
................................
</manifest>
</jar>
ที่ไหน
<property name="external-lib-dir"
value="C:\...\eclipseWorkspace\Filter\external\...\lib" />
เป็นผบ. กับไหภายนอก แค่นี้แหละ ...
ไม่ใช่โดยไม่ต้องเขียนตัวโหลดคลาสของคุณเอง คุณสามารถเพิ่มไหลงในคลาสพา ธ ของโถได้ แต่ต้องอยู่ร่วมกันไม่ได้บรรจุอยู่ในโถหลัก
คุณต้องสร้างคลาสโหลดเดอร์แบบกำหนดเองเพื่อทำสิ่งนี้หรือไลบรารีของบุคคลที่สามที่รองรับสิ่งนี้ ทางออกที่ดีที่สุดของคุณคือดึง jar ออกจากรันไทม์และเพิ่มลงใน classpath (หรือเพิ่มลงใน classpath แล้ว)
ฉันใช้ Maven สำหรับ Java ของฉันสร้างซึ่งมีปลั๊กอินที่เรียกว่าMaven ประกอบปลั๊กอิน
มันทำในสิ่งที่คุณถาม แต่ก็เหมือนกับคำแนะนำอื่น ๆ ที่อธิบายไว้ - โดยพื้นฐานแล้วจะระเบิดขวดที่ขึ้นอยู่กับทั้งหมดและรวมเข้าไว้ในโถเดียว
หากคุณมี eclpise IDE คุณเพียงแค่ต้องส่งออก JAR ของคุณและเลือก "Package Required libraries into created JAR" eclipse จะเพิ่ม JAR ที่ต้องการโดยอัตโนมัติลงใน JAR ที่สร้างขึ้นรวมทั้งสร้างตัวโหลดคลาสแบบกำหนดเองของ eclipse ที่โหลด JAR เหล่านี้โดยอัตโนมัติ
ฉันกำลังจะแนะนำให้แตกไฟล์ทั้งหมดในระดับเดียวกันจากนั้นให้สร้าง jar จากผลลัพธ์เนื่องจากระบบแพ็กเกจควรแยกออกจากกันอย่างเรียบร้อย นั่นจะเป็นวิธีการด้วยตนเองฉันคิดว่าเครื่องมือที่สตีฟระบุจะทำอย่างนั้นได้ดี
มีวิธีที่ง่ายมากหากคุณใช้ Eclipse
ส่งออกโครงการของคุณเป็นไฟล์ Jar "Runnable" (คลิกขวาที่โฟลเดอร์โครงการจากภายใน Eclipse เลือก "ส่งออก ... ") เมื่อคุณกำหนดการตั้งค่าการส่งออกโปรดเลือก "แยกไลบรารีที่ต้องการลงใน Jar ที่สร้างขึ้น" โปรดทราบว่าเลือก "Extract ... " ไม่ใช่ "Package required libraries ... "
นอกจากนี้ : คุณต้องเลือกการกำหนดค่าการรันในการตั้งค่าการส่งออกของคุณ ดังนั้นคุณสามารถสร้าง main () ที่ว่างเปล่าในบางคลาสและใช้สำหรับการกำหนดค่าการรันของคุณได้
อย่างไรก็ตามไม่รับประกันว่าจะทำงานได้ 100% เนื่องจากคุณจะสังเกตเห็นข้อความป๊อปอัปแจ้งให้คุณตรวจสอบสิทธิ์การใช้งานของไฟล์ Jar ที่คุณรวมไว้และบางอย่างเกี่ยวกับการไม่คัดลอกไฟล์ลายเซ็น อย่างไรก็ตามฉันทำแบบนี้มาหลายปีแล้วและไม่เคยพบปัญหา
การแยกลงใน Uber-dir ใช้งานได้สำหรับฉันเพราะเราทุกคนควรใช้ root: \ java และมีรหัสร้านค้าในแพ็คเกจที่มีการกำหนดเวอร์ชัน ได้แก่ ca.tecreations-1.0.0 การเซ็นชื่อเป็นสิ่งที่ถูกต้องเนื่องจากขวดโหลไม่เสียหายจากตำแหน่งที่ดาวน์โหลด ลายเซ็นของบุคคลที่สามเหมือนเดิมแยกเป็น c: \ java มีผบ. โครงการของฉัน เรียกใช้จากตัวเรียกใช้งานดังนั้น java -cp c: \ java Launcher