2011-12-14 31 views
10

Tôi đã tự hỏi nếu có một cách để sử dụng Windows Error Reporting từ "bên trong" một chương trình Java?Có thể sử dụng "Báo cáo lỗi Windows" cho các sự cố Java không gây tử vong không?

Nói cách khác, hãy sử dụng cơ chế để báo cáo ngoại lệ trở lại vị trí trung tâm mà không gặp sự cố JVM thực sự (theo hiểu biết của tôi là điều gì kích hoạt điều này ngay từ đầu).

Ý tưởng ở đây là giúp thu thập báo cáo lỗi từ người dùng Windows dễ dàng hơn.


Tôi cũng muốn nghe nếu nó có thể là một phần của việc tắt máy được kiểm soát. I E. không phải là một JVM sụp đổ mà là một lối thoát được kiểm soát bình thường từ một chương trình Java.


Sau khi suy nghĩ lại thật kỹ, nghĩ rằng nó sẽ là đủ cho mục đích của chúng tôi để tạo ra một tập hợp các tập tin văn bản (hoặc có lẽ chỉ đường ống trong một dòng văn bản duy nhất) để một ứng dụng Windows nhỏ nằm bên trong một phần của chúng ta về hệ thống tệp. Ứng dụng Windows cho biết sau đó đổ vỡ nổi bật và khiến báo cáo được gửi bao gồm cả văn bản do chúng tôi cung cấp. Liệu điều đó có hiệu quả?

+0

[NTEventLogAppender] (http://logging.apache.org/log4j/1.2/apidocs/org/apache/log4j/nt/NTEventLogAppender.html) hoặc tương tự? Chỉnh sửa: [Có thể câu hỏi liên quan] (http://stackoverflow.com/questions/164879/how-to-write-from-java-to-the-windows-event-log) –

+0

@VineetReynolds, nó sẽ kích hoạt "Gửi báo cáo lỗi cho Microsoft "hành động? –

+0

[Không. Đó là cấu hình để xảy ra chỉ trên một vụ tai nạn.] (Http://support.microsoft.com/kb/310414) –

Trả lời

4

Bạn có thể tương tác với các hàm thư viện WER gốc.

Dưới đây là tài liệu MSDN liên quan:

  1. Creating a report
  2. Submitting a report

Có lẽ ai đó với nhiều kinh nghiệm Java interop có thể cung cấp cho bạn với các ví dụ mã, tôi nhiều hơn một. NET anh chàng không may.

EDIT:

tôi đã làm một số nghiên cứu nhiều hơn, và tôi nghĩ rằng bạn có thể thử sử dụng GlueGen hoặc SWIG để tạo ra các ràng buộc Java. Bạn sẽ phải download the Windows SDK để lấy tệp tiêu đề werapi nếu bạn muốn tạo các kết buộc.

+0

Bạn có thể thực hiện công việc trong UncaughtExceptionHandler toàn bộ nếu bạn muốn: http://docs.oracle.com/javase/1.5.0/docs/api/java/lang/Thread.UncaughtExceptionHandler.html. Nhưng điều này có lẽ không phải là một thực hành tốt. –

6

Tôi đã có khả năng tương tác giữa Java và .NET trong quá khứ, vì vậy tôi đã bắt đầu thực hiện một số nghiên cứu về cách sử dụng .NET để tương tác với WER với ý định xem liệu có thể tương tác với WER trong một ứng dụng .NET mà bạn có thể giao tiếp với Java. Thật thú vị, tôi đã xem qua bài đăng này trên SOF - Is there a .Net API for Windows Error Reporting

Bài đăng đó có một số thông tin tốt có liên quan đến tương tác với WER. Tôi biết rằng bài viết xoay quanh việc sử dụng .NET chống lại WER, nhưng khi bạn đang cố gắng tương tác với chức năng Windows nguyên bản, tôi khuyên bạn nên sử dụng .NET để tương tác với nó vì việc SO tương tác dễ dàng hơn với tài nguyên Windows nguyên gốc dễ dàng hơn nhiều. sử dụng .NET hơn là với Java (và nó thường mất một nửa mã trong Java). Sau đó bạn có thể giao diện với ứng dụng .NET (có thể được thiết lập tốt nhất như một dịch vụ Windows) với Java (ví dụ, bạn có thể sử dụng các tệp "trigger" tạm thời trong ứng dụng .NET để chỉ ra khi ứng dụng .NET được thực hiện với nó sau đó ứng dụng Java có thể thăm dò để xem khi nào tệp "kích hoạt" đã được tạo và tiếp tục từ đó ...).Tuy nhiên, vì câu trả lời được chấp nhận trong bài viết đó có thể là tốt nhất để sử dụng Dịch vụ Trực tuyến Chất lượng của Windows thay vì lập trình để tương tác với WER vì dường như WER không được sử dụng bởi các ứng dụng khác.

+0

Không chắc chắn nếu có ai sẽ trả lời điều này, nhưng sẽ rất hữu ích khi biết tại sao câu trả lời này lại bị giảm giá - cảm ơn. –

10

Bạn chắc chắn có thể sử dụng API báo cáo lỗi của Windows được giao trong wer.dll như một phần của API Win32.

Cách tốt nhất để gọi các hàm dựa trên DLL từ Java là sử dụng tích cực phát triển Java Native Access project.

Để thực hiện các cuộc gọi hàm API cần Win32, chúng tôi sẽ cần phải dạy JNA về ít nhất các chức năng:

HRESULT WINAPI WerReportCreate(
    __in  PCWSTR pwzEventType, 
    __in  WER_REPORT_TYPE repType, 
    __in_opt PWER_REPORT_INFORMATION pReportInformation, 
    __out  HREPORT *phReportHandle 
); 

HRESULT WINAPI WerReportSubmit(
    __in  HREPORT hReportHandle, 
    __in  WER_CONSENT consent, 
    __in  DWORD dwFlags, 
    __out_opt PWER_SUBMIT_RESULT pSubmitResult 
); 

và cũng struct này:

typedef struct _WER_REPORT_INFORMATION { 
    DWORD dwSize; 
    HANDLE hProcess; 
    WCHAR wzConsentKey[64]; 
    WCHAR wzFriendlyEventName[128]; 
    WCHAR wzApplicationName[128]; 
    WCHAR wzApplicationPath[MAX_PATH]; 
    WCHAR wzDescription[512]; 
    HWND hwndParent; 
} WER_REPORT_INFORMATION, *PWER_REPORT_INFORMATION; 

Để làm điều này, chúng tôi sẽ tạo WER.java:

package com.sun.jna.platform.win32; 

import com.sun.jna.Native; 
import com.sun.jna.Pointer; 
import com.sun.jna.platform.win32.WinDef.HWND; 
import com.sun.jna.platform.win32.WinNT.HANDLE; 
import com.sun.jna.platform.win32.WinNT.HRESULT; 
import com.sun.jna.ptr.PointerByReference; 
import com.sun.jna.win32.StdCallLibrary; 
import com.sun.jna.win32.W32APIOptions; 

public interface Wer extends StdCallLibrary { 
    Wer INSTANCE = (Wer) Native.loadLibrary("wer", Wer.class, 
               W32APIOptions.DEFAULT_OPTIONS); 

    public static class HREPORT extends HANDLE { 
     public HREPORT() { } 
     public HREPORT(Pointer p) { super(p); } 
     public HREPORT(int value) { super(new Pointer(value)); } 
    } 

    public static class HREPORTByReference extends ByReference { 
     public HREPORTByReference() { 
      this(null); 
     } 

     public HREPORTByReference(HREPORT h) { 
      super(Pointer.SIZE); 
      setValue(h); 
     } 

     public void setValue(HREPORT h) { 
      getPointer().setPointer(0, h != null ? h.getPointer() : null); 
     } 

     public HREPORT getValue() { 
      Pointer p = getPointer().getPointer(0); 
      if (p == null) 
       return null; 
      if (WinBase.INVALID_HANDLE_VALUE.getPointer().equals(p)) 
       return (HKEY) WinBase.INVALID_HANDLE_VALUE; 
      HREPORT h = new HREPORT(); 
      h.setPointer(p); 
      return h; 
     } 
    } 

    public class WER_REPORT_INFORMATION extends Structure { 
     public DWORD dwSize; 
     public HANDLE hProcess; 
     public char[] wzConsentKey = new char[64]; 
     public char[] wzFriendlyEventName = new char[128]; 
     public char[] wzApplicationName = new char[MAX_PATH]; 
     public char[] wzDescription = new char[512]; 
     public HWND hwndParent; 

     dwSize = new DWORD(size()); 
    } 

    public abstract class WER_REPORT_TYPE { 
     public static final int WerReportNonCritical = 0; 
     public static final int WerReportCritical = 1; 
     public static final int WerReportApplicationCrash = 2; 
     public static final int WerReportApplicationHang = 3; 
     public static final int WerReportKernel = 4; 
     public static final int WerReportInvalid = 5; 
    } 

    HRESULT WerReportCreate(String pwzEventType, int repType, WER_REPORT_INFORMATION pReportInformation, HREPORTByReference phReportHandle); 
    HRESULT WerReportSubmit(HREPORT hReportHandle, int consent, DWORD dwFlags, WER_SUBMIT_RESULT.ByReference pSubmitResult); 
} 

Tôi vừa mới loại bỏ điều đó cùng với quá trình DCou dcoumentation trong vài phút s - trong trường hợp nó không đầy đủ hoặc không chính xác, có tons of examplespretty good documentation trên trang web của JNA.

Để chạy JNA, bạn cần jna.jarplatform.jar, bạn cũng có thể lấy từ trang web của JNA.

0

Bạn có ý nói rằng thay vì hs_err_pid * .log tệp được tạo WER nên ghi nhật ký với nó? Hoặc bạn có ý định ghi thông báo ngoại lệ chi tiết của bất kỳ ngoại lệ nào có thể được xử lý trong các chương trình Java trong WER?

Nếu trường hợp là 1 thì rõ ràng bạn không thể làm điều đó gọn gàng. Bạn có thể có một daemon riêng chạy tất cả thời gian để tìm hs_err_pid * .log được tạo ra-> giải thích nó bằng cách sử dụng các thư viện bên ngoài-> sử dụng các API WER được gợi ý ở trên để viết nó trong các recorords WER.

Nếu trường hợp là trường hợp thứ 2 thì bạn có thể thực hiện cuộc gọi JNI và thực hiện các cuộc gọi đến WER API để viết nội dung bằng WER.

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