2009-02-05 33 views
56

Tôi có phụ thuộc thời gian chạy trên một số lọ bên ngoài mà tôi muốn "rejar" vào một cái bình. Các phụ thuộc bên ngoài này được lưu trữ trong một thư mục external_jars và tôi muốn không thể liệt kê tất cả chúng (tức là, không cần thay đổi các kịch bản xây dựng của tôi nếu các phụ thuộc của tôi thay đổi). Có suy nghĩ gì không?Làm cách nào để kết hợp nhiều lọ? Tốt hơn là sử dụng Ant

Google đã cho tôi một câu trả lời tốt về cách để làm điều này - nếu bạn không nhớ liệt kê ra mỗi lọ như một sự phụ thuộc:

http://markmail.org/message/zijbwm46maxzzoo5

đại khái, tôi muốn một cái gì đó dọc theo dòng những điều sau đây , mà sẽ kết hợp tất cả các lọ trong thư mục lib vào out.jar (với một số quy tắc ghi đè sane).

jar -combine -out out.jar -in lib/*.jar 

Trả lời

53

Chỉ cần sử dụng zipgroupfileset với Ant Zip task

<zip destfile="out.jar"> 
    <zipgroupfileset dir="lib" includes="*.jar"/> 
</zip> 

này sẽ san bằng nội dung tất cả các thư viện jar bao gồm.

+0

Xin lỗi để chiếm đoạt câu hỏi của người khác. Tôi đã làm điều này nhưng bây giờ tôi có thể chạy ứng dụng của mình. Nó không thể tìm thấy một số lớp học. Tôi vẫn cần phải sepcifiy classpath như java -cp xxx -jar yyy.jar? – uriDium

+8

Nó làm cho tôi buồn rằng tất cả các câu trả lời làm việc dường như xoay quanh việc viết một tệp xây dựng kiến ​​và không ai trong số họ liên quan đến một lời gọi dòng lệnh đơn giản. –

+2

Nếu bạn làm điều đó trong kiến, sau đó bạn có thể bao gồm nó trong kịch bản xây dựng của bạn như là một mục tiêu, mà có lẽ là thời gian duy nhất mà bạn muốn này. –

23

Bạn có thể kiểm tra Jarjar:

http://code.google.com/p/jarjar/

+0

ba phút để hoàn thành câu trả lời = <3 stackoverflow – Jacob

+2

doh! Tôi nhìn vào điều này. Nó có rất nhiều chức năng nâng cao mà hóa ra tôi không cần. Những gì nó bị thiếu (ít nhất là từ tài liệu trên trang web) là một cách dễ dàng để làm điều gì đó như: jar -combine-out out.jar -in lib/*. Jar đó là những gì tôi cần – Jacob

+0

jar jar jar nó hoạt động –

9

Hãy thử giải nén JAR của bạn để thư mục marshalling đầu tiên:

<target name="combine-jars"> 
    <mkdir dir="${marshall.dir}"/> 
    <unzip dest="${marshall.dir}"> 
     <fileset dir="${external.jar.dir}"> 
      <include name="**/*.jar"/> 
     </fileset> 
    </unzip> 
    <jar destfile="${combined.jar}" basedir="${marshall.dir"}> 
    <delete dir="${marshall.dir}"/> 
</target> 

đâu ${marshall.dir} là một thư mục tạm thời, ${external.jar.dir} là nơi bạn giữ JAR và ${combined.jar} là JAR mục tiêu.

+2

Các ví dụ trước sẽ bao gồm các lọ khác - trong lọ. Cái này, mặt khác, trước hết sẽ làm chệch hướng tất cả các lọ thành các tệp * .class, và sau đó tạo một lọ từ tất cả các tệp lớp. – Yossale

1

Bạn đã cân nhắc sử dụng Maven hoặc một số hệ thống khác tự động quản lý phụ thuộc của bạn? Sau đó, bạn sẽ không cần phải xác định nơi mỗi thư viện được đặt, tên của chúng là gì và phụ thuộc transitive nào mà các phụ thuộc trực tiếp của bạn có. Bạn sẽ chỉ nói ở một nơi những gì phụ thuộc và phiên bản của nó, và hệ thống sẽ chăm sóc tải xuống các thư viện, cấu hình classpath và xây dựng dự án.

65

Câu trả lời của Vladimir là câu trả lời đúng, nhưng tôi cảm thấy rằng những gì ông gợi ý ngụ ý đóng gói tất cả các lọ trong một tệp out.jar lớn, sau đó được cấp cho tác vụ Ant Jar dưới dạng <zipfileset> hoặc thứ gì đó tương tự. Cách tiếp cận hai bước này là không cần thiết. Tôi không chắc liệu điều này có được kết nối với phiên bản Ant hay không, nhưng tôi có Ant 1.7.1 và nhiệm vụ <jar> của chúng tôi hiểu được <zipgroupfileset>, cho phép cung cấp trực tiếp tất cả nội dung của các bên thứ ba.

<jar destfile="MyApplication.jar"> 
    <zipgroupfileset dir="lib" includes="*.jar" /> 
    <!-- other options --> 
    <manifest> 
    <attribute name="Main-Class" value="Main.MainClass" /> 
    </manifest> 
</jar> 
0

Vâng, tôi không quá nhiều để lập trình - nhưng điều gì đó đơn giản hơn cho tôi ... nếu câu hỏi có nghĩa là - kết hợp các tệp jar vào một. Ofcourse, đây là hướng dẫn sử dụng, giải pháp bẩn. Tôi chỉ sửa chữa tất cả các tars ... và sau đó .. tạo một tập tin tar mới, bằng cách thêm tất cả các thư mục được tạo bởi untarring- vào tập tin tar mới. nó đã làm việc.

0

Maven hoặc các công cụ xây dựng khác không thể "quản lý" độ phân giải của nhiều phiên bản tệp lớp. Trong thực tế, Maven gây ra những vấn đề này ở nơi đầu tiên, thông qua bao gồm chuyển tiếp của tất cả các tập tin jar hạ lưu mà không được yêu cầu một cách rõ ràng bởi một dự án.

Giả sử một nơi nào đó trong quá trình đóng cửa dự án (tất cả thư viện và mô-đun được dự án yêu cầu và tất cả các dự án phụ thuộc của nó, đệ quy) có hai phiên bản của tệp lớp.Làm thế nào Maven có thể biết cái nào là cái 'đúng'? cái nào được người lập trình dự định? Không thể vì thông tin này đã bị mất khi các phụ thuộc rõ ràng bị vứt bỏ để ủng hộ những người chuyển tiếp (để lưu nhập XML).

+0

http://stackoverflow.com/questions/816858/maven-remove-a-single- transitive-dependency giải thích cách loại trừ sự phụ thuộc chuyển tiếp. –

2

Đây là giải pháp của tôi:

<target name="-post-jar"> 
    <echo>Packaging ${application.title} into a single JAR</echo> 

    <jar destfile="${basedir}${file.separator}${dist.dir}${file.separator}_${ant.project.name}_.jar"> 
     <zipgroupfileset dir="${basedir}${file.separator}${dist.dir}" includes="${ant.project.name}.jar"/> 
     <zipgroupfileset dir="${basedir}${file.separator}${dist.dir}${file.separator}lib" includes="*.jar"/> 
     <manifest> 
      <attribute name="Main-Class" value="${main.class}"/> 
     </manifest> 
    </jar> 
</target> 
+1

Cách đặt giá trị $ {basedir} $ {file.separator} – Mubasher

+0

@Mubasher: $ {basedir} và $ {file.separator} được cung cấp mặc định bởi Ant, bạn không cần phải đặt chúng. Bạn có thể thử điều này trong một file build.xml đơn giản: $ {basedir} $ {} file.separator

4

Nếu sử dụng maven, tại sao không? :) Chỉ cần sử dụng plugin maven-shade, hoạt động như một sự quyến rũ!

<project> 
    ... 
    <build> 
    <plugins> 
     <plugin> 
     <groupId>org.apache.maven.plugins</groupId> 
     <artifactId>maven-shade-plugin</artifactId> 
     <version>1.5</version> 
     <executions> 
      <execution> 
      <phase>package</phase> 
      <goals> 
       <goal>shade</goal> 
      </goals> 
      <configuration> 
       <transformers> 
       <transformer implementation="org.apache.maven.plugins.shade.resource.ManifestResourceTransformer"> 
        <mainClass>com.YOUR_COMPANY.YOUR_MAIN_CLASS</mainClass> 
       </transformer> 
       </transformers> 
      </configuration> 
      </execution> 
     </executions> 
     </plugin> 
    </plugins> 
    </build> 
    ... 
</project> 
1

Câu hỏi được trả lời đúng. Tôi muốn đề cập đến một công cụ tôi thấy hữu ích - One-Jar. One-Jar xử lý tài nguyên một cách rõ ràng hơn (bằng cách giữ tất cả chúng). Đây hữu ích hơn nếu mã cần XML process MANIFEST files.

mẫu sao chép từ trang web ..

<import file="one-jar-ant-task.xml"/> 

    <target name="hello" depends="init"> 
     <!-- Build lib.jar --> 
     <javac destdir="${classes.dir}/lib"> 
      <src path="${lib.dir}" /> 
     </javac> 
     <jar destfile="${build.dir}/lib.jar" > 
      <fileset dir="${classes.dir}/lib"/> 
     </jar> 
     <!-- Build classes for main.jar --> 
     <javac destdir="${classes.dir}/src"> 
      <src path="${src.dir}" /> 
      <classpath path="${build.dir}/lib.jar"/> 
     </javac> 
     <!-- Construct the One-JAR file --> 
     <one-jar destfile="hello.jar" manifest="hello.mf"> 
      <main> 
       <!-- Construct main.jar from classes and source code --> 
       <fileset dir="${classes.dir}/src"/> 
      </main> 
      <lib> 
       <fileset file="${build.dir}/lib.jar" /> 
      </lib> 
     </one-jar> 
     <echo> 
      Now you can run the Hello One-JAR example using 
      $ java -jar hello.jar 
     </echo> 

    </target> 
0

Nếu bạn đang xây dựng với kiến ​​(Tôi đang sử dụng kiến ​​từ nhật thực), bạn chỉ có thể thêm các tập tin jar thêm bằng cách nói với kiến ​​để thêm chúng ... Không nhất thiết phải là phương pháp tốt nhất nếu bạn có một dự án được duy trì bởi nhiều người nhưng nó hoạt động cho dự án một người và rất dễ dàng.

ví dụ mục tiêu của tôi được xây dựng file .jar là:

<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> 

Tôi chỉ cần thêm một dòng để làm cho nó:

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

nơi

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

là dir với các lọ bên ngoài. Và đó là ... Bạn cũng có thể thêm nhiều thẻ zipgroupfileset.

Các vấn đề liên quan