我已将我的spring boot Web服务部署在tomcat 7容器中.此问题随机弹出,我注意到当我重新启动TC容器并部署新版本的服务时,此问题会间歇性显示. 任何潜在客户均受到高度赞赏.我花了整整一天的时间来弄清楚哪里出了问题,最终感到很愚蠢<dependency> <groupId>com.github.jai-imageio</groupId> <artifactId>jai-imageio-core</artifactId> <version>1.3.0</version></dependency><dependency> <groupId>com.github.jai-imageio</groupId> <artifactId>jai-imageio-jpeg2000</artifactId> <version>1.3.0</version></dependency>java.lang.NoClassDefFoundError: com/github/jaiimageio/stream/RawImageInputStream at com.github.jaiimageio.impl.plugins.raw.RawImageReaderSpi.canDecodeInput(RawImageReaderSpi.java:102) ~[jai-imageio-core-1.3.0.jar:1.3.0] at javax.imageio.ImageIO$CanDecodeInputFilter.filter(ImageIO.java:567) ~[na:1.8.0_121] at javax.imageio.spi.FilterIterator.advance(ServiceRegistry.java:821) ~[na:1.8.0_121] at javax.imageio.spi.FilterIterator.(ServiceRegistry.java:815) ~[na:1.8.0_121] at javax.imageio.spi.ServiceRegistry.getServiceProviders(ServiceRegistry.java:516) ~[na:1.8.0_121] at javax.imageio.ImageIO.getImageReaders(ImageIO.java:646) ~[na:1.8.0_121] at javax.imageio.ImageIO.read(ImageIO.java:1438) ~[na:1.8.0_121] at javax.imageio.ImageIO.read(ImageIO.java:1352) ~[na:1.8.0_121] at my-package.a.b(a.java:155) ~[classes/:na] at my-package.a.b(a.java:181) ~[classes/:na] at my-package.a.b(a.java:84) ~[classes/:na] at my-package.a$$FastClassBySpringCGLIB$$5f66283f.invoke() ~[spring-core-4.1.3.RELEASE.jar:na] at org.springframework.cglib.proxy.MethodProxy.invoke(MethodProxy.java:204) ~[spring-core-4.1.3.RELEASE.jar:4.1.3.RELEASE] at org.springframework.aop.framework.CglibAopProxy$CglibMethodInvocation.invokeJoinpoint(CglibAopProxy.java:717) ~[spring-aop-4.1.3.RELEASE.jar:4.1.3.RELEASE] at org.springframework.aop.framework.ReflectiveMethodInvocation.proceed(ReflectiveMethodInvocation.java:157) ~[spring-aop-4.1.3.RELEASE.jar:4.1.3.RELEASE] at org.springframework.transaction.interceptor.TransactionInterceptor$1.proceedWithInvocation(TransactionInterceptor.java:99) ~[spring-tx-4.1.3.RELEASE.jar:4.1.3.RELEASE] at org.springframework.transaction.interceptor.TransactionAspectSupport.invokeWithinTransaction(TransactionAspectSupport.java:267) ~[spring-tx-4.1.3.RELEASE.jar:4.1.3.RELEASE] at org.springframework.transaction.interceptor.TransactionInterceptor.invoke(TransactionInterceptor.java:96) ~[spring-tx-4.1.3.RELEASE.jar:4.1.3.RELEASE] at org.springframework.aop.framework.ReflectiveMethodInvocation.proceed(ReflectiveMethodInvocation.java:179) ~[spring-aop-4.1.3.RELEASE.jar:4.1.3.RELEASE] at org.springframework.aop.framework.CglibAopProxy$DynamicAdvisedInterceptor.intercept(CglibAopProxy.java:653) ~[spring-aop-4.1.3.RELEASE.jar:4.1.3.RELEASE] at my-package.a$$EnhancerBySpringCGLIB$$dfc04a57.b() ~[spring-core-4.1.3.RELEASE.jar:na] at my-package.a.b(c.java:165) ~[classes/:na] at my-package.a$$FastClassBySpringCGLIB$$67dbe4b2.invoke() ~[spring-core-4.1.3.RELEASE.jar:na] at org.springframework.cglib.proxy.MethodProxy.invoke(MethodProxy.java:204) ~[spring-core-4.1.3.RELEASE.jar:4.1.3.RELEASE] at org.springframework.aop.framework.CglibAopProxy$CglibMethodInvocation.invokeJoinpoint(CglibAopProxy.java:717) ~[spring-aop-4.1.3.RELEASE.jar:4.1.3.RELEASE] at org.springframework.aop.framework.ReflectiveMethodInvocation.proceed(ReflectiveMethodInvocation.java:157) ~[spring-aop-4.1.3.RELEASE.jar:4.1.3.RELEASE] at org.springframework.transaction.interceptor.TransactionInterceptor$1.proceedWithInvocation(TransactionInterceptor.java:99) ~[spring-tx-4.1.3.RELEASE.jar:4.1.3.RELEASE] at org.springframework.transaction.interceptor.TransactionAspectSupport.invokeWithinTransaction(TransactionAspectSupport.java:267) ~[spring-tx-4.1.3.RELEASE.jar:4.1.3.RELEASE] at org.springframework.transaction.interceptor.TransactionInterceptor.invoke(TransactionInterceptor.java:96) ~[spring-tx-4.1.3.RELEASE.jar:4.1.3.RELEASE] at org.springframework.aop.framework.ReflectiveMethodInvocation.proceed(ReflectiveMethodInvocation.java:179) ~[spring-aop-4.1.3.RELEASE.jar:4.1.3.RELEASE] at org.springframework.aop.framework.CglibAopProxy$DynamicAdvisedInterceptor.intercept(CglibAopProxy.java:653) ~[spring-aop-4.1.3.RELEASE.jar:4.1.3.RELEASE] at my-package.a$$EnhancerBySpringCGLIB$$d153236a.processApprovedApplications() ~[spring-core-4.1.3.RELEASE.jar:na] at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method) ~[na:1.8.0_121] at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:62) ~[na:1.8.0_121] at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43) ~[na:1.8.0_121] at java.lang.reflect.Method.invoke(Method.java:498) ~[na:1.8.0_121] at org.springframework.scheduling.support.ScheduledMethodRunnable.run(ScheduledMethodRunnable.java:65) ~[spring-context-4.1.3.RELEASE.jar:4.1.3.RELEASE] at org.springframework.scheduling.support.DelegatingErrorHandlingRunnable.run(DelegatingErrorHandlingRunnable.java:54) ~[spring-context-4.1.3.RELEASE.jar:4.1.3.RELEASE] at org.springframework.scheduling.concurrent.ReschedulingRunnable.run(ReschedulingRunnable.java:81) [spring-context-4.1.3.RELEASE.jar:4.1.3.RELEASE] at java.util.concurrent.Executors$RunnableAdapter.call(Executors.java:511) [na:1.8.0_121] at java.util.concurrent.FutureTask.run(FutureTask.java:266) [na:1.8.0_121] at java.util.concurrent.ScheduledThreadPoolExecutor$ScheduledFutureTask.access$201(ScheduledThreadPoolExecutor.java:180) [na:1.8.0_121] at java.util.concurrent.ScheduledThreadPoolExecutor$ScheduledFutureTask.run(ScheduledThreadPoolExecutor.java:293) [na:1.8.0_121] at java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1142) [na:1.8.0_121] at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:617) [na:1.8.0_121]解决方案此处的问题是ImageIO插件和容器(如Web/Servlet容器)的已知问题. ImageIO不能很好地支持将插件作为Web应用程序的一部分进行部署. ImageIO 注册表跟踪注册的插件实际上是JVM全局的(实际上是每个应用程序上下文的注册表,但是,通常只有一个应用程序上下文*). 最安全的选择是将插件(及其所有依赖项)安装在容器的共享"或公共" lib文件夹中.这样可以确保插件仅安装一次,并且可用于所有容器上下文. 如果您希望将插件作为Web应用程序的一部分进行部署,那么我所知道的唯一选择就是使用com.twelvemonkeys.servlet.image.IIOProviderContextListener,如此处.或者,要在没有web.xml文件的Spring Boot项目中使用它,可以将以下行添加到SpringBootServletInitializer子类中的onStartup()方法中,如此处:servletContext.addListener(IIOProviderContextListener.class);请注意,第一次启用上下文侦听器后,必须完全重启容器,因为ImageIO可能已被早期部署污染". *)不要与容器的Web应用程序上下文(可能有很多上下文)混淆. [怎么回事]一个类文件(RawImageReaderSpi)被加载到JVM中,但是 RawImageInputStream未加载?链接中提到的情况是这样的,其中Web应用程序的一个较早部署已在注册表中注册了RawImageReaderSpi类,而由于重新部署,该部署中的其余类已被删除. .新部署中可能会提供RawImageInputStream类 ,但是由于新的Web应用程序上下文使用了不同的ClassLoader实例,因此原始Spi类无法将其视为与所寻找的类相同的类I am very confused with this issue. I am using 1.3.0 version on jai-imageio-core please check the dependecy below and I am at complete loss to figure out from the jar how can one class file (RawImageReaderSpi) is loaded in JVM but RawImageInputStream is not loaded.I have deployed my spring boot web service in tomcat 7 container.This issue pops up randomly and I have noticed that when I have restarted the TC container and deployed new version of my service, this issue shows up intermittently.Any lead is highly appreciated.I have spent a day trying to figure out what is wrong and ended up feeling stupid<dependency> <groupId>com.github.jai-imageio</groupId> <artifactId>jai-imageio-core</artifactId> <version>1.3.0</version></dependency><dependency> <groupId>com.github.jai-imageio</groupId> <artifactId>jai-imageio-jpeg2000</artifactId> <version>1.3.0</version></dependency>java.lang.NoClassDefFoundError: com/github/jaiimageio/stream/RawImageInputStream at com.github.jaiimageio.impl.plugins.raw.RawImageReaderSpi.canDecodeInput(RawImageReaderSpi.java:102) ~[jai-imageio-core-1.3.0.jar:1.3.0] at javax.imageio.ImageIO$CanDecodeInputFilter.filter(ImageIO.java:567) ~[na:1.8.0_121] at javax.imageio.spi.FilterIterator.advance(ServiceRegistry.java:821) ~[na:1.8.0_121] at javax.imageio.spi.FilterIterator.(ServiceRegistry.java:815) ~[na:1.8.0_121] at javax.imageio.spi.ServiceRegistry.getServiceProviders(ServiceRegistry.java:516) ~[na:1.8.0_121] at javax.imageio.ImageIO.getImageReaders(ImageIO.java:646) ~[na:1.8.0_121] at javax.imageio.ImageIO.read(ImageIO.java:1438) ~[na:1.8.0_121] at javax.imageio.ImageIO.read(ImageIO.java:1352) ~[na:1.8.0_121] at my-package.a.b(a.java:155) ~[classes/:na] at my-package.a.b(a.java:181) ~[classes/:na] at my-package.a.b(a.java:84) ~[classes/:na] at my-package.a$$FastClassBySpringCGLIB$$5f66283f.invoke() ~[spring-core-4.1.3.RELEASE.jar:na] at org.springframework.cglib.proxy.MethodProxy.invoke(MethodProxy.java:204) ~[spring-core-4.1.3.RELEASE.jar:4.1.3.RELEASE] at org.springframework.aop.framework.CglibAopProxy$CglibMethodInvocation.invokeJoinpoint(CglibAopProxy.java:717) ~[spring-aop-4.1.3.RELEASE.jar:4.1.3.RELEASE] at org.springframework.aop.framework.ReflectiveMethodInvocation.proceed(ReflectiveMethodInvocation.java:157) ~[spring-aop-4.1.3.RELEASE.jar:4.1.3.RELEASE] at org.springframework.transaction.interceptor.TransactionInterceptor$1.proceedWithInvocation(TransactionInterceptor.java:99) ~[spring-tx-4.1.3.RELEASE.jar:4.1.3.RELEASE] at org.springframework.transaction.interceptor.TransactionAspectSupport.invokeWithinTransaction(TransactionAspectSupport.java:267) ~[spring-tx-4.1.3.RELEASE.jar:4.1.3.RELEASE] at org.springframework.transaction.interceptor.TransactionInterceptor.invoke(TransactionInterceptor.java:96) ~[spring-tx-4.1.3.RELEASE.jar:4.1.3.RELEASE] at org.springframework.aop.framework.ReflectiveMethodInvocation.proceed(ReflectiveMethodInvocation.java:179) ~[spring-aop-4.1.3.RELEASE.jar:4.1.3.RELEASE] at org.springframework.aop.framework.CglibAopProxy$DynamicAdvisedInterceptor.intercept(CglibAopProxy.java:653) ~[spring-aop-4.1.3.RELEASE.jar:4.1.3.RELEASE] at my-package.a$$EnhancerBySpringCGLIB$$dfc04a57.b() ~[spring-core-4.1.3.RELEASE.jar:na] at my-package.a.b(c.java:165) ~[classes/:na] at my-package.a$$FastClassBySpringCGLIB$$67dbe4b2.invoke() ~[spring-core-4.1.3.RELEASE.jar:na] at org.springframework.cglib.proxy.MethodProxy.invoke(MethodProxy.java:204) ~[spring-core-4.1.3.RELEASE.jar:4.1.3.RELEASE] at org.springframework.aop.framework.CglibAopProxy$CglibMethodInvocation.invokeJoinpoint(CglibAopProxy.java:717) ~[spring-aop-4.1.3.RELEASE.jar:4.1.3.RELEASE] at org.springframework.aop.framework.ReflectiveMethodInvocation.proceed(ReflectiveMethodInvocation.java:157) ~[spring-aop-4.1.3.RELEASE.jar:4.1.3.RELEASE] at org.springframework.transaction.interceptor.TransactionInterceptor$1.proceedWithInvocation(TransactionInterceptor.java:99) ~[spring-tx-4.1.3.RELEASE.jar:4.1.3.RELEASE] at org.springframework.transaction.interceptor.TransactionAspectSupport.invokeWithinTransaction(TransactionAspectSupport.java:267) ~[spring-tx-4.1.3.RELEASE.jar:4.1.3.RELEASE] at org.springframework.transaction.interceptor.TransactionInterceptor.invoke(TransactionInterceptor.java:96) ~[spring-tx-4.1.3.RELEASE.jar:4.1.3.RELEASE] at org.springframework.aop.framework.ReflectiveMethodInvocation.proceed(ReflectiveMethodInvocation.java:179) ~[spring-aop-4.1.3.RELEASE.jar:4.1.3.RELEASE] at org.springframework.aop.framework.CglibAopProxy$DynamicAdvisedInterceptor.intercept(CglibAopProxy.java:653) ~[spring-aop-4.1.3.RELEASE.jar:4.1.3.RELEASE] at my-package.a$$EnhancerBySpringCGLIB$$d153236a.processApprovedApplications() ~[spring-core-4.1.3.RELEASE.jar:na] at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method) ~[na:1.8.0_121] at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:62) ~[na:1.8.0_121] at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43) ~[na:1.8.0_121] at java.lang.reflect.Method.invoke(Method.java:498) ~[na:1.8.0_121] at org.springframework.scheduling.support.ScheduledMethodRunnable.run(ScheduledMethodRunnable.java:65) ~[spring-context-4.1.3.RELEASE.jar:4.1.3.RELEASE] at org.springframework.scheduling.support.DelegatingErrorHandlingRunnable.run(DelegatingErrorHandlingRunnable.java:54) ~[spring-context-4.1.3.RELEASE.jar:4.1.3.RELEASE] at org.springframework.scheduling.concurrent.ReschedulingRunnable.run(ReschedulingRunnable.java:81) [spring-context-4.1.3.RELEASE.jar:4.1.3.RELEASE] at java.util.concurrent.Executors$RunnableAdapter.call(Executors.java:511) [na:1.8.0_121] at java.util.concurrent.FutureTask.run(FutureTask.java:266) [na:1.8.0_121] at java.util.concurrent.ScheduledThreadPoolExecutor$ScheduledFutureTask.access$201(ScheduledThreadPoolExecutor.java:180) [na:1.8.0_121] at java.util.concurrent.ScheduledThreadPoolExecutor$ScheduledFutureTask.run(ScheduledThreadPoolExecutor.java:293) [na:1.8.0_121] at java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1142) [na:1.8.0_121] at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:617) [na:1.8.0_121] 解决方案 The problem here, is a known issue with ImageIO plug-ins and containers (like a web/servlet container). Deploying plug-ins as part of the web application is not well supported by ImageIO.The ImageIO registry that keeps track of registered plug-ins is in effect JVM global (it is actually a registry per application context, however, there is usually only a single application context*).The safest option is install the plug-ins (and all their dependencies) in the container's "shared" or "common" lib folder. This ensures that the plug-ins are only installed once, and that they are available to all the container's contexts. This requires control of the container environment, and also may be a hassle to upgrade, due to manual install and full container restart required.If you prefer to deploy the plug-ins as part of the web application, the only option I know of, is to use the com.twelvemonkeys.servlet.image.IIOProviderContextListener as described here.Altenatively, to use it in a Spring Boot project without a web.xml file, you can add the following line to the onStartup() method in your SpringBootServletInitializer subclass as described here:servletContext.addListener(IIOProviderContextListener.class);Note that you must do a full restart of the container after enabling the context listener for the first time, as the ImageIO may already be "polluted" from earlier deployments.*) Not to be confused with the container's web application contexts, which there may be many of. [How can it be that] one class file (RawImageReaderSpi) is loaded in JVM but RawImageInputStream is not loaded?This is the case mentioned in the link, where one earlier deployment of the web application has registered the RawImageReaderSpi class in the registry, while the rest of the classes from that deployment has been removed, due to a re-deployement. The RawImageInputStream class may be available from the new deployment, but as the new web application context uses a different ClassLoader instance, the original Spi class can't see it as the same class it's looking for. 这篇关于用于RawImageInputStream的JAI ImageIO NoClassDefFoundError的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持! 1403页,肝出来的.. 09-06 14:49