- 背景
當時是在將Excel導出從POI轉成使用EasyExcel
POI使用的maven座標如下:
<dependency>
<groupId>org.apache.poi</groupId>
<artifactId>poi</artifactId>
<version>3.8</version>
</dependency>
<dependency>
<groupId>org.apache.poi</groupId>
<artifactId>poi-ooxml</artifactId>
<version>3.8</version>
</dependency>
EasyExcel添加的maven座標如下:
<dependency>
<groupId>com.alibaba</groupId>
<artifactId>easyexcel</artifactId>
<version>1.1.2-beat1</version>
</dependency>
編寫好代碼debug啓動項目,啓動沒任何報錯,在執行改方法時,控制檯報錯了,報錯信息如下:
org.springframework.web.util.NestedServletException: Handler dispatch failed; nested exception is java.lang.NoSuchMethodError: org.apache.poi.ss.usermodel.Font.setBold(Z)V
at org.springframework.web.servlet.DispatcherServlet.doDispatch(DispatcherServlet.java:978)
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.doGet(FrameworkServlet.java:861)
at javax.servlet.http.HttpServlet.service(HttpServlet.java:635)
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.session.web.http.SessionRepositoryFilter.doFilterInternal(SessionRepositoryFilter.java:167)
at org.springframework.session.web.http.OncePerRequestFilter.doFilter(OncePerRequestFilter.java:80)
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:748)
Caused by: java.lang.NoSuchMethodError: org.apache.poi.ss.usermodel.Font.setBold(Z)V
at com.alibaba.excel.util.StyleUtil.buildDefaultCellStyle(StyleUtil.java:22)
at com.alibaba.excel.context.WriteContext.<init>(WriteContext.java:99)
at com.alibaba.excel.write.ExcelBuilderImpl.<init>(ExcelBuilderImpl.java:38)
at com.alibaba.excel.ExcelWriter.<init>(ExcelWriter.java:58)
at com.alibaba.excel.ExcelWriter.<init>(ExcelWriter.java:34)
at com.wyj.controller.EasyExcelDemo.findAllExcelByEasyExcel(EasyExcelDemo.java:45)
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)
... 47 common frames omitted
-
報錯信息大概的信息是說
在at com.alibaba.excel.util.StyleUtil類中的buildDefaultCellStyle方法中沒找到setBold(Z)V這個方法,點進StyleUtil這個類的源碼中,找到setBold(Z)V這個方法,在這裏調用了org.apache.poi.ss.usermodel.Font類的setBold(Z)V方法,從源碼中進入Font類中,發現的確沒有setBold(Z)V這個方法,但是不科學啊,EasyExcel底層是封裝了POI的,那麼它裏面一定引用了POI的jar包,相當於調用自己內部代碼的方法,不可能會找不到方法啊 -
突然意識到
既然EasyExcel內部引用了POI的jar包,但是我本來的pom.xml文件中也引用POI的jar,會不會是jar包版本衝突造成的呢?接下來,分別查看了本身pom.xml引用POI的版本,爲3.8,EasyExcel版本1.1.2-beat1內部引用的POI版本爲3.17 -
確認猜測
那麼就到POI版本爲3.8和3.17當中找到org.apache.poi.ss.usermodel.Font類看是否有setBold(Z)V這個方法
發現在POI3.8版本中Font這個類中並沒有setBold(Z)V這個方法,但是在POI3.17版本中Font這個類中卻有setBold(Z)V這個方法
- 確認原因
至此,差不多可以知道到底是什麼原因造成控制檯拋出這異常了:原因是EasyExcel 1.1.2-beat1版本中本應使用POI 3.17版本中的代碼,但是由於版本衝突卻使用了POI 3.8版本中的代碼,造成類中方法找不到而拋出這個異常的
- 那麼爲什麼會造成版本衝突呢?
maven在做版本管理時有一個重要的原則就是就近原則。啥是就是就近原則呢?就拿本例子來說,POI 3.8版本距離當前jar更近,而POI3.17版本更遠(POI 3.17版本還經過了一層EasyExcel 1.1.2-beat1版本),所以在maven版本管理中,將使用POI 3.8版本
- 那麼如何解決呢?
將自身pom.xml文件中的POI 3.8依賴註釋掉即可
- 註釋了再ReImport
發現還是報這個錯
- 還存在的問題
突然想到會不會是依賴其他模塊,在其他模塊中也依賴了POI 3.8版本,導致在依賴的過程中也將依賴中的POI 3.8版本的jar也依賴進來了,IDEA使用Ctrl+Shirt+F全項目搜索poi,發現果然在依賴的模塊中也存在。
- 那麼如何解決呢?
在模塊的依賴中除去POI的jar包
<dependency>
<groupId>com.wyj</groupId>
<artifactId>test</artifactId>
<version>0.0.1.RELEASE</version>
</dependency>
換成
<dependency>
<groupId>com.wyj</groupId>
<artifactId>test</artifactId>
<version>0.0.1.RELEASE</version>
<exclusions>
<exclusion>
<groupId>org.apache.poi</groupId>
<artifactId>poi</artifactId>
</exclusion>
<exclusion>
<groupId>org.apache.poi</groupId>
<artifactId>poi-ooxml</artifactId>
</exclusion>
<exclusion>
<groupId>org.apache.poi</groupId>
<artifactId>poi-ooxml-schemas</artifactId>
</exclusion>
</exclusions>
</dependency>
- 完成之後再ReImport
運行完美解決