【问题标题】:Using Maven-assembly to pack single jar使用 Maven-assembly 打包单个 jar
【发布时间】:2014-04-27 04:12:01
【问题描述】:

我想创建一个 REST 服务器。

我添加了maven依赖,我的pom.xml看起来像这样:

<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>abptc_server</groupId>
    <artifactId>abptc_server</artifactId>
    <version>0.0.1-SNAPSHOT</version>
    <build>
        <sourceDirectory>src</sourceDirectory>
        <plugins>
            <plugin>
                <artifactId>maven-compiler-plugin</artifactId>
                <version>3.0</version>
                <configuration>
                    <source>1.7</source>
                    <target>1.7</target>
                </configuration>
            </plugin>

            <plugin>
                <artifactId>maven-assembly-plugin</artifactId>
                <executions>
                    <execution>
                        <phase>package</phase>
                        <goals>
                            <goal>single</goal>
                        </goals>
                    </execution>
                </executions>
                <configuration>
                    <descriptorRefs>
                        <descriptorRef>jar-with-dependencies</descriptorRef>
                    </descriptorRefs>
                </configuration>
            </plugin>
        </plugins>
    </build>
    <dependencies>
        <dependency>
            <groupId>javax.servlet</groupId>
            <artifactId>servlet-api</artifactId>
            <version>2.5</version>
        </dependency>

        <dependency>
            <groupId>org.eclipse.jetty</groupId>
            <artifactId>jetty-server</artifactId>
            <version>9.1.3.v20140225</version>
        </dependency>

        <dependency>
            <groupId>org.eclipse.jetty</groupId>
            <artifactId>jetty-servlet</artifactId>
            <version>9.1.3.v20140225</version>
        </dependency>

        <dependency>
            <groupId>javax.ws.rs</groupId>
            <artifactId>jsr311-api</artifactId>
            <version>1.1.1</version>
        </dependency>

        <dependency>
            <groupId>com.sun.jersey</groupId>
            <artifactId>jersey-core</artifactId>
            <version>1.18.1</version>
        </dependency>

        <dependency>
            <groupId>com.sun.jersey</groupId>
            <artifactId>jersey-server</artifactId>
            <version>1.18.1</version>
        </dependency>

        <dependency>
            <groupId>com.sun.jersey</groupId>
            <artifactId>jersey-client</artifactId>
            <version>1.18.1</version>
        </dependency>

        <dependency>
            <groupId>com.sun.jersey</groupId>
            <artifactId>jersey-servlet</artifactId>
            <version>1.18.1</version>
        </dependency>

        <dependency>
            <groupId>com.sun.jersey</groupId>
            <artifactId>jersey-json</artifactId>
            <version>1.18.1</version>
        </dependency>

    </dependencies>
</project>

我添加了maven-assembly-plugin,因为我想要一个可以执行的 jar:

java -cp target/abptc_server-0.0.1-SNAPSHOT-jar-with-dependencies.jar server.MinimalServerRest

当我在eclipse中运行服务器时,它运行良好,但是当我执行jar时,服务器在一个REST请求后失败:GET http://localhost:9999/employee/getEmployee

错误:

2014-03-20 11:40:46.996:INFO::main: Logging initialized @576ms
2014-03-20 11:40:47.133:INFO:oejs.Server:main: jetty-9.1.z-SNAPSHOT
2014-03-20 11:40:47.176:INFO:oejsh.ContextHandler:main: Started o.e.j.s.ServletContextHandler@7dbe444b{/,null,AVAILABLE}
2014-03-20 11:40:47.194:INFO:oejs.ServerConnector:main: Started ServerConnector@6bb9db06{HTTP/1.1}{0.0.0.0:9999}
2014-03-20 11:40:47.194:INFO:oejs.Server:main: Started @777ms
márc. 20, 2014 11:40:53 DE com.sun.jersey.api.core.PackagesResourceConfig init
INFO: Scanning for root resource and provider classes in the packages:
  rest
márc. 20, 2014 11:40:53 DE com.sun.jersey.api.core.ScanningResourceConfig logClasses
INFO: Root resource classes found:
  class rest.EmployeeSvc
  class rest.StudentSvc
márc. 20, 2014 11:40:53 DE com.sun.jersey.api.core.ScanningResourceConfig init
INFO: No provider classes found.
márc. 20, 2014 11:40:54 DE com.sun.jersey.server.impl.application.WebApplicationImpl _initiate
INFO: Initiating Jersey application, version 'Jersey: 1.18.1 02/19/2014 03:28 AM'
márc. 20, 2014 11:40:54 DE com.sun.jersey.spi.container.ContainerResponse write
SEVERE: A message body writer for Java class dto.Employee, and Java type class dto.Employee, and MIME media type application/json was not found.
The registered message body writers compatible with the MIME media type are:
*/* ->
  com.sun.jersey.core.impl.provider.entity.FormProvider
  com.sun.jersey.core.impl.provider.entity.StringProvider
  com.sun.jersey.core.impl.provider.entity.ByteArrayProvider
  com.sun.jersey.core.impl.provider.entity.FileProvider
  com.sun.jersey.core.impl.provider.entity.InputStreamProvider
  com.sun.jersey.core.impl.provider.entity.DataSourceProvider
  com.sun.jersey.core.impl.provider.entity.XMLJAXBElementProvider$General
  com.sun.jersey.core.impl.provider.entity.ReaderProvider
  com.sun.jersey.core.impl.provider.entity.DocumentProvider
  com.sun.jersey.core.impl.provider.entity.StreamingOutputProvider
  com.sun.jersey.core.impl.provider.entity.SourceProvider$SourceWriter
  com.sun.jersey.core.impl.provider.entity.XMLRootElementProvider$General
  com.sun.jersey.core.impl.provider.entity.XMLListElementProvider$General

márc. 20, 2014 11:40:54 DE com.sun.jersey.spi.container.ContainerResponse logException
SEVERE: Mapped exception to response: 500 (Internal Server Error)
javax.ws.rs.WebApplicationException: com.sun.jersey.api.MessageException: A message body writer for Java class dto.Employee, and Java type class dto.Employee, and MIME media type application/json was not found.

    at com.sun.jersey.spi.container.ContainerResponse.write(ContainerResponse.java:284)
    at com.sun.jersey.server.impl.application.WebApplicationImpl._handleRequest(WebApplicationImpl.java:1510)
    at com.sun.jersey.server.impl.application.WebApplicationImpl.handleRequest(WebApplicationImpl.java:1419)
    at com.sun.jersey.server.impl.application.WebApplicationImpl.handleRequest(WebApplicationImpl.java:1409)
    at com.sun.jersey.spi.container.servlet.WebComponent.service(WebComponent.java:409)
    at com.sun.jersey.spi.container.servlet.ServletContainer.service(ServletContainer.java:540)
    at com.sun.jersey.spi.container.servlet.ServletContainer.service(ServletContainer.java:715)
    at javax.servlet.http.HttpServlet.service(HttpServlet.java:820)
    at org.eclipse.jetty.servlet.ServletHolder.handle(ServletHolder.java:711)
    at org.eclipse.jetty.servlet.ServletHandler.doHandle(ServletHandler.java:552)
    at org.eclipse.jetty.server.session.SessionHandler.doHandle(SessionHandler.java:219)
    at org.eclipse.jetty.server.handler.ContextHandler.doHandle(ContextHandler.java:1112)
    at org.eclipse.jetty.servlet.ServletHandler.doScope(ServletHandler.java:479)
    at org.eclipse.jetty.server.session.SessionHandler.doScope(SessionHandler.java:183)
    at org.eclipse.jetty.server.handler.ContextHandler.doScope(ContextHandler.java:1046)
    at org.eclipse.jetty.server.handler.ScopedHandler.handle(ScopedHandler.java:141)
    at org.eclipse.jetty.server.handler.HandlerWrapper.handle(HandlerWrapper.java:97)
    at org.eclipse.jetty.server.Server.handle(Server.java:462)
    at org.eclipse.jetty.server.HttpChannel.handle(HttpChannel.java:281)
    at org.eclipse.jetty.server.HttpConnection.onFillable(HttpConnection.java:232)
    at org.eclipse.jetty.io.AbstractConnection$1.run(AbstractConnection.java:505)
    at org.eclipse.jetty.util.thread.QueuedThreadPool.runJob(QueuedThreadPool.java:607)
    at org.eclipse.jetty.util.thread.QueuedThreadPool$3.run(QueuedThreadPool.java:536)
    at java.lang.Thread.run(Thread.java:744)
Caused by: com.sun.jersey.api.MessageException: A message body writer for Java class dto.Employee, and Java type class dto.Employee, and MIME media type application/json was not found.

    ... 24 more

我搜索了答案:

https://stackoverflow.com/a/12427046/598280https://stackoverflow.com/a/6027161/598280 我已经添加了jersey-json 依赖。

https://stackoverflow.com/a/11936282/598280我没有web.xml,服务器运行良好,当我在eclipse中执行时,问题出在maven上。

https://stackoverflow.com/a/13108540/598280 相同。

根据Mark Needham blog,我的服务器类看起来不错:

ServletHolder sh = new ServletHolder(ServletContainer.class);
sh.setInitParameter("com.sun.jersey.config.property.resourceConfigClass", "com.sun.jersey.api.core.PackagesResourceConfig");

// Set the package where the services reside
sh.setInitParameter("com.sun.jersey.config.property.packages", "rest");
sh.setInitParameter("com.sun.jersey.api.json.POJOMappingFeature", "true");

Server server = new Server(9999);
ServletContextHandler context = new ServletContextHandler(server, "/", ServletContextHandler.SESSIONS);
context.addServlet(sh, "/*");
server.start();
server.join();

我该如何解决这个问题?

更新:

我的包装罐看起来像这样:

我没有检查所有依赖项(它有 23 个单独的依赖项),但从这里看起来很好。我应该全部检查吗?

这里是 maven clean install 输出:http://pastebin.com/Whk2qr2i

【问题讨论】:

  • 您是否扩展了 JAR(带有依赖项)并手动检查了所有必需的 JARS 是否都在正确的位置?
  • 感谢您的评论。我已经更新了我的答案。我相信 maven 打包好了。

标签: java eclipse maven maven-assembly-plugin


【解决方案1】:

嗯,这种方法的问题在于,如果多个 JARS 具有相同的文件,它们就会被覆盖。例如。所有这些 jar 可能都有 META-INF/MANIFEST.MF 文件,但实际上只有一个存在。这可能适用于其他文件。这可能会导致奇怪的行为

我会尝试使用 maven 将它们构建为单独的 JARS,然后尝试运行,看看是否可行。您可以使用程序集插件构建一个 ZIP,其中包含您的应用程序 JAR 和 lib 文件夹中的所有 JAR 文件,以及运行它的脚本。例如。 zip 的内容如下所示:

abptcserver/
    lib/
        dependency1.jar
        dependency2.jar
        dependency3.jar
    abptcserver.jar
    run.sh
    run.bat

然后,您可以配置 shell 和批处理脚本,以使用类路径上 lib 目录中的所有 JARS 运行您的服务器。我想这样你会得到更少的意外行为,它也更健壮,运行起来对用户更友好

【讨论】:

    【解决方案2】:

    使用maven的shade插件代替汇编插件。

    它不会覆盖类,即使在不同的 jar 中存在同名的类,也会解决这个问题。

    【讨论】:

      猜你喜欢
      • 2013-01-30
      • 2023-03-27
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2011-06-24
      • 1970-01-01
      • 2017-07-07
      相关资源
      最近更新 更多