Maven Scope 정리

pom.xml에서 상용되는 scope에 대한 정리

compile
- 아무런 scope를 명시하지 않았을때 사용되는 기본값.
- 테스트 및 런타임에도 classpath에포함된다.

※provied
- JDK 또는 컨테이너에 의해서 runtime에 제공되는 모듈
- 이 scope는 이미 컨테이너가 해당 라이브러리를 제공하고 있을때 유용 그러므로 실제로 배포시에 제외대상
- 예를 들면 아래 servlet api의 경우 이미 웹서버에서 제공하고 있는 경우에 maven scope를 provied로 기재

1
2
3
4
5
6
<dependency>
    <groupId>javax.servlet</groupId>
    <artifactId>servlet-api</artifactId>
    <version>2.5</version>
    <scope>provided</scope>
</dependency>
cs

※runtime
- 런타임시 필요하지만 컴파일시에 필요하지 않는 경우에 사용
- 테스트와 런타임에는 사용 되지만 컴파일시에 사용 되지 않음
- 대표적 예로 JDBC Driver

1
2
3
4
5
6
<dependency>
    <groupId>mysql</groupId>
    <artifactId>mysql-connector-java</artifactId>
    <version>6.0.6</version>
    <scope>runtime</scope>
</dependency>
cs


※test
테스트 코드 컴파일시 필요, 배포시 제외


참고
https://www.baeldung.com/maven-dependency-scopes


Scope를 Provided로 지정했을때 문제사례
인텔리제이에서 간단한 spring project를 만들고 실행시킬때 NoClassDefFoundError: javax/servlet/Filter 에러가 발생했다.

그 이유를 구글링해서 확인해보니 실행시 사용할 spring-boot-starter-tomcat의 스코프를 provided로 지정해서 에러가 발생했다. 스코프를 지워서 default인 compile로 사용하지 정상적으로 동작했다.
https://stackoverflow.com/questions/31494183/getting-a-caused-by-java-lang-noclassdeffounderror-javax-servlet-http-httpser


Maven에서는 큰 문제가 없었으나 Gradle로 프로젝트를 변경하고 나서 Freemaker NoSuchFieldError 오류가 계속 발생했다.

Freemaker는 템플릿엔진인데 나는 이것을 사용하지 않고 JSP를 사용했는데 왜 오류가 발생하는지 원인은 처음에 몰랐다.

그래서 구글링을 하였지만 쉽게 원인이 해결되지 않았다. 

하나 발견하여 freemaker disable을 적용을 하였으나 여전히 오류가 발생했다.

https://fastfoodcoding.com/questions/1506440393799/how-to-disable-freemarker-templates-in-spring-boot


1. Configuration 페이지 설정

1
@EnableAutoConfiguration(exclude = { FreeMarkerAutoConfiguration.class })
cs


2. application 설정

1
2
// freemaker check template
spring.freemarker.check-template-location=false
cs



그래서 다시 한번 구글링을 했다. 역시 삽질은 계속되었다. 
해결방법은 중국 사이트에서 찾았다. 
https://www.cnblogs.com/lixiuming521125/p/6472691.html


원인은 webmvc 모듈에서 사용하는 freemaker 버전이 낮아서 발생한 문제였다.

간단하게 gradle에 freemaker를 최신 버전으로 설정하니 정상적으로 동작하였다.

1
compile group: 'org.freemarker', name: 'freemarker', version:'2.3.23'
cs


Maven 프로젝트를 Gradle로 변경해봤다.

멈저 PC에 cmd 창에서 gradle 명령어를 사용할 수 있도록 환경 변수를 편집해보자.
우선 시스템 환경변수에서 시스템 변수 편집에 들어가 Path를 수정하여 gradle\bin의 위치를 설정해준다. (gradle은 홈페이지에서 별도로 다운로드)



정상적으로 환경변수가 설정이 되면 cmd 창을 키고 gradle -v 명령어를 사용하면 다음과 같이 gradle 버전정보가 출력된다



그리고 maven 프로젝트 디렉토리에서 pom.xml이 존재하는 위치로 이동하여 다음 명령어를 사용하면 자동으로 build.gradle이 생성되면서 gradle 설정파일이 추가된다.

1
gradle init --type pom
cs


Spring Boot를 통해 다양한 공부를 하던 도중에 View는 편하게 사용하던 JSP를 사용하였다.  IDE 환경에서는 application.properties에서 다음과 같이 설정해주고 src/main/webapp/WEB-INF/ 밑에 jsp를 위치시키면 사용이 가능했다.

#JSP
spring.mvc.view.prefix=/WEB-INF/views/**/
spring.mvc.view.suffix=.jsp

그때 메이븐 wrapper인 mvnw를 이용해서 jar 파일로 패키징을 진행하였을 때 다음과 같이 오류가 발생합니다.

오류내용

[2018-07-01 23:02:04] [ERROR] [DirectJDKLog.java:182] Servlet.service() for servlet [jsp] threw exception
javax.servlet.ServletException: File [&#47;WEB-INF&#47;views&#47;error&#47;error.jsp] not found
	at org.apache.jasper.servlet.JspServlet.handleMissingResource(JspServlet.java:408)
	at org.apache.jasper.servlet.JspServlet.serviceJspFile(JspServlet.java:375)
	at org.apache.jasper.servlet.JspServlet.service(JspServlet.java:330)
	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.catalina.core.ApplicationDispatcher.invoke(ApplicationDispatcher.java:728)
	at org.apache.catalina.core.ApplicationDispatcher.doInclude(ApplicationDispatcher.java:591)
	at org.apache.catalina.core.ApplicationDispatcher.include(ApplicationDispatcher.java:527)
	at org.apache.tiles.request.servlet.ServletRequest.doInclude(ServletRequest.java:243)
	at org.apache.tiles.request.AbstractClientRequest.dispatch(AbstractClientRequest.java:54)
	at org.apache.tiles.request.render.DispatchRenderer.render(DispatchRenderer.java:47)
	at org.apache.tiles.impl.BasicTilesContainer.render(BasicTilesContainer.java:259)
	at org.apache.tiles.impl.BasicTilesContainer.render(BasicTilesContainer.java:397)
	at org.apache.tiles.impl.BasicTilesContainer.render(BasicTilesContainer.java:238)
	at org.apache.tiles.impl.BasicTilesContainer.render(BasicTilesContainer.java:221)
	at org.apache.tiles.renderer.DefinitionRenderer.render(DefinitionRenderer.java:59)
	at org.springframework.web.servlet.view.tiles3.TilesView.renderMergedOutputModel(TilesView.java:146)
	at org.springframework.web.servlet.view.AbstractView.render(AbstractView.java:314)
	at org.springframework.web.servlet.DispatcherServlet.render(DispatcherServlet.java:1325)
	at org.springframework.web.servlet.DispatcherServlet.processDispatchResult(DispatcherServlet.java:1069)
	at org.springframework.web.servlet.DispatcherServlet.doDispatch(DispatcherServlet.java:1008)
	at org.springframework.web.servlet.DispatcherServlet.doService(DispatcherServlet.java:925)
	at org.springframework.web.servlet.FrameworkServlet.processRequest(FrameworkServlet.java:974)
	at org.springframework.web.servlet.FrameworkServlet.doGet(FrameworkServlet.java:866)
	at javax.servlet.http.HttpServlet.service(HttpServlet.java:635)
	at org.springframework.web.servlet.FrameworkServlet.service(FrameworkServlet.java:851)
	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.springframework.security.web.FilterChainProxy$VirtualFilterChain.doFilter(FilterChainProxy.java:320)
	at org.springframework.security.web.access.intercept.FilterSecurityInterceptor.invoke(FilterSecurityInterceptor.java:116)
	at org.springframework.security.web.access.intercept.FilterSecurityInterceptor.doFilter(FilterSecurityInterceptor.java:91)
	at org.springframework.security.web.FilterChainProxy$VirtualFilterChain.doFilter(FilterChainProxy.java:334)
	at org.springframework.security.web.access.ExceptionTranslationFilter.doFilter(ExceptionTranslationFilter.java:119)
	at org.springframework.security.web.FilterChainProxy$VirtualFilterChain.doFilter(FilterChainProxy.java:334)
	at org.springframework.security.web.session.SessionManagementFilter.doFilter(SessionManagementFilter.java:84)
	at org.springframework.security.web.FilterChainProxy$VirtualFilterChain.doFilter(FilterChainProxy.java:334)
	at org.springframework.security.web.authentication.AnonymousAuthenticationFilter.doFilter(AnonymousAuthenticationFilter.java:111)
	at org.springframework.security.web.FilterChainProxy$VirtualFilterChain.doFilter(FilterChainProxy.java:334)
	at org.springframework.security.web.servletapi.SecurityContextHolderAwareRequestFilter.doFilter(SecurityContextHolderAwareRequestFilter.java:170)
	at org.springframework.security.web.FilterChainProxy$VirtualFilterChain.doFilter(FilterChainProxy.java:334)
	at org.springframework.security.web.savedrequest.RequestCacheAwareFilter.doFilter(RequestCacheAwareFilter.java:63)
	at org.springframework.security.web.FilterChainProxy$VirtualFilterChain.doFilter(FilterChainProxy.java:334)
	at org.springframework.security.web.authentication.AbstractAuthenticationProcessingFilter.doFilter(AbstractAuthenticationProcessingFilter.java:200)
	at org.springframework.security.web.FilterChainProxy$VirtualFilterChain.doFilter(FilterChainProxy.java:334)
	at org.springframework.security.web.authentication.logout.LogoutFilter.doFilter(LogoutFilter.java:116)
	at org.springframework.security.web.FilterChainProxy$VirtualFilterChain.doFilter(FilterChainProxy.java:334)
	at org.springframework.web.filter.OncePerRequestFilter.doFilter(OncePerRequestFilter.java:101)
	at org.springframework.security.web.FilterChainProxy$VirtualFilterChain.doFilter(FilterChainProxy.java:334)
	at org.springframework.web.filter.OncePerRequestFilter.doFilter(OncePerRequestFilter.java:101)
	at org.springframework.security.web.FilterChainProxy$VirtualFilterChain.doFilter(FilterChainProxy.java:334)
	at org.springframework.security.web.context.SecurityContextPersistenceFilter.doFilter(SecurityContextPersistenceFilter.java:105)
	at org.springframework.security.web.FilterChainProxy$VirtualFilterChain.doFilter(FilterChainProxy.java:334)
	at org.springframework.web.filter.OncePerRequestFilter.doFilter(OncePerRequestFilter.java:101)
	at org.springframework.security.web.FilterChainProxy$VirtualFilterChain.doFilter(FilterChainProxy.java:334)
	at org.springframework.security.web.FilterChainProxy.doFilterInternal(FilterChainProxy.java:215)
	at org.springframework.security.web.FilterChainProxy.doFilter(FilterChainProxy.java:178)
	at org.springframework.web.filter.DelegatingFilterProxy.invokeDelegate(DelegatingFilterProxy.java:357)
	at org.springframework.web.filter.DelegatingFilterProxy.doFilter(DelegatingFilterProxy.java:270)
	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.ApplicationDispatcher.invoke(ApplicationDispatcher.java:728)
	at org.apache.catalina.core.ApplicationDispatcher.processRequest(ApplicationDispatcher.java:472)
	at org.apache.catalina.core.ApplicationDispatcher.doForward(ApplicationDispatcher.java:395)
	at org.apache.catalina.core.ApplicationDispatcher.forward(ApplicationDispatcher.java:316)
	at org.apache.catalina.core.StandardHostValve.custom(StandardHostValve.java:395)
	at org.apache.catalina.core.StandardHostValve.status(StandardHostValve.java:254)
	at org.apache.catalina.core.StandardHostValve.invoke(StandardHostValve.java:177)
	at org.apache.catalina.valves.ErrorReportValve.invoke(ErrorReportValve.java:81)
	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:803)
	at org.apache.coyote.AbstractProcessorLight.process(AbstractProcessorLight.java:66)
	at org.apache.coyote.AbstractProtocol$ConnectionHandler.process(AbstractProtocol.java:790)
	at org.apache.tomcat.util.net.NioEndpoint$SocketProcessor.doRun(NioEndpoint.java:1459)
	at org.apache.tomcat.util.net.SocketProcessorBase.run(SocketProcessorBase.java:49)
	at java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1149)
	at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:624)
	at org.apache.tomcat.util.threads.TaskThread$WrappingRunnable.run(TaskThread.java:61)
	at java.lang.Thread.run(Thread.java:748)
[2018-07-01 23:02:04] [ERROR] [DirectJDKLog.java:182] Servlet.service() for servlet [dispatcherServlet] threw exception
javax.servlet.ServletException: File [&#47;WEB-INF&#47;views&#47;error&#47;error.jsp] not found
	at org.apache.jasper.servlet.JspServlet.handleMissingResource(JspServlet.java:408)
	at org.apache.jasper.servlet.JspServlet.serviceJspFile(JspServlet.java:375)
	at org.apache.jasper.servlet.JspServlet.service(JspServlet.java:330)
	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.catalina.core.ApplicationDispatcher.invoke(ApplicationDispatcher.java:728)
	at org.apache.catalina.core.ApplicationDispatcher.doInclude(ApplicationDispatcher.java:591)
	at org.apache.catalina.core.ApplicationDispatcher.include(ApplicationDispatcher.java:527)
	at org.apache.tiles.request.servlet.ServletRequest.doInclude(ServletRequest.java:243)
	at org.apache.tiles.request.AbstractClientRequest.dispatch(AbstractClientRequest.java:54)
	at org.apache.tiles.request.render.DispatchRenderer.render(DispatchRenderer.java:47)
	at org.apache.tiles.impl.BasicTilesContainer.render(BasicTilesContainer.java:259)
	at org.apache.tiles.impl.BasicTilesContainer.render(BasicTilesContainer.java:397)
	at org.apache.tiles.impl.BasicTilesContainer.render(BasicTilesContainer.java:238)
	at org.apache.tiles.impl.BasicTilesContainer.render(BasicTilesContainer.java:221)
	at org.apache.tiles.renderer.DefinitionRenderer.render(DefinitionRenderer.java:59)
	at org.springframework.web.servlet.view.tiles3.TilesView.renderMergedOutputModel(TilesView.java:146)
	at org.springframework.web.servlet.view.AbstractView.render(AbstractView.java:314)
	at org.springframework.web.servlet.DispatcherServlet.render(DispatcherServlet.java:1325)
	at org.springframework.web.servlet.DispatcherServlet.processDispatchResult(DispatcherServlet.java:1069)
	at org.springframework.web.servlet.DispatcherServlet.doDispatch(DispatcherServlet.java:1008)
	at org.springframework.web.servlet.DispatcherServlet.doService(DispatcherServlet.java:925)
	at org.springframework.web.servlet.FrameworkServlet.processRequest(FrameworkServlet.java:974)
	at org.springframework.web.servlet.FrameworkServlet.doGet(FrameworkServlet.java:866)
	at javax.servlet.http.HttpServlet.service(HttpServlet.java:635)
	at org.springframework.web.servlet.FrameworkServlet.service(FrameworkServlet.java:851)
	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.springframework.security.web.FilterChainProxy$VirtualFilterChain.doFilter(FilterChainProxy.java:320)
	at org.springframework.security.web.access.intercept.FilterSecurityInterceptor.invoke(FilterSecurityInterceptor.java:116)
	at org.springframework.security.web.access.intercept.FilterSecurityInterceptor.doFilter(FilterSecurityInterceptor.java:91)
	at org.springframework.security.web.FilterChainProxy$VirtualFilterChain.doFilter(FilterChainProxy.java:334)
	at org.springframework.security.web.access.ExceptionTranslationFilter.doFilter(ExceptionTranslationFilter.java:119)
	at org.springframework.security.web.FilterChainProxy$VirtualFilterChain.doFilter(FilterChainProxy.java:334)
	at org.springframework.security.web.session.SessionManagementFilter.doFilter(SessionManagementFilter.java:84)
	at org.springframework.security.web.FilterChainProxy$VirtualFilterChain.doFilter(FilterChainProxy.java:334)
	at org.springframework.security.web.authentication.AnonymousAuthenticationFilter.doFilter(AnonymousAuthenticationFilter.java:111)
	at org.springframework.security.web.FilterChainProxy$VirtualFilterChain.doFilter(FilterChainProxy.java:334)
	at org.springframework.security.web.servletapi.SecurityContextHolderAwareRequestFilter.doFilter(SecurityContextHolderAwareRequestFilter.java:170)
	at org.springframework.security.web.FilterChainProxy$VirtualFilterChain.doFilter(FilterChainProxy.java:334)
	at org.springframework.security.web.savedrequest.RequestCacheAwareFilter.doFilter(RequestCacheAwareFilter.java:63)
	at org.springframework.security.web.FilterChainProxy$VirtualFilterChain.doFilter(FilterChainProxy.java:334)
	at org.springframework.security.web.authentication.AbstractAuthenticationProcessingFilter.doFilter(AbstractAuthenticationProcessingFilter.java:200)
	at org.springframework.security.web.FilterChainProxy$VirtualFilterChain.doFilter(FilterChainProxy.java:334)
	at org.springframework.security.web.authentication.logout.LogoutFilter.doFilter(LogoutFilter.java:116)
	at org.springframework.security.web.FilterChainProxy$VirtualFilterChain.doFilter(FilterChainProxy.java:334)
	at org.springframework.web.filter.OncePerRequestFilter.doFilter(OncePerRequestFilter.java:101)
	at org.springframework.security.web.FilterChainProxy$VirtualFilterChain.doFilter(FilterChainProxy.java:334)
	at org.springframework.web.filter.OncePerRequestFilter.doFilter(OncePerRequestFilter.java:101)
	at org.springframework.security.web.FilterChainProxy$VirtualFilterChain.doFilter(FilterChainProxy.java:334)
	at org.springframework.security.web.context.SecurityContextPersistenceFilter.doFilter(SecurityContextPersistenceFilter.java:105)
	at org.springframework.security.web.FilterChainProxy$VirtualFilterChain.doFilter(FilterChainProxy.java:334)
	at org.springframework.web.filter.OncePerRequestFilter.doFilter(OncePerRequestFilter.java:101)
	at org.springframework.security.web.FilterChainProxy$VirtualFilterChain.doFilter(FilterChainProxy.java:334)
	at org.springframework.security.web.FilterChainProxy.doFilterInternal(FilterChainProxy.java:215)
	at org.springframework.security.web.FilterChainProxy.doFilter(FilterChainProxy.java:178)
	at org.springframework.web.filter.DelegatingFilterProxy.invokeDelegate(DelegatingFilterProxy.java:357)
	at org.springframework.web.filter.DelegatingFilterProxy.doFilter(DelegatingFilterProxy.java:270)
	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.ApplicationDispatcher.invoke(ApplicationDispatcher.java:728)
	at org.apache.catalina.core.ApplicationDispatcher.processRequest(ApplicationDispatcher.java:472)
	at org.apache.catalina.core.ApplicationDispatcher.doForward(ApplicationDispatcher.java:395)
	at org.apache.catalina.core.ApplicationDispatcher.forward(ApplicationDispatcher.java:316)
	at org.apache.catalina.core.StandardHostValve.custom(StandardHostValve.java:395)
	at org.apache.catalina.core.StandardHostValve.status(StandardHostValve.java:254)
	at org.apache.catalina.core.StandardHostValve.invoke(StandardHostValve.java:177)
	at org.apache.catalina.valves.ErrorReportValve.invoke(ErrorReportValve.java:81)
	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:803)
	at org.apache.coyote.AbstractProcessorLight.process(AbstractProcessorLight.java:66)
	at org.apache.coyote.AbstractProtocol$ConnectionHandler.process(AbstractProtocol.java:790)
	at org.apache.tomcat.util.net.NioEndpoint$SocketProcessor.doRun(NioEndpoint.java:1459)
	at org.apache.tomcat.util.net.SocketProcessorBase.run(SocketProcessorBase.java:49)
	at java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1149)
	at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:624)
	at org.apache.tomcat.util.threads.TaskThread$WrappingRunnable.run(TaskThread.java:61)
	at java.lang.Thread.run(Thread.java:748)
[2018-07-01 23:02:04] [ERROR] [DirectJDKLog.java:182] Exception Processing ErrorPage[errorCode=0, location=/error]
org.springframework.web.util.NestedServletException: Request processing failed; nested exception is org.apache.tiles.request.render.CannotRenderException: ServletException including path '/WEB-INF/views/error/error.jsp'.
	at org.springframework.web.servlet.FrameworkServlet.processRequest(FrameworkServlet.java:982)
	at org.springframework.web.servlet.FrameworkServlet.doGet(FrameworkServlet.java:866)
	at javax.servlet.http.HttpServlet.service(HttpServlet.java:635)
	at org.springframework.web.servlet.FrameworkServlet.service(FrameworkServlet.java:851)
	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.springframework.security.web.FilterChainProxy$VirtualFilterChain.doFilter(FilterChainProxy.java:320)
	at org.springframework.security.web.access.intercept.FilterSecurityInterceptor.invoke(FilterSecurityInterceptor.java:116)
	at org.springframework.security.web.access.intercept.FilterSecurityInterceptor.doFilter(FilterSecurityInterceptor.java:91)
	at org.springframework.security.web.FilterChainProxy$VirtualFilterChain.doFilter(FilterChainProxy.java:334)
	at org.springframework.security.web.access.ExceptionTranslationFilter.doFilter(ExceptionTranslationFilter.java:119)
	at org.springframework.security.web.FilterChainProxy$VirtualFilterChain.doFilter(FilterChainProxy.java:334)
	at org.springframework.security.web.session.SessionManagementFilter.doFilter(SessionManagementFilter.java:84)
	at org.springframework.security.web.FilterChainProxy$VirtualFilterChain.doFilter(FilterChainProxy.java:334)
	at org.springframework.security.web.authentication.AnonymousAuthenticationFilter.doFilter(AnonymousAuthenticationFilter.java:111)
	at org.springframework.security.web.FilterChainProxy$VirtualFilterChain.doFilter(FilterChainProxy.java:334)
	at org.springframework.security.web.servletapi.SecurityContextHolderAwareRequestFilter.doFilter(SecurityContextHolderAwareRequestFilter.java:170)
	at org.springframework.security.web.FilterChainProxy$VirtualFilterChain.doFilter(FilterChainProxy.java:334)
	at org.springframework.security.web.savedrequest.RequestCacheAwareFilter.doFilter(RequestCacheAwareFilter.java:63)
	at org.springframework.security.web.FilterChainProxy$VirtualFilterChain.doFilter(FilterChainProxy.java:334)
	at org.springframework.security.web.authentication.AbstractAuthenticationProcessingFilter.doFilter(AbstractAuthenticationProcessingFilter.java:200)
	at org.springframework.security.web.FilterChainProxy$VirtualFilterChain.doFilter(FilterChainProxy.java:334)
	at org.springframework.security.web.authentication.logout.LogoutFilter.doFilter(LogoutFilter.java:116)
	at org.springframework.security.web.FilterChainProxy$VirtualFilterChain.doFilter(FilterChainProxy.java:334)
	at org.springframework.web.filter.OncePerRequestFilter.doFilter(OncePerRequestFilter.java:101)
	at org.springframework.security.web.FilterChainProxy$VirtualFilterChain.doFilter(FilterChainProxy.java:334)
	at org.springframework.web.filter.OncePerRequestFilter.doFilter(OncePerRequestFilter.java:101)
	at org.springframework.security.web.FilterChainProxy$VirtualFilterChain.doFilter(FilterChainProxy.java:334)
	at org.springframework.security.web.context.SecurityContextPersistenceFilter.doFilter(SecurityContextPersistenceFilter.java:105)
	at org.springframework.security.web.FilterChainProxy$VirtualFilterChain.doFilter(FilterChainProxy.java:334)
	at org.springframework.web.filter.OncePerRequestFilter.doFilter(OncePerRequestFilter.java:101)
	at org.springframework.security.web.FilterChainProxy$VirtualFilterChain.doFilter(FilterChainProxy.java:334)
	at org.springframework.security.web.FilterChainProxy.doFilterInternal(FilterChainProxy.java:215)
	at org.springframework.security.web.FilterChainProxy.doFilter(FilterChainProxy.java:178)
	at org.springframework.web.filter.DelegatingFilterProxy.invokeDelegate(DelegatingFilterProxy.java:357)
	at org.springframework.web.filter.DelegatingFilterProxy.doFilter(DelegatingFilterProxy.java:270)
	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.ApplicationDispatcher.invoke(ApplicationDispatcher.java:728)
	at org.apache.catalina.core.ApplicationDispatcher.processRequest(ApplicationDispatcher.java:472)
	at org.apache.catalina.core.ApplicationDispatcher.doForward(ApplicationDispatcher.java:395)
	at org.apache.catalina.core.ApplicationDispatcher.forward(ApplicationDispatcher.java:316)
	at org.apache.catalina.core.StandardHostValve.custom(StandardHostValve.java:395)
	at org.apache.catalina.core.StandardHostValve.status(StandardHostValve.java:254)
	at org.apache.catalina.core.StandardHostValve.invoke(StandardHostValve.java:177)
	at org.apache.catalina.valves.ErrorReportValve.invoke(ErrorReportValve.java:81)
	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:803)
	at org.apache.coyote.AbstractProcessorLight.process(AbstractProcessorLight.java:66)
	at org.apache.coyote.AbstractProtocol$ConnectionHandler.process(AbstractProtocol.java:790)
	at org.apache.tomcat.util.net.NioEndpoint$SocketProcessor.doRun(NioEndpoint.java:1459)
	at org.apache.tomcat.util.net.SocketProcessorBase.run(SocketProcessorBase.java:49)
	at java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1149)
	at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:624)
	at org.apache.tomcat.util.threads.TaskThread$WrappingRunnable.run(TaskThread.java:61)
	at java.lang.Thread.run(Thread.java:748)
Caused by: org.apache.tiles.request.render.CannotRenderException: ServletException including path '/WEB-INF/views/error/error.jsp'.
	at org.apache.tiles.impl.BasicTilesContainer.render(BasicTilesContainer.java:399)
	at org.apache.tiles.impl.BasicTilesContainer.render(BasicTilesContainer.java:238)
	at org.apache.tiles.impl.BasicTilesContainer.render(BasicTilesContainer.java:221)
	at org.apache.tiles.renderer.DefinitionRenderer.render(DefinitionRenderer.java:59)
	at org.springframework.web.servlet.view.tiles3.TilesView.renderMergedOutputModel(TilesView.java:146)
	at org.springframework.web.servlet.view.AbstractView.render(AbstractView.java:314)
	at org.springframework.web.servlet.DispatcherServlet.render(DispatcherServlet.java:1325)
	at org.springframework.web.servlet.DispatcherServlet.processDispatchResult(DispatcherServlet.java:1069)
	at org.springframework.web.servlet.DispatcherServlet.doDispatch(DispatcherServlet.java:1008)
	at org.springframework.web.servlet.DispatcherServlet.doService(DispatcherServlet.java:925)
	at org.springframework.web.servlet.FrameworkServlet.processRequest(FrameworkServlet.java:974)
	... 57 common frames omitted
Caused by: java.io.IOException: ServletException including path '/WEB-INF/views/error/error.jsp'.
	at org.apache.tiles.request.servlet.ServletUtil.wrapServletException(ServletUtil.java:63)
	at org.apache.tiles.request.servlet.ServletRequest.doInclude(ServletRequest.java:245)
	at org.apache.tiles.request.AbstractClientRequest.dispatch(AbstractClientRequest.java:54)
	at org.apache.tiles.request.render.DispatchRenderer.render(DispatchRenderer.java:47)
	at org.apache.tiles.impl.BasicTilesContainer.render(BasicTilesContainer.java:259)
	at org.apache.tiles.impl.BasicTilesContainer.render(BasicTilesContainer.java:397)
	... 67 common frames omitted
Caused by: javax.servlet.ServletException: File [&#47;WEB-INF&#47;views&#47;error&#47;error.jsp] not found
	at org.apache.jasper.servlet.JspServlet.handleMissingResource(JspServlet.java:408)
	at org.apache.jasper.servlet.JspServlet.serviceJspFile(JspServlet.java:375)
	at org.apache.jasper.servlet.JspServlet.service(JspServlet.java:330)
	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.catalina.core.ApplicationDispatcher.invoke(ApplicationDispatcher.java:728)
	at org.apache.catalina.core.ApplicationDispatcher.doInclude(ApplicationDispatcher.java:591)
	at org.apache.catalina.core.ApplicationDispatcher.include(ApplicationDispatcher.java:527)
	at org.apache.tiles.request.servlet.ServletRequest.doInclude(ServletRequest.java:243)
	… 71 common frames omitted

 

스프링 부트는 공식적으로 jsp를 지원하지 않기 때문에 jar로 묶을 수 없다. 1.4.3 이하에서는 resources/META-INF/resources/WEB-INF/ 폴더 내의 내용을 src/main/webapp/WEB-INF/ 폴더 내로 복사해서 해결할 수 있지만 1.4.3부터는 그 것마저 막혔다.

그래서 1.4.3은 jar가 아닌 was로 패키징을 진행하면 해결할 수 있다.

pom.xml만 수정하고 다시 진행하면 정상적으로 jsp가 호출된다.

스프링 부트 애플리케이션을 Docker image로 빌드해서 컨테이너에 올리는 작업을 진행해 보겠다.

 

필요사항

  • JDK 1.8 later
  • Maven 3.2 이상
  • STS
  • Docker

 

Pom.xml 수정을 먼저 진행해야한다.

  • wedul 이라는 이름의 jar 파일이 생성된다.
  • docker에서 실행하기 위한 Maven 설정이 들어있는 jar file이 만들어 진다.
  • 만약 image prefix 값을 별도로 지정하지 않으면 artifact id가 명시된다.
<properties>
   <docker.image.prefix>wedul</docker.image.prefix>
</properties>
<build>
    <plugins>
        <plugin>
            <groupId>com.spotify</groupId>
            <artifactId>dockerfile-maven-plugin</artifactId>
            <version>1.3.6</version>
            <configuration>
                <repository>${docker.image.prefix}/${project.artifactId}</repository>
                <buildArgs>
                    <JAR_FILE>target/${project.build.finalName}.jar</JAR_FILE>
                </buildArgs>
            </configuration>
        </plugin>
    </plugins>
</build>

 

그리고 프로젝트 Root에 Dockerfile을 위치시켜야 한다. 

FROM java:8
VOLUME /tmp
ADD /target/wedulpos-0.0.1-SNAPSHOT.jar wedulpos.jar
ENTRYPOINT ["java","-jar","wedulpos.jar"]

DockerFile 옵션 설명 (출처 : https://www.callicoder.com/spring-boot-docker-example/)

VOLUME 

볼륨은 호스트 OS에서 컨테이너에 의해 생성 된 데이터를 유지하고 호스트 OS에서 컨테이너로 디렉토리를 공유하는 메커니즘입니다.

VOLUME 명령은 컨테이너에 지정된 경로로 마운트 포인트를 작성합니다. 컨테이너를 실행할 때 지정된 마운트 지점이 매핑 될 Hot OS의 디렉토리를 지정할 수 있습니다. 그런 다음, 컨테이너가 마운트 된 경로에 쓰는 것이 호스트 OS의 매핑 된 디렉토리에 기록됩니다. 볼륨의 가장 일반적인 사용 사례 중 하나는 컨테이너에 의해 생성 된 로그 파일을 호스트 OS에 저장하는 것입니다.

예를 들어, 응용 프로그램이 로그 파일을 /var/log/app.log 위치에 기록한다고 가정 해 봅시다. Dockerfile에 / var / log 경로로 VOLUME을 마운트 한 다음 컨테이너를 실행하는 동안이 마운트 지점이 매핑 될 호스트 OS의 디렉토리를 지정할 수 있습니다. 그런 다음 호스트 OS의 매핑 된 디렉토리에서 로그에 액세스 할 수 있습니다.

위의 Dockerfile에서 / tmp 경로를 사용하여 마운트 지점을 만들었습니다. 이것이 스프링 부트 응용 프로그램이 Tomcat에 대한 작업 디렉토리를 기본적으로 만드는 위치이기 때문입니다. 이 스프링 부트 응용 프로그램에는 바람둥이 디렉토리에 관심이 있기 때문에 필수는 아니지만. 그러나 Tomcat 액세스 로그와 같은 항목을 저장하려는 경우 VOLUMES는 매우 유용합니다.

 

ADD

ADD 명령은 새 파일과 디렉토리를 고정 이미지에 복사하는 데 사용됩니다.

 

ENTRYPOINT

응용 프로그램이 컨테이너 내부에서 실행되는 방법을 구성하는 곳입니다. 

 

그렇게 설정을 마치고 명령어를 통해 docker에서 사용할 수 있는 이미지 파일로 빌드를 진행한다.

./mvnw install dockerfile:build

설정을 정상적으로 하고 빌드가 진행이 완료되면 BUILD SUCCESS가 보일 것이다.

Docker image ls 명령어를 통해 지금 설치가 완료된 이미지 파일도 확인할 수 있다.

 

 

+ Recent posts