maven - 使用Maven-assembly-plugin创建uber jar时,Jersey失败

标签 maven jersey jersey-2.0 embedded-jetty jar-with-dependencies

我已经创建了一个Maven jersey starter webapp。我也使用码头插件在我的应用程序中嵌入了码头服务器。

使用mvn jetty:run命令运行项目时,我的项目运行正常。

但是,当我使用mvn clean package命令打包项目并运行名称为jar-with-dependencies的jar文件时,项目会从泽西资源返回json响应时引发此异常。

:严重:找不到针对媒体type = application/json,type = class com.nitish.freecharge.model.Count,genericType = class com.nitish.freecharge.model.Count的MessageBodyWriter。

这是我的pom.xml文件

http://maven.apache.org/maven-v4_0_0.xsd“>

<modelVersion>4.0.0</modelVersion>

<groupId>com.nitish.freecharge</groupId>
<artifactId>wordcount</artifactId>
<packaging>war</packaging>
<version>2.0</version>
<name>wordcount</name>

<build>
    <finalName>wordcount</finalName>
    <resources>
        <resource>
            <directory>src/main/java</directory>
        </resource>
        <resource>
            <directory>src/main/resources</directory>
        </resource>
        <resource>
            <directory>src/main/webapp</directory>
        </resource>
    </resources>
    <plugins>
        <plugin>
            <groupId>org.apache.maven.plugins</groupId>
            <artifactId>maven-compiler-plugin</artifactId>
            <version>2.5.1</version>
            <inherited>true</inherited>
            <configuration>
                <source>1.7</source>
                <target>1.7</target>
            </configuration>
        </plugin>
        <plugin>
            <groupId>org.eclipse.jetty</groupId>
            <artifactId>jetty-maven-plugin</artifactId>
            <version>9.3.0.v20150612</version>
            <configuration>
                <scanIntervalSeconds>5</scanIntervalSeconds>
                <webApp>
                    <contextPath>/wordcount</contextPath>
                </webApp>
                <httpConnector>
                    <!--host>localhost</host -->
                    <port>9999</port>
                </httpConnector>
            </configuration>
        </plugin>
        <plugin>
            <groupId>org.apache.maven.plugins</groupId>
            <artifactId>maven-jar-plugin</artifactId>
            <version>2.4</version>
            <executions>
                <execution>
                    <id>package-jar</id>
                    <phase>package</phase>
                    <goals>
                        <goal>jar</goal>
                    </goals>
                </execution>
            </executions>
        </plugin>
        <plugin>
            <groupId>org.apache.maven.plugins</groupId>
            <artifactId>maven-assembly-plugin</artifactId>
            <version>2.6</version>
            <configuration>
                <finalName>awesomeProject</finalName>
                <descriptorRefs>
                    <descriptorRef>jar-with-dependencies</descriptorRef>
                </descriptorRefs>
                <appendAssemblyId>false</appendAssemblyId>
                <archive>
                    <manifest>
                        <mainClass>App</mainClass>
                    </manifest>
                </archive>
            </configuration>
            <executions>
                <execution>
                    <phase>package</phase>
                    <goals>
                        <goal>single</goal>
                    </goals>
                </execution>
            </executions>
        </plugin>
    </plugins>
</build>
<dependencyManagement>
    <dependencies>
        <dependency>
            <groupId>org.glassfish.jersey</groupId>
            <artifactId>jersey-bom</artifactId>
            <version>${jersey.version}</version>
            <type>pom</type>
            <scope>import</scope>
        </dependency>
    </dependencies>
</dependencyManagement>

<dependencies>
    <dependency>
        <groupId>org.glassfish.jersey.core</groupId>
        <artifactId>jersey-server</artifactId>
    </dependency>
    <dependency>
        <groupId>org.glassfish.jersey.containers</groupId>
        <artifactId>jersey-container-servlet-core</artifactId>
    </dependency>
    <dependency>
        <groupId>org.glassfish.jersey.media</groupId>
        <artifactId>jersey-media-moxy</artifactId>
    </dependency>
    <dependency>
        <groupId>org.eclipse.jetty</groupId>
        <artifactId>jetty-server</artifactId>
        <version>9.3.8.v20160314</version>
    </dependency>
    <dependency>
        <groupId>org.eclipse.jetty</groupId>
        <artifactId>jetty-servlet</artifactId>
        <version>9.3.8.v20160314</version>
    </dependency>
    <dependency>
        <groupId>junit</groupId>
        <artifactId>junit</artifactId>
        <version>4.4</version>
    </dependency>
</dependencies>
<properties>
    <jersey.version>2.22.2</jersey.version>
    <project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
</properties>

我已经在默认包中将主驱动程序类创建为App.java。这是我的App.java内容
import org.eclipse.jetty.server.Server;
import org.eclipse.jetty.servlet.ServletContextHandler;
import org.eclipse.jetty.servlet.ServletHolder;

public class App {
    public static void main(String []gg){

        Server server = new Server(9999);

        ServletContextHandler context = new ServletContextHandler(ServletContextHandler.NO_SESSIONS);
        context.setContextPath("/");
        server.setHandler(context);

        ServletHolder jerseyServlet = context.addServlet(org.glassfish.jersey.servlet.ServletContainer.class, "/wordcount/*");
        jerseyServlet.setInitOrder(1);
        jerseyServlet.setInitParameter("jersey.config.server.provider.packages","com.nitish.freecharge.resources");
        try {
            System.out.println("Starting the server..");
            server.start();
            System.out.println("Server started");
            server.join();
        } catch(Exception e) {
            System.out.println("Exception in starting the server ");
            e.printStackTrace();
        }
    }
}

这是我启动服务器后访问项目URL时执行的唯一 Jersey 资源类:
package com.nitish.freecharge.resources;

import javax.ws.rs.GET;
import javax.ws.rs.Path;
import javax.ws.rs.Produces;
import javax.ws.rs.QueryParam;
import javax.ws.rs.core.MediaType;
import javax.ws.rs.core.Response;
import javax.ws.rs.core.Response.Status;
import com.nitish.freecharge.dao.FileDAO;
import com.nitish.freecharge.model.Count;

/**
 * Root resource (exposed at "count" path) which handles HTTP GET method and returns the count value;
 */
@Path("/count")
public class CountResource {

    private FileDAO fileDAO=new FileDAO();

    /**
     * Method handling HTTP GET requests. The returned object will be sent
     * to the client as "application/json" media type.
     *
     * @return String that will be returned as a application/json response.
     */
    @GET
    @Produces(MediaType.APPLICATION_JSON)
    @QueryParam("query")
    public Response getWordCount(@QueryParam("query")String query) {
        Error error=null;
        Count count=null;
        try{   
            if(query!=null){
                query=query.trim();
                if(query.length()>0 && query.matches("^[A-Za-z]+$")){
                    long c=fileDAO.getCount(query.toLowerCase());
                    count=new Count(c);
                }else{
                    error=new Error("Some Error Occured.Please Try Again With a new word!");
                }
            }else{
                error=new Error("Some Error Occured.Please Try Again!");
            }
        }catch(Exception e){
            error=new Error(e.getMessage());
            return Response.status(Status.INTERNAL_SERVER_ERROR).entity(error).build();
        }
        if(count!=null){
            return Response.status(Status.OK).entity(count).build();
        }else{
            return Response.status(Status.BAD_REQUEST).entity(error).build();
        }
    }
}

打包并使用命令运行完整的嵌入式项目之后
java -jar awesomeProject.jar

我在服务器提示符下得到此输出

我已经尝试了很多,但无法以解决此问题的方式打包我的嵌入式Web应用程序。我是Maven和包装的新手。请帮助我犯错的地方。

最佳答案

如果您在MOXy jar中查看,则会看到一个文件夹META-INF/services。在该文件夹中,您将看到一个名为org.glassfish.jersey.internal.spi.AutoDiscoverable的文件。该文件的内容应为一行

org.glassfish.jersey.moxy.json.internal.MoxyJsonAutoDiscoverable

该文件的作用是让 Jersey 发现MoxyJsonAutoDiscoverable,它为 Jersey 注册MOXy。此服务加载程序模式使Jersey可以发现功能并进行注册,而无需我们自己注册。

创建uber jar时造成的问题是,可能有多个jar包含相同的文件,因为不同的jar具有不同的发现功能,但是文件必须具有正确的名称,因为这是服务加载程序模式的工作方式。

因此,您有一堆具有相同文件的jar,但是在创建uber jar时,不能有多个具有相同名称的文件。只是不可能。因此,只有一个文件被放入最终的jar中。哪一个..谁知道。但这意味着,如果MOXy的文件不是一个文件,则不会自动发现其功能,因此我们需要自己注册。因此,这些类被打包在uber jar中,但是主要功能部件只是未注册。您可以自己注册
jerseyServlet.setInitParameter("jersey.config.server.provider.classnames",
                               "org.glassfish.jersey.moxy.json.MoxyJsonFeature");

但是由于不包括其自动发现文件而可能遗漏的所有其他可能功能又如何呢?

因此,您应该使用 maven-shade-plugin 而不是Assembly插件,它具有转换器,可让我们将服务文件的内容连接到一个文件中。

配置看起来像
<plugin>
    <groupId>org.apache.maven.plugins</groupId>
    <artifactId>maven-shade-plugin</artifactId>
    <version>2.3</version>
    <configuration>
        <createDependencyReducedPom>true</createDependencyReducedPom>
        <filters>
            <filter>
                <artifact>*:*</artifact>
                <excludes>
                    <exclude>META-INF/*.SF</exclude>
                    <exclude>META-INF/*.DSA</exclude>
                    <exclude>META-INF/*.RSA</exclude>
                </excludes>
            </filter>
        </filters>
    </configuration>
    <executions>
        <execution>
            <phase>package</phase>
            <goals>
                <goal>shade</goal>
            </goals>
            <configuration>
                <transformers>
                    <transformer implementation="org.apache.maven.plugins.shade.resource.ServicesResourceTransformer"/>
                    <transformer implementation="org.apache.maven.plugins.shade.resource.ManifestResourceTransformer">
                        <mainClass>com.example.YourApp</mainClass>
                    </transformer>
                </transformers>
            </configuration>
        </execution>
    </executions>
</plugin>
ServicesResorceTransformaer是连接文件的文件。该插件的特定配置来自Dropwizard getting started。您可能需要检查一下以进一步解释。

关于maven - 使用Maven-assembly-plugin创建uber jar时,Jersey失败,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/36687312/

相关文章:

java - 在 Jersey 资源中缓存对象?

java - Jersey 2.0 "Getting Started"指南,未找到 mainClass

java - 找不到适合 jdbc mysql 驱动程序的驱动程序

java - Docker 中的应用程序服务器 - 使用 IntelliJ 进行 war 部署

maven - 在 Maven 项目中分析 TypeScript SonarQube

java - Maven POM 是否可以并且应该指定它是否需要 Maven 3 或更高版本?

java - 在 glassfish 上部署时出现异常 : ArrayIndexOutOfBoundsException: 9578

java - 从 GET 请求返回 pojo 时 Jersey Web 服务挂起

rest - Spring boot Embedded tomcat 中 jersey Servlet 注册的编程等效

等待 Mysql 连接的 Java 线程,但 Mysql 没有显示这方面的证据