2008-10-19 29 views
12

Vì nó đã được làm rõ trong recent question của tôi, các ứng dụng Swing cần gọi rõ ràng System.exit() khi chúng được chạy bằng trình khởi chạy Sun Webstart (ít nhất là của Java SE 6).Cách tốt nhất để phát hiện xem một ứng dụng có được khởi chạy bởi Webstart

Tôi muốn hạn chế việc hack này càng nhiều càng tốt và tôi đang tìm kiếm một cách đáng tin cậy để phát hiện xem ứng dụng có đang chạy dưới Webstart hay không. Ngay bây giờ tôi kiểm tra rằng giá trị của thuộc tính hệ thống "webstart.version" không phải là null, nhưng tôi không thể tìm thấy bất kỳ đảm bảo nào trong tài liệu mà thuộc tính này sẽ được thiết lập bởi các phiên bản sau/triển khai thay thế.

Có cách nào tốt hơn (tốt nhất là những người mà không ceate một sự phụ thuộc vào các API webstart?)

Trả lời

9

Khi mã của bạn được khởi chạy qua javaws, javaws.jar được tải và các lớp JNLP API mà bạn không muốn phụ thuộc vào khả dụng. Thay vì thử nghiệm cho một tài sản hệ thống mà không được bảo đảm để tồn tại, bạn thay vì có thể thấy nếu một lớp JNLP API tồn tại:

private boolean isRunningJavaWebStart() { 
    boolean hasJNLP = false; 
    try { 
     Class.forName("javax.jnlp.ServiceManager"); 
     hasJNLP = true; 
    } catch (ClassNotFoundException ex) { 
     hasJNLP = false; 
    } 
    return hasJNLP; 
} 

này cũng tránh cần phải bao gồm javaws.jar trên con đường lớp học của bạn khi biên dịch.

Hoặc bạn có thể chuyển sang biên dịch bằng javaws.jar và bắt NoClassDefFoundError thay vì:

private boolean isRunningJavaWebStart() { 
    try { 
     ServiceManager.getServiceNames(); 
     return ds != null; 
    } catch (NoClassDefFoundError e) { 
     return false; 
    } 
} 

Sử dụng ServiceManager.lookup (String) và UnavailableServiceException là rắc rối vì cả hai đều là một phần của API JNLP. ServiceManager.getServiceNames() không phải là tài liệu để ném. Chúng tôi đặc biệt gọi mã này để kiểm tra NoClassDefFoundError.

+2

jnlp.jar là đủ, nó có sẵn trong kho lưu trữ zip chứa các bản demo và mẫu của Java SE. JAR này chỉ chứa các giao diện. Nó tốt hơn vì javaws.jar chứa toàn bộ việc triển khai thực hiện vô dụng vì nó đã được cung cấp bởi JRE nhưng nó không có trong classpath (chỉ trong đường dẫn khởi động?). – gouessej

5

Sử dụng javax.jnlp.ServiceManager để lấy một dịch vụ webstart. Nếu có, bạn đang chạy dưới Webstart.

Xem http://download.java.net/jdk7/docs/jre/api/javaws/jnlp/index.html

+0

Cảm ơn đề xuất. Tôi đã tìm ra điều này, nhưng nó biến WS không phải là một phần của classpath JRE chuẩn và vì tôi không muốn gửi jar API, tôi không muốn sử dụng nó (và không, sự phản chiếu không phải là câu trả lời mà tôi đang tìm kiếm.) – ddimitrov

+0

Hoặc bạn đang sử dụng plugin 6u10 mới ... –

+2

@ddimitrov, tại sao bạn muốn tránh phản ánh? Nếu bạn nhận được một 'ClassNotFoundException' cho' ServiceManager' bạn biết rằng bạn đang * không * chạy dưới JWS. – finnw

4

Như bạn đã đề cập, kiểm tra tài sản hệ thống như sau có lẽ là cách sạch:

private boolean isRunningJavaWebStart() { 
    return System.getProperty("javawebstart.version", null) != null; 
} 

Trong một hệ thống sản xuất, tôi đã sử dụng các kỹ thuật nói trên trong nhiều năm.

Bạn cũng có thể thử kiểm tra xem có bất kỳ thuộc tính nào bắt đầu bằng "jnlpx" hay không. nhưng không ai trong số đó thực sự "được bảo đảm" ở đó hoặc xa như tôi biết.

Một thay thế có thể là cố gắng để nhanh chóng DownloadService chúng tôi đề xuất bởi Tom:

private boolean isRunningJavaWebStart() { 
    try { 
     DownloadService ds = (DownloadService) ServiceManager.lookup("javax.jnlp.DownloadService"); 
     return ds != null; 
    } catch (UnavailableServiceException e) { 
     return false; 
    } 
} 

Dĩ nhiên điều đó không có nhược điểm của ghép mã của bạn để API mà.

+0

ServiceManager vẫn nằm trong javaws.jar; Bạn có biết liệu có bất kỳ tài liệu chính thức nào nêu rõ các thuộc tính hệ thống được thiết lập không? – ddimitrov

+0

Tôi không thể tìm thấy bất kỳ thứ gì trong tài liệu của họ. Tài liệu API không chỉ định bất kỳ thông số hệ thống nào. Tôi nghĩ nếu bạn muốn cách phát hiện WebStart "chính thức", bạn sẽ phải sử dụng API của họ. –

+0

Có các triển khai JNLP khác với WebStart của Sun. –

3

Tôi không có kinh nghiệm thực tế với Java web bắt đầu khác hơn là nhìn vào nó một vài năm trở lại.

Làm thế nào để bắt đầu ứng dụng của bạn với một tham số mà bạn xác định hơn bạn đặt khi ứng dụng được bắt đầu thông qua bắt đầu web Java.

Nếu bạn muốn chuyển đối số cho ứng dụng của mình, bạn phải thêm chúng vào tệp khởi động (còn gọi là bộ mô tả JNLP) sử dụng hoặc các phần tử.

Sau đó kiểm tra xem các thuộc tính này có được đặt hay không.

Một lần nữa đây là một gợi ý tôi chưa được mã hóa cho JWS và nó có thể không dễ dàng như vậy.

+0

Đó là một tùy chọn khả thi, nhưng yêu cầu ứng dụng sửa đổi tệp jnlp của nó đang lan truyền hack thành nhiều nơi. – ddimitrov

+1

Hoặc sử dụng một chính riêng biệt. –

0

Bạn có thể kiểm tra xem trình nạp lớp hiện tại có phải là một thể hiện của com.sun.jnlp.JNLPClassLoader (Java plugin 1) hoặc sun.plugin2.applet.JNLP2ClassLoader (Java plugin 2) hay không. Mặc dù gói "applet", một applet sử dụng JNLP với plugin Java 2 sử dụng trình nạp lớp khác, sun.plugin2.applet.Applet2ClassLoader. Nó cũng làm việc với OpenJDK.

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