org.netbeans.modules.uihandler.AfterRestartExceptions Maven / Gradle / Ivy
/*
* Licensed to the Apache Software Foundation (ASF) under one
* or more contributor license agreements. See the NOTICE file
* distributed with this work for additional information
* regarding copyright ownership. The ASF licenses this file
* to you under the Apache License, Version 2.0 (the
* "License"); you may not use this file except in compliance
* with the License. You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing,
* software distributed under the License is distributed on an
* "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
* KIND, either express or implied. See the License for the
* specific language governing permissions and limitations
* under the License.
*/
package org.netbeans.modules.uihandler;
import java.io.File;
import java.io.FileInputStream;
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.ObjectInputStream;
import java.io.ObjectOutputStream;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.HashSet;
import java.util.LinkedHashSet;
import java.util.Set;
import java.util.logging.LogRecord;
import javax.swing.JButton;
import org.openide.DialogDisplayer;
import org.openide.NotifyDescriptor;
import org.openide.awt.Mnemonics;
import org.openide.util.NbBundle;
import org.openide.util.io.NbObjectInputStream;
/**
*
* @author Martin Entlicher
*/
class AfterRestartExceptions implements Runnable {
private static final Set scheduledThrowableClasses = new HashSet<>(
Arrays.asList(new String[] {
OutOfMemoryError.class.getName(),
"org.netbeans.modules.deadlock.detector.Detector$DeadlockDetectedException",
}));
private static final Object IOLock = new Object();
private static volatile Set afterRestartRecords;
private static boolean ignoreOOME;
private AfterRestartExceptions() {}
static void setIgnoreOOME(boolean ignoreOOME) {
AfterRestartExceptions.ignoreOOME = ignoreOOME;
}
static boolean willSchedule(LogRecord record) {
return getScheduledThrownClassName(record) != null;
}
private static String getScheduledThrownClassName(LogRecord record) {
Throwable thrown = record.getThrown();
if (thrown == null) {
return null;
}
Throwable cause;
while (((cause = thrown.getCause()) != null) && (cause.getStackTrace().length != 0)){
thrown = cause;
}
String thrownClassName = thrown.getClass().getName();
if (scheduledThrowableClasses.contains(thrownClassName)) {
return thrownClassName;
} else {
return null;
}
}
static boolean schedule(LogRecord record) {
String thrownClassName = getScheduledThrownClassName(record);
if (thrownClassName != null) {
if (OutOfMemoryError.class.getName().equals(thrownClassName)) {
if (ignoreOOME) {
return true; // Simulate scheduling, but ignore
}
addHeapDump(record);
}
return save(record);
} else {
return false;
}
}
private static File getLogRecordsFile() {
File varLog = Installer.logsDirectory();
if (varLog == null) {
return null;
}
return new File(varLog, AfterRestartExceptions.class.getSimpleName());
}
private static void addHeapDump(LogRecord record) {
File heapDump = Installer.getHeapDump();
if (heapDump != null) {
String heapDumpPath = heapDump.getAbsolutePath();
Object[] parameters = record.getParameters();
if (parameters == null) {
parameters = new Object[] { heapDumpPath };
} else {
Object[] newParams = new Object[parameters.length + 1];
System.arraycopy(parameters, 0, newParams, 0, parameters.length);
newParams[parameters.length] = heapDumpPath;
parameters = newParams;
}
record.setParameters(parameters);
}
}
private static boolean save(LogRecord record) {
File exceptionsFile = getLogRecordsFile();
ObjectOutputStream os = null;
synchronized (IOLock) {
try {
os = new ObjectOutputStream(new FileOutputStream(exceptionsFile, true));
os.writeObject(record);
return true;
} catch (IOException ioex) {
return false;
} finally {
if (os != null) {
try {
os.close();
} catch (IOException ex) {}
}
}
}
}
static void report() {
if (readRecords()) {
org.openide.windows.WindowManager.getDefault().invokeWhenUIReady(new AfterRestartExceptions());
}
}
static boolean isAfterRestartRecord(LogRecord record) {
Set records = afterRestartRecords;
return records != null && records.contains(record);
}
private static boolean readRecords() {
File logRecords = getLogRecordsFile();
if (logRecords == null || !logRecords.exists()) {
return false;
}
Set records = new LinkedHashSet<>();
ObjectInputStream in = null;
synchronized (IOLock) {
try {
in = new NbObjectInputStream(new FileInputStream(logRecords));
while (true) {
Object obj = in.readObject();
if (obj instanceof LogRecord) {
records.add((LogRecord) obj);
}
}
} catch (IOException | ClassNotFoundException ex) {
} finally {
if (in != null) {
try {
in.close();
} catch (IOException ioex) {}
}
logRecords.delete();
}
}
if (records.isEmpty()) {
return false;
}
afterRestartRecords = records;
return true;
}
@NbBundle.Messages({ "TTL_AfterRestartReport=Unexpected Exception on Last Run",
"MSG_AfterRestartReportQuestion=There was an error during the last run of NetBeans IDE.\nCan you please report the problem?",
"BTN_ReviewAndReport=&Review and Report Problem" })
@Override
public void run() {
final Set records = afterRestartRecords;
String msg = Bundle.MSG_AfterRestartReportQuestion();
String title = Bundle.TTL_AfterRestartReport();
int optionType = NotifyDescriptor.QUESTION_MESSAGE;
JButton reportOption = new JButton();
Mnemonics.setLocalizedText(reportOption, Bundle.BTN_ReviewAndReport());
NotifyDescriptor confMessage = new NotifyDescriptor(msg, title, optionType,
NotifyDescriptor.QUESTION_MESSAGE,
new Object[] { reportOption, NotifyDescriptor.CANCEL_OPTION },
reportOption);
Object ret = DialogDisplayer.getDefault().notify(confMessage);
if (ret == reportOption) {
Installer.RP.post(new Runnable() {
@Override
public void run() {
Installer.displaySummary("ERROR_URL", true, false, true,
Installer.DataType.DATA_UIGESTURE,
new ArrayList<>(records), null, true);
Installer.setSelectedExcParams(null);
afterRestartRecords = null;
}
});
}
}
}
© 2015 - 2025 Weber Informatics LLC | Privacy Policy