7 Replies Latest reply on Nov 14, 2010 5:08 AM by dredtkd

    Inject CDI Class in SOAP Endpoint

    weldbsdape

      Hello,


      I use Weld 1.0.1, JAX-WS 2.2 (Metro) on a Tomcat 6.0.20 and can't inject an object into a SOAP-Endpoint. The client makes a SOAP-call and the service gets invoked, but the value is null.


      This is the SOAP-Endpoint




      package soap.test;
      
      import javax.annotation.Resource;
      import javax.enterprise.inject.spi.BeanManager;
      import javax.inject.Inject;
      import javax.jws.WebService;
      import javax.xml.ws.WebServiceContext;
      
      @WebService
      public class TestSOAP {
      
           @Resource
           WebServiceContext wsContext;
           
           @Inject
           private BeanManager bm;
      
           @Inject @MaxNum
           private int maxNum;
      
           public TestSOAP() {
           }
      
           public void test(String s) {
                System.out.println(s);
           }
      }




      The BeanManager is also null.


      The Producer looks like



      package soap.test;
      
      import javax.enterprise.context.ApplicationScoped;
      import javax.enterprise.inject.Produces;
      
      @ApplicationScoped
      public class Producer {
      
           private int maxNum = 666;
      
           @Produces @MaxNum
           public int getMaxNum() {
              return maxNum;
           }
      }




      Injecting @MaxNum in a servlet in the same project works fine.


      Thanks for your help!


      Dario

        • 1. Re: Inject CDI Class in SOAP Endpoint
          marcelkolsteren

          The problem is that combining Tomcat 6.0.20 with JAX-WS and Weld doesn't turn it into not a full fledged Java EE 6 application server. I quote from section 6.4 of the Weld documentation, which is about deploying Weld on Apache Tomcat:




          Servlet containers are not required to support Java EE services like CDI. However, you can use CDI in a servlet container like Tomcat by embedding a standalone CDI implementation such as Weld.

          Weld comes with a servlet listener which bootstraps the CDI environment, registers the BeanManager in JNDI and provides injection into servlets. Basically, it emulates some of the work done by the Java EE container. (But you don't get enterprise features such as session beans and container-managed transactions.)


          Injection into servlets is explicitly mentioned as a feature, and you saw indeed that it works. Apparently, injection into JAX-WS web service end points is not one of the EE features that Weld emulates for you.

          • 2. Re: Inject CDI Class in SOAP Endpoint
            weldbsdape

            The same code works fine on a GlassFish v3 with its own weld and jax-ws implementations. In this case weld do the injection in a jax-ws endpoint.


            Maybe GlassFish has a special configuration for weld and jax-ws (metro).

            • 3. Re: Inject CDI Class in SOAP Endpoint
              marcelkolsteren

              GlassFish v3 is a Java EE 6 application server, so injection into web service endpoints is something that must work in that environment.


              Glassfish has custom code for turning EE components into CDI injection targets. It's here: WebComponentInjectionManager.java.


              More information about how Weld can be integrated with EE application servers can be found in Appendix A.2. The contract with the container of the Weld documentation, subsection Performing CDI injection on Java EE component classes. There you'll find some code examples that match with what the WebComponentInjectionManager.java of Glassfish is doing. Maybe you could even do something similar in your Tomcat based application.

              • 4. Re: Inject CDI Class in SOAP Endpoint
                weldbsdape

                Well, I think in this case an EE application server is the better choice. At least for my needs.


                Thank you!


                Regards,


                Dario

                • 5. Re: Inject CDI Class in SOAP Endpoint
                  cjalmeida

                  When working with Weld, in 90% of cases using a EE AS is the best choice. Why settle for a Chevrolet if you can get a Cadillac for the same price? ;)

                  • 6. Re: Inject CDI Class in SOAP Endpoint
                    weldbsdape

                    Sometimes the customer decides which technologie to use. I would like to support an AS as well as a servlet-container like Tomcat (of course Tomcat needs some extra management). But if the client connects with SOAP-WS, it seems that I won't be able to use Weld and I will have to develop the business-layer without EE-Features like Injection, Interceptors ... Of course only developing with a single source or trying to reduce the costs when implementing on Tomcat.

                    • 7. Re: Inject CDI Class in SOAP Endpoint
                      dredtkd

                      Hello Weld Users !


                      I would like to use WELD to inject bean implementation into Web Service class. I end up with really simple example that works correctly on Glassfish 3.0.1 but fails on JBoss 6 M5.


                      Due to my company support agreements I need to use JBoss, so I would really appreciate any comments or hints here.


                      I am deploying the following simple war file:




                      HelloService.war
                          |
                          /WEB-INF
                                  |
                                  /classes
                                        |
                                        /test
                                            |
                                            /Hello.class
                                            /Printer.class
                                            /PrinterImpl.class
                                  /web.xml
                                  /beans.xml
                      



                      Listed files have the following content:


                      Hello.java


                      package test;
                      
                      import javax.inject.Inject;
                      import javax.jws.WebMethod;
                      import javax.jws.WebService;
                      
                      @WebService
                      public class Hello {
                      
                          @Inject Printer printer;
                          
                          @WebMethod
                          public String sayHello() {
                              return printer.getMessage();
                          }
                      }
                      



                      Printer.java


                      package test;
                      
                      public interface Printer {
                          String getMessage();
                      }
                      



                      PrinterImpl.java


                      package test;
                      
                      public class PrinterImpl implements Printer {
                      
                          public String getMessage() {
                              return "Hello from Printer";
                          }
                      }
                      



                      web.xml




                      <?xml version="1.0" encoding="UTF-8"?>
                      <web-app xmlns="http://java.sun.com/xml/ns/javaee"
                               xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
                               xsi:schemaLocation="http://java.sun.com/xml/ns/javaee
                                  http://java.sun.com/xml/ns/javaee/web-app_3_0.xsd"
                               version="3.0">
                      
                          <servlet>
                              <servlet-name>HelloServlet</servlet-name>
                              <servlet-class>test.Hello</servlet-class>
                          </servlet>
                      
                          <servlet-mapping>
                              <servlet-name>HelloServlet</servlet-name>
                              <url-pattern>/*</url-pattern>
                          </servlet-mapping>
                      
                          <session-config>
                              <session-timeout>
                                  30
                              </session-timeout>
                          </session-config>
                      
                      </web-app>
                      



                      beans.xml is empty.


                      As you can see it's awfully simple. On Glassfish it's running ok. On JBoss 6 M5 I always end up with  NullPointerException while invoking printer.getMessage(). It seems like the service class has never been a target for injection.


                      Based on what has been written in this topic, I think I'm missing similar weld initialization as Glassfish has, but unfortunately I'm clueless on how to do it.


                      I would appreciate any help.


                      Thanks in advance


                      Michal Nowak