2016-03-05 1 views
3

я написал клиент Джерси, который взаимодействует со службой 3 партии и это работает, если я запустить его из Eclipse, но бросает MessageBodyProviderNotFoundException если я запустил файл jar.Gradle банки с зависимостями джерси производит MessageBodyReader не найдена для типа носителя = приложений/JSON

Мой build.gradle:

// Apply the java plugin to add support for Java 
apply plugin: 'java' 

version = '1.0' 

// In this section you declare where to find the dependencies of your project 
repositories { 
    jcenter() 
} 

//create a single Jar with all dependencies 
task createJar(type: Jar) { 
    manifest { 
     attributes 'Implementation-Title': 'MeteorDesk Whatsapp Images Parser', 
      'Implementation-Version': version, 
      'Main-Class': 'controller.ImagesParser' 
    } 
    from { configurations.compile.collect { it.isDirectory() ? it : zipTree(it) } } 
    with jar 
} 

// In this section you declare the dependencies for your production and test code 
dependencies { 
    compile 'org.slf4j:slf4j-api:1.7.12' 

    compile 'org.glassfish.jersey.core:jersey-client:2.22.1' 
    compile 'org.glassfish.jersey.containers:jersey-container-servlet-core:2.22.1' 
    compile 'org.glassfish.jersey.media:jersey-media-json-jackson:2.22.1' 
    compile 'com.google.guava:guava:19.0' 
    compile 'joda-time:joda-time:2.4' 
} 

Здесь идет исключение:

org.glassfish.jersey.message.internal.MessageBodyProviderNotFoundException: MessageBodyReader not found for media type=application/json, type=class model.login.LoginResult, genericType=class model.login.LoginResult. 
    at org.glassfish.jersey.message.internal.ReaderInterceptorExecutor$TerminalReaderInterceptor.aroundReadFrom(ReaderInterceptorExecutor.java:231) 
    at org.glassfish.jersey.message.internal.ReaderInterceptorExecutor.proceed(ReaderInterceptorExecutor.java:155) 
    at org.glassfish.jersey.message.internal.MessageBodyFactory.readFrom(MessageBodyFactory.java:1085) 
    at org.glassfish.jersey.message.internal.InboundMessageContext.readEntity(InboundMessageContext.java:874) 
    at org.glassfish.jersey.message.internal.InboundMessageContext.readEntity(InboundMessageContext.java:808) 
    at org.glassfish.jersey.client.ClientResponse.readEntity(ClientResponse.java:326) 
    at org.glassfish.jersey.client.InboundJaxrsResponse$1.call(InboundJaxrsResponse.java:115) 
    at org.glassfish.jersey.internal.Errors.process(Errors.java:315) 
    at org.glassfish.jersey.internal.Errors.process(Errors.java:297) 
    at org.glassfish.jersey.internal.Errors.process(Errors.java:228) 
    at org.glassfish.jersey.process.internal.RequestScope.runInScope(RequestScope.java:419) 
    at org.glassfish.jersey.client.InboundJaxrsResponse.runInScopeIfPossible(InboundJaxrsResponse.java:267) 
    at org.glassfish.jersey.client.InboundJaxrsResponse.readEntity(InboundJaxrsResponse.java:112) 
    at controller.MeteorDeskService.login(MeteorDeskService.java:42) 

Я прочитал this post от кого-то, кто имел точно такую ​​же проблему, и его решение было использовать Maven вместо этого, так что я попробовал также с Maven, но я получил то же исключение.

Я также могу видеть MessageBodyReader.class внутри сгенерированной банки.

У кого-нибудь есть ключ, почему это происходит?

+1

Я предполагаю, что файлы META-INF/services переписывают друг друга, когда вы создаете жировую банку. Файлы META-INF/services - это то, как Джерси загружает много своих автозарегистрированных функций, включая Джексона. Если это так, я полагаю, вы можете просто зарегистрировать «JacksonFeature» с помощью «Client». Решение проблемы META/services - это использование плагина тени при создании толстой банки. С оттенком вы можете комбинировать содержимое файлов с тем же именем, чтобы они не перезаписывали друг друга. Я не уверен в Gradle. Я действительно не использую его –

+1

Файл META-INF/services, на который я ссылаюсь, является файлом 'org.glassfish.jersey.internal.spi.AutoDiscoverable'. В разных банках есть один и тот же файл, и он используется для автоматической загрузки функций, характерных для этой банки. Возможно, вы можете создать задачу Gradle, чтобы объединить файлы в один. Я не знаю, как это сделать. Или просто зарегистрируйте «JacksonFeature», как я уже упоминал. Но я не уверен, есть ли другие функции, которые вы можете потерять. Но если вы используете только клиент, я бы подумал, что это не должно быть проблемой. –

+0

@peeskillet Мне понадобилось некоторое время, но, наконец, я использовал теневой плагин maven и теперь он работает. Вы спасли меня дважды на той же неделе, я должен вам хотя бы пиво! – muilpp

ответ

3

Как @peeskillet предложил, используя Maven плагин Shade сделал трюк, это то, что я добавил к моему pom.xml:

<build> 
    <plugins> 
     <plugin> 
      <groupId>org.apache.maven.plugins</groupId> 
      <artifactId>maven-shade-plugin</artifactId> 
      <version>2.4.3</version> 
      <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>your main class here</mainClass> 
          </transformer> 
         </transformers> 
        </configuration> 
       </execution> 
      </executions> 
     </plugin> 
    </plugins> 
</build> 
-2

+1 на пиво @peeskillet. Имел ту же проблему с maven-сборкой теста производительности JMH, который строит затененную банку. Вот соответствующая часть pom.xml:

 <plugin> 
      <groupId>org.apache.maven.plugins</groupId> 
      <artifactId>maven-shade-plugin</artifactId> 
      <version>2.2</version> 
      <executions> 
       <execution> 
        <phase>package</phase> 
        <goals> 
         <goal>shade</goal> 
        </goals> 
        <configuration> 
         <finalName>${uberjar.name}</finalName> 
         <transformers> 
          <transformer implementation="org.apache.maven.plugins.shade.resource.ServicesResourceTransformer"/> 
          <transformer implementation="org.apache.maven.plugins.shade.resource.ManifestResourceTransformer"> 
           <mainClass>org.openjdk.jmh.Main</mainClass> 
          </transformer> 
         </transformers> 
         <filters> 
          <filter> 
           <!-- Shading signed JARs will fail without this. http://stackoverflow.com/questions/999489/invalid-signature-file-when-attempting-to-run-a-jar --> 
           <artifact>*:*</artifact> 
           <excludes> 
            <exclude>META-INF/*.SF</exclude> 
            <exclude>META-INF/*.DSA</exclude> 
            <exclude>META-INF/*.RSA</exclude> 
           </excludes> 
          </filter> 
         </filters> 
        </configuration> 
       </execution> 
      </executions> 
     </plugin> 
0

Для кого-то ищет решения в самой Gradle используйте Shadow plugin. Добавьте следующие строки в свой build.gradle.

buildscript { 
     repositories { 
     maven { 
      url "https://plugins.gradle.org/m2/" 
     } 
    } 
    dependencies { 
     classpath "com.github.jengelman.gradle.plugins:shadow:1.2.4" 
    } 
} 
apply plugin: "com.github.johnrengelman.shadow" 

shadowJar { 
    baseName = '__Title__' 
    mergeServiceFiles() //For Merging Service Descriptor Files 
}