2016-08-10 24 views
8

Sau khi nâng cấp từ Spring Boot 1.3.7 lên 1.4.0, chúng tôi không còn có thể khởi chạy ứng dụng của chúng tôi như một bản dựng jar đơn lẻ với plugin Spring Boot Maven. Ứng dụng của chúng tôi là một giao diện REST nhỏ sử dụng Jersey và Jetty. Chúng tôi sử dụng Maven và tệp pom của chúng tôi là Spring Boot khá chuẩn.Việc khởi động jar không thành công sau khi nâng cấp từ Spring Boot 1.3.7 lên 1.4.0

Chúng tôi vẫn có thể chạy ứng dụng bằng cách sử dụng mvn spring-boot:run và từ bên trong Eclipse, nhưng khi chạy dưới dạng một chiếc bình Jersey ResourceFinder phàn nàn rằng nó không thể tìm thấy .jar!/BOOT-INF/classes.

Khi tôi giải nén bình, thư mục BOOT-INF/classes hiện diện và chứa các lớp và tài nguyên mong muốn.

Bất kỳ trợ giúp đánh giá cao.

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) 

Trả lời

8

Từ Spring Boot 1.4 release notes:

Sự thay đổi cách bố trí của lọ thực thi nghĩa là một limitation in Jersey's classpath scanning bây giờ ảnh hưởng tập tin jar thực thi cũng như các tập chiến tranh thực thi. Để giải quyết vấn đề này, các lớp học mà bạn muốn quét bởi Jersey nên được đóng gói trong một cái lọ và được bao gồm như một sự phụ thuộc trong BOOT-INF/lib. Trình khởi chạy Spring Boot sẽ là configured to unpack those jars on start up để Jersey có thể quét nội dung của chúng.

+0

Cảm ơn! Bỏ lỡ cái đó. Hoạt động khi các tài nguyên được đăng ký riêng lẻ. – oleb

+0

@oleb Bạn đã lưu lại ngày của tôi !! Cảm ơn –

1

Với mùa xuân Boot (+ Jersey 2) nó có thể trông giống như lớp cấu hình riêng biệt (để đạt được đăng ký tài nguyên cá nhân):

@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

Chỉ cần một giải pháp:

Mặc dù Jersey không thể quét lớp học của bạn bên trong phiên bản mới của bình khởi động chất béo, bạn có thể đạt được hiệu ứng tương tự bằng cách sử dụng tiện ích quét lớp đường dẫn Spring. Bằng cách này bạn có thể quét một gói tương tự như 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())); 

Lưu ý: Hãy có một cái nhìn tại nguồn của org.glassfish.jersey.server.internal.scanning.AnnotationAcceptingListener. Đây là giải pháp chứng khoán và bạn có thể thấy rằng nó hoạt động tương tự: nó quét các lớp được chú thích với @Path hoặc @Provider (nhưng không quản lý được bất kỳ thứ gì vì cơ chế quét bị hỏng).

Bằng cách này, phương thức dựa trên bean được đăng bởi lanwen có thể rõ ràng hơn :) Chỉ cần thêm @Provider vào đó.

Các vấn đề liên quan