Ошибка java lang reflect undeclaredthrowableexception

I have the following code

public Object handlePermission(ProceedingJoinPoint joinPoint, RequirePermission permission) throws AccessException, Throwable {
    System.out.println("Permission = " + permission.value());
    if (user.hasPermission(permission.value())) {
        System.out.println("Permission granted ");
        return joinPoint.proceed();
    } else {
        System.out.println("No Permission");
        throw new AccessException("Current user does not have required permission");
    }

}

When I use a user that does not have permissions, I get java.lang.reflect.UndeclaredThrowableException instead of AccessException.

Emerson Luiz's user avatar

asked Mar 30, 2011 at 17:53

user373201's user avatar

user373201user373201

10.9k34 gold badges112 silver badges168 bronze badges

1

AccessException is a checked exception, but it was thrown from the method that doesn’t declare it in its throws clause (actually — from the aspect intercepting that method). It’s an abnormal condition in Java, so your exception is wrapped with UndeclaredThrowableException, which is unchecked.

To get your exception as is, you can either declare it in the throws clause of the method being intercepted by your aspect, or use another unchecked exception (i.e. a subclass of RuntimeException) instead of AccessException.

answered Mar 30, 2011 at 18:12

axtavt's user avatar

6

I have the following code

public Object handlePermission(ProceedingJoinPoint joinPoint, RequirePermission permission) throws AccessException, Throwable {
    System.out.println("Permission = " + permission.value());
    if (user.hasPermission(permission.value())) {
        System.out.println("Permission granted ");
        return joinPoint.proceed();
    } else {
        System.out.println("No Permission");
        throw new AccessException("Current user does not have required permission");
    }

}

When I use a user that does not have permissions, I get java.lang.reflect.UndeclaredThrowableException instead of AccessException.

Emerson Luiz's user avatar

asked Mar 30, 2011 at 17:53

user373201's user avatar

user373201user373201

10.9k34 gold badges112 silver badges168 bronze badges

1

AccessException is a checked exception, but it was thrown from the method that doesn’t declare it in its throws clause (actually — from the aspect intercepting that method). It’s an abnormal condition in Java, so your exception is wrapped with UndeclaredThrowableException, which is unchecked.

To get your exception as is, you can either declare it in the throws clause of the method being intercepted by your aspect, or use another unchecked exception (i.e. a subclass of RuntimeException) instead of AccessException.

answered Mar 30, 2011 at 18:12

axtavt's user avatar

6

Предисловие

Я начал писать веб-интерфейс в последние два дня, так как бэк-энд проекта — мой единственный человек, писать его медленно. , Обнаружено много странных проблем, и в основном их может решить только один человек. Сегодня днем ​​надолго задержался на этом вопросе. Теперь у меня все еще болит мозг.

проблема

Бизнесу необходимо реализовать функцию перехвата параметров запроса. Проверьте, включен ли токен. Проект реализован на базе springmvc, здесь естественно использовать технологию пружинного аспекта. Перехватите все запросы контроллера, а затем проверьте, передан ли параметр токена. Если он не переносится, генерируется настраиваемое исключение. Затем вызовите единый класс обработки исключений для его обработки.
Участвуют следующие классы:

package com.insigmaunited.lightai.base;

import com.insigmaunited.lightai.exception.TokenEmptyException;
import com.insigmaunited.lightai.result.Response;
import com.insigmaunited.lightai.util.StringUtil;
import org.aspectj.lang.annotation.Before;
import org.springframework.stereotype.Component;

import org.aspectj.lang.ProceedingJoinPoint;
import org.aspectj.lang.annotation.Around;
import org.aspectj.lang.annotation.Aspect;
import org.aspectj.lang.annotation.Pointcut;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.web.context.request.RequestAttributes;
import org.springframework.web.context.request.RequestContextHolder;
import org.springframework.web.context.request.ServletRequestAttributes;

import javax.servlet.http.HttpServletRequest;

/**
   * Разрешение на перехват АОП
 * @author Administrator
 *
 */
@Component
@Aspect
public class PermissionAop {

    private final Logger logger = LoggerFactory.getLogger(PermissionAop.class);

         // Определяем pointcut
    @Pointcut("execution(* com.insigmaunited.lightai.controller.*Controller.*(..))")
    public void pointCut(){}

    @Before("pointCut()")
    public void before() throws Throwable {
        RequestAttributes ra = RequestContextHolder.getRequestAttributes();
        ServletRequestAttributes sra = (ServletRequestAttributes) ra;
        HttpServletRequest request = sra.getRequest();

        String url = request.getRequestURL().toString();
        String method = request.getMethod();
        String uri = request.getRequestURI();
        String queryString = request.getQueryString();
        System.out.println(url);
        System.out.println(method);
        System.out.println(uri);
        System.out.println(queryString);

        if (StringUtil.isNotEmpty(queryString) && queryString.indexOf("token") != -1 ){
        }else{
                         выбросить новое TokenEmptyException («токен отсутствует»);
        }
    }


}

Пользовательский класс исключения

package com.insigmaunited.lightai.exception;

public class TokenEmptyException extends Exception {
    public TokenEmptyException(String message) {
        super(message);
    }
}

Единый класс обработки исключений

package com.insigmaunited.lightai.exception;

import com.insigmaunited.lightai.base.BaseException;
import com.insigmaunited.lightai.result.Response;
import org.springframework.http.HttpStatus;
import org.springframework.web.HttpMediaTypeNotSupportedException;
import org.springframework.web.HttpRequestMethodNotSupportedException;
import org.springframework.web.bind.annotation.ControllerAdvice;
import org.springframework.web.bind.annotation.ExceptionHandler;
import org.springframework.web.bind.annotation.ResponseBody;
import org.springframework.web.bind.annotation.ResponseStatus;
import com.insigmaunited.lightai.exception.TokenEmptyException;

import javax.xml.bind.ValidationException;

@ControllerAdvice
@ResponseBody
public class ExceptionAdvice extends BaseException {

    /**
     * 400 - Bad Request
     */
    @ResponseStatus(HttpStatus.BAD_REQUEST)
    @ExceptionHandler(ValidationException.class)
    public Response handleValidationException(ValidationException e) {
                 logger.error («Ошибка проверки параметра», e);
        return new Response().failure("validation_exception");
    }

    /**
     * 405 - Method Not Allowed
     */
    @ResponseStatus(HttpStatus.METHOD_NOT_ALLOWED)
    @ExceptionHandler(HttpRequestMethodNotSupportedException.class)
    public Response handleHttpRequestMethodNotSupportedException(HttpRequestMethodNotSupportedException e) {
                 logger.error («Текущий метод запроса не поддерживается», д);
        return new Response().failure("request_method_not_supported");
    }

    /**
     * 415 - Unsupported Media Type
     */
    @ResponseStatus(HttpStatus.UNSUPPORTED_MEDIA_TYPE)
    @ExceptionHandler(HttpMediaTypeNotSupportedException.class)
    public Response handleHttpMediaTypeNotSupportedException(Exception e) {
                 logger.error («Текущий тип носителя не поддерживается», д);
        return new Response().failure("content_type_not_supported");
    }

    @ResponseStatus(HttpStatus.INTERNAL_SERVER_ERROR)
    @ExceptionHandler(TokenEmptyException.class)
    public Response handleTokenEmptyException(Exception e) {
                 logger.error («отсутствует параметр токена», e);
                 return new Response (). failure («параметр токена отсутствует»);
    }

    /**
     * 500 - Internal Server Error
     */
    @ResponseStatus(HttpStatus.INTERNAL_SERVER_ERROR)
    @ExceptionHandler(Exception.class)
    public Response handleException(Exception e) {
                 logger.error ("Ненормальная работа службы", e);
                 вернуть новый Response (). failure («Ненормальная работа службы»);
    }
}

Интерфейс вызывается в это время, и ожидается, что он должен

{
    "success": false,
         "message": "Отсутствует параметр токена",
    "data": null
}

На самом деле возвращено

{
    "success": false,
    "message": "Служба работает ненормально",
    "data": null
}

Ошибка консоли выглядит следующим образом:

http://localhost:8080/user/3/profile
GET
/user/3/profile
null
 [ОШИБКА] 2017-12-08 18:29:19-com.insigmaunited.lightai.exception.ExceptionAdvice-ExceptionAdvice.java (63) - Ненормальная операция службы
java.lang.reflect.UndeclaredThrowableException
    at com.insigmaunited.lightai.controller.UserController$$EnhancerBySpringCGLIB$$e4eb8ece.profile(<generated>)
    at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
    at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:62)
    at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)
    at java.lang.reflect.Method.invoke(Method.java:498)
    at org.springframework.web.method.support.InvocableHandlerMethod.doInvoke(InvocableHandlerMethod.java:221)
    at org.springframework.web.method.support.InvocableHandlerMethod.invokeForRequest(InvocableHandlerMethod.java:136)
    at org.springframework.web.servlet.mvc.method.annotation.ServletInvocableHandlerMethod.invokeAndHandle(ServletInvocableHandlerMethod.java:110)
    at org.springframework.web.servlet.mvc.method.annotation.RequestMappingHandlerAdapter.invokeHandlerMethod(RequestMappingHandlerAdapter.java:832)
    at org.springframework.web.servlet.mvc.method.annotation.RequestMappingHandlerAdapter.handleInternal(RequestMappingHandlerAdapter.java:743)
    at org.springframework.web.servlet.mvc.method.AbstractHandlerMethodAdapter.handle(AbstractHandlerMethodAdapter.java:85)
    at org.springframework.web.servlet.DispatcherServlet.doDispatch(DispatcherServlet.java:961)
    at org.springframework.web.servlet.DispatcherServlet.doService(DispatcherServlet.java:895)
    at org.springframework.web.servlet.FrameworkServlet.processRequest(FrameworkServlet.java:967)
    at org.springframework.web.servlet.FrameworkServlet.doGet(FrameworkServlet.java:858)
    at javax.servlet.http.HttpServlet.service(HttpServlet.java:634)
    at org.springframework.web.servlet.FrameworkServlet.service(FrameworkServlet.java:843)
    at javax.servlet.http.HttpServlet.service(HttpServlet.java:741)
    at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:231)
    at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:166)
    at org.apache.tomcat.websocket.server.WsFilter.doFilter(WsFilter.java:53)
    at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:193)
    at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:166)
    at org.apache.catalina.core.StandardWrapperValve.invoke(StandardWrapperValve.java:199)
    at org.apache.catalina.core.StandardContextValve.invoke(StandardContextValve.java:96)
    at org.apache.catalina.authenticator.AuthenticatorBase.invoke(AuthenticatorBase.java:475)
    at org.apache.catalina.core.StandardHostValve.invoke(StandardHostValve.java:140)
    at org.apache.catalina.valves.ErrorReportValve.invoke(ErrorReportValve.java:80)
    at org.apache.catalina.valves.AbstractAccessLogValve.invoke(AbstractAccessLogValve.java:651)
    at org.apache.catalina.core.StandardEngineValve.invoke(StandardEngineValve.java:87)
    at org.apache.catalina.connector.CoyoteAdapter.service(CoyoteAdapter.java:342)
    at org.apache.coyote.http11.Http11Processor.service(Http11Processor.java:498)
    at org.apache.coyote.AbstractProcessorLight.process(AbstractProcessorLight.java:66)
    at org.apache.coyote.AbstractProtocol$ConnectionHandler.process(AbstractProtocol.java:796)
    at org.apache.tomcat.util.net.Nio2Endpoint$SocketProcessor.doRun(Nio2Endpoint.java:1688)
    at org.apache.tomcat.util.net.SocketProcessorBase.run(SocketProcessorBase.java:49)
    at org.apache.tomcat.util.net.AbstractEndpoint.processSocket(AbstractEndpoint.java:914)
    at org.apache.tomcat.util.net.Nio2Endpoint$Nio2SocketWrapper$4.completed(Nio2Endpoint.java:536)
    at org.apache.tomcat.util.net.Nio2Endpoint$Nio2SocketWrapper$4.completed(Nio2Endpoint.java:514)
    at sun.nio.ch.Invoker.invokeUnchecked(Invoker.java:126)
    at sun.nio.ch.Invoker$2.run(Invoker.java:218)
    at sun.nio.ch.AsynchronousChannelGroupImpl$1.run(AsynchronousChannelGroupImpl.java:112)
    at java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1142)
    at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:617)
    at java.lang.Thread.run(Thread.java:748)
 Вызвано: com.insigmaunited.lightai.exception.TokenEmptyException: токен отсутствует
    at com.insigmaunited.lightai.base.PermissionAop.before(PermissionAop.java:53)
    at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
    at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:62)
    at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)
    at java.lang.reflect.Method.invoke(Method.java:498)
    at org.springframework.aop.aspectj.AbstractAspectJAdvice.invokeAdviceMethodWithGivenArgs(AbstractAspectJAdvice.java:620)
    at org.springframework.aop.aspectj.AbstractAspectJAdvice.invokeAdviceMethod(AbstractAspectJAdvice.java:602)
    at org.springframework.aop.aspectj.AspectJMethodBeforeAdvice.before(AspectJMethodBeforeAdvice.java:41)
    at org.springframework.aop.framework.adapter.MethodBeforeAdviceInterceptor.invoke(MethodBeforeAdviceInterceptor.java:51)
    at org.springframework.aop.framework.ReflectiveMethodInvocation.proceed(ReflectiveMethodInvocation.java:179)
    at org.springframework.aop.interceptor.ExposeInvocationInterceptor.invoke(ExposeInvocationInterceptor.java:92)
    at org.springframework.aop.framework.ReflectiveMethodInvocation.proceed(ReflectiveMethodInvocation.java:179)
    at org.springframework.aop.framework.CglibAopProxy$DynamicAdvisedInterceptor.intercept(CglibAopProxy.java:655)
    ... 45 more

Это странно. Почему созданное мной настраиваемое исключение превратилось в UndeclaredThrowableException, которое не могло быть обработано единым обработчиком исключений.

причина

Через поисковик наконец нашел причину:

Наш класс обработки исключений на самом деле является реализацией динамического прокси.

Если исключение является проверенным исключением и не объявлено в интерфейсе динамического прокси, оно будет заключено в оболочку UndeclaredThrowableException.
Определенное нами настраиваемое исключение определяется как проверенное исключение, что приводит к его упаковке как UndeclaredThrowableException.

Официальное объяснение документа

Аномальное различие

решить

Узнать причину очень просто. Либо вызовите непроверенное исключение java.lang.RuntimeException или java.lang.Error, либо интерфейс должен объявить исключение.

Здесь вы можете изменить настраиваемое исключение как исключение времени выполнения.

package com.insigmaunited.lightai.exception;

public class TokenEmptyException extends RuntimeException {
    public TokenEmptyException(String message) {
        super(message);
    }
}

урок

1. По возможности определяйте настраиваемые исключения как исключения времени выполнения.
2. Понятие исключения неясно. Фундамент не прочный.

Автор оригинала: Mona Mohamadinia.

1. Обзор

В этом уроке мы рассмотрим, что заставляет Java выбрасывать экземпляр UndeclaredThrowableException exception.

Во-первых, мы начнем с небольшой теории. Затем мы попытаемся лучше понять природу этого исключения с помощью двух реальных примеров.

Теоретически говоря, Java создаст экземпляр UndeclaredThrowableException , когда мы попытаемся создать необъявленное проверенное исключение . То есть мы не объявляли проверенное исключение в предложении throws , но мы выбрасываем это исключение в теле метода.

Можно возразить, что это невозможно, так как компилятор Java предотвращает это с помощью ошибки компиляции. Например, если мы попытаемся скомпилировать:

public void undeclared() {
    throw new IOException();
}

Компилятор Java завершает работу с сообщением:

java: unreported exception java.io.IOException; must be caught or declared to be thrown

Даже если выбрасывание необъявленных проверенных исключений может не произойти во время компиляции, это все еще возможно во время выполнения. Например, давайте рассмотрим прокси-сервер времени выполнения, перехватывающий метод, который не создает никаких исключений:

public void save(Object data) {
    // omitted
}

Если прокси-сервер сам создает проверенное исключение, с точки зрения вызывающего, метод save создает это проверенное исключение. Вызывающий, вероятно, ничего не знает об этом прокси-сервере и будет обвинять save в этом исключении.

В таких обстоятельствах Java обернет фактическое проверенное исключение в исключение UndeclaredThrowableException и вместо этого выбросит исключение UndeclaredThrowableException . Стоит отметить, что UndeclaredThrowableException само по себе является непроверенным исключением.

Теперь, когда мы достаточно знаем об этой теории, давайте рассмотрим несколько реальных примеров.

3. Динамический прокси-сервер Java

В качестве нашего первого примера давайте создадим runtime proxy для java.util.Перечислите интерфейс и перехватите вызовы его методов. Во-первых, мы должны реализовать интерфейс InvocationHandler и поместить туда дополнительную логику:

public class ExceptionalInvocationHandler implements InvocationHandler {

    @Override
    public Object invoke(Object proxy, Method method, Object[] args) throws Throwable {
        if ("size".equals(method.getName())) {
            throw new SomeCheckedException("Always fails");
        }
            
        throw new RuntimeException();
    }
}

public class SomeCheckedException extends Exception {

    public SomeCheckedException(String message) {
        super(message);
    }
}

Этот прокси-сервер выдает проверенное исключение, если проксируемый метод имеет размер . В противном случае он вызовет непроверенное исключение.

Давайте посмотрим, как Java справляется с обеими ситуациями. Сначала мы вызовем метод List.size() :

ClassLoader classLoader = getClass().getClassLoader();
InvocationHandler invocationHandler = new ExceptionalInvocationHandler();
List proxy = (List) Proxy.newProxyInstance(classLoader, 
  new Class[] { List.class }, invocationHandler);

assertThatThrownBy(proxy::size)
  .isInstanceOf(UndeclaredThrowableException.class)
  .hasCauseInstanceOf(SomeCheckedException.class);

Как показано выше, мы создаем прокси-сервер для интерфейса List и вызываем на нем метод size . Прокси, в свою очередь, перехватывает вызов и выдает проверенное исключение. Затем Java обертывает это проверенное исключение внутри экземпляра UndeclaredThrowableException. Это происходит потому, что мы каким-то образом выбрасываем проверенное исключение, не объявляя его в объявлении метода.

Если мы вызовем любой другой метод в интерфейсе List :

assertThatThrownBy(proxy::isEmpty).isInstanceOf(RuntimeException.class);

Поскольку прокси-сервер выдает непроверенное исключение, Java позволяет исключению распространяться как есть.

4. Пружинный аспект

То же самое происходит, когда мы выбрасываем проверенное исключение в аспекте Spring , в то время как рекомендуемые методы их не объявляли. Давайте начнем с аннотации:

@Target(ElementType.METHOD)
@Retention(RetentionPolicy.RUNTIME)
public @interface ThrowUndeclared {}

Теперь мы собираемся посоветовать все методы, аннотированные этой аннотацией:

@Aspect
@Component
public class UndeclaredAspect {

    @Around("@annotation(undeclared)")
    public Object advise(ProceedingJoinPoint pjp, ThrowUndeclared undeclared) throws Throwable {
        throw new SomeCheckedException("AOP Checked Exception");
    }
}

В принципе, этот совет заставит все аннотированные методы выдавать проверенное исключение, даже если они не объявили такое исключение . Теперь давайте создадим сервис:

@Service
public class UndeclaredService {

    @ThrowUndeclared
    public void doSomething() {}
}

Если мы вызовем аннотированный метод, Java выдаст экземпляр UndeclaredThrowableException exception:

@RunWith(SpringRunner.class)
@SpringBootTest(classes = UndeclaredApplication.class)
public class UndeclaredThrowableExceptionIntegrationTest {

    @Autowired private UndeclaredService service;

    @Test
    public void givenAnAspect_whenCallingAdvisedMethod_thenShouldWrapTheException() {
        assertThatThrownBy(service::doSomething)
          .isInstanceOf(UndeclaredThrowableException.class)
          .hasCauseInstanceOf(SomeCheckedException.class);
    }
}

Как показано выше, Java инкапсулирует фактическое исключение в качестве причины и вместо этого вызывает исключение UndeclaredThrowableException .

5. Заключение

В этом уроке мы увидели, что заставляет Java выбрасывать экземпляр UndeclaredThrowableException exception.

Как обычно, все примеры доступны на GitHub .

I have the following code

public Object handlePermission(ProceedingJoinPoint joinPoint, RequirePermission permission) throws AccessException, Throwable {
    System.out.println("Permission = " + permission.value());
    if (user.hasPermission(permission.value())) {
        System.out.println("Permission granted ");
        return joinPoint.proceed();
    } else {
        System.out.println("No Permission");
        throw new AccessException("Current user does not have required permission");
    }

}

When I use a user that does not have permissions, I get java.lang.reflect.UndeclaredThrowableException instead of AccessException.

Emerson Luiz's user avatar

asked Mar 30, 2011 at 17:53

user373201's user avatar

user373201user373201

10.7k33 gold badges111 silver badges168 bronze badges

1

AccessException is a checked exception, but it was thrown from the method that doesn’t declare it in its throws clause (actually — from the aspect intercepting that method). It’s an abnormal condition in Java, so your exception is wrapped with UndeclaredThrowableException, which is unchecked.

To get your exception as is, you can either declare it in the throws clause of the method being intercepted by your aspect, or use another unchecked exception (i.e. a subclass of RuntimeException) instead of AccessException.

answered Mar 30, 2011 at 18:12

axtavt's user avatar

6

Summary:

Ctors

| Methods

| Inherited Methods


public

class
UndeclaredThrowableException

extends RuntimeException

java.lang.Object
   ↳ java.lang.Throwable
     ↳ java.lang.Exception
       ↳ java.lang.RuntimeException
         ↳ java.lang.reflect.UndeclaredThrowableException

Thrown by a method invocation on a proxy instance if its invocation
handler’s invoke method throws a
checked exception (a Throwable that is not assignable
to RuntimeException or Error) that
is not assignable to any of the exception types declared in the
throws clause of the method that was invoked on the
proxy instance and dispatched to the invocation handler.

An UndeclaredThrowableException instance contains
the undeclared checked exception that was thrown by the invocation
handler, and it can be retrieved with the
getUndeclaredThrowable() method.
UndeclaredThrowableException extends
RuntimeException, so it is an unchecked exception
that wraps a checked exception.

As of release 1.4, this exception has been retrofitted to
conform to the general purpose exception-chaining mechanism. The
«undeclared checked exception that was thrown by the invocation
handler» that may be provided at construction time and accessed via
the getUndeclaredThrowable() method is now known as the
cause, and may be accessed via the Throwable.getCause() method, as well as the aforementioned «legacy
method.»

Summary

Public constructors


UndeclaredThrowableException(Throwable undeclaredThrowable)

Constructs an UndeclaredThrowableException with the
specified Throwable.


UndeclaredThrowableException(Throwable undeclaredThrowable, String s)

Constructs an UndeclaredThrowableException with the
specified Throwable and a detail message.

Public methods


Throwable


getCause()

Returns the cause of this exception (the Throwable
instance wrapped in this UndeclaredThrowableException,
which may be null).


Throwable


getUndeclaredThrowable()

Returns the Throwable instance wrapped in this
UndeclaredThrowableException, which may be null.

Inherited methods

From class

java.lang.Throwable

final

void


addSuppressed(Throwable exception)

Appends the specified exception to the exceptions that were
suppressed in order to deliver this exception.


Throwable


fillInStackTrace()

Fills in the execution stack trace.


Throwable


getCause()

Returns the cause of this throwable or null if the
cause is nonexistent or unknown.


String


getLocalizedMessage()

Creates a localized description of this throwable.


String


getMessage()

Returns the detail message string of this throwable.


StackTraceElement[]


getStackTrace()

Provides programmatic access to the stack trace information printed by
printStackTrace().

final

Throwable[]


getSuppressed()

Returns an array containing all of the exceptions that were
suppressed, typically by the try-with-resources
statement, in order to deliver this exception.


Throwable


initCause(Throwable cause)

Initializes the cause of this throwable to the specified value.


void


printStackTrace()

Prints this throwable and its backtrace to the
standard error stream.


void


printStackTrace(PrintWriter s)

Prints this throwable and its backtrace to the specified
print writer.


void


printStackTrace(PrintStream s)

Prints this throwable and its backtrace to the specified print stream.


void


setStackTrace(StackTraceElement[] stackTrace)

Sets the stack trace elements that will be returned by
getStackTrace() and printed by printStackTrace()
and related methods.


String


toString()

Returns a short description of this throwable.

From class

java.lang.Object


Object


clone()

Creates and returns a copy of this object.


boolean


equals(Object obj)

Indicates whether some other object is «equal to» this one.


void


finalize()

Called by the garbage collector on an object when garbage collection
determines that there are no more references to the object.

final

Class<?>


getClass()

Returns the runtime class of this Object.


int


hashCode()

Returns a hash code value for the object.

final

void


notify()

Wakes up a single thread that is waiting on this object’s
monitor.

final

void


notifyAll()

Wakes up all threads that are waiting on this object’s monitor.


String


toString()

Returns a string representation of the object.

final

void


wait(long timeout, int nanos)

Causes the current thread to wait until another thread invokes the
notify() method or the
notifyAll() method for this object, or
some other thread interrupts the current thread, or a certain
amount of real time has elapsed.

final

void


wait(long timeout)

Causes the current thread to wait until either another thread invokes the
notify() method or the
notifyAll() method for this object, or a
specified amount of time has elapsed.

final

void


wait()

Causes the current thread to wait until another thread invokes the
notify() method or the
notifyAll() method for this object.

Public constructors

UndeclaredThrowableException

public UndeclaredThrowableException (Throwable undeclaredThrowable)

Constructs an UndeclaredThrowableException with the
specified Throwable.

Parameters
undeclaredThrowable Throwable: the undeclared checked exception
that was thrown

UndeclaredThrowableException

public UndeclaredThrowableException (Throwable undeclaredThrowable, 
                String s)

Constructs an UndeclaredThrowableException with the
specified Throwable and a detail message.

Parameters
undeclaredThrowable Throwable: the undeclared checked exception
that was thrown
s String: the detail message

Public methods

getCause

public Throwable getCause ()

Returns the cause of this exception (the Throwable
instance wrapped in this UndeclaredThrowableException,
which may be null).

Returns
Throwable the cause of this exception.

getUndeclaredThrowable

public Throwable getUndeclaredThrowable ()

Returns the Throwable instance wrapped in this
UndeclaredThrowableException, which may be null.

This method predates the general-purpose exception chaining facility.
The Throwable#getCause() method is now the preferred means of
obtaining this information.

Returns
Throwable the undeclared checked exception that was thrown

Thrown by a method invocation on a proxy instance if its invocation
handler’s invoke method throws a
checked exception (a Throwable that is not assignable
to RuntimeException or Error) that
is not assignable to any of the exception types declared in the
throws clause of the method that was invoked on the
proxy instance and dispatched to the invocation handler.

An UndeclaredThrowableException instance contains
the undeclared checked exception that was thrown by the invocation
handler, and it can be retrieved with the
getUndeclaredThrowable() method.
UndeclaredThrowableException extends
RuntimeException, so it is an unchecked exception
that wraps a checked exception.

As of release 1.4, this exception has been retrofitted to
conform to the general purpose exception-chaining mechanism. The
«undeclared checked exception that was thrown by the invocation
handler» that may be provided at construction time and accessed via
the getUndeclaredThrowable() method is now known as the
cause, and may be accessed via the Throwable.getCause() method, as well as the aforementioned «legacy
method.»

Public Constructor Summary

Public Method Summary

Throwable

getCause()

Returns the cause of this exception (the Throwable
instance wrapped in this UndeclaredThrowableException,
which may be null).

Throwable

getUndeclaredThrowable()

Returns the Throwable instance wrapped in this
UndeclaredThrowableException, which may be null.

Inherited Method Summary


From class
java.lang.Object

Object

clone()

Creates and returns a copy of this Object.

boolean

equals(Object obj)

Compares this instance with the specified object and indicates if they
are equal.

void

finalize()

Invoked when the garbage collector has detected that this instance is no longer reachable.

final

Class<?>

getClass()

Returns the unique instance of Class that represents this
object’s class.

int

hashCode()

Returns an integer hash code for this object.

final

void

notify()

Causes a thread which is waiting on this object’s monitor (by means of
calling one of the wait() methods) to be woken up.

final

void

notifyAll()

Causes all threads which are waiting on this object’s monitor (by means
of calling one of the wait() methods) to be woken up.

String

toString()

Returns a string containing a concise, human-readable description of this
object.

final

void

wait(long timeout, int nanos)

Causes the calling thread to wait until another thread calls the notify() or notifyAll() method of this object or until the
specified timeout expires.

final

void

wait(long timeout)

Causes the calling thread to wait until another thread calls the notify() or notifyAll() method of this object or until the
specified timeout expires.

final

void

wait()

Causes the calling thread to wait until another thread calls the notify() or notifyAll() method of this object.

Public Constructors


public

UndeclaredThrowableException
(Throwable undeclaredThrowable)

Constructs an UndeclaredThrowableException with the
specified Throwable.

Parameters
undeclaredThrowable the undeclared checked exception
that was thrown


public

UndeclaredThrowableException
(Throwable undeclaredThrowable, String s)

Constructs an UndeclaredThrowableException with the
specified Throwable and a detail message.

Parameters
undeclaredThrowable the undeclared checked exception
that was thrown
s the detail message

Public Methods


public

Returns the cause of this exception (the Throwable
instance wrapped in this UndeclaredThrowableException,
which may be null).

Returns
  • the cause of this exception.


public

Throwable

getUndeclaredThrowable
()

Returns the Throwable instance wrapped in this
UndeclaredThrowableException, which may be null.

This method predates the general-purpose exception chaining facility.
The Throwable.getCause() method is now the preferred means of
obtaining this information.

Returns
  • the undeclared checked exception that was thrown

Предисловие

Я начал писать веб-интерфейс в последние два дня, так как бэк-энд проекта — мой единственный человек, писать его медленно. , Обнаружено много странных проблем, и в основном их может решить только один человек. Сегодня днем ​​надолго задержался на этом вопросе. Теперь у меня все еще болит мозг.

проблема

Бизнесу необходимо реализовать функцию перехвата параметров запроса. Проверьте, включен ли токен. Проект реализован на базе springmvc, здесь естественно использовать технологию пружинного аспекта. Перехватите все запросы контроллера, а затем проверьте, передан ли параметр токена. Если он не переносится, генерируется настраиваемое исключение. Затем вызовите единый класс обработки исключений для его обработки.
Участвуют следующие классы:

package com.insigmaunited.lightai.base;

import com.insigmaunited.lightai.exception.TokenEmptyException;
import com.insigmaunited.lightai.result.Response;
import com.insigmaunited.lightai.util.StringUtil;
import org.aspectj.lang.annotation.Before;
import org.springframework.stereotype.Component;

import org.aspectj.lang.ProceedingJoinPoint;
import org.aspectj.lang.annotation.Around;
import org.aspectj.lang.annotation.Aspect;
import org.aspectj.lang.annotation.Pointcut;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.web.context.request.RequestAttributes;
import org.springframework.web.context.request.RequestContextHolder;
import org.springframework.web.context.request.ServletRequestAttributes;

import javax.servlet.http.HttpServletRequest;

/**
   * Разрешение на перехват АОП
 * @author Administrator
 *
 */
@Component
@Aspect
public class PermissionAop {

    private final Logger logger = LoggerFactory.getLogger(PermissionAop.class);

         // Определяем pointcut
    @Pointcut("execution(* com.insigmaunited.lightai.controller.*Controller.*(..))")
    public void pointCut(){}

    @Before("pointCut()")
    public void before() throws Throwable {
        RequestAttributes ra = RequestContextHolder.getRequestAttributes();
        ServletRequestAttributes sra = (ServletRequestAttributes) ra;
        HttpServletRequest request = sra.getRequest();

        String url = request.getRequestURL().toString();
        String method = request.getMethod();
        String uri = request.getRequestURI();
        String queryString = request.getQueryString();
        System.out.println(url);
        System.out.println(method);
        System.out.println(uri);
        System.out.println(queryString);

        if (StringUtil.isNotEmpty(queryString) && queryString.indexOf("token") != -1 ){
        }else{
                         выбросить новое TokenEmptyException («токен отсутствует»);
        }
    }


}

Пользовательский класс исключения

package com.insigmaunited.lightai.exception;

public class TokenEmptyException extends Exception {
    public TokenEmptyException(String message) {
        super(message);
    }
}

Единый класс обработки исключений

package com.insigmaunited.lightai.exception;

import com.insigmaunited.lightai.base.BaseException;
import com.insigmaunited.lightai.result.Response;
import org.springframework.http.HttpStatus;
import org.springframework.web.HttpMediaTypeNotSupportedException;
import org.springframework.web.HttpRequestMethodNotSupportedException;
import org.springframework.web.bind.annotation.ControllerAdvice;
import org.springframework.web.bind.annotation.ExceptionHandler;
import org.springframework.web.bind.annotation.ResponseBody;
import org.springframework.web.bind.annotation.ResponseStatus;
import com.insigmaunited.lightai.exception.TokenEmptyException;

import javax.xml.bind.ValidationException;

@ControllerAdvice
@ResponseBody
public class ExceptionAdvice extends BaseException {

    /**
     * 400 - Bad Request
     */
    @ResponseStatus(HttpStatus.BAD_REQUEST)
    @ExceptionHandler(ValidationException.class)
    public Response handleValidationException(ValidationException e) {
                 logger.error («Ошибка проверки параметра», e);
        return new Response().failure("validation_exception");
    }

    /**
     * 405 - Method Not Allowed
     */
    @ResponseStatus(HttpStatus.METHOD_NOT_ALLOWED)
    @ExceptionHandler(HttpRequestMethodNotSupportedException.class)
    public Response handleHttpRequestMethodNotSupportedException(HttpRequestMethodNotSupportedException e) {
                 logger.error («Текущий метод запроса не поддерживается», д);
        return new Response().failure("request_method_not_supported");
    }

    /**
     * 415 - Unsupported Media Type
     */
    @ResponseStatus(HttpStatus.UNSUPPORTED_MEDIA_TYPE)
    @ExceptionHandler(HttpMediaTypeNotSupportedException.class)
    public Response handleHttpMediaTypeNotSupportedException(Exception e) {
                 logger.error («Текущий тип носителя не поддерживается», д);
        return new Response().failure("content_type_not_supported");
    }

    @ResponseStatus(HttpStatus.INTERNAL_SERVER_ERROR)
    @ExceptionHandler(TokenEmptyException.class)
    public Response handleTokenEmptyException(Exception e) {
                 logger.error («отсутствует параметр токена», e);
                 return new Response (). failure («параметр токена отсутствует»);
    }

    /**
     * 500 - Internal Server Error
     */
    @ResponseStatus(HttpStatus.INTERNAL_SERVER_ERROR)
    @ExceptionHandler(Exception.class)
    public Response handleException(Exception e) {
                 logger.error ("Ненормальная работа службы", e);
                 вернуть новый Response (). failure («Ненормальная работа службы»);
    }
}

Интерфейс вызывается в это время, и ожидается, что он должен

{
    "success": false,
         "message": "Отсутствует параметр токена",
    "data": null
}

На самом деле возвращено

{
    "success": false,
    "message": "Служба работает ненормально",
    "data": null
}

Ошибка консоли выглядит следующим образом:

http://localhost:8080/user/3/profile
GET
/user/3/profile
null
 [ОШИБКА] 2017-12-08 18:29:19-com.insigmaunited.lightai.exception.ExceptionAdvice-ExceptionAdvice.java (63) - Ненормальная операция службы
java.lang.reflect.UndeclaredThrowableException
    at com.insigmaunited.lightai.controller.UserController$$EnhancerBySpringCGLIB$$e4eb8ece.profile(<generated>)
    at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
    at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:62)
    at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)
    at java.lang.reflect.Method.invoke(Method.java:498)
    at org.springframework.web.method.support.InvocableHandlerMethod.doInvoke(InvocableHandlerMethod.java:221)
    at org.springframework.web.method.support.InvocableHandlerMethod.invokeForRequest(InvocableHandlerMethod.java:136)
    at org.springframework.web.servlet.mvc.method.annotation.ServletInvocableHandlerMethod.invokeAndHandle(ServletInvocableHandlerMethod.java:110)
    at org.springframework.web.servlet.mvc.method.annotation.RequestMappingHandlerAdapter.invokeHandlerMethod(RequestMappingHandlerAdapter.java:832)
    at org.springframework.web.servlet.mvc.method.annotation.RequestMappingHandlerAdapter.handleInternal(RequestMappingHandlerAdapter.java:743)
    at org.springframework.web.servlet.mvc.method.AbstractHandlerMethodAdapter.handle(AbstractHandlerMethodAdapter.java:85)
    at org.springframework.web.servlet.DispatcherServlet.doDispatch(DispatcherServlet.java:961)
    at org.springframework.web.servlet.DispatcherServlet.doService(DispatcherServlet.java:895)
    at org.springframework.web.servlet.FrameworkServlet.processRequest(FrameworkServlet.java:967)
    at org.springframework.web.servlet.FrameworkServlet.doGet(FrameworkServlet.java:858)
    at javax.servlet.http.HttpServlet.service(HttpServlet.java:634)
    at org.springframework.web.servlet.FrameworkServlet.service(FrameworkServlet.java:843)
    at javax.servlet.http.HttpServlet.service(HttpServlet.java:741)
    at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:231)
    at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:166)
    at org.apache.tomcat.websocket.server.WsFilter.doFilter(WsFilter.java:53)
    at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:193)
    at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:166)
    at org.apache.catalina.core.StandardWrapperValve.invoke(StandardWrapperValve.java:199)
    at org.apache.catalina.core.StandardContextValve.invoke(StandardContextValve.java:96)
    at org.apache.catalina.authenticator.AuthenticatorBase.invoke(AuthenticatorBase.java:475)
    at org.apache.catalina.core.StandardHostValve.invoke(StandardHostValve.java:140)
    at org.apache.catalina.valves.ErrorReportValve.invoke(ErrorReportValve.java:80)
    at org.apache.catalina.valves.AbstractAccessLogValve.invoke(AbstractAccessLogValve.java:651)
    at org.apache.catalina.core.StandardEngineValve.invoke(StandardEngineValve.java:87)
    at org.apache.catalina.connector.CoyoteAdapter.service(CoyoteAdapter.java:342)
    at org.apache.coyote.http11.Http11Processor.service(Http11Processor.java:498)
    at org.apache.coyote.AbstractProcessorLight.process(AbstractProcessorLight.java:66)
    at org.apache.coyote.AbstractProtocol$ConnectionHandler.process(AbstractProtocol.java:796)
    at org.apache.tomcat.util.net.Nio2Endpoint$SocketProcessor.doRun(Nio2Endpoint.java:1688)
    at org.apache.tomcat.util.net.SocketProcessorBase.run(SocketProcessorBase.java:49)
    at org.apache.tomcat.util.net.AbstractEndpoint.processSocket(AbstractEndpoint.java:914)
    at org.apache.tomcat.util.net.Nio2Endpoint$Nio2SocketWrapper$4.completed(Nio2Endpoint.java:536)
    at org.apache.tomcat.util.net.Nio2Endpoint$Nio2SocketWrapper$4.completed(Nio2Endpoint.java:514)
    at sun.nio.ch.Invoker.invokeUnchecked(Invoker.java:126)
    at sun.nio.ch.Invoker$2.run(Invoker.java:218)
    at sun.nio.ch.AsynchronousChannelGroupImpl$1.run(AsynchronousChannelGroupImpl.java:112)
    at java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1142)
    at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:617)
    at java.lang.Thread.run(Thread.java:748)
 Вызвано: com.insigmaunited.lightai.exception.TokenEmptyException: токен отсутствует
    at com.insigmaunited.lightai.base.PermissionAop.before(PermissionAop.java:53)
    at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
    at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:62)
    at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)
    at java.lang.reflect.Method.invoke(Method.java:498)
    at org.springframework.aop.aspectj.AbstractAspectJAdvice.invokeAdviceMethodWithGivenArgs(AbstractAspectJAdvice.java:620)
    at org.springframework.aop.aspectj.AbstractAspectJAdvice.invokeAdviceMethod(AbstractAspectJAdvice.java:602)
    at org.springframework.aop.aspectj.AspectJMethodBeforeAdvice.before(AspectJMethodBeforeAdvice.java:41)
    at org.springframework.aop.framework.adapter.MethodBeforeAdviceInterceptor.invoke(MethodBeforeAdviceInterceptor.java:51)
    at org.springframework.aop.framework.ReflectiveMethodInvocation.proceed(ReflectiveMethodInvocation.java:179)
    at org.springframework.aop.interceptor.ExposeInvocationInterceptor.invoke(ExposeInvocationInterceptor.java:92)
    at org.springframework.aop.framework.ReflectiveMethodInvocation.proceed(ReflectiveMethodInvocation.java:179)
    at org.springframework.aop.framework.CglibAopProxy$DynamicAdvisedInterceptor.intercept(CglibAopProxy.java:655)
    ... 45 more

Это странно. Почему созданное мной настраиваемое исключение превратилось в UndeclaredThrowableException, которое не могло быть обработано единым обработчиком исключений.

причина

Через поисковик наконец нашел причину:

Наш класс обработки исключений на самом деле является реализацией динамического прокси.

Если исключение является проверенным исключением и не объявлено в интерфейсе динамического прокси, оно будет заключено в оболочку UndeclaredThrowableException.
Определенное нами настраиваемое исключение определяется как проверенное исключение, что приводит к его упаковке как UndeclaredThrowableException.

Официальное объяснение документа

Аномальное различие

решить

Узнать причину очень просто. Либо вызовите непроверенное исключение java.lang.RuntimeException или java.lang.Error, либо интерфейс должен объявить исключение.

Здесь вы можете изменить настраиваемое исключение как исключение времени выполнения.

package com.insigmaunited.lightai.exception;

public class TokenEmptyException extends RuntimeException {
    public TokenEmptyException(String message) {
        super(message);
    }
}

урок

1. По возможности определяйте настраиваемые исключения как исключения времени выполнения.
2. Понятие исключения неясно. Фундамент не прочный.

java.lang.reflect.Proxy and checked exceptions

On-the-Fly Proxy

Say on have an interface Foo with several (hundreds) methods. Is it possible to implement an
interface on-the-fly? Without having an implementation code? Yes. It is possible.
The standard possibility is
java.lang.reflect.Proxy.
The newProxyInstance method helps to create an on-the-fly implementation. One provides
an interceptor object that is called for every method invocation on the interface implementation instance.

Besides the standard Proxy API, there are libraries, that do the same thing, for example,
Byte Buddy or CGLIB.

In this post, we will use the standard JRE API — java.lang.reflect.Proxy

Proxy and Checked Exceptions

Let’s consider the following code in Java:

import java.lang.reflect.InvocationHandler;
import java.lang.reflect.Method;
import java.lang.reflect.Proxy;

interface Foo {
  void bar();
}

public static void main(String[] args) {
  final Foo proxy = (Foo)Proxy.newProxyInstance(Foo.class.getClassLoader(), new Class[]{Foo.class}, new InvocationHandler() {
    @Override
    public Object invoke(Object proxy, Method method, Object[] args) throws Throwable {
      throw new Exception("fail");
    }
  });
  //what is the exception?
  proxy.bar();
}

The code is trivial. We have the interface Foo, and we implement it via Proxy#newProxyInstance.
The implementation of the Proxy instance throws an exception of type Exception.
Will we have the exception of type Exception as a result?

Running the Example

Let’s execute the example and see what we have:

Exception in thread "main" java.lang.reflect.UndeclaredThrowableException
	at $Proxy0.bar(Unknown Source)
	at ProxyJava.main(ProxyJava.java:22)
Caused by: java.lang.Exception: fail
	at ProxyJava$1.invoke(ProxyJava.java:17)
	... 2 more

The answer is NO. We have java.lang.reflect.UndeclaredThrowableException exception.

Checked Exceptions in Java

As we all know, Java has checked exceptions. It means one declares what exceptions are
possibly thrown from a method. The main class of all exceptions is
java.lang.Throwable.

In Java language, we use throws to indicate that a method may throw an exception. For example,
throws IOException.

There are two specific sub-classes of Throwable, which does not require to be declared
by the throws keyword — java.lang.Error and java.lang.RuntimeException. All sub-classes
of those two types are free to throw without declaration.

The UndeclaredThrowableException
is the specific exception type that is used in the create a proxy implementation of an interface
to preserve checked exceptions in Java.
As we see from the Javadoc, the exception is used to wrap any checked exceptions that are not
declared with the throws block in the interface declaration.

Proxy and JVM Languages

JVM ecosystem is huge. There are many languages for the JVM, including
Kotlin,
Groovy,
Scala
and so on, that does not have checked exceptions.

Checked exceptions are checked by the compiler, on the JVM bytecode level,
there is no difference between exceptions at all.

It is quite easy to get UndeclaredThrowableException at some
unexpected places if mixing such languages with java.lang.reflect.Proxy!

For example, in Kotlin:

import java.lang.reflect.Proxy

internal interface Foo {
  fun bar()
}

fun main(args: Array<String>) {
  val proxy = Proxy.newProxyInstance(
    Foo::class.java.classLoader,
    arrayOf<Class<*>>(Foo::class.java)
  ) { _, _, _ ->
    throw Exception("fail")
  } as Foo

  proxy.bar()
}

The same code reads correctly but does not work. It is allowed in Kotlin to throw Exception from
a method (because exceptions are not checked), but it will not work via the
java.lang.reflect.Proxy. We will have the following execution result

Exception in thread "main" java.lang.reflect.UndeclaredThrowableException
	at com.sun.proxy.$Proxy0.bar(Unknown Source)
	at ProxyKTKt.main(ProxyKT.kt:15)
Caused by: java.lang.Exception: fail
	at ProxyKTKt$main$proxy$1.invoke(ProxyKT.kt:12)
	at ProxyKTKt$main$proxy$1.invoke(ProxyKT.kt)
	... 2 more

Fixing the UndeclaredThrowableException

To avoid the UndeclaredThrowableException one need to declare the exceptions
explicitly with throws block. That solves the problem in Java example above.
Similarly, it solves the problem in the Kotlin snippet too: we add the
@Throws(Exception::class) annotation on the bar function.

One may have a look at the implementation of the Proxy#newProxyInstance
in the sources of JVM. It turns out it is not possible to disable that
logic in the implementation. One is not allowed to breach Java’s checked
exceptions with Proxy#newProxyInstance.

There are two ways. One is to declare throws for all interfaces
that are used with Proxy#newProxyInstance. Of course, it is too easy to
forget doing in languages without checked exceptions. Tests may help.

An alternative could be to implement or use another variant of the
Proxy#newProxyInstance, that does not do the check. Let me know
in the comments if you’d like to learn more, how exactly the
Proxy#newProxyInstance or similar proxies are implemented.

comments powered by

  • Ошибка java lang nullpointerexception на андроид
  • Ошибка java io ioexception stalcraft
  • Ошибка java io filenotfoundexception
  • Ошибка java install in progress
  • Ошибка java failed to validate certificate the application will not be executed