SIngle jar startup failed after upgrade from Spring Boot 1.3.7 to 1.4.0

时光总嘲笑我的痴心妄想 提交于 2019-12-07 00:23:01

问题


After upgrading from Spring Boot 1.3.7 to 1.4.0 we can no longer start our application as a single jar build with the Spring Boot Maven plugin. Our application is a small REST interface using Jersey and Jetty. We use Maven and our pom file is pretty standard Spring Boot.

We can still run the application using mvn spring-boot:run and from within Eclipse, but when run as a single jar Jersey ResourceFinder complains that it cannot find .jar!/BOOT-INF/classes.

When I unpack the jar the folder BOOT-INF/classes is present and contains the expected classes and resources.

Any help appreciated.

2016-08-10 14:58:31.162 ERROR 16071 --- [           main] o.s.boot.SpringApplication               
: Application startup failed

org.springframework.beans.factory.BeanCreationException: 
Error creating bean with name 'jerseyConfig' defined in URL
[jar:file:/acmesource/acme/acme-core/acme-core-api/target/acme-core-api-0.1
SNAPSHOT.jar!/BOOT-INF/classes!/com/acme/core/api/JerseyConfig.class]: Bean 
instantiation via constructor failed; nested exception is 
org.springframework.beans.BeanInstantiationException: Failed to instantiate 
[com.acme.core.api.JerseyConfig]: Constructor threw exception; nested 
exception is
org.glassfish.jersey.server.internal.scanning.ResourceFinderException:
java.io.FileNotFoundException: /acmesource/acme/acme-core/acme-core
api/target/acme-core-api-0.1-SNAPSHOT.jar!/BOOT-INF/classes (No such file or directory)

回答1:


From the Spring Boot 1.4 release notes:

The change to the layout of executable jars means that a limitation in Jersey's classpath scanning now affects executable jar files as well as executable war files. To work around the problem, classes that you wish to be scanned by Jersey should be packaged in a jar and included as a dependency in BOOT-INF/lib. The Spring Boot launcher should then be configured to unpack those jars on start up so that Jersey can scan their contents.




回答2:


Just another solution:

Although Jersey cannot scan your classes inside the new version of the fat boot jar, you can achieve the same effect using Spring classpath scanning facilities. This way you can scan a package similarly to ResourceConfig.packages():

ClassPathScanningCandidateComponentProvider scanner = new ClassPathScanningCandidateComponentProvider(false);
scanner.addIncludeFilter(new AnnotationTypeFilter(Provider.class));
scanner.addIncludeFilter(new AnnotationTypeFilter(Path.class));
config.registerClasses(scanner.findCandidateComponents("your.package.to.scan").stream()
            .map(beanDefinition -> ClassUtils.resolveClassName(beanDefinition.getBeanClassName(), config.getClassLoader()))
            .collect(Collectors.toSet()));

Note: please have a look at the source of org.glassfish.jersey.server.internal.scanning.AnnotationAcceptingListener. This is the stock solution and you can see that it does the same: it scans for classes annotated with @Path or @Provider (but doesn't manage to find anything because of the broken scanning mechanism).

By the way the bean based method posted by lanwen may be clearer :) Just add @Provider to that too.




回答3:


With Spring Boot (+ Jersey 2) it can look like separate config class (to achieve individual resource registration):

@Configuration
public class RestBeansConfiguration {
    private static final Logger LOG = LoggerFactory.getLogger(RestBeansConfiguration.class);

    @Inject
    private ApplicationContext appCtx;

    @Bean
    public ResourceConfigCustomizer jersey() {
        return config -> {
            LOG.info("Jersey resource classes found:");
            appCtx.getBeansWithAnnotation(Path.class).forEach((name, resource) -> {
                LOG.info(" -> {}", resource.getClass().getName());
                config.register(resource);
            });
        };
    }
}


来源:https://stackoverflow.com/questions/38875379/single-jar-startup-failed-after-upgrade-from-spring-boot-1-3-7-to-1-4-0

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!