Using JRebel with web fragments

by Allard BuijzeNovember 26, 2011

Our team recently added JRebel to our toolbox, and we love it. We use Tomcat in our day-to-day development and getting rid of the annoying reboot to see the changes in code and resources was a big relief.

We have recently started to work on a new project which uses a Servlet 3.0 feature: web fragments. Web fragments allow you to modularize your deployment descriptor which means that a part of your web application can reside in a separate module along with its own descriptor.

With such a project structure we didn’t get our JRebel configuration right from the beginning but once you know how to do it it seems extremely trivial. Nevertheless, I would like to share here a working JRebel configuration for a project including web fragments.

Let’s assume we have a maven project structure including the main web application and a web fragment. We want JRebel to monitor for changes both classes and resources in our web fragment as in the main web

-- web-fragment
    -- src
        -- main
            -- java
            -- resources
                -- META-INF
                    -- web-fragment.xml
                    -- freemarker
                    -- resources
                        -- static
                            -- js
                            -- css
-- web
    -- main
        -- java
        -- resources
        -- webapp
            -- static
            -- WEB-INF
                -- web.xml
                -- index.jsp

Thanks to Servlet 3.0 any resources under META-INF/resources are accessible from the root context of the web application. This needs some special attention in our JRebel configuration.

<?xml version="1.0" encoding="UTF-8"?>
<application xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns="http://www.zeroturnaround.com"
             xsi:schemaLocation="http://www.zeroturnaround.com http://www.zeroturnaround.com/alderaan/rebel-2_0.xsd">

  <classpath>
      <dir name="/path/to/web/src/main/resources"/>
      <dir name="/path/to//web/target/classes"/>
      <dir name="/path/to/web-fragment/src/main/resources"/>
      <dir name="/path/to/web-fragment/target/classes"/>
  </classpath>

  <web>
      <link target="/">
          <dir name="/path/to/web/web/src/main/webapp">
	      <exclude name="WEB-INF/lib/**"/>
	  </dir>
      </link>
      <link target="static/">
          <dir name="/path/to/web-fragment/src/main/resources/META-INF/resources/static"/>
      </link>
  </web>
</application>

The web fragment’s resources have to be defined using “link” element with a target matching the directory name. This way you only need to hit refresh in the browser to see the changes in your JavaScript, CSS or other static resources.

The above configuration uses absolute paths to define the location of directories. If you would like to commit your configuration to your VCS you can define a placeholder like ${project.root} which then every team member has to define as a custom property in JRebel Agent settings.