2016-08-10 3 views
8

Spring Boot 1.3.7から1.4.0にアップグレードした後、Spring Boot Mavenプラグインを使用して単一のjarビルドとしてアプリケーションを起動できなくなりました。私たちのアプリケーションは、JerseyとJettyを使用する小さなRESTインターフェイスです。私たちはMavenを使い、私たちのpomファイルはかなり標準のSpring Bootです。Spring Boot 1.3.7から1.4.0へのアップグレード後にSIngle jarの起動に失敗しました

mvn spring-boot:runを使用してアプリケーションを実行することはできますが、Eclipse内では1つのjarファイルとして実行すると、ResourceFinder.jar!/BOOT-INF/classesが見つからないと訴えます。

jarを解凍すると、フォルダBOOT-INF/classesが存在し、予想されるクラスとリソースが含まれています。

助けてください。 Spring Boot 1.4 release notesから

2016-08-10 14:58:31.162 ERROR 16071 --- [   main] o.s.boot.SpringApplication    
: Application startup failed 

org.springframework.beans.factory.BeanCreationException: 
Error creating bean with name 'jerseyConfig' defined in URL 
[jar:file:/acmesource/acme/acme-core/acme-core-api/target/acme-core-api-0.1 
SNAPSHOT.jar!/BOOT-INF/classes!/com/acme/core/api/JerseyConfig.class]: Bean 
instantiation via constructor failed; nested exception is 
org.springframework.beans.BeanInstantiationException: Failed to instantiate 
[com.acme.core.api.JerseyConfig]: Constructor threw exception; nested 
exception is 
org.glassfish.jersey.server.internal.scanning.ResourceFinderException: 
java.io.FileNotFoundException: /acmesource/acme/acme-core/acme-core 
api/target/acme-core-api-0.1-SNAPSHOT.jar!/BOOT-INF/classes (No such file or directory) 

答えて

8

実行可能なjarファイルのレイアウトへの変更はlimitation in Jersey's classpath scanningが現在実行可能jarファイル だけでなく、実行可能なwarファイルに影響を与えることを意味します。この問題を回避するには、Jerseyによってスキャンするクラスをjarファイルにパッケージ化し、BOOT-INF/libに依存関係として含める必要があります。 Jerseyがその内容をスキャンできるように、Spring起動ランチャはconfigured to unpack those jars on start upになります。それは(個々のリソース登録を達成するために)個別の設定クラスのように見えることができます春ブーツ(+ジャージー2)で

+0

ありがとうございます!それを逃した。リソースが個別に登録されている場合に機能します。 – oleb

+0

@olebあなたは私の一日を救った!ありがとう –

1

@Configuration 
public class RestBeansConfiguration { 
    private static final Logger LOG = LoggerFactory.getLogger(RestBeansConfiguration.class); 

    @Inject 
    private ApplicationContext appCtx; 

    @Bean 
    public ResourceConfigCustomizer jersey() { 
     return config -> { 
      LOG.info("Jersey resource classes found:"); 
      appCtx.getBeansWithAnnotation(Path.class).forEach((name, resource) -> { 
       LOG.info(" -> {}", resource.getClass().getName()); 
       config.register(resource); 
      }); 
     }; 
    } 
} 
1

ちょうど別の解決策:

ジャージーは、あなたのクラスをスキャンすることはできませんが、 fatブートjarの新しいバージョンの中で、Springクラスパススキャン機能を使って同じ効果を達成することができます。この方法は、あなたがResourceConfig.packages()と同様にパッケージをスキャンすることができます:

ClassPathScanningCandidateComponentProvider scanner = new ClassPathScanningCandidateComponentProvider(false); 
scanner.addIncludeFilter(new AnnotationTypeFilter(Provider.class)); 
scanner.addIncludeFilter(new AnnotationTypeFilter(Path.class)); 
config.registerClasses(scanner.findCandidateComponents("your.package.to.scan").stream() 
      .map(beanDefinition -> ClassUtils.resolveClassName(beanDefinition.getBeanClassName(), config.getClassLoader())) 
      .collect(Collectors.toSet())); 

注:org.glassfish.jersey.server.internal.scanning.AnnotationAcceptingListenerのソースを見てください。これはストックソリューションであり、同じことがわかります。@Pathまたは@Providerで注釈が付けられたクラスをスキャンします(ただし、スキャンメカニズムが壊れているため何も検索できません)。

ところで、lanwenによって投稿されたBeanベースのメソッドはもっと明確になるかもしれません:)ちょうど@Providerをそれに追加してください。

関連する問題