Можно ли использовать «Отчеты об ошибках Windows» для нефатальных проблем с Java? - PullRequest
10 голосов
/ 14 декабря 2011

Мне было интересно, есть ли способ использовать Windows Error Reporting изнутри Java-программы?

Другими словами, используйте механизм для сообщения об исключениях обратно в центральное местоположение без фактического сбоя JVM (что, на мой взгляд, вызывает это в первую очередь).

Идея в том, чтобы упростить сбор отчетов об ошибках от пользователей Windows.


Мне бы тоже хотелось услышать, может ли это быть частью управляемого отключения. То есть не сбой JVM, а обычный, контролируемый выход из программы Java.


Подумав, я думаю, что для наших целей было бы достаточно создать набор текстовых файлов (или, возможно, просто передать в один текстовый поток) крошечному приложению Windows, расположенному внутри нашей части файловой системы. Затем указанное приложение Windows заметно вылетает и вызывает отправку отчета, включая текст, предоставленный нами. Будет ли это работать?

Ответы [ 4 ]

9 голосов
/ 29 декабря 2011

Вы определенно можете использовать API отчетов об ошибках Windows, который поставляется в wer.dll, как часть Win32 API.

Лучший способ вызывать функции на основе DLL из Java - использовать активно разработанный Java Native Access проект .

Чтобы сделать необходимые вызовы Win32 API, нам нужно научить JNA по крайней мере следующим функциям:

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

, а также эта структура:

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;

Для этого мы создадим 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);
}

Я только что выбил это из документации MSDN за несколько минут - на случай, если она неполная или неправильная, есть тонн примеров и довольно хорошая документация на веб-сайте JNA.

Для запуска JNA вам понадобятся jna.jar и platform.jar, которые вы также можете получить с веб-сайта JNA.

6 голосов
/ 22 декабря 2011

В прошлом мне приходилось программировать совместимость между Java и .NET, поэтому я начал проводить исследования по использованию .NET для взаимодействия с WER с целью выяснить, возможно ли взаимодействие с WER в .NET-приложение, которое вы затем можете взаимодействовать с Java. Интересно, что я сталкивался с этим сообщением на SOF - . Существует ли .Net API для Windows Error Reporting

В этом посте содержится полезная информация о взаимодействии с WER.

Я знаю, что этот пост посвящен использованию .NET против WER, но, поскольку вы пытаетесь взаимодействовать с собственными функциональными возможностями Windows, я рекомендую использовать .NET для взаимодействия с ним, так как намного проще взаимодействовать с собственными ресурсами Windows, используя .NET, чем в Java (и обычно занимает половину кода, который был бы в Java). Затем вы можете подключиться к приложению .NET (лучше всего настроить его как службу Windows) с помощью Java (например, вы можете использовать временные файлы-триггеры в приложении .NET, чтобы указать, когда приложение .NET завершает работу с ним. обработка; приложение Java может затем проверить, был ли создан этот «триггерный» файл, и продолжить с него ...).

Однако, как рекомендует принятый ответ в этом посте, лучше всего использовать Windows Quality Online Services вместо программирования чего-либо для взаимодействия с WER, так как кажется, что WER не предназначен для использования другими приложениями.

4 голосов
/ 22 декабря 2011

Вы можете взаимодействовать с собственными функциями библиотеки WER.

Вот соответствующая документация MSDN:

  1. Создание отчета
  2. Отправка отчета

Возможно, кто-то с большим опытом взаимодействия с Java может предоставить вам примеры кода, я, к сожалению, скорее парень .NET.

EDIT:

Я провел еще несколько исследований, и я думаю, что вы можете попробовать использовать GlueGen или SWIG для создания привязок Java.Вам нужно будет загрузить Windows SDK , чтобы получить файл заголовка werapi, если вы хотите сгенерировать привязки.

0 голосов
/ 29 декабря 2011

Вы хотите сказать, что вместо создаваемых файлов hs_err_pid * .log WER должен регистрировать журналы вместе с ним? Или вы намереваетесь записать подробное сообщение об исключении любого исключения, которое может быть обработано в программах Java в WER?

Если случай равен 1, то, очевидно, вы не можете сделать это аккуратно. Возможно, у вас постоянно работает отдельный демон для поиска hs_err_pid * .log созданного -> интерпретировать его с помощью внешних библиотек -> использовать предложенные выше API-интерфейсы WER для записи его в записи WER.

Если случай 2-й, то вы можете сделать вызов JNI и сделать вызовы в API WER для написания материала в WER.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...