2009-02-19 34 views
5

Tôi đã xây dựng một ứng dụng Java độc lập có một loạt các phụ thuộc (các thư viện Apache Commons, vv) cũng như một sự phụ thuộc vào khung công tác Spring. phụ thuộc.Đóng gói và chạy một ứng dụng Java với các phụ thuộc mùa xuân

Tôi đã xây dựng nó trong Eclipse, nơi nó chạy tốt. Bây giờ tôi cần phải triển khai nó để sản xuất và vì vậy tôi đang cố gắng tìm ra cách tốt nhất để gói nó với tất cả các phụ thuộc và cũng làm thế nào để thậm chí gọi điều (nó sẽ được gọi từ dòng lệnh).

Cách bạo lực sẽ xuất dự án của tôi làm bình, tìm tất cả các lọ phụ thuộc (và phụ thuộc của chúng!), Sao chép chúng vào một thư mục chung, viết kịch bản lệnh bao gồm mọi tập trên đường dẫn lớp và chạy nó. Rõ ràng là có vẻ ngu ngốc và tẻ nhạt.

Tôi có nên sử dụng Ant, Maven không? Tôi có nên gói tất cả các lọ phụ thuộc vào một tập tin lớn không? Bất kỳ lời khuyên về việc xử lý này sẽ là hữu ích.

Trả lời

4

Triển khai Java vẫn ngu ngốc và tẻ nhạt trong năm 2009. Vì vậy, tùy chọn thông thường là viết tập lệnh nhỏ này. Nếu bạn đặt tất cả các tệp JAR của mình vào một thư mục (ví dụ: lib\), bạn có thể sử dụng tập lệnh chung để tạo đường dẫn lớp tự động (xem this blog entry). Tôi đề nghị thêm cd /d %~dp0 vào đầu cd vào thư mục của tập lệnh.

Maven 2 có plugin có thể lắp ráp ứng dụng của bạn trong một "siêu JAR" (mvn assembly:assembly). Điều này hoạt động trừ khi bạn sử dụng trình điều khiển JCC của DB2 (chứa các gói "COM.ibm. " được chuyển đổi thành com.ibm. -> ClassNotFoundException).

Giải pháp cuối cùng, nếu bạn đã có tệp build.xml ANT hoạt động, hãy giải nén tất cả các JAR phụ thuộc và tự tạo một "siêu JAR".

1

Chúng tôi nhận thấy rằng giải pháp tốt nhất cho quản lý và đóng gói phụ thuộc là sử dụng Maven với plugin Assembly. Điều này cung cấp một phương tiện rất thanh lịch để đóng gói các dự án của bạn, cùng với tất cả các phụ thuộc thời gian chạy và các kịch bản hỗ trợ vào một bản phân phối nhị phân. Một trong những lợi thế lớn nhất của việc sử dụng các assembly là có thể chia các dự án của bạn thành các thành phần riêng biệt theo sự cần thiết. Nếu bạn đang sử dụng Spring Integration của nó khá phổ biến, bạn sẽ có các thành phần riêng biệt được chia thành nhiều máy. Plugin lắp ráp cho phép bạn định cấu hình cho yêu cầu của mình.

0

Bạn có thể sử dụng trình chạy đặt đường dẫn lớp chính xác. Sau đó, bạn sẽ có nhiều linh hoạt hơn để đóng gói các JAR của bạn. Bạn có thể dễ dàng đặt tất cả chúng vào một thư mục, đó là sạch hơn nhiều so với việc tạo ra một "bastard" ueber jar ...

Một trong những trình khởi chạy như vậy là commons-launcher.

2

Với Ant bạn có thể làm một cái gì đó dọc theo sau:

  1. Nhóm tất cả phụ thuộc với nhau.
  2. Đóng gói tệp JAR bằng ứng dụng của bạn và nhúng tham chiếu đến các phụ thuộc trong tệp MANIFEST.MF với chỉ dẫn "Lớp-Đường dẫn", bên trong bình. Điều đó sẽ loại bỏ sự cần thiết phải xây dựng classpath khi khởi động.
  3. Ghép tất cả lại với nhau dưới dạng bản lưu trữ và phân phối nó. Cần đủ để chạy trực tiếp jar bằng "java -jar your.jar".

Để quản lý phụ thuộc của bạn, bạn có thể đi với Ivy.Giống như Maven, nó có thể truy xuất các phụ thuộc vào thời gian xây dựng từ bất kỳ kho lưu trữ nào bạn cấu hình, bao gồm kho lưu trữ Maven hoặc kho lưu trữ riêng của riêng bạn.

0

Chúng tôi đang sử dụng Maven 2 với plugin m2eclipse; hoạt động khá tốt. Plugin có chế độ xem biểu đồ phụ thuộc, sẽ hiển thị xung đột, v.v.

Bây giờ, nếu bạn muốn đóng gói tất cả các phụ thuộc vào một bình, bạn có thể xem Jar Jar Links (không đùa).

0

Rất nhiều mối quan tâm của bạn biến mất nếu bạn thực hiện tệp JAR của mình và thêm tệp kê khai bao gồm ClassPath. Bạn phải nén ZIP và các phụ thuộc của nó lại với nhau, thật không may, nhưng các vấn đề về CLASSPATH của bạn được xử lý.

Điều gì về việc tạo gói OSGi? Tôi chưa tự nhìn vào nó, nhưng nó được cho là thứ tiếp theo để đóng gói các ứng dụng Java. Nó được sử dụng trong các máy chủ ứng dụng như Máy chủ dm của Spring. Có lẽ nó cũng có thể giúp bạn.

0

Trong kịch bản xây dựng ANT của mình, tôi tạo tập lệnh khởi động * .bat và * .sh với danh sách các JAR được tạo động vào thời gian xây dựng dựa trên nội dung của thư mục lib của bản dựng.

Ví dụ, để tạo ra danh sách các lọ có dải phân cách thích hợp:

<path id="jar-classpath"> 
    <fileset dir="${build.war.dir}/WEB-INF/lib"> 
     <include name="**/*.jar" /> 
    </fileset> 
</path> 

<pathconvert refid="jar-classpath" targetos="unix" property="exec.classpath.unix"> 
     <map from="${build.war.dir}\WEB-INF\lib\" to="../lib/"/> 
</pathconvert> 

<pathconvert refid="jar-classpath" targetos="windows" property="exec.classpath.windows"> 
     <map from="${build.war.dir}\WEB-INF\lib\" to="../lib/"/> 
</pathconvert> 

Sau đó bạn có thể sử dụng các giá trị ${exec.classpath.unix}${exec.classpath.windows} trong kịch bản java gọi.

1

Tất cả tình yêu Maven này và không ai đề cập đến Ivy? Ôi trời ơi!

Vâng, đây là Ant Ivy và đây là comparison to Maven2. Hãy nhìn vào nó quá trước khi đi với hầu như tất cả mọi người là gợi ý.

0

Plugin maven-assembly có thể không phải là lựa chọn tốt nhất. Bạn nên có một cái nhìn tại-maven-plugin onejar, như mô tả ở đây:

http://blog.jayway.com/2009/03/22/executable-jar-with-onejar-maven-plugin/

Nó cho phép tất cả các lọ phụ thuộc của bạn ở lại lọ, và mã của bạn là trong lọ riêng của mình. Tất cả các lọ được đặt trong một cái lọ lớn hơn, được làm cho thực thi.

0

Bạn cũng có thể sử dụng Gradle và đây là cách bạn có thể làm điều đó có:

mainClassName = "my.App" 

task runnableJar(type: Jar, dependsOn: [':assemble']) { 
    from files(sourceSets.main.output.classesDir) 
    from files(sourceSets.main.output.resourcesDir) 
    from configurations.runtime.asFileTree.files.collect { zipTree(it) } 

    manifest { 
     attributes 'Main-Class': mainClassName 
    } 
} 
Các vấn đề liên quan