2016-08-10 8 views
8

स्प्रिंग बूट 1.3.7 से 1.4.0 तक अपग्रेड करने के बाद सिग्नल जार स्टार्टअप विफल रहा, हम अब स्प्रिंग बूट मेवेन प्लगइन के साथ एक जार बिल्ड के रूप में अपना आवेदन शुरू नहीं कर सकते हैं। हमारा आवेदन जर्सी और जेट्टी का उपयोग कर एक छोटा सा आरईएसटी इंटरफ़ेस है। हम मेवेन का उपयोग करते हैं और हमारी पोम फ़ाइल सुंदर मानक वसंत बूट है।स्प्रिंग बूट 1.3.7 से 1.4.0

हम अभी भी mvn spring-boot:run और ग्रहण के भीतर से का उपयोग कर आवेदन चला सकते हैं, लेकिन जब एक भी जार के रूप में चलाने जर्सी ResourceFinder शिकायत है कि यह .jar!/BOOT-INF/classes नहीं मिल रहा।

जब मैं जार को अनपैक करता हूं तो फ़ोल्डर BOOT-INF/classes मौजूद है और अपेक्षित कक्षाएं और संसाधन शामिल हैं।

किसी भी मदद की सराहना की।

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

Spring Boot 1.4 release notes से:

निष्पादन योग्य जार के लेआउट में परिवर्तन का मतलब है कि एक limitation in Jersey's classpath scanning अब निष्पादन योग्य जार फ़ाइलों के साथ ही निष्पादन युद्ध फ़ाइलों को प्रभावित करता है। समस्या के आसपास काम करने के लिए, जर्सी द्वारा स्कैन किए जाने वाले वर्गों को एक जार में पैक किया जाना चाहिए और BOOT-INF/lib में निर्भरता के रूप में शामिल किया जाना चाहिए। स्प्रिंग बूट लॉन्चर configured to unpack those jars on start up होना चाहिए ताकि जर्सी अपनी सामग्री स्कैन कर सके।

+0

धन्यवाद! उसको याद किया। जब संसाधन अलग-अलग पंजीकृत होते हैं तो काम करता है। – oleb

+0

@oleb आपने मेरा दिन बचा लिया है !! धन्यवाद –

1
स्प्रिंग बूट (+ जर्सी 2) के साथ

यह अलग कॉन्फ़िग वर्ग की तरह लग सकता है (अलग-अलग संसाधन पंजीकरण प्राप्त करने के लिए):

@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

बस एक और समाधान:

हालांकि जर्सी अपनी कक्षाओं स्कैन नहीं कर सकते वसा बूट जार के नए संस्करण के अंदर, आप स्प्रिंग क्लासपाथ स्कैनिंग सुविधाओं का उपयोग करके एक ही प्रभाव प्राप्त कर सकते हैं। इस तरह से आप 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 के साथ एनोटेटेड कक्षाओं के लिए स्कैन करता है (लेकिन टूटा स्कैनिंग तंत्र की वजह से कुछ भी ढूंढने का प्रबंधन नहीं करता है)।

जिस तरह से लैनवेन द्वारा पोस्ट किया गया बीन आधारित विधि स्पष्ट हो सकता है :) बस उसमें @Provider जोड़ें।