2013-05-31 64 views
8

Tôi có thư viện aa được đóng gói dưới dạng tệp jar thực thi và được thêm vào đường dẫn weblogic/tomcat, làm cách nào tôi có thể thực thi phương thức chính từ tệp jar khi máy chủ khởi động và đang tải các lớp từ tệp jar.tệp jar thực thi bootstrap trong classpath khi máy chủ bắt đầu

những gì tôi muốn là để có một số mã khởi tạo được thực thi trước tiên khi tệp jar được tải và máy chủ bắt đầu mà không có sự can thiệp của người dùng. Lưu ý: Tôi biết tôi có thể gói jar của tôi trong một tập tin chiến tranh, nhưng tôi có một số mã aspectj trong thư viện của tôi mà tôi muốn dệt tất cả các ứng dụng đang chạy trong jvm, khi tôi gói jar của tôi trong tập tin chiến tranh, các aspectj mã sẽ chỉ dệt vào các lớp trong tệp chiến tranh vì vậy tôi đã thêm tệp jar thư viện của mình vào đường dẫn lớp.

Xin cảm ơn trước.

Trả lời

2

Có lẽ điều đơn giản nhất cần làm là triển khai một servlet tầm thường trong tệp .war tham chiếu tệp .jar của bạn. Servlet có thể được cấu hình thành start up upon deployment/container start và sau đó có thể gọi lớp có chứa phương thức main() của bạn.

+0

Tôi có một số mã khía cạnh trong thư viện của mình mà tôi muốn dệt tất cả các ứng dụng đang chạy trong jvm, khi tôi nhóm jar vào tệp chiến tranh, mã aspectj sẽ chỉ dệt vào các lớp trong tệp chiến tranh. – Sammy

+0

Đoán phương thức này sẽ không hoạt động, vì nó không thực hiện các lớp hoặc lớp toàn cục trong các tệp WAR khác. Xin vui lòng xem giải pháp của tôi dưới đây nếu nó phù hợp. – Subhas

0

Vì các máy chủ ứng dụng/thùng chứa servlet thường có nhiều trình nạp lớp khác nhau, bạn có thể cần một chiến lược khác để dệt các khía cạnh vào mã của bạn hơn trong các ứng dụng độc lập.

Tôi khuyên bạn nên thêm các khía cạnh cho mọi tệp chiến tranh được triển khai tại thời gian xây dựng. Điều này có thể là sau một kỹ thuật phổ biến - như trái ngược với một máy chủ cụ thể.

Hơn nữa, tôi không chắc nó thực sự có thể được thực hiện (đúng cách & được hỗ trợ) trên máy chủ hay không. Thông thường một máy chủ được xây dựng để tách tất cả các ứng dụng web khỏi nhau. Bạn có thể làm cho nó hoạt động, nhưng nó có thể phá vỡ bản cập nhật tiếp theo của máy chủ.

Có thể dễ dàng đề xuất một kỹ thuật thay thế nếu bạn nêu rõ vấn đề mà bạn muốn giải quyết bằng cách tiếp cận được đề xuất của mình.

Chỉnh sửa sau nhận xét của bạn: Xem xét vòng đời ứng dụng web chuẩn: Bạn có thể thực thi một số mã, ví dụ: trong một servlet, khi nó được triển khai. Nếu bạn nhấn mạnh vào mã của bạn đang được chứa trong main, bạn có thể gọi phương thức này từ mã khởi tạo của ứng dụng web của bạn.

+0

im viết một công cụ giám sát hiệu suất tùy theo nhu cầu kinh doanh của chúng tôi, và tôi muốn có thể giám sát tất cả các ứng dụng được triển khai mà không cần phải bao gồm các jar trong mỗi tập tin chiến tranh, cho đến nay nó hoạt động tốt bằng cách gộp tất cả các khía cạnh và phụ thuộc cần thiết trong một tệp jar và thêm nó vào classpath của máy chủ (weblogic và tomcat cho bây giờ), tôi có thể dệt vào tất cả các ứng dụng được triển khai cho JVM. nhưng tôi vẫn cần chạy một số mã khởi tạo từ tệp jar khi nó được tải, mà không phải thay đổi các ứng dụng khác – Sammy

+0

... vì vậy đó là ý định của câu hỏi là có một số mã khởi tạo thực thi từ bình để thực hiện khởi tạo cần thiết cho các khía cạnh. – Sammy

+0

Vấn đề duy nhất với cách tiếp cận được đề xuất là jar với khía cạnh được cho là được tải trước bất kỳ ứng dụng web nào, vì vậy việc gọi phương thức chính trong servlet có thể đã quá muộn. – Sammy

5

Thêm một lớp bên trong JAR của bạn với đoạn mã sau:

public class TomcatStartupListener implements org.apache.catalina.LifecycleListener { 
    public void lifecycleEvent(org.apache.catalina.LifecycleEvent event) { 
    if (event.getType().equals("after_start")) { 
     // call your main method here 
    } 
    } 
} 

Lưu ý: Để biên dịch này, bạn cần phải thêm <tomcat-dir>/lib/catalina.jar vào classpath của bạn. Nếu không, khi biên dịch nó sẽ không thể tìm thấy các giao diện cần thiết (org.apache.catalina.LifecycleListenerorg.apache.catalina.LifecycleEvent). Khi bạn đã hoàn tất việc biên dịch, hãy đặt JAR như bình thường dưới <tomcat-dir>/lib.

Bây giờ mở <tomcat-dir>/conf/server.xml và thêm dòng sau dưới phần <Server>:

<Listener className="com.yourpackage.TomcatStartupListener" /> 

Bây giờ bất cứ khi nào máy chủ Tomcat của bạn bắt đầu, lớp này TomcatStartupListener bên JAR của bạn sẽ được gọi, và bạn có thể gọi phương thức chính của bạn. Có rất nhiều loại sự kiện khác nữa!Bạn có thể sử dụng bất kỳ các loại sự kiện:

  • before_init
  • after_init
  • before_start
  • configure_start
  • bắt đầu
  • after_start
  • before_stop
  • dừng
  • configure_stop
  • after_stop
  • before_destroy
  • after_destroy

Cách tiếp cận này là cần thiết vì cách làm việc (JVM hoặc thậm chí hầu hết) classloaders work in Tomcat. Dưới đây là các điểm quan trọng từ liên kết đó:

There are three aspects of a class loader behavior 
    Lazy Loading 
    Class Caching 
    Separate Namespaces 

JVM sẽ rất nặng nếu tất cả các lớp trong tất cả các JAR được tải bừa bãi. Vì vậy, các lớp bên trong các tệp JAR được chia sẻ chỉ được tải theo yêu cầu. Cách duy nhất để bạn gọi phương thức chính là thêm trình nghe vòng đời trên.

+0

Có giải pháp toàn cầu nào hoạt động trên tất cả các máy chủ ứng dụng không cụ thể với tomcat không? – Sammy

+0

Không. Oracle có trình lắng nghe APEX riêng của nó, và tương tự mỗi máy chủ có các trình nghe riêng của nó. J2EE chỉ định nghĩa người nghe cho một ngữ cảnh web cụ thể, nó không chỉ định người nghe cho toàn bộ máy chủ. Vì vậy, mỗi máy chủ có cách riêng để nghe các sự kiện trên toàn máy chủ. – Subhas

+0

Nếu bạn đang tạo một JAR, thì cách các thư viện khác thực hiện là - có ** HAI JAR **. Một là JAR chính của bạn. Thứ hai là một JAR * Listener JAR * dành riêng cho máy chủ, chỉ có lớp người nghe. ví dụ. đối với Tomcat, bạn sẽ có mã trên trong 'yourapp-tomcat.jar', và với Oracle bạn sẽ có mã khác trong' yourapp-oracle.jar'.Sau đó cho phép người dùng sử dụng bất kỳ JAR người nghe bổ sung nào tương ứng với máy chủ ứng dụng mà họ sử dụng. – Subhas

0

Bạn cần đăng ký tác nhân Java. Xem liên kết này: java.lang.instrument.

java.lang.instrument cung cấp các dịch vụ cho phép tác nhân ngôn ngữ lập trình Java cho các chương trình cụ chạy trên JVM.

Đây là cách phù hợp để thực hiện việc này.