JBoss Modules Example – Modular Web Application
I’ve started with the following goal in mind – to create a web application using some service defined by my own JBoss module. The service prepared by me was pretty simple. I named it Echo Service:
1 2 3 4 5 6 7 | package warlock.echo; public interface EchoService { String echo(String param); } |
and placed into a separate jar file, named echo-api. Then I implemented this service:
01 02 03 04 05 06 07 08 09 10 11 | package warlock.echo.impl; import warlock.echo.EchoService; public class DefaultEchoService implements EchoService { public String echo(String param) { return param; } } |
and placed the implementation in a new jar file, named echo-module. Having in mind that my web application should have knowledge of the service API only, not the specific implementation, I decided to go with the way described in Creating Extensible Applications With the Java Platform – that choice required adding to echo-module jar special file under: META-INF/services/warlock.echo.EchoService, holding the “pointer” to the service implementation (fully qualified name of implementing class).
At this point, I retrieved and unpacked JBoss Application Server 7, stepped into the unpacked JBoss, and then into the modules directory. In this directory I’ve added the following structure:
Two jar files visible here are mentioned above, module.xml file is the definition of my JBoss Module – named ‘warlock.echo’, and has the following content:
01 02 03 04 05 06 07 08 09 10 | <? xml version = "1.0" encoding = "UTF-8" ?> < module xmlns = "urn:jboss:module:1.0" name = "warlock.echo" > < resources > < resource-root path = "echo-module-1.0.0-SNAPSHOT.jar" /> < resource-root path = "echo-api-1.0.0-SNAPSHOT.jar" /> </ resources > </ module > |
After the completion of the JBoss Module definition, I’ve prepared a simple Spring Framework based application (which uses echo-api jar only during the compilation of project and doesn’t use the echo-module jar at all) with only one Controller:
01 02 03 04 05 06 07 08 09 10 11 12 13 14 15 16 17 18 19 20 21 22 23 | package warlock; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.stereotype.Controller; import org.springframework.web.bind.annotation.RequestMapping; import org.springframework.web.bind.annotation.RequestMethod; import org.springframework.web.bind.annotation.ResponseBody; import warlock.echo.EchoService; @Controller @RequestMapping ( "/echo.html" ) public class EchoController { @Autowired private EchoService service; @RequestMapping (method = RequestMethod.GET) @ResponseBody public String handleGet() { return service.echo( "It workzzzzz!" ); } } |
As you can see, the Controller returns as response body the result of Echo Service call for some string. Now to the most important part – Echo Service definition in Web Application:
01 02 03 04 05 06 07 08 09 10 11 12 13 14 | <? xml version = "1.0" encoding = "UTF-8" ?> xsi:schemaLocation = "http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans-3.0.xsd" > ... < bean class = "org.springframework.beans.factory.serviceloader.ServiceFactoryBean" > < property name = "serviceType" value = "warlock.echo.EchoService" /> </ bean > ... </ beans > |
I know, one thing is bothering you :) – how the hell will Echo Service implementation be found if we don’t add either echo-api and echo-module jars to the Web Application?!
Well, this is the beauty itself ;) – We just need one more thing – WEB-INF/jboss-deployment-structure.xml file:
1 2 3 4 5 6 7 | < jboss-deployment-structure > < deployment > < dependencies > < module name = "warlock.echo" services = "export" /> </ dependencies > </ deployment > </ jboss-deployment-structure > |
This way we tell JBoss that this application depends on the ‘warlock.echo’ module and the services defined in this module. The rest is pure JBoss Module magic ;)
Lectures for the dessert:
Reference: Modular Web Application based on JBoss Modules from our JCG partner Warlock at the “Warlock’s Thoughts” blog.
Related Articles :
If I package the sample application in an ear file. The modules are not working. It is throwing ClassNotFound Exception. Any idea how to get modules working with ear?