Spring Boot和Jersey产生ClassNotFound [英] Spring Boot and Jersey produces ClassNotFound

查看:150
本文介绍了Spring Boot和Jersey产生ClassNotFound的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我正在尝试打包使用Jersey的Spring Boot App.在开发过程中启动该应用程序时,它没有运行问题,当我使用

I'm trying to package my Spring Boot App which uses Jersey. When the app is launched during development it has no problems to run, the problem comes when I generate a jar file using

mvnw package && java -jar target/gs-spring-boot-docker-0.1.0.jar

哪个会产生以下错误.

创建名称为'org.springframework.boot.autoconfigure.jersey.JerseyAutoConfiguration'的bean时出错:不满意的依赖 通过构造函数参数1表示的相关性;嵌套的异常是org.springframework.beans.factory.BeanCreationException:创建名称为'jerseyConfig'的bean时出错 在URL [jar:file:.. path/Backend/target/celulascontentas-2.0.jar!/BOOT-INF/classes!/tech/aabo/celulascontenta中定义 s/config/JerseyConfig.class]:实例化Bean失败;嵌套的异常是org.springframework.beans.BeanInstantiationException:无法实例化[tech.aabo.ce lulascontentas.config.JerseyConfig]:构造函数抛出异常;嵌套的异常是org.glassfish.jersey.server.internal.scanning.ResourceFinderException:java.io.File NotFoundException:..path \ Backend \ target \ celulascontentas-2.0.jar!\ BOOT-INF \ classes(系统找不到路径s 已确认)

Error creating bean with name 'org.springframework.boot.autoconfigure.jersey.JerseyAutoConfiguration': Unsatisfied depend ency expressed through constructor parameter 1; nested exception is org.springframework.beans.factory.BeanCreationException: Error creating bean with name 'jerseyConfig' defined in URL [jar:file:..path/Backend/target/celulascontentas-2.0.jar!/BOOT-INF/classes!/tech/aabo/celulascontenta s/config/JerseyConfig.class]: Instantiation of bean failed; nested exception is org.springframework.beans.BeanInstantiationException: Failed to instantiate [tech.aabo.ce lulascontentas.config.JerseyConfig]: Constructor threw exception; nested exception is org.glassfish.jersey.server.internal.scanning.ResourceFinderException: java.io.File NotFoundException: ..path\Backend\target\celulascontentas-2.0.jar!\BOOT-INF\classes (The system cannot find the path s pecified)

我的Jersey配置看起来像这样:

My Jersey Config looks like this:

package tech.aabo.celulascontentas.config;

import com.fasterxml.jackson.jaxrs.json.JacksonJaxbJsonProvider;
import org.glassfish.jersey.server.ResourceConfig;
import org.glassfish.jersey.server.ServerProperties;
import org.springframework.stereotype.Component;

import javax.ws.rs.ApplicationPath;

@Component
@ApplicationPath("/api")
public class JerseyConfig extends ResourceConfig {

    public JerseyConfig() {
        register(JacksonJaxbJsonProvider.class);
        packages("tech.aabo.celulascontentas.endpoint");
        property(ServerProperties.BV_SEND_ERROR_IN_RESPONSE, true);
    }
}

我的pom.xml看起来像:

And my pom.xml looks like:

<?xml version="1.0" encoding="UTF-8"?>
<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
         xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
    <modelVersion>4.0.0</modelVersion>

    <groupId>tech.aabo</groupId>
    <artifactId>celulascontentas</artifactId>
    <version>2.0</version>
    <packaging>jar</packaging>

    <name>celulascontentas</name>
    <description>API para celulas contentas</description>

    <parent>
        <groupId>org.springframework.boot</groupId>
        <artifactId>spring-boot-starter-parent</artifactId>
        <version>1.5.9.RELEASE</version>
    </parent>

    <properties>
        <project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
        <project.reporting.outputEncoding>UTF-8</project.reporting.outputEncoding>
        <java.version>1.8</java.version>
    </properties>

    <dependencies>
        <!-- Core -->

        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter</artifactId>
        </dependency>

        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-jersey</artifactId>
        </dependency>

        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-jetty</artifactId>
        </dependency>

        <dependency>
           <groupId>org.springframework.boot</groupId>
           <artifactId>spring-boot-starter-actuator</artifactId>
        </dependency>

        <!-- DB -->

        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-jdbc</artifactId>
        </dependency>

        <dependency>
            <groupId>mysql</groupId>
            <artifactId>mysql-connector-java</artifactId>
            <scope>runtime</scope>
        </dependency>

        <!-- Extra -->

        <dependency>
            <groupId>commons-beanutils</groupId>
            <artifactId>commons-beanutils</artifactId>
            <version>1.9.3</version>
        </dependency>

        <dependency>
            <groupId>org.apache.commons</groupId>
            <artifactId>commons-lang3</artifactId>
            <version>3.7</version>
        </dependency>

        <dependency>
            <groupId>com.amazonaws</groupId>
            <artifactId>aws-java-sdk</artifactId>
            <version>1.11.133</version>
        </dependency>

    </dependencies>

    <build>
        <plugins>
            <plugin>
                <groupId>org.springframework.boot</groupId>
                <artifactId>spring-boot-maven-plugin</artifactId>
            </plugin>
            <plugin>
                <artifactId>maven-resources-plugin</artifactId>
                <executions>
                    <execution>
                        <id>copy-resources</id>
                        <phase>validate</phase>
                        <goals>
                            <goal>copy-resources</goal>
                        </goals>
                        <configuration>
                            <outputDirectory>${basedir}/target/</outputDirectory>
                            <resources>
                                <resource>
                                    <directory>src/main/resources</directory>
                                    <filtering>true</filtering>
                                </resource>
                            </resources>
                        </configuration>
                    </execution>
                </executions>
            </plugin>
        </plugins>
    </build>
</project>

我尝试了各种组合,但始终会产生相同的错误.那些人现在如何解决它?

I have tried various combinations but it always produces the same error. Those anybody now how to fix it?

谢谢

推荐答案

Jersey classpath scanning limitations

对可执行jar布局的更改意味着在 泽西岛的类路径扫描现在也影响可执行的jar文件 作为可执行的war文件.要变通解决此问题,您可以 希望被泽西岛扫描的物品应包装在一个罐子中并包括在内 作为BOOT-INF/lib中的依赖项.然后,Spring Boot启动器应 配置为在启动时解压缩这些罐子,以便Jersey可以扫描 他们的内容.

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.

这是一个已知的问题,有一个未合并的打开的请求然而.我建议您参考问题,其中提到了一些解决方法.

This is a known problem and there is a open pull request that's not merged yet. I suggest you refer this issue which mentions some workarounds.

解决方法

  1. 配置Boot的Maven插件以解压缩包含该插件的jar 包

  1. Configure Boot's Maven plugin to unpack the jars containing that package

使用以下解决方法

jersey 1:

import java.util.Map;

import javax.annotation.PostConstruct;
import javax.ws.rs.Path;

import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.context.ApplicationContext;
import org.springframework.stereotype.Component;

import com.sun.jersey.api.core.DefaultResourceConfig;

@Component
public class RestApplication extends DefaultResourceConfig {

    private static final Logger log = LoggerFactory.getLogger(RestApplication.class);

    public RestApplication() {
        getFeatures().put("com.sun.jersey.api.json.POJOMappingFeature", true);
    }

    @Autowired
    ApplicationContext appCtx;

    @PostConstruct
    public void setup() {
        log.info("Rest classes found:");
        Map<String,Object> beans = appCtx.getBeansWithAnnotation(Path.class);
        for (Object o : beans.values()) {
            log.info(" -> " + o.getClass().getName());
            getSingletons().add(o);
        }
    }

}
and

    @Autowired
    RestApplication restApplication;

    @Bean
    public ServletRegistrationBean jersey() {
        ServletRegistrationBean bean = new ServletRegistrationBean();
        bean.setServlet(new ServletContainer(restApplication));
        bean.addInitParameter("com.sun.jersey.api.json.POJOMappingFeature", "true");
        bean.setUrlMappings(Arrays.asList("/rest/*"));
        return bean;
    }
jersery2:

import java.util.Map;

import javax.annotation.PostConstruct;
import javax.ws.rs.ApplicationPath;
import javax.ws.rs.Path;

import org.glassfish.jersey.server.ResourceConfig;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.context.ApplicationContext;
import org.springframework.stereotype.Component;

import com.sun.jersey.api.core.ResourceConfig;

@Component
@ApplicationPath("/rest")
public class JerseyConfig extends ResourceConfig {

    private static final Logger log = LoggerFactory.getLogger(JerseyConfig.class);

    @Autowired
    ApplicationContext appCtx;

    @PostConstruct
    public void setup() {
        log.info("Rest classes found:");
        Map<String,Object> beans = appCtx.getBeansWithAnnotation(Path.class);
        for (Object o : beans.values()) {
            log.info(" -> " + o.getClass().getName());
            register(o);
        }
    }

}

这篇关于Spring Boot和Jersey产生ClassNotFound的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆