6

maven jerseyスターターwebappを作成しました。また、jettyプラグインを使用して私のアプリにjettyサーバーを埋め込んでいます。maven-assembly-pluginを使用してuber jarを作成するとジャージが失敗する

私のプロジェクトをmvn jetty:runコマンドを使って実行すると、私のプロジェクトは正常に動作しています。

しかし、mvn clean packageコマンドを使用してプロジェクトをパッケージ化し、jar-with-dependenciesという名前のjarファイルを実行すると、ジャーナルリソースからjson応答を返している間にこの例外がスローされます。

SEVERE:メディアタイプ= application/json、type = class com.nitish.freecharge.model.Count、genericType = class com.nitish.freecharge.model.CountでMessageBodyWriterが見つかりません。ここで

は、私は私のメインドライバを作成しました>

<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> 

私のpom.xmlファイル

http://maven.apache.org/maven-v4_0_0.xsd」でありますクラスを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(); 
     } 
    } 
} 

ここは私のonlです私は、サーバーを起動した後に私のプロジェクトのURLにアクセスしたときに実行されますYジャージリソースクラス:梱包後

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(); 
     } 
    } 
} 

とawesomeProject.jar

-jarコマンド Javaを使用して、完全な組み込みプロジェクトを実行し、私はこの出力を取得

enter image description here

プロンプトサーバー上で、私は多くのことをしようと、この問題が解決されるように、私の埋め込まれたWebアプリケーションをパッケージ化することができませんでしてきました。私はMavenとパッケージングに新しいです。親切に私が間違いを犯しているところを助けてください。

答えて

15

MOXy jarを見ると、フォルダMETA-INF/servicesが表示されます。そのフォルダには、org.glassfish.jersey.internal.spi.AutoDiscoverableという名前のファイルが表示されます。そのファイルの内容は、このファイルはジャージージャージーのためMOXYを登録MoxyJsonAutoDiscoverable、発見できるようにすることであるためには何の単一ライン

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

でなければなりません。このサービスローダーパターンにより、ジャージーは機能を発見して登録することができます。登録する必要はありません。

uber jarを作成するときに問題となるのは、同じファイルを持つ複数のjarが存在する可能性があるということです。異なるJarファイルには異なる機能がありますが、そのファイル名はサービスローダーパターンは機能する。

同じファイルのjarファイルがたくさんありますが、uber jarファイルを作成すると、同じ名前のファイルを複数持つことはできません。それだけでは不可能です。したがって、ファイルの1つのみが最終的なjarファイルに入れられます。誰が知っているのかしかし、それは、MOXyのファイルがそのファイルでない場合、その機能は自動検出されず、自分で登録する必要があることを意味します。したがって、クラスはuber jarにパッケージ化されていますが、主要な機能コンポーネントは登録されていません。

jerseyServlet.setInitParameter("jersey.config.server.provider.classnames", 
           "org.glassfish.jersey.moxy.json.MoxyJsonFeature"); 

しかし、自動検出可能なファイルが含まれていない可能性がある他のすべての機能についてはどうでしょうか?

このため、アセンブリプラグインの代わりにmaven-shade-pluginを使用する必要があります。maven-shade-pluginには、同じ名前のファイルの内容をファイルに連結できるようにする変圧器があります。

設定が

<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から取得していました。それ以上の説明のためにそれをチェックしたいかもしれません。

+0

ありがとうございました。 jerseyServlet.setInitParameter( "jersey.config.server.provider.classnames"、 "org.glassfish.jersey.moxy.json.MoxyJsonFeature"); 問題を解決しました。 しかし、maven-shade-pluginを使用する場合、最終出力はawesomeProject.warファイルですが、代わりにjarファイルが必要です。 mave-shade-pluginを使用してメインクラスの実行可能なjarファイルを取得するには? –

+0

pom.xmlファイルの ''を見てください。それは「戦争」ではなく「瓶」でなければなりません。 'jetty-maven-plugin'を使うには' war'が必要だと分かりますが、jarファイルを入手するにはjarファイルに変更することを忘れないでください。 –

+0

ありがとうpeeskillet!それは完璧にうまくいった。 –

関連する問題