작성
·
565
1
2023-07-12 01:18:17.448 ERROR 27420 --- [nio-8080-exec-2] o.a.c.c.C.[.[.[/].[dispatcherServlet] : Servlet.service() for servlet [dispatcherServlet] in context with path [] threw exception [Request processing failed; nested exception is java.lang.IllegalArgumentException] with root cause
java.lang.IllegalArgumentException: null
at java.base/java.util.Optional.orElseThrow(Optional.java:408) ~[na:na]
at com.group.libraryapp.service.book.BookService.loanBook(BookService.java:38) ~[main/:na]
at com.group.libraryapp.service.book.BookService$$FastClassBySpringCGLIB$$9fdbff4c.invoke(<generated>) ~[main/:na]
at org.springframework.cglib.proxy.MethodProxy.invoke(MethodProxy.java:218) ~[spring-core-5.3.24.jar:5.3.24]
at org.springframework.aop.framework.CglibAopProxy$CglibMethodInvocation.invokeJoinpoint(CglibAopProxy.java:793) ~[spring-aop-5.3.24.jar:5.3.24]
at org.springframework.aop.framework.ReflectiveMethodInvocation.proceed(ReflectiveMethodInvocation.java:163) ~[spring-aop-5.3.24.jar:5.3.24]
at org.springframework.aop.framework.CglibAopProxy$CglibMethodInvocation.proceed(CglibAopProxy.java:763) ~[spring-aop-5.3.24.jar:5.3.24]
at org.springframework.transaction.interceptor.TransactionInterceptor$1.proceedWithInvocation(TransactionInterceptor.java:123) ~[spring-tx-5.3.24.jar:5.3.24]
at org.springframework.transaction.interceptor.TransactionAspectSupport.invokeWithinTransaction(TransactionAspectSupport.java:388) ~[spring-tx-5.3.24.jar:5.3.24]
at org.springframework.transaction.interceptor.TransactionInterceptor.invoke(TransactionInterceptor.java:119) ~[spring-tx-5.3.24.jar:5.3.24]
at org.springframework.aop.framework.ReflectiveMethodInvocation.proceed(ReflectiveMethodInvocation.java:186) ~[spring-aop-5.3.24.jar:5.3.24]
at org.springframework.aop.framework.CglibAopProxy$CglibMethodInvocation.proceed(CglibAopProxy.java:763) ~[spring-aop-5.3.24.jar:5.3.24]
at org.springframework.aop.framework.CglibAopProxy$DynamicAdvisedInterceptor.intercept(CglibAopProxy.java:708) ~[spring-aop-5.3.24.jar:5.3.24]
at com.group.libraryapp.service.book.BookService$$EnhancerBySpringCGLIB$$5e9f8aa4.loanBook(<generated>) ~[main/:na]
at com.group.libraryapp.controller.book.BookController.loanBook(BookController.java:27) ~[main/:na]
at java.base/jdk.internal.reflect.NativeMethodAccessorImpl.invoke0(Native Method) ~[na:na]
at java.base/jdk.internal.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:62) ~[na:na]
at java.base/jdk.internal.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43) ~[na:na]
at java.base/java.lang.reflect.Method.invoke(Method.java:566) ~[na:na]
at org.springframework.web.method.support.InvocableHandlerMethod.doInvoke(InvocableHandlerMethod.java:205) ~[spring-web-5.3.24.jar:5.3.24]
at org.springframework.web.method.support.InvocableHandlerMethod.invokeForRequest(InvocableHandlerMethod.java:150) ~[spring-web-5.3.24.jar:5.3.24]
at org.springframework.web.servlet.mvc.method.annotation.ServletInvocableHandlerMethod.invokeAndHandle(ServletInvocableHandlerMethod.java:117) ~[spring-webmvc-5.3.24.jar:5.3.24]
at org.springframework.web.servlet.mvc.method.annotation.RequestMappingHandlerAdapter.invokeHandlerMethod(RequestMappingHandlerAdapter.java:895) ~[spring-webmvc-5.3.24.jar:5.3.24]
at org.springframework.web.servlet.mvc.method.annotation.RequestMappingHandlerAdapter.handleInternal(RequestMappingHandlerAdapter.java:808) ~[spring-webmvc-5.3.24.jar:5.3.24]
at org.springframework.web.servlet.mvc.method.AbstractHandlerMethodAdapter.handle(AbstractHandlerMethodAdapter.java:87) ~[spring-webmvc-5.3.24.jar:5.3.24]
at org.springframework.web.servlet.DispatcherServlet.doDispatch(DispatcherServlet.java:1071) ~[spring-webmvc-5.3.24.jar:5.3.24]
at org.springframework.web.servlet.DispatcherServlet.doService(DispatcherServlet.java:964) ~[spring-webmvc-5.3.24.jar:5.3.24]
at org.springframework.web.servlet.FrameworkServlet.processRequest(FrameworkServlet.java:1006) ~[spring-webmvc-5.3.24.jar:5.3.24]
at org.springframework.web.servlet.FrameworkServlet.doPost(FrameworkServlet.java:909) ~[spring-webmvc-5.3.24.jar:5.3.24]
at javax.servlet.http.HttpServlet.service(HttpServlet.java:696) ~[tomcat-embed-core-9.0.69.jar:4.0.FR]
at org.springframework.web.servlet.FrameworkServlet.service(FrameworkServlet.java:883) ~[spring-webmvc-5.3.24.jar:5.3.24]
at javax.servlet.http.HttpServlet.service(HttpServlet.java:779) ~[tomcat-embed-core-9.0.69.jar:4.0.FR]
at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:227) ~[tomcat-embed-core-9.0.69.jar:9.0.69]
at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:162) ~[tomcat-embed-core-9.0.69.jar:9.0.69]
at org.apache.tomcat.websocket.server.WsFilter.doFilter(WsFilter.java:53) ~[tomcat-embed-websocket-9.0.69.jar:9.0.69]
at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:189) ~[tomcat-embed-core-9.0.69.jar:9.0.69]
at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:162) ~[tomcat-embed-core-9.0.69.jar:9.0.69]
at org.springframework.web.filter.RequestContextFilter.doFilterInternal(RequestContextFilter.java:100) ~[spring-web-5.3.24.jar:5.3.24]
at org.springframework.web.filter.OncePerRequestFilter.doFilter(OncePerRequestFilter.java:117) ~[spring-web-5.3.24.jar:5.3.24]
at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:189) ~[tomcat-embed-core-9.0.69.jar:9.0.69]
at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:162) ~[tomcat-embed-core-9.0.69.jar:9.0.69]
at org.springframework.web.filter.FormContentFilter.doFilterInternal(FormContentFilter.java:93) ~[spring-web-5.3.24.jar:5.3.24]
at org.springframework.web.filter.OncePerRequestFilter.doFilter(OncePerRequestFilter.java:117) ~[spring-web-5.3.24.jar:5.3.24]
at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:189) ~[tomcat-embed-core-9.0.69.jar:9.0.69]
at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:162) ~[tomcat-embed-core-9.0.69.jar:9.0.69]
at org.springframework.web.filter.CharacterEncodingFilter.doFilterInternal(CharacterEncodingFilter.java:201) ~[spring-web-5.3.24.jar:5.3.24]
at org.springframework.web.filter.OncePerRequestFilter.doFilter(OncePerRequestFilter.java:117) ~[spring-web-5.3.24.jar:5.3.24]
at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:189) ~[tomcat-embed-core-9.0.69.jar:9.0.69]
at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:162) ~[tomcat-embed-core-9.0.69.jar:9.0.69]
at org.apache.catalina.core.StandardWrapperValve.invoke(StandardWrapperValve.java:177) ~[tomcat-embed-core-9.0.69.jar:9.0.69]
at org.apache.catalina.core.StandardContextValve.invoke(StandardContextValve.java:97) ~[tomcat-embed-core-9.0.69.jar:9.0.69]
at org.apache.catalina.authenticator.AuthenticatorBase.invoke(AuthenticatorBase.java:541) ~[tomcat-embed-core-9.0.69.jar:9.0.69]
at org.apache.catalina.core.StandardHostValve.invoke(StandardHostValve.java:135) ~[tomcat-embed-core-9.0.69.jar:9.0.69]
at org.apache.catalina.valves.ErrorReportValve.invoke(ErrorReportValve.java:92) ~[tomcat-embed-core-9.0.69.jar:9.0.69]
at org.apache.catalina.core.StandardEngineValve.invoke(StandardEngineValve.java:78) ~[tomcat-embed-core-9.0.69.jar:9.0.69]
at org.apache.catalina.connector.CoyoteAdapter.service(CoyoteAdapter.java:360) ~[tomcat-embed-core-9.0.69.jar:9.0.69]
at org.apache.coyote.http11.Http11Processor.service(Http11Processor.java:399) ~[tomcat-embed-core-9.0.69.jar:9.0.69]
at org.apache.coyote.AbstractProcessorLight.process(AbstractProcessorLight.java:65) ~[tomcat-embed-core-9.0.69.jar:9.0.69]
at org.apache.coyote.AbstractProtocol$ConnectionHandler.process(AbstractProtocol.java:891) ~[tomcat-embed-core-9.0.69.jar:9.0.69]
at org.apache.tomcat.util.net.NioEndpoint$SocketProcessor.doRun(NioEndpoint.java:1784) ~[tomcat-embed-core-9.0.69.jar:9.0.69]
at org.apache.tomcat.util.net.SocketProcessorBase.run(SocketProcessorBase.java:49) ~[tomcat-embed-core-9.0.69.jar:9.0.69]
at org.apache.tomcat.util.threads.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1191) ~[tomcat-embed-core-9.0.69.jar:9.0.69]
at org.apache.tomcat.util.threads.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:659) ~[tomcat-embed-core-9.0.69.jar:9.0.69]
at org.apache.tomcat.util.threads.TaskThread$WrappingRunnable.run(TaskThread.java:61) ~[tomcat-embed-core-9.0.69.jar:9.0.69]
at java.base/java.lang.Thread.run(Thread.java:829) ~[na:na]
안녕하세요! 강의 항상 잘 듣고있습니다! 다름이 아니라 31강수업을 듣다가 오류가 발생했는데 도저히 대출기능이 구현이 안되어서 여쭤봅니다! 살펴보니까 null 때문에 이 오류가 뜨는 것 같은데 DB에 맞는 데이터가 있는 상태에도 계속 뜹니다!ㅠ어디가 잘못 된 것 일까요?ㅠㅠ 코드는 깃허브에 올려놨습니다!(yul9910)
답변 1
1
안녕하세요, yul9910님!! 질문 올려주셔서 감사드립니다~~!! 😊
github의 코드까지 확인해본 결과 코드상 문제는 없는 것 같습니다!!
때문에, 보내주신 에러가 왜 발생했는지, 어떻게 디버깅할 수 있는지 설명드려보겠습니다!
java.lang.IllegalArgumentException: null
at java.base/java.util.Optional.orElseThrow(Optional.java:408) ~[na:na]
at com.group.libraryapp.service.book.BookService.loanBook(BookService.java:38) ~[main/:na]
at com.group.libraryapp.service.book.BookService$$FastClassBySpringCGLIB$$9fdbff4c.invoke(<generated>) ~[main/:na]
at org.springframework.cglib.proxy.MethodProxy.invoke(MethodProxy.java:218) ~[spring-core-5.3.24.jar:5.3.24]
보내주신 에러의 앞 부분만 가져왔습니다!
에러가 발생하게 되면, 가장 위에 어디에서 어떤 에러가 발생했는지 나오고, 아래로 갈수록 보다 근본적인 원인을 확인할 수 있는데요! 이 경우는 윗 부분으로도 충분히 상황 파악이 가능합니다.
위의 에러를 가장 위에서부터 읽어가다 보시면, 3번째 줄
at com.group.libraryapp.service.book.BookService.loanBook(BookService.java:38) ~[main/:na]
을 확인할 수 있는데요! 현재 에러는 BookService.java
코드의 38번째 줄에서 발생했다는 의미이고,
1~2번째 줄의 의미는 우리가 사용한 orElseThrow
에서 IllegalArgumentException
에러가 발생했다는 의미입니다.
java.lang.IllegalArgumentException: null
at java.base/java.util.Optional.orElseThrow(Optional.java:408) ~[na:na]
우리가 작성한 38번째 줄 코드는
Book book = bookRepository.findByName(request.getBookName())
.orElseThrow(IllegalArgumentException::new);
위와 같이 생겼고, 따라서 주어진 이름으로 책을 찾으려 했으나 책이 없어 에러가 발생하게 되었다고 생각할 수 있겠네요!!
하지만 분명 겉보기에는 library.book
데이터베이스에 "클린 코드"가 잘 들어 있고, 책 이름 역시 "클린 코드"로 대출 요청이 잘 이루어지고 있습니다.
이럴 때는 디버깅 도구 (https://www.youtube.com/watch?v=OHrLRg150As) 를 활용하셔서 BookLoanRequest의 bookName 필드에 어떤 값이 있는지, 혹시나 "클린 코드"가 아니라 " 클린 코드" 라거나 "클린 코드 " 같이 미세하게 다른 부분이 있는건 아닌지 확인해보는 것이 제일 좋습니다.
디버깅 도구가 어려우시다면, 아래 코드와 같이 직접 출력해보시는 것도 괜찮습니다.
@Transactional
public void loanBook(BookLoanRequest request) {
System.out.println(request.getBookName()); // 출력 추가!
// 1. 책 정보 가져오기
Book book = bookRepository.findByName(request.getBookName())
.orElseThrow(IllegalArgumentException::new);
또한, 들어오는 bookName의 이름도 확인했다면, 서버에서 Book을 정말 잘 찾고 있는지 확인해보는 것도 좋습니다. 예를 들어,
@Transactional
public void loanBook(BookLoanRequest request) {
System.out.println(request.getBookName()); // 출력 추가!
// 잠시 디버깅용
List<Book> books = bookRepository.findAll();
// Book을 하나씩 출력해서 확인해보기!
// 1. 책 정보 가져오기
Book book = bookRepository.findByName(request.getBookName())
.orElseThrow(IllegalArgumentException::new);
위의 코드처럼 Book을 가져와 이름이나 정보들을 출력해보며 매치되지 않은 원인을 파악해보는 것이죠. 이 역시 디버거 툴을 활용하실 수도 있습니다.
한 줄 요약 드려보면, 1) 데이터도 있고~ 2) 코드도 틀린 부분이 없어~ 실제 로그를 찍어보며 엄밀하게 비교해보아야 알 수 있을 것 같습니다!
답변이 도움이 되어 꼭 해결하셨으면 좋겠습니다!!!
감사합니다!!! 🙏🙏