2017-07-19 5 views
7

cxf.jaxrs.classes-scan and cxf.jaxrs.classes-scan-packagesを使用して、Springブートアプリケーションで既存のバニラJAX-RSアプリケーションJARをラッピングしています。 JARまたはmaven spring-boot:runで実行すると、依存関係注入が正常に動作します。 WAR(WebSphere Liberty 17.0.0.2上で)として実行すると、@Inject対応フィールドは、REST要求中にnullとなります。ここでSpringブートJAX-RS/CXF依存性注入はJARでは有効ですが、WARではありません

SpringBootApplicationです:

@SpringBootApplication(scanBasePackages = { "com.test" }) 
public class CustomerServiceApplication extends SpringBootServletInitializer { 
    public static void main(String[] args) { 
    SpringApplication.run(CustomerServiceApplication.class, args); 
    } 

    @Override 
    protected SpringApplicationBuilder configure(SpringApplicationBuilder application) { 
    return application.sources(CustomerServiceApplication.class); 
    } 
} 

はここsrc/main/resources/application.propertiesです:

cxf.path=/ 
cxf.jaxrs.classes-scan=true 
cxf.jaxrs.classes-scan-packages=com.test,com.fasterxml.jackson.jaxrs.json 

はここ(バニラJAX-RSアプリケーションのJARをローカルリポジトリにあるたCustomerService-javaのです)Mavenのpom.xmlです:

<?xml version="1.0" encoding="UTF-8"?> 
<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" 
    xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/maven-v4_0_0.xsd"> 
    <modelVersion>4.0.0</modelVersion> 
    <groupId>customerservice-springboot</groupId> 
    <artifactId>customerservice-springboot</artifactId> 
    <packaging>war</packaging> 
    <version>2.0.0-SNAPSHOT</version> 
    <name>Customer Service :: Spring Boot</name> 

    <!-- We need to use cxf-spring-boot-starter-jaxrs 3.2.0 because of https://issues.apache.org/jira/browse/CXF-7237 
     At the time of writing this code, the latest available version in Maven central 
     is 3.1.7 so we need to use the Apache snapshot repository. --> 
    <repositories> 
     <repository> 
      <id>apache.snapshots</id> 
      <name>Apache Development Snapshot Repository</name> 
      <url>https://repository.apache.org/content/repositories/snapshots/</url> 
      <releases> 
       <enabled>false</enabled> 
      </releases> 
      <snapshots> 
       <enabled>true</enabled> 
      </snapshots> 
     </repository> 
    </repositories> 

    <properties> 
     <maven.compiler.source>1.8</maven.compiler.source> 
     <maven.compiler.target>1.8</maven.compiler.target> 
    </properties> 
    <parent> 
     <groupId>org.springframework.boot</groupId> 
     <artifactId>spring-boot-starter-parent</artifactId> 
     <version>1.5.4.RELEASE</version> 
    </parent> 
    <dependencies> 
     <dependency> 
      <groupId>org.springframework.boot</groupId> 
      <artifactId>spring-boot-starter-web</artifactId> 
      <exclusions> 
       <exclusion> 
        <groupId>org.springframework.boot</groupId> 
        <artifactId>spring-boot-starter-tomcat</artifactId> 
       </exclusion> 
      </exclusions> 
     </dependency> 
     <dependency> 
      <groupId>org.apache.cxf</groupId> 
      <artifactId>cxf-spring-boot-starter-jaxrs</artifactId> 
      <version>3.2.0-SNAPSHOT</version> 
     </dependency> 
     <dependency> 
      <groupId>javax.servlet</groupId> 
      <artifactId>javax.servlet-api</artifactId> 
      <scope>provided</scope> 
     </dependency> 
     <dependency> 
      <groupId>javax.json</groupId> 
      <artifactId>javax.json-api</artifactId> 
      <version>1.0</version> 
     </dependency> 
     <dependency> 
      <groupId>javax.inject</groupId> 
      <artifactId>javax.inject</artifactId> 
      <version>1</version> 
     </dependency> 
     <dependency> 
      <groupId>customerservice-java</groupId> 
      <artifactId>customerservice-java</artifactId> 
      <version>2.0.0-SNAPSHOT</version> 
      <classifier>jar</classifier> 
     </dependency> 
     <dependency> 
      <groupId>com.fasterxml.jackson.jaxrs</groupId> 
      <artifactId>jackson-jaxrs-json-provider</artifactId> 
     </dependency> 
     <dependency> 
      <groupId>org.glassfish</groupId> 
      <artifactId>javax.json</artifactId> 
      <version>1.0.4</version> 
     </dependency> 
    </dependencies> 
    <build> 
     <plugins> 
      <plugin> 
       <groupId>org.springframework.boot</groupId> 
       <artifactId>spring-boot-maven-plugin</artifactId> 
       <executions> 
        <execution> 
         <goals> 
          <goal>repackage</goal> 
         </goals> 
        </execution> 
       </executions> 
      </plugin> 
     </plugins> 
    </build> 
</project> 

JARプロジェクトにおけるWebサービス:

package com.test; 
import javax.inject.Inject; 
import javax.ws.rs.CookieParam; 
import javax.ws.rs.GET; 
import javax.ws.rs.Path; 
import javax.ws.rs.PathParam; 
import javax.ws.rs.Produces; 
import javax.ws.rs.core.Response; 

@Path("/") 
public class CustomerServiceRest { 

    @Inject 
    CustomerService customerService; 

    @GET 
    @Path("/byid/{custid}") 
    @Produces("text/plain") 
    public Response getCustomer(@PathParam("custid") String customerid, @CookieParam("token") String jwtToken) { 
     return Response.ok(customerService.getCustomerId(customerid)).build(); 
    } 
} 

はここにBeanの:

package com.test; 
import javax.inject.Named; 
@Named 
public class CustomerService { 
    public String getCustomerById(String username) { 
    // ... implementation .. 
    return customerDoc.toJson(); 
    } 
} 

はここでWARのログ出力です:

. ____   _   __ _ _ 
/\\/___'_ __ _ _(_)_ __ __ _ \ \ \ \ 
(()\___ | '_ | '_| | '_ \/ _` | \ \ \ \ 
\\/ ___)| |_)| | | | | || (_| | )))) 
    ' |____| .__|_| |_|_| |_\__, |//// 
=========|_|==============|___/=/_/_/_/ 
:: Spring Boot ::  (v1.5.4.RELEASE) 
INFO c.a.s.CustomerServiceApplication - Starting CustomerServiceApplication on 23fb5f5646c3 with PID 20 (/opt/ibm/wlp/usr/servers/defaultServer/apps/expanded/customerservice-springboot-2.0.0-SNAPSHOT.war/WEB-INF/classes started by root in /opt/ibm/wlp/output/defaultServer) 
INFO c.a.s.CustomerServiceApplication - No active profile set, falling back to default profiles: default 
INFO o.s.b.c.e.AnnotationConfigEmbeddedWebApplicationContext - Refreshing org.springframework.boot[email protected]67e7ebcd: startup date [Wed Jul 19 19:36:12 UTC 2017]; root of context hierarchy 
INFO o.s.b.f.x.XmlBeanDefinitionReader - Loading XML bean definitions from class path resource [META-INF/cxf/cxf.xml] 
INFO o.s.b.f.a.AutowiredAnnotationBeanPostProcessor - JSR-330 'javax.inject.Inject' annotation found and supported for autowiring 
INFO c.i.w.w.webapp - SRVE0292I: Servlet Message - [customerservice-springboot-2.0.0-SNAPSHOT]:.Initializing Spring embedded WebApplicationContext 
INFO o.s.w.c.ContextLoader - Root WebApplicationContext: initialization completed in 3654 ms 
INFO o.s.b.w.s.ServletRegistrationBean - Mapping servlet: 'dispatcherServlet' to [/] 
INFO o.s.b.w.s.ServletRegistrationBean - Mapping servlet: 'CXFServlet' to [/*] 
INFO o.s.b.w.s.FilterRegistrationBean - Mapping filter: 'errorPageFilter' to: [/*] 
INFO o.s.b.w.s.FilterRegistrationBean - Mapping filter: 'characterEncodingFilter' to: [/*] 
INFO o.s.b.w.s.FilterRegistrationBean - Mapping filter: 'hiddenHttpMethodFilter' to: [/*] 
INFO o.s.b.w.s.FilterRegistrationBean - Mapping filter: 'httpPutFormContentFilter' to: [/*] 
INFO o.s.b.w.s.FilterRegistrationBean - Mapping filter: 'requestContextFilter' to: [/*] 
INFO o.s.w.s.m.m.a.RequestMappingHandlerAdapter - Looking for @ControllerAdvice: org.springframework.boot[email protected]67e7ebcd: startup date [Wed Jul 19 19:36:12 UTC 2017]; root of context hierarchy 
INFO o.s.w.s.m.m.a.RequestMappingHandlerMapping - Mapped "{[/error],produces=[text/html]}" onto public org.springframework.web.servlet.ModelAndView org.springframework.boot.autoconfigure.web.BasicErrorController.errorHtml(javax.servlet.http.HttpServletRequest,javax.servlet.http.HttpServletResponse) 
INFO o.s.w.s.m.m.a.RequestMappingHandlerMapping - Mapped "{[/error]}" onto public org.springframework.http.ResponseEntity<java.util.Map<java.lang.String, java.lang.Object>> org.springframework.boot.autoconfigure.web.BasicErrorController.error(javax.servlet.http.HttpServletRequest) 
INFO o.s.w.s.h.SimpleUrlHandlerMapping - Mapped URL path [/webjars/**] onto handler of type [class org.springframework.web.servlet.resource.ResourceHttpRequestHandler] 
INFO o.s.w.s.h.SimpleUrlHandlerMapping - Mapped URL path [/**] onto handler of type [class org.springframework.web.servlet.resource.ResourceHttpRequestHandler] 
INFO o.s.w.s.h.SimpleUrlHandlerMapping - Mapped URL path [/**/favicon.ico] onto handler of type [class org.springframework.web.servlet.resource.ResourceHttpRequestHandler] 
INFO o.a.c.e.ServerImpl - Setting the server's publish address to be/
INFO o.s.j.e.a.AnnotationMBeanExporter - Registering beans for JMX exposure on startup 
INFO c.a.s.CustomerServiceApplication - Started CustomerServiceApplication in 14.955 seconds (JVM running for 271.749) 
INFO o.a.c.e.S.e.o.i.l.E.i.w.j.2.0.c.0.17.cl170220170523-1818(id=171)] - Setting the server's publish address to be/

私はapplication.propertieslogging.level.org.springframework.beans.factory.support=TRACEを有効にした場合、私は依存性注入を見ますアプリケーション起動時の作業:

DEBUG o.s.b.f.s.DefaultListableBeanFactory - Creating shared instance of singleton bean 'customerService' 
DEBUG o.s.b.f.s.DefaultListableBeanFactory - Creating instance of bean 'customerService' 
DEBUG o.s.b.f.s.DefaultListableBeanFactory - Eagerly caching bean 'customerService' to allow for resolving potential circular references 
DEBUG o.s.b.f.s.DefaultListableBeanFactory - Finished creating instance of bean 'customerService' [...] 
DEBUG o.s.b.f.s.DefaultListableBeanFactory - Creating instance of bean 'com.test.CustomerServiceRest' 
DEBUG o.s.b.f.s.DefaultListableBeanFactory - Returning cached instance of singleton bean 'customerService' 
DEBUG o.s.b.f.s.DefaultListableBeanFactory - Finished creating instance of bean 'com.test.CustomerServiceRest' 

しかし、私はREST要求を行うとき、私はCustomerServiceRestの新しいインスタンスが各要求(コンストラクタでSystem.out.println)上で作成され、@Inject -able依存関係がnullNullPointerExceptionにresuting)されていることがわかります。だから、私は@SingletonCustomerServiceRestに追加すると考えていたかもしれませんが、依然としてリクエストごとに新しいオブジェクトが作成されています。

誰かが単一のWebサービスBeanを使用する方法、またはSpringがすべての依存関係を確実に注入する方法を知っている人はいますか?バニラのJAX-RSアプリケーションJARは、それ自身がSpringの依存関係を引き継ぐことはできません。

答えて

4

I(例えばservlet & jsp機能の代わりに[リバティのjaxrs機能にもたらす] webProfile機能を使用して)、そして@SpringBootApplicationアノテーションにexclude = { DispatcherServletAutoConfiguration.class }を添加リバティのCXFを使用しないことにより、この問題を解決することができました。これは、自分のタイプのユースケース(たとえば、デフォルトのサーブレットとしてDispatcherServletがインストールされており、およびCXFServletcxf.path=/でマウントされています(したがって、/* URLマッピングを作成しています)。 Spring MVCがCXFと混在しているが、CXFサービスが非ルートURLマッピングにあるその他の場合は、excludeは必要ありません。私はまだこれをLibertyのCXFで動作させる方法を調査しています。私が知っていれば、この回答を更新します。

+0

Libertyでは、アプリケーションパッケージ化されたCXF JARをWEB-INF/libから削除していくつかの競合を引き起こした場合に動作します。 – kgibm

4

は、この種の問題は、使用されてきた私たちは、クラスの宣言と同じ修飾子に@Qualifier(「名前」)を使用していたが、スプリングプロジェクト のいずれかで発生しました@Inject

+0

私は '@ Named'文字列名を提供しようとしましたが、カスタム' @修飾子 'を作成してそれを' @Inject'に追加しましたが、どちらもうまくいきませんでした。 – kgibm

0

と自動配線JDK 1.8を使用してTomcat 8.5.xにコードをデプロイし、CustomerServiceが正常に注入されました。

あなたはTomcatで戦争をテストする機会がありますか?少なくとも、それがコードまたはアプリケーションサーバーに関する問題であるかどうかを理解する。 WebSphere/Weblogic内の組み込みライブラリは、あなたのwarパッケージから来たjarファイルを上書きし、同様の問題が発生することがあります。

+0

こんにちは、はい、それはTomcatの下で動作します。私はWebSphereで 'webProfile-7.0'機能を使用していて、' jaxrs-2.0'機能を導入していたことを知ったので、最後の文章で何かをしていると思います。私は今 '' servlet-3.1'と 'jsp-2.3'だけでしようとしていますが、' dispatcherServlet'が 'CXFServlet'の代わりにリクエストを処理しているように見えるので、現在404件の問題が発生しています。まだ調査中です... – kgibm

+0

こんにちは、あなたはapplication.propertiesからcxfを設定する必要がありますか? CustomerServiceApplication内でcxfを設定することで、WS Libertyの下で動作させることができました。 [cxf spring boot](http://cxf.apache.org/docs/springboot.html)ガイドのマニュアル設定を参照してください。 – taner

+0

手動設定がうまくいくかもしれませんが、簡単な注釈ベースの設定をするためのSpring Bootの精神に反していると感じています。私はどのように動作するかについて別の回答を投稿しようとしています... – kgibm

関連する問題