2011-12-14 12 views
10

Mi chiedevo se esistesse un modo per utilizzare Segnalazione errori di Windows da "dentro" un programma Java?È possibile utilizzare "Segnalazione errori Windows" per problemi Java non fatali?

In altre parole, utilizzare il meccanismo di riferire le eccezioni di nuovo ad una posizione centrale senza avere il blocco della JVM effettivo (che alla mia comprensione è ciò che fa scattare questo in primo luogo).

L'idea è di semplificare la raccolta di segnalazioni di bug da parte di utenti Windows.


Mi piacerebbe sentire anche se può essere parte di uno spegnimento controllato. Cioè non un crash JVM ma un'uscita normale e controllata da un programma Java.


dopo averci pensato su, credo che sarebbe sufficiente per i nostri scopi per creare un insieme di file di testo (o forse solo il tubo in un unico flusso di testo) per una piccola applicazione di Windows che si trova all'interno parte della nostra il file system. L'applicazione Windows quindi si blocca in modo prominente e causa l'invio di un rapporto incluso il testo da noi fornito. Funzionerebbe?

+0

[NTEventLogAppender] (http://logging.apache.org/log4j/1.2/apidocs/org/apache/log4j/nt/NTEventLogAppender.html) o simili? Modifica: [Forse domanda correlata] (http://stackoverflow.com/questions/164879/how-to-write-from-java-to-the-windows-event-log) –

+0

@VineetReynolds, si attiverà il "Invia segnalazione di bug a Microsoft "azione? –

+0

[No. Che è configurato per verificarsi solo in caso di arresto anomalo.] (Http://support.microsoft.com/kb/310414) –

risposta

4

È possibile utilizzare le funzioni della libreria WER nativa.

Ecco la relativa documentazione MSDN:

  1. Creating a report
  2. Submitting a report

Forse qualcuno con più esperienza su Java interoperabilità può fornire esempi di codice, sono più di una. NET guy purtroppo.

EDIT:

ho fatto un po 'di ricerche, e penso che si potrebbe provare a utilizzare GlueGen o SWIG per generare i binding Java. Dovrai download the Windows SDK per ottenere il file di intestazione werapi se vuoi generare i bind.

+0

È possibile eseguire il lavoro in UncaughtExceptionHandler a livello di thread se si desidera: http://docs.oracle.com/javase/1.5.0/docs/api/java/lang/Thread.UncaughtExceptionHandler.html. Ma probabilmente non è una buona pratica. –

6

Ho dovuto programmare l'interoperabilità tra Java e .NET in passato, quindi ho iniziato a fare alcune ricerche sull'uso di .NET per interagire con WER con l'intenzione di vedere se è possibile interagire con WER in un'app .NET che è quindi possibile interfacciare con Java. È interessante notare che mi sono imbattuto in questo post su SOF - Is there a .Net API for Windows Error Reporting

Questo post contiene alcune informazioni utili relative all'interazione con WER.

So che il post ruota attorno all'utilizzo di .NET contro WER, ma mentre stai cercando di interagire con la funzionalità nativa di Windows, ti consiglio di utilizzare .NET per interagire con esso in quanto è molto più facile interagire con le risorse native di Windows. usando .NET di quanto non lo sia con Java (e di solito impiega metà del codice che avrebbe in Java). Si potrebbe quindi interfacciare con l'app .NET (potrebbe essere meglio impostato come servizio Windows) con Java (ad esempio, è possibile utilizzare i file temporanei "trigger" nell'app .NET per indicare quando l'app .NET è terminata con elaborazione, l'app Java potrebbe quindi sondare per vedere quando quel file "trigger" è stato creato e continuare da lì ...).

Poiché la risposta accettata in questo post consiglia, tuttavia, potrebbe essere preferibile utilizzare i servizi online di qualità di Windows invece di programmare qualcosa per interagire con WER in quanto sembra che il WER non sia destinato ad essere utilizzato da altre applicazioni.

+0

Non so se qualcuno risponderà mai a questo, ma sarebbe utile sapere perché questa risposta è stata downvoted - grazie. –

10

È possibile utilizzare l'API Segnalazione errori Windows fornita in wer.dll come parte dell'API Win32.

Il modo migliore per richiamare le funzioni basate su DLL da Java è l'utilizzo dello sviluppo attivo Java Native Access project.

Al fine di rendere le chiamate API Win32 richiesti, avremo bisogno di insegnare JNA su almeno queste funzioni:

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

e anche questa struct:

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; 

A tale scopo, creeremo 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); 
} 

ho appena bussato che insieme dalla dcoumentation MSDN in pochi minuti s - nel caso in cui sia incompleto o errato, ci sono tons of examples e pretty good documentation sul sito web JNA.

Per eseguire JNA, è necessario jna.jar e platform.jar, che è possibile anche prelevare dal sito Web JNA.

0

Intendi dire che anziché i file hs_err_pid * .log creati WER dovrebbe registrare i registri con esso? O intendi registrare il messaggio di eccezione dettagliato di qualsiasi eccezione che possa essere gestita nei programmi Java in WER?

Se il caso è 1, ovviamente non è possibile farlo in modo ordinato. Potresti avere un demone separato in esecuzione tutto il tempo per cercare hs_err_pid * .log creato-> interpretarlo usando librerie esterne-> usa le API WER suggerite sopra per scriverlo nei recorord WER.

Se il caso è il secondo, è possibile effettuare una chiamata JNI e fare le chiamate alle API WER per scrivere materiale in WER.

Problemi correlati