blob: 05c79ab9302ab768ec404962f8ba83545d1c0572 [file] [log] [blame]
/*
* 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 java.lang;
import java.lang.reflect.Field;
/**
* {@code Exception} is the superclass of all classes that represent recoverable
* exceptions. When exceptions are thrown, they may be caught by application
* code.
*
* @see Throwable
* @see Error
* @see RuntimeException
*/
public class Exception extends Throwable {
private static final long serialVersionUID = -3387516993124229948L;
private transient Class[] classContext = SecurityManagerEx.getInstance().getThrowableContext(this);
/**
* Constructs a new {@code Exception} that includes the current stack trace.
*/
public Exception() {
super();
}
/**
* Constructs a new {@code Exception} with the current stack trace and the
* specified detail message.
*
* @param detailMessage
* the detail message for this exception.
*/
public Exception(String detailMessage) {
super(detailMessage);
}
/**
* Constructs a new {@code Exception} with the current stack trace, the
* specified detail message and the specified cause.
*
* @param detailMessage
* the detail message for this exception.
* @param throwable
* the cause of this exception.
*/
public Exception(String detailMessage, Throwable throwable) {
super(detailMessage, throwable);
}
/**
* Constructs a new {@code Exception} with the current stack trace and the
* specified cause.
*
* @param throwable
* the cause of this exception.
*/
public Exception(Throwable throwable) {
super(throwable);
}
/**
* Constructs a new exception with the specified detail message,
* cause, suppression enabled or disabled, and writable stack
* trace enabled or disabled.
*
* @param message the detail message.
* @param cause the cause. (A {@code null} value is permitted,
* and indicates that the cause is nonexistent or unknown.)
* @param enableSuppression whether or not suppression is enabled
* or disabled
* @param writableStackTrace whether or not the stack trace should
* be writable
*/
protected Exception(String message, Throwable cause, boolean enableSuppression, boolean writableStackTrace) {
try {
Field field = null;
if (writableStackTrace) {
fillInStackTrace();
} else {
field = Throwable.class.getDeclaredField("stackTrace");
field.setAccessible(true);
field.set(this, null);
}
field = Throwable.class.getDeclaredField("detailMessage");
field.setAccessible(true);
field.set(this, message);
field = Throwable.class.getDeclaredField("cause");
field.setAccessible(true);
field.set(this, cause);
if (!enableSuppression) {
field = Throwable.class.getDeclaredField("suppressedExceptions");
field.setAccessible(true);
field.set(this, null);
}
} catch (Exception e) {
e.printStackTrace();
}
}
public Class[] getClassContext() {
return classContext;
}
private static class SecurityManagerEx extends SecurityManager
{
private static SecurityManagerEx sm;
public static SecurityManagerEx getInstance() {
// No synchronized block because we don't really care
// if multiple instances are created at some point
if (sm == null) {
sm = new SecurityManagerEx();
}
return sm;
}
public Class[] getThrowableContext(Throwable t) {
try {
Class[] context = getClassContext();
int nb = 0;
for (;;) {
if (context[context.length - 1 - nb] == t.getClass()) {
break;
}
nb++;
}
Class[] nc = new Class[nb];
System.arraycopy(context, context.length - nb, nc, 0, nb);
return nc;
} catch (Exception e) {
return null;
}
}
}
}