Monday, May 25, 2009

Guice Axis2 integration

Google Guice is a dependency injection (DI) framework, it provides somewhat different configuration option than spring. Axis2’s spring support is already proven, in this post I will explain how to integrate Guice beans in to Axis2 services.

To integrate Guice with axis2 we have to fulfill flowing two requirements,
  1. Load the relevant Guice “Module “(similar to ApplicationContext in Spring) at the service start up time.
  2. Above Guice beans should be accessible by Axis2 services during the run time.
We can achieve above two requirements as follows.
  1. It is possible to use an implementation of ServletContextListener interface to load the Guice module at the start-up time.
  2. Axis2 provide a interface called ServiceObjectSupplier, it is possible to use this interface to provide a custom beans for axis2 web services. Axis2 – Spring support is already based on this concept.
You can access to source code form here or possible to download binary JAR file directly from here.

Please see the following simple example.

I have following interface to expose as a Axis2 web service, but the actual implementation will provide by the Guice framework.

public interface SimpleService {

public String sayHello();
}

This is our Guice module class..

public class SimpleModule extends AbstractModule {

protected void configure() {
bind(SimpleLogger.class).to(SimpleLoggerImpl.class);
bind(SimpleService.class).to(SimpleServiceImpl.class);

}

}

Next step is to configure our service.xml file for Guice integration, in this case I used a new parameter name called “GuiceBeanName” to define the Guice service bean.



Actually we don’t need to have this parameter "GuiceBeanName" , “ServiceClass” parameter can be used for Guice integration too ,but I used two parameters to clearly separate each task we assign for each parameters, “ServiceClass” Is only used as the service interface to generate WSDL definition for our service where “GuiceBeanName” is used to define Guice bean name for “ServiceObjectSupplier” implementation.

<parameter name="ServiceObjectSupplier" locked="false">
org.apache.axis2.integration.guice.GuiceContextObjectSupplier<
/parameter>
<parameter name="GuiceBeanName" locked="false">org.google.guice.sample.SimpleService<
/parameter>
<parameter name="ServiceClass" locked="false">org.google.guice.sample.SimpleService</parameter>

Final step is to define our “GuiceServletContextListener” in the web.xml as follows.

<context-param>
<param-name>module</param-name>
<param-value>org.google.guice.sample.SimpleModule
</param-value>
</context-param>

<listener>
<listener-class>
org.apache.axis2.integration.guice.
GuiceServletContextListener
</listener-class>
</listener>

here, context parameter called “module” is used to provide the Guice module name , GuiceServletContextListener will try to load this “module” within it’s contextInitialized method.


You can download the complete example from here.

13 comments:

Anonymous said...

Hi Sagara,
Nice tutorial about axis2 integration with guice.
But I am not able to download the sample source code...Can you do the favour to provide it to me.

sagara said...

I checked it again , cant see any problem with download links for me . those are hosted in mediafire ( http://www.mediafire.com/?sharekey=021260d4192b3efb931c7453395df0251b87d0ba5c178bbeb8eada0a1ae8665a)

Anonymous said...

HI Sagara,
As mentioned I used the code and deployed in tomcat/axis2 .Service is deployed properly but i can not access it in rest approach http://localhost:8080/axis2/services/SimpleService/sayHello.

I have used services.xml provided in code. Probably I am not able to correctly modify axis2/web.xml to context-param and register
listeners.Please do the favor and help me.

sagara said...

For the provided sample app,correct URL for REST access is http://localhost:8080/services/SimpleService/sayHello try for that without modifying anything on services.xml or web.xml

shirdhi said...

Hi Sagara, i try to run this application in eclipse environment through tomcat server but i am getting SEVERE: Error configuring application listener of class org.apache.axis2.integration.guice.GuiceServletContextListener
java.lang.NoClassDefFoundError: Lorg/apache/log4j/Logger; error so please correct me where i am wrong

thanks kiran

sagara said...

@shirdhi
You are getting this error because you don't have log4j jar file in your Classpath. I used Maven to manage dependencies, so you can easily use this sample with Maven. If you don't want to use Maven, look at the POM.xml file and make sure to available those required libraries on your project Classpath.

shirdhi said...

Hi sagara sorry to disturb you but i am new to java also so please bare with me please give me solution for the below errors
[INFO] calling....... public void contextInitialized(ServletContextEvent servletContextEvent)
[INFO] Could not find axis2.xml, loading default org/apache/axis2/deployment/axis2_default.xml from classpath
[INFO] Deploying Web service: SimpleService - file:/C:/eclipse/adminApp/.metadata/.plugins/org.eclipse.wst.server.core/tmp0/wtpwebapps/guiceSample/WEB-INF/services/SimpleService/

sagara said...

@shirdhi

1.) Those are not error messages those are INFO level logging message, so i cant see any error in your post.

2.)As i told earlier best and simplest way to do this is Maven. first download and setup Maven2 properly then go to this sample project and run "mvn clean jetty:run" in the command line, this will deploy the application on embedded Jetty server.

shirdhi said...

Hi sagara thanx it is working in maven but i have to do this in tomcat so please give me any solution, i have observed one diffence that jetty has [INFO] Deploying module: addressing - file:/C:/Documents and Settings/Kiran/.m2/repository/org/apache/axis2/axis2/1.4.1/axis2-1.4.1.jar this line which is not in my tomcat so please do u have any idea please give me solution

thanks
Shirdhi.

sagara said...

its a deploying message for addressing module ,it's not an issue. Even you want to deploy on Tomcat you can use Maven/Eclipse/Jetty for development, using "mavn package" command you can package the application as a .WAR archive and then you can deploy it on Tomcat "wabapps" directory. If you want to edit the application ,you can import it as a Maven project in Eclipse IDE.

shirdhi said...

hi sagara i have created war file using maven then i deployed it in tomcat and run http://localhost:6667/services/SimpleService/sayHello but http 404 is coming my port is 6667 only please advice

thanks shirdhi.

Anonymous said...

Thank you so much for the posting. That definitely helps. a silly question - we are using WSO2 WSAS2.2. I am not sure how I could include web.xml into the system. It looks to me that I shall just create a singleton to server the class into supplier. Any issue with that approach?

Eric Jablow said...

We've been trying to use your code in my current project at work, and we've been failing. We are using WSAS, and when the getServiceObject method of GuiceContextObjectSupplier tries to get the HTTP_SERVLETCONFIG parameter from the Axis configuration, it gets only a null, causing an exception to be thrown at line 45.

I don't even know where I would configure that parameter or what it should be. Have you any suggestions?

Respectfully,
Eric Jablow