问题描述
我有一个
2017- 06-28 02:36:52.942错误4632 --- [nio-8080-exec-1] clcrest.AttendanceRestController:异常发生
2017-06-28 02:52:32.485 INFO 2796 --- [io -8080-exec-10] clcrest.AttendanceRestController:发生了什么事情
异常
java.lang.reflect.UndeclaredThrowableException
at com.lynas.service.AttendanceService $$ EnhancerBySpringCGLIB $$ 7b42c004.post(< generated>)
at com.lynas.controller.rest.AttendanceRestController.postAttendance(AttendanceRestController.kt:34)
at sun.reflect.NativeMethodAccessorImpl.invoke0( Native方法)
at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:62)
at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)
在java.lang。 reflect.Method.invoke(Method.java:498)
在org.springframework.web.method.support.InvocableHandlerMethod.doInvoke(InvocableHandlerMethod.java:205)
在org.springframework.web.method。 support.InvocableHandlerMethod.invokeForRequest(InvocableHandlerMethod.java:133)
在org.springframework.web.servlet.mvc.method.annotation.ServletInvocableHandlerMethod.invokeAndHandle(ServletInvocableHandlerMethod.java:97)
在org.springframework。 web.servlet.mvc.method.annotation.RequestMappingHandlerAdapter.invokeHandlerMethod(RequestMappingHandlerAdapter.java:827)
在org.springframework.web.servlet.mvc.method.annotation.RequestMappingHandlerAdapter.handleInternal(RequestMappingHandlerAdapter.java:738)
在org.springframework.web.servlet.mvc.method.AbstractHandlerMethodAd apter.handle(AbstractHandlerMethodAdapter.java:85)
在org.springframework.web.servlet.DispatcherServlet.doDispatch(DispatcherServlet.java:963)
在org.springframework.web.servlet.DispatcherServlet.doService( DispatcherServlet.java:897)
在org.springframework.web.servlet.FrameworkServlet.processRequest(FrameworkServlet.java:970)
在org.springframework.web.servlet.FrameworkServlet.doPost(FrameworkServlet.java: 872)
在javax.servlet.http.HttpServlet.service(HttpServlet.java:661)
在org.springframework.web.servlet.FrameworkServlet.service(FrameworkServlet.java:846)
在javax.servlet.http.HttpServlet.service(HttpServlet.java:742)
在org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:231)
在org.apache.catalina .core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:166)
在org.apache.tomcat.websocket.server.WsFilter.doFilter(WsFilter.java:52)
在org.apache.catalina.core .ApplicationFilterCha in.internalDoFilter(ApplicationFilterChain.java:193)
在org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:166)
在org.springframework.boot.web.filter.ApplicationContextHeaderFilter。 doFilterInternal(ApplicationContextHeaderFilter.java:55)
在org.springframework.web.filter.OncePerRequestFilter.doFilter(OncePerRequestFilter.java:107)
在org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain。 java:193)
在org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:166)
在org.springframework.boot.actuate.trace.WebRequestTraceFilter.doFilterInternal(WebRequestTraceFilter.java: 110)
在org.springframework.web.filter.OncePerRequestFilter.doFilter(OncePerRequestFilter.java:107)
在org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:193)
在org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.j ava:166)
在org.springframework.security.web.FilterChainProxy $ VirtualFilterChain.doFilter(FilterChainProxy.java:317)
在org.springframework.security.web.access.intercept.FilterSecurityInterceptor.invoke( FilterSecurityInterceptor.java:127)
在org.springframework.security.web.access.intercept.FilterSecurityInterceptor.doFilter(FilterSecurityInterceptor.java:91)
在org.springframework.security.web.FilterChainProxy $ VirtualFilterChain。 doFilter(FilterChainProxy.java:331)
在org.springframework.security.web.access.ExceptionTranslationFilter.doFilter(ExceptionTranslationFilter.java:114)
在org.springframework.security.web.FilterChainProxy $ VirtualFilterChain。 doFilter(FilterChainProxy.java:331)
在org.springframework.security.web.session.SessionManagementFilter.doFilter(SessionManagementFilter.java:137)
在org.springframework.security.web.FilterChainProxy $ VirtualFilterChain。 doFilter(FilterChainProxy.java:331)
在org.springframework.security.web.authen tication.AnonymousAuthenticationFilter.doFilter(AnonymousAuthenticationFilter.java:111)
在org.springframework.security.web.FilterChainProxy $ VirtualFilterChain.doFilter(FilterChainProxy.java:331)
在org.springframework.security.web。 servletapi.SecurityContextHolderAwareRequestFilter.doFilter(SecurityContextHolderAwareRequestFilter.java:170)
在org.springframework.security.web.FilterChainProxy $ VirtualFilterChain.doFilter(FilterChainProxy.java:331)
在org.springframework.security.web。 saverequest.RequestCacheAwareFilter.doFilter(RequestCacheAwareFilter.java:63)
在org.springframework.security.web.FilterChainProxy $ VirtualFilterChain.doFilter(FilterChainProxy.java:331)
在org.springframework.security.web。 authentication.AbstractAuthenticationProcessingFilter.doFilter(AbstractAuthenticationProcessingFilter.java:200)
在org.springframework.security.web.FilterChainProxy $ VirtualFilterChain.doFilter(FilterChainProxy.java:331)
在org.springframework.security .web.authentication.logout.LogoutFilter.doFilter(LogoutFilter.java:116)
在org.springframework.security.web.FilterChainProxy $ VirtualFilterChain.doFilter(FilterChainProxy.java:331)
在org.springframework .security.web.csrf.CsrfFilter.doFilterInternal(CsrfFilter.java:124)
在org.springframework.web.filter.OncePerRequestFilter.doFilter(OncePerRequestFilter.java:107)
在org.springframework.security .web.FilterChainProxy $ VirtualFilterChain.doFilter(FilterChainProxy.java:331)
在org.springframework.security.web.header.HeaderWriterFilter.doFilterInternal(HeaderWriterFilter.java:64)
在org.springframework.web .filter.OncePerRequestFilter.doFilter(OncePerRequestFilter.java:107)
在org.springframework.security.web.FilterChainProxy $ VirtualFilterChain.doFilter(FilterChainProxy.java:331)
在org.springframework.security.web .context.SecurityContextPersistenceFilter.doFilter(SecurityContextPersistenceFilter.java:105)
在org.springframework.security.web.FilterC hainProxy $ VirtualFilterChain.doFilter(FilterChainProxy.java:331)
在org.springframework.security.web.context.request.async.WebAsyncManagerIntegrationFilter.doFilterInternal(WebAsyncManagerIntegrationFilter.java:56)
在org.springframework。 web.filter.OncePerRequestFilter.doFilter(OncePerRequestFilter.java:107)
在org.springframework.security.web.FilterChainProxy $ VirtualFilterChain.doFilter(FilterChainProxy.java:331)
在org.springframework.security。 (org.springframework.web.filter.DelegatingFilterProxy)
invokeDelegate(DelegatingFilterProxy.java:346)
在org.springframework.web.filter.DelegatingFilterProxy.doFilter(DelegatingFilterProxy.java:262)
在org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain。 java:193)
在org.apache.catalina.core.ApplicationFilterChain .doFilter(ApplicationFilterChain.java:166)
在org.springframework.web.filter.RequestContextFilter.doFilterInternal(RequestContextFilter.java:99)
在org.springframework.web.filter.OncePerRequestFilter.doFilter(OncePerRequestFilter .java:107)
在org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:193)
在org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:166 )
在org.springframework.web.filter.HttpPutFormContentFilter.doFilterInternal(HttpPutFormContentFilter.java:105)
在org.springframework.web.filter.OncePerRequestFilter.doFilter(OncePerRequestFilter.java:107)
在org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:193)
在org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:166)
在org。 springframework.web.filter.HiddenHttpMethodFilter.doFilterInternal(HiddenHttpMethodFilter.java:81)
在org.spr ingframework.web.filter.OncePerRequestFilter.doFilter(OncePerRequestFilter.java:107)
在org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:193)
在org.apache.catalina。 core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:166)
在org.springframework.web.filter.CharacterEncodingFilter.doFilterInternal(CharacterEncodingFilter.java:197)
在org.springframework.web.filter.OncePerRequestFilter。 doFilter(OncePerRequestFilter.java:107)
在org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:193)
在org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain。 java:166)
在org.springframework.boot.actuate.autoconfigure.MetricsFilter.doFilterInternal(MetricsFilter.java:106)
在org.springframework.web.filter.OncePerRequestFilter.doFilter(OncePerRequestFilter.java: 107)
在org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(Applicatio nFilterChain.java:193)
在org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:166)
在org.apache.catalina.core.StandardWrapperValve.invoke(StandardWrapperValve.java: 198)
在org.apache.catalina.core.StandardContextValve.invoke(StandardContextValve.java:96)
在org.apache.catalina.authenticator.AuthenticatorBase.invoke(AuthenticatorBase.java:478)
在org.apache.catalina.core.StandardHostValve.invoke(StandardHostValve.java:140)
在org.apache.catalina.valves.ErrorReportValve.invoke(ErrorReportValve.java:80)
在org .apache.catalina.core.StandardEngineValve.invoke(StandardEngineValve.java:87)
在org.apache.catalina.connector.CoyoteAdapter.service(CoyoteAdapter.java:342)
在org.apache.coyote .http11.Http11Processor.service(Http11Processor.java:799)
在org.apache.coyote.AbstractProcessorLight.process(AbstractProcessorLight.java:66)
在org.apache.coyote.AbstractProtocol $ ConnectionHandler.process (AbstractProtocol .java:861)
在org.apache.tomcat.util.net.NioEndpoint $ SocketProcessor.doRun(NioEndpoint.java:1455)
在org.apache.tomcat.util.net.SocketProcessorBase.run (SocketProcessorBase.java:49)
在java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1142)
在java.util.concurrent.ThreadPoolExecutor $ Worker.run(ThreadPoolExecutor.java:617 )
在org.apache.tomcat.util.threads.TaskThread $ WrappingRunnable.run(TaskThread.java:61)
在java.lang.Thread.run(Thread.java:745)
引起的:java.text.ParseException:不可稀释的日期:28--2017
在java.text.DateFormat.parse(DateFormat.java:366)
在com.lynas.util.UtilKt .convertToDate(Util.kt:56)
at com.lynas.service.AttendanceService.post(AttendanceService.kt:23)
at com.lynas.service.AttendanceService $$ FastClassBySpringCGLIB $$ 2b941a4b.invoke (< generate>)
在org.springframework.cglib.proxy.MethodProxy.invoke(MethodProxy.java:204)
在org.springframework.aop.framework.CglibAopProx y $ CglibMethodInvocation.invokeJoinpoint(CglibAopProxy.java:738)
在org.springframework.aop.framework.ReflectiveMethodInvocation.proceed(ReflectiveMethodInvocation.java:157)
在org.springframework.transaction.interceptor.TransactionInterceptor $ 1 .proceedWithInvocation(TransactionInterceptor.java:99)
在org.springframework.transaction.interceptor.TransactionAspectSupport.invokeWithinTransaction(TransactionAspectSupport.java:282)
在org.springframework.transaction.interceptor.TransactionInterceptor.invoke(TransactionInterceptor .java:96)
在org.springframework.aop.framework.ReflectiveMethodInvocation.proceed(ReflectiveMethodInvocation.java:179)
在org.springframework.aop.framework.CglibAopProxy $ DynamicAdvisedInterceptor.intercept(CglibAopProxy.java :673)
... 103更多
UndeclaredThrowableException 是由kotlin引起的。为什么?我们知道kotlin没有检查例外。
说:
我们知道几乎所有流行的框架都是基于 java.reflect 包创建的,包括。
在简而言之,当kotlin函数抛出一个java 检查异常,并且不声明它可能会抛出的异常。
然后调用一个java 您可能会收到这样一个。
在java中,您可以声明一个检查异常将抛出如下:
// v ---它是一个检查的异常在java
int read()throws IOException {/ ** /}
感谢@ glee8e指出我的错误。
你也可以在kotlin中抛出异常,因为kotlin没有 throws 关键字,所以你必须使用 @Throws 声明一个异常将抛出:
@Throws(IOException :: class)
fun read ):Int {/ ** /}
在kotlin中复制:
//抛出一个UndeclaredThrowableException将原始的IOException作为它的原因
//,因为java.lang.Runnable don' t声明任何已检查的异常
// |
// v
Runnable :: class.proxying(:: throwsAJavaCheckedException).run()
//直接抛出原始的IOException,因为java.util。 concurrent.Callable
//已声明它将抛出一个检查的异常
// |
// v
Callable :: class.proxying(:: throwsAJavaCheckedException).call()
fun throwsAJavaCheckedException(proxy:Any,method:Method,args:Array< Any>?) {
throw IOException();
}
typealias Invocation =(Any,Method,Array< Any>?) - >任何?;
fun< T:Any> KClass< T> .proxying(handler:Invocation)= cast(Proxy.newProxyInstance(
ClassLoader.getSystemClassLoader(),
arrayOf(java),
handler
)
如何避免此问题?
如果这个函数是由你自己编写的,那么这个解决方案就比较简单
是的,声明函数将抛出一个被检查的异常。例如:
@Throws(ParseException :: class)
fun convertToDate(){/ ** /}
或写一些毕业插件,如 allopen ,我在这里命名为 allthrows 。
但你也可以做一些妥协。如果你不确定在像spring这样的框架中会发生什么,你应该将你的调用包含在一个帮助方法中。例如:
val task = Runnable :: class.proxying(:: throwsAJavaCheckedException)
/ / v--如果没有发生异常,结果将通过catch-block返回结果
val result:Unit = catch(task :: run).by {actual:Throwable - >
val例外:Unit = Unit;
// v ---你可以选择返回一个特殊的值或者重新抛出异常
当(实际){
是RuntimeException - >异常
是ParseException - > logger.info(acutal)
else - >抛出实际
}
}
val结果:单位? = catch(task :: run).only {actual:Throwable - >
//只处理异常不返回异常值
logger.info(actual);
}
inline fun< T> catch(crossinline block:() - > T):() - > T {
return {block(); };
}
inline fun< T> (() - > T).by(特别:(Throwable) - > T):T {
只返回{异常(它)}!
}
内联乐趣< T:R,R> (( - )→T).only(特别:(Throwable)→R):R {
try {
return invoke();
} catch(e:UndeclaredThrowableException){
异常返回(e.cause?:e);
} catch(e:Exception){
异常返回(e);
}
}
I have an extension method that converts string to Date in Kotlin.
fun String.convertToDate() : Date { var pattern: String = "dd-mm-yyyy" val dateFormatter = SimpleDateFormat(pattern) return dateFormatter.parse(this) // parse method throw ParseException }
And this is the code where I am trying to catch possible exception.
try { "22---2017".convertToDate() } catch (ex: ParseException) { // ParseException supposed to be caught in this block logger.error("Parse exception occur") } catch (ex: Exception) { // ParseException caught in this block logger.error("Exception occur") }
The ParseException caught in the last block that is where Exception is caught. But should it be caught in the ParseException block ? What am I missing here ?
===UPDATE===
I am developing an Spring MVC project. I have run the code in simple stand alone kotlin program where it behaves accordingly. But in my spring project it behaves differently. I am giving the the full code, Controller and the Service layer.
Controller
@PostMapping @PreAuthorize("hasAnyRole('USER','ROLE_USER','ROLE_ADMIN','ADMIN')") fun postAttendance(@RequestBody attendanceJson: AttendanceJsonWrapper, request: HttpServletRequest): ResponseEntity<*> { val organization = getOrganizationFromSession(request) try { val attendanceBook: AttendanceBook = attendanceService.post(attendanceJson, organization.id!!) logger.info("Post successfully attendance book {}", attendanceBook) } catch (ex: SameDateAttendanceException) { logger.error("Duplicate attendance entry found at date [{}]", attendanceJson.date, attendanceJson.classId) return responseConflict(attendanceJson) } catch (ex: java.text.ParseException) { ex.printStackTrace() logger.error("Parse exception occur") return responseError(ErrorObject( attendanceJson, "date", Constants.INVALID_DATE_FORMAT, Constants.EXPECTED_DATE_FORMAT)) } catch (ex: Exception) { ex.printStackTrace() logger.error("Exception occur") if (ex.cause is ParseException) { logger.info("What the hell is happening") } return responseOK(attendanceJson) }
Service
@Service open class AttendanceService constructor(val attendanceRepository: AttendanceRepository) { @Transactional open fun post(attendanceJsonWrapper: AttendanceJsonWrapper, orgId: Long): AttendanceBook { // ParseException should thrown from this line. val _attendanceDate = attendanceJsonWrapper.date.convertToDate() // Other logic goes here return attendanceRepository.save(attendanceBook) } }
Log
for given input 28--2017 from front end following log produced.
2017-06-28 02:36:52.942 ERROR 4632 --- [nio-8080-exec-1] c.l.c.rest.AttendanceRestController : Exception occur 2017-06-28 02:52:32.485 INFO 2796 --- [io-8080-exec-10] c.l.c.rest.AttendanceRestController : What the hell is happening
Exception
java.lang.reflect.UndeclaredThrowableException at com.lynas.service.AttendanceService$$EnhancerBySpringCGLIB$$7b42c004.post(<generated>) at com.lynas.controller.rest.AttendanceRestController.postAttendance(AttendanceRestController.kt:34) 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:205) at org.springframework.web.method.support.InvocableHandlerMethod.invokeForRequest(InvocableHandlerMethod.java:133) at org.springframework.web.servlet.mvc.method.annotation.ServletInvocableHandlerMethod.invokeAndHandle(ServletInvocableHandlerMethod.java:97) at org.springframework.web.servlet.mvc.method.annotation.RequestMappingHandlerAdapter.invokeHandlerMethod(RequestMappingHandlerAdapter.java:827) at org.springframework.web.servlet.mvc.method.annotation.RequestMappingHandlerAdapter.handleInternal(RequestMappingHandlerAdapter.java:738) at org.springframework.web.servlet.mvc.method.AbstractHandlerMethodAdapter.handle(AbstractHandlerMethodAdapter.java:85) at org.springframework.web.servlet.DispatcherServlet.doDispatch(DispatcherServlet.java:963) at org.springframework.web.servlet.DispatcherServlet.doService(DispatcherServlet.java:897) at org.springframework.web.servlet.FrameworkServlet.processRequest(FrameworkServlet.java:970) at org.springframework.web.servlet.FrameworkServlet.doPost(FrameworkServlet.java:872) at javax.servlet.http.HttpServlet.service(HttpServlet.java:661) at org.springframework.web.servlet.FrameworkServlet.service(FrameworkServlet.java:846) at javax.servlet.http.HttpServlet.service(HttpServlet.java:742) 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:52) at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:193) at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:166) at org.springframework.boot.web.filter.ApplicationContextHeaderFilter.doFilterInternal(ApplicationContextHeaderFilter.java:55) at org.springframework.web.filter.OncePerRequestFilter.doFilter(OncePerRequestFilter.java:107) at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:193) at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:166) at org.springframework.boot.actuate.trace.WebRequestTraceFilter.doFilterInternal(WebRequestTraceFilter.java:110) at org.springframework.web.filter.OncePerRequestFilter.doFilter(OncePerRequestFilter.java:107) at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:193) at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:166) at org.springframework.security.web.FilterChainProxy$VirtualFilterChain.doFilter(FilterChainProxy.java:317) at org.springframework.security.web.access.intercept.FilterSecurityInterceptor.invoke(FilterSecurityInterceptor.java:127) at org.springframework.security.web.access.intercept.FilterSecurityInterceptor.doFilter(FilterSecurityInterceptor.java:91) at org.springframework.security.web.FilterChainProxy$VirtualFilterChain.doFilter(FilterChainProxy.java:331) at org.springframework.security.web.access.ExceptionTranslationFilter.doFilter(ExceptionTranslationFilter.java:114) at org.springframework.security.web.FilterChainProxy$VirtualFilterChain.doFilter(FilterChainProxy.java:331) at org.springframework.security.web.session.SessionManagementFilter.doFilter(SessionManagementFilter.java:137) at org.springframework.security.web.FilterChainProxy$VirtualFilterChain.doFilter(FilterChainProxy.java:331) at org.springframework.security.web.authentication.AnonymousAuthenticationFilter.doFilter(AnonymousAuthenticationFilter.java:111) at org.springframework.security.web.FilterChainProxy$VirtualFilterChain.doFilter(FilterChainProxy.java:331) at org.springframework.security.web.servletapi.SecurityContextHolderAwareRequestFilter.doFilter(SecurityContextHolderAwareRequestFilter.java:170) at org.springframework.security.web.FilterChainProxy$VirtualFilterChain.doFilter(FilterChainProxy.java:331) at org.springframework.security.web.savedrequest.RequestCacheAwareFilter.doFilter(RequestCacheAwareFilter.java:63) at org.springframework.security.web.FilterChainProxy$VirtualFilterChain.doFilter(FilterChainProxy.java:331) at org.springframework.security.web.authentication.AbstractAuthenticationProcessingFilter.doFilter(AbstractAuthenticationProcessingFilter.java:200) at org.springframework.security.web.FilterChainProxy$VirtualFilterChain.doFilter(FilterChainProxy.java:331) at org.springframework.security.web.authentication.logout.LogoutFilter.doFilter(LogoutFilter.java:116) at org.springframework.security.web.FilterChainProxy$VirtualFilterChain.doFilter(FilterChainProxy.java:331) at org.springframework.security.web.csrf.CsrfFilter.doFilterInternal(CsrfFilter.java:124) at org.springframework.web.filter.OncePerRequestFilter.doFilter(OncePerRequestFilter.java:107) at org.springframework.security.web.FilterChainProxy$VirtualFilterChain.doFilter(FilterChainProxy.java:331) at org.springframework.security.web.header.HeaderWriterFilter.doFilterInternal(HeaderWriterFilter.java:64) at org.springframework.web.filter.OncePerRequestFilter.doFilter(OncePerRequestFilter.java:107) at org.springframework.security.web.FilterChainProxy$VirtualFilterChain.doFilter(FilterChainProxy.java:331) at org.springframework.security.web.context.SecurityContextPersistenceFilter.doFilter(SecurityContextPersistenceFilter.java:105) at org.springframework.security.web.FilterChainProxy$VirtualFilterChain.doFilter(FilterChainProxy.java:331) at org.springframework.security.web.context.request.async.WebAsyncManagerIntegrationFilter.doFilterInternal(WebAsyncManagerIntegrationFilter.java:56) at org.springframework.web.filter.OncePerRequestFilter.doFilter(OncePerRequestFilter.java:107) at org.springframework.security.web.FilterChainProxy$VirtualFilterChain.doFilter(FilterChainProxy.java:331) at org.springframework.security.web.FilterChainProxy.doFilterInternal(FilterChainProxy.java:214) at org.springframework.security.web.FilterChainProxy.doFilter(FilterChainProxy.java:177) at org.springframework.web.filter.DelegatingFilterProxy.invokeDelegate(DelegatingFilterProxy.java:346) at org.springframework.web.filter.DelegatingFilterProxy.doFilter(DelegatingFilterProxy.java:262) at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:193) at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:166) at org.springframework.web.filter.RequestContextFilter.doFilterInternal(RequestContextFilter.java:99) at org.springframework.web.filter.OncePerRequestFilter.doFilter(OncePerRequestFilter.java:107) at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:193) at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:166) at org.springframework.web.filter.HttpPutFormContentFilter.doFilterInternal(HttpPutFormContentFilter.java:105) at org.springframework.web.filter.OncePerRequestFilter.doFilter(OncePerRequestFilter.java:107) at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:193) at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:166) at org.springframework.web.filter.HiddenHttpMethodFilter.doFilterInternal(HiddenHttpMethodFilter.java:81) at org.springframework.web.filter.OncePerRequestFilter.doFilter(OncePerRequestFilter.java:107) at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:193) at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:166) at org.springframework.web.filter.CharacterEncodingFilter.doFilterInternal(CharacterEncodingFilter.java:197) at org.springframework.web.filter.OncePerRequestFilter.doFilter(OncePerRequestFilter.java:107) at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:193) at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:166) at org.springframework.boot.actuate.autoconfigure.MetricsFilter.doFilterInternal(MetricsFilter.java:106) at org.springframework.web.filter.OncePerRequestFilter.doFilter(OncePerRequestFilter.java:107) 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:198) at org.apache.catalina.core.StandardContextValve.invoke(StandardContextValve.java:96) at org.apache.catalina.authenticator.AuthenticatorBase.invoke(AuthenticatorBase.java:478) at org.apache.catalina.core.StandardHostValve.invoke(StandardHostValve.java:140) at org.apache.catalina.valves.ErrorReportValve.invoke(ErrorReportValve.java:80) 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:799) at org.apache.coyote.AbstractProcessorLight.process(AbstractProcessorLight.java:66) at org.apache.coyote.AbstractProtocol$ConnectionHandler.process(AbstractProtocol.java:861) at org.apache.tomcat.util.net.NioEndpoint$SocketProcessor.doRun(NioEndpoint.java:1455) at org.apache.tomcat.util.net.SocketProcessorBase.run(SocketProcessorBase.java:49) at java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1142) at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:617) at org.apache.tomcat.util.threads.TaskThread$WrappingRunnable.run(TaskThread.java:61) at java.lang.Thread.run(Thread.java:745) Caused by: java.text.ParseException: Unparseable date: "28--2017" at java.text.DateFormat.parse(DateFormat.java:366) at com.lynas.util.UtilKt.convertToDate(Util.kt:56) at com.lynas.service.AttendanceService.post(AttendanceService.kt:23) at com.lynas.service.AttendanceService$$FastClassBySpringCGLIB$$2b941a4b.invoke(<generated>) at org.springframework.cglib.proxy.MethodProxy.invoke(MethodProxy.java:204) at org.springframework.aop.framework.CglibAopProxy$CglibMethodInvocation.invokeJoinpoint(CglibAopProxy.java:738) at org.springframework.aop.framework.ReflectiveMethodInvocation.proceed(ReflectiveMethodInvocation.java:157) at org.springframework.transaction.interceptor.TransactionInterceptor$1.proceedWithInvocation(TransactionInterceptor.java:99) at org.springframework.transaction.interceptor.TransactionAspectSupport.invokeWithinTransaction(TransactionAspectSupport.java:282) at org.springframework.transaction.interceptor.TransactionInterceptor.invoke(TransactionInterceptor.java:96) at org.springframework.aop.framework.ReflectiveMethodInvocation.proceed(ReflectiveMethodInvocation.java:179) at org.springframework.aop.framework.CglibAopProxy$DynamicAdvisedInterceptor.intercept(CglibAopProxy.java:673) ... 103 more
The UndeclaredThrowableException is caused by kotlin. why? we know kotlin does not have checked exceptions.
The documentation of UndeclaredThrowableException says:
On the other hand, Kotlin can throw any exceptions but in java them will are: unchecked/checked exception and error.we know almost all of the popular frameworks is created base on java.reflect package includes java.reflect.Proxy.
In short, when the kotlin function throw a java checked exception and don't declare the exception that it will maybe throwing.then call a java Proxy you maybe receive such a UndeclaredThrowableException.
In java you can declare a checked-exception will be throwing as below:
// v--- it is a checked exception in java int read() throws IOException{/**/}
Thanks for @glee8e to points my mistake.you also can throws an exception in kotlin, since kotlin don't have throws keyword so you must using @Throws to declare an exception will be throwing:
@Throws(IOException::class) fun read():Int{/**/}
let's reproduce the UndeclaredThrowableException in kotlin:
//throws a UndeclaredThrowableException takes the original IOException as its cause // because java.lang.Runnable don't declare any checked exception at all // | // v Runnable::class.proxying(::throwsAJavaCheckedException).run() // throws the original IOException directly because java.util.concurrent.Callable // has declared that it will be throwing a checked Exception // | // v Callable::class.proxying(::throwsAJavaCheckedException).call()
fun throwsAJavaCheckedException(proxy:Any, method:Method, args:Array<Any>?): Any? { throw IOException(); } typealias Invocation = (Any, Method, Array<Any>?) -> Any?; fun <T:Any> KClass<T>.proxying(handler:Invocation) = cast(Proxy.newProxyInstance( ClassLoader.getSystemClassLoader(), arrayOf(java), handler ));
How to avoiding this problem?
If the function is wrote by yourself the solution is so simpler.yes, declare the function will be throwing a checked exception. for example:
@Throws(ParseException::class) fun convertToDate(){/**/}
OR write some gradle-plugin like as allopen, I named it allthrows here.
But you also can make some compromises. If you are not sure what will be happens in the frameworks like as spring, you should wrap your invocation into a helper method. for example:
val task = Runnable::class.proxying(::throwsAJavaCheckedException) // v-- the result return by catch-block immediately if no exception occurs val result : Unit = catch(task::run).by { actual: Throwable -> val exceptional: Unit = Unit; // v--- you can choose return an exceptional value or rethrow the exception when (actual) { is RuntimeException -> exceptional is ParseException -> logger.info(acutal) else -> throw actual } } val result : Unit? = catch(task::run).only { actual:Throwable -> // only handle the exception don't return the exceptional value logger.info(actual); }
inline fun <T> catch(crossinline block: () -> T): () -> T { return { block(); }; } inline fun <T> (() -> T).by(exceptionally: (Throwable) -> T): T { return only { exceptionally(it) }!! } inline fun <T : R, R> (() -> T).only(exceptionally: (Throwable) -> R): R? { try { return invoke(); } catch(e: UndeclaredThrowableException) { return exceptionally(e.cause ?: e); } catch(e: Exception) { return exceptionally(e); } }
这篇关于为什么Kotlin收到这样一个UndeclaredThrowableException而不是ParseException?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持!