问题:
某一天把spring-boot从1.3.6版本升级到1.4.3版本,然后在使用 java -jar uber.jar
运行启动项目的时候会出现
Caused by: org.glassfish.jersey.server.internal.scanning.ResourceFinderException: java.io.FileNotFoundException: /Users/dragon/Workspace/WorkSources/longzhe/demo/target/demo-0.0.1-SNAPSHOT.jar!/BOOT-INF/classes (No such file or directory)
at org.glassfish.jersey.server.internal.scanning.JarZipSchemeResourceFinderFactory.create(JarZipSchemeResourceFinderFactory.java:89) ~[jersey-server-2.25.1.jar!/:na]
at org.glassfish.jersey.server.internal.scanning.JarZipSchemeResourceFinderFactory.create(JarZipSchemeResourceFinderFactory.java:65) ~[jersey-server-2.25.1.jar!/:na]
at org.glassfish.jersey.server.internal.scanning.PackageNamesScanner.addResourceFinder(PackageNamesScanner.java:282) ~[jersey-server-2.25.1.jar!/:na]
at org.glassfish.jersey.server.internal.scanning.PackageNamesScanner.init(PackageNamesScanner.java:198) ~[jersey-server-2.25.1.jar!/:na]
at org.glassfish.jersey.server.internal.scanning.PackageNamesScanner.<init>(PackageNamesScanner.java:154) ~[jersey-server-2.25.1.jar!/:na]
at org.glassfish.jersey.server.internal.scanning.PackageNamesScanner.<init>(PackageNamesScanner.java:110) ~[jersey-server-2.25.1.jar!/:na]
at org.glassfish.jersey.server.ResourceConfig.packages(ResourceConfig.java:680) ~[jersey-server-2.25.1.jar!/:na]
at org.glassfish.jersey.server.ResourceConfig.packages(ResourceConfig.java:660) ~[jersey-server-2.25.1.jar!/:na]
at com.example.JerseyConfig.<init>(JerseyConfig.java:34) ~[classes!/:0.0.1-SNAPSHOT]
at com.example.JerseyAnnotationConfiguration.jerseyConfig(JerseyAnnotationConfiguration.java:65) ~[classes!/:0.0.1-SNAPSHOT]
at com.example.JerseyAnnotationConfiguration$$EnhancerBySpringCGLIB$$6207da77.CGLIB$jerseyConfig$1(<generated>) ~[classes!/:0.0.1-SNAPSHOT]
at com.example.JerseyAnnotationConfiguration$$EnhancerBySpringCGLIB$$6207da77$$FastClassBySpringCGLIB$$5bd2b833.invoke(<generated>) ~[classes!/:0.0.1-SNAPSHOT]
at org.springframework.cglib.proxy.MethodProxy.invokeSuper(MethodProxy.java:228) ~[spring-core-4.3.7.RELEASE.jar!/:4.3.7.RELEASE]
at org.springframework.context.annotation.ConfigurationClassEnhancer$BeanMethodInterceptor.intercept(ConfigurationClassEnhancer.java:358) ~[spring-context-4.3.7.RELEASE.jar!/:4.3.7.RELEASE]
at com.example.JerseyAnnotationConfiguration$$EnhancerBySpringCGLIB$$6207da77.jerseyConfig(<generated>) ~[classes!/:0.0.1-SNAPSHOT]
at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method) ~[na:1.8.0_73]
at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:62) ~[na:1.8.0_73]
at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43) ~[na:1.8.0_73]
at java.lang.reflect.Method.invoke(Method.java:497) ~[na:1.8.0_73]
at org.springframework.beans.factory.support.SimpleInstantiationStrategy.instantiate(SimpleInstantiationStrategy.java:162) ~[spring-beans-4.3.7.RELEASE.jar!/:4.3.7.RELEASE]
... 49 common frames omitted
Caused by: java.io.FileNotFoundException: /Users/dragon/Workspace/WorkSources/longzhe/demo/target/demo-0.0.1-SNAPSHOT.jar!/BOOT-INF/classes (No such file or directory)
at java.io.FileInputStream.open0(Native Method) ~[na:1.8.0_73]
at java.io.FileInputStream.open(FileInputStream.java:195) ~[na:1.8.0_73]
at java.io.FileInputStream.<init>(FileInputStream.java:138) ~[na:1.8.0_73]
at java.io.FileInputStream.<init>(FileInputStream.java:93) ~[na:1.8.0_73]
at sun.net.www.protocol.file.FileURLConnection.connect(FileURLConnection.java:90) ~[na:1.8.0_73]
at sun.net.www.protocol.file.FileURLConnection.getInputStream(FileURLConnection.java:188) ~[na:1.8.0_73]
at java.net.URL.openStream(URL.java:1045) ~[na:1.8.0_73]
at org.glassfish.jersey.server.internal.scanning.JarZipSchemeResourceFinderFactory.getInputStream(JarZipSchemeResourceFinderFactory.java:177) ~[jersey-server-2.25.1.jar!/:na]
at org.glassfish.jersey.server.internal.scanning.JarZipSchemeResourceFinderFactory.create(JarZipSchemeResourceFinderFactory.java:87) ~[jersey-server-2.25.1.jar!/:na]
... 68 common frames omitted
的异常
环境
springboot 1.5.2
jersey 2.25.1
原因
spring-boot升级到1.4+ 以后,spring-boot专门用来打包的maven plugin对目录结构进行了改变,如果使用了jersey来代替springmvc作为restful的方案,然后并且自己在生成的JerseyConfig类里面,通过 package()
函数来指定要扫描的包的路径的话,会导致找不到对应的路径,从而导致了出现java.io.FileNotFoundException
的异常
解决
网上一搜, 果然有很多相关的提问, 其中官方网站的升级wiki里面,也说了这个问题,并且给出了解决方案:
http://docs.spring.io/spring-boot/docs/1.5.x/reference/htmlsingle/#howto-extract-specific-libraries-when-an-executable-jar-runs
但是,按照这个方案进行配置,修改了相关的jar的坐标,但是没有效果(可能是我配置错误,如果有人知道如何通过配置,麻烦告知,十分感谢)
然后没有办法,只能找其他的解决方案
既然是 package()
函数来指定扫描包的时候找不到对应的路径,那就替换这个方法,最终使用了
ClassPathScanningCandidateComponentProvider scanner = new ClassPathScanningCandidateComponentProvider(false);
// add more annotation filters if you need
scanner.addIncludeFilter(new AnnotationTypeFilter(Path.class));
scanner.addIncludeFilter(new AnnotationTypeFilter(Provider.class));
this.registerClasses(scanner.findCandidateComponents(scanPackage).stream()
.map(beanDefinition -> ClassUtils
.resolveClassName(beanDefinition.getBeanClassName(), this.getClassLoader()))
.collect(Collectors.toSet()));
来替换了传统的 package()
的方式,然后打包、运行。 可以看到项目成功启动了,并且简单的接口也可以访问了。
不过接下来需要进一步验证是否能在其他环境正常运行。