I'm currently evaluating/trying out JRebel, and will use this page to take a few notes.

With IntelliJ

  • Install the JRebel plugin
  • Enable the JRebel "facet" on each module of your facet where you want JRebel to be used (use the jrebel tab and check the boxes)
  • Optional: using nightly builds of jrebel:
    • Download: JRebel Nightly
    • Unzip and configure the plugin to use the jar from this download:

  • If you have a licence token:

With Maven

If you're using a Magnolia parent pom version 28+, you can enable the jrebel profile. (either in your IDE if you have it configured to build your project with Maven, or on the command line with mvn -P jrebel ...) (since  BUILD-141 - Getting issue details... STATUS )

Status

The first issue detailed below is the most problematic, since 4.5. We ended up harcoding a workaround for it in info.magnolia.objectfactory.configuration.LegacyComponentsConfigurer (see MAGNOLIA-4455 - Getting issue details... STATUS )

It'd really be nice to come up with either a Magnolia module that enables all sorts of JRebel-niceness for Magnolia, and/or a JRebel plugin. See http://zeroturnaround.com/jrebel/resources/jrebel-plugins/ for details; it doesn't seem all that hard to do (smile)

There is a (partially working) Magnolia plugin in the latest nightly builds of jrebel.

FreeMarker also does some funky things for integration, without really having a plugin, afaik. See freemarker.ext.beans.JavaRebelIntegration and freemarker.ext.beans.BeansWrapper#isJavaRebelAvailable.

Issues

System properties

JRebel adds a couple of properties in java.lang.System#properties. One of them is com.zeroturnaround.bundled.org.apache.commons.logging.Log; unfortunately, it interferes with component configuration using properties. When you start up Magnolia with JRebel you could see Guice having problems stating that com.zeroturnaround.bundled.org.apache.commons.logging.Log doesn't have a public empty constructor. This has been worked around in Magnolia 4.5.9 with MAGNOLIA-4455 - Getting issue details... STATUS . Other workarounds could have been to patch info.magnolia.init.properties.SystemPropertySource or MagnoliaServletContextListener.

Node2Bean / Content2Bean

The type mapping cached by info.magnolia.jcr.node2bean.impl.TypeMappingImpl and info.magnolia.content2bean.impl.TypeMappingImpl might need to be flushed for n2b/c2b to work properly after classes were modified.

Perhaps this is something that could be implemented in c2b itself, much like FreeMarker has some built-in support for JRebel (see freemarker.ext.beans.JavaRebelIntegration and its usage in freemarker.ext.beans.BeansWrapper#isJavaRebelAvailable()), or simply by not caching anything when in dev mode.

Filesystem dependency

(warning) This might not be relevant if you don't enable jrebel for your webapp module in IntelliJ.

Despite the fact that the rebel.xml file now seems to detect the overlays well (contrary to these year old forum posts), some files can not be loaded, because Path.getAppRootDir() points to src/main/webapp when JRebel is enabled.

Overriding these two properties and setting them to absolute paths seems to solve the issue:

magnolia.repositories.config
magnolia.repositories.jackrabbit.config

Or add the overlay to the rebel.xml of your webapp which also seems to work:

  <web>
    <link target="/">
      <dir name="absolute path to your webapp project/overlays/info.magnolia.magnolia-empty-webapp-4.5.7">
      </dir>
    </link>
    <link target="/">
      <dir name="/absolute path to your webapp project/src/main/webapp">
      </dir>
    </link>
  </web>

But as a general solution, using the ServletContext methods instead of java.io.File would probably be a better idea in anyway.

// how "app root dir" is set:
context.getRealPath("") : [...]/src/main/webapp

// how config files are further loaded:
new File(context.getRealPath(""), "WEB-INF/config/default/repositories.xml").exists() --> false.

// how it could work
new File(context.getRealPath("WEB-INF/config/default/repositories.xml")).exists() --> true.

FreeMarker

Not related to JRebel, but I thought JRebel would help. In Intellij, I "compile" a .ftl; intellij tells me "file packaged"... but the template in my target directory hasn't changed, so FreeMarker still displays the old one, despite a NullCacheStorage configured in FreeMarkerHelper

See http://devnet.jetbrains.net/message/5317525#5317525 for updates. Turns out we don't even need to do anything to FreeMarker caching nor template loaders, but as far as my experiments go, the only way to get the template to be refreshed is to "make module".

When developing a Magnolia project, put this configuration in the POM of your module(s) and also make sure to include it in the POM of your Magnolia webapp.

Vaadin client-side code

JRebel is not required to re-deploy Vaadin (GWT) client-side code, because those Java classes are not really deployed anywhere: GWT compiler operates over the source files.

SCSS files with Vaadin

In order to be able to redeploy the SASS stylesheets with Jrebel the following actions have to be taken:

  • Pre-compilation at Maven process-resources phase has to be disabled (see groovy-maven-plugin configuration in magnolia-ui-admincentral and magnolia-ui-vaadin-theme pom files).
  • Vaadin production mode has to be disabled in the empty-webapp web.xml file (productionMode param has to be set to false).

After that Vaadin will re-compile the SASS files every time the app is restarted (I'd recommend using ?restartApplication query parameter in app URL) and JRebel will re-deploy them just like it would do for the Java classes.

 

More Resources

 

  • No labels

9 Comments

  1. Using JRebel with the Maven setup (also for the webapp), FreeMarker changes get picked up immediately without having to compile, make, deploy... (using IDEA Ultimate 12.0.3).

  2. Re the issues w/ the system properties: at leas in intellij, you can define the following property under file/settings/jrebel/advanced:

    advanced property with

    key =com.zeroturnaround.bundled.org.apache.commons.logging.Log

    value=org.apache.commons.logging.impl.SimpleLog

     

    Edit: Na, doesn't work, sorry. Patching Magnolia then?

  3. There is some article that explains step by step the configuration of JRebel with Magnolia CMS ? I'm interested in to use JRebel with Magnolia CMS, could you give me some recommendations, please ? (wink)

    1. You just need to think of Magnolia as an arbitrary web application. So integrating with Magnolia would be almost the same as integrating with any other web app. I say almost because there is a patch that needs to be used in some cases. See the "Issues" section of this wiki.

      Other than that you need to configure a rebel.xml file. See http://zeroturnaround.com/software/jrebel/how-to-configure-rebel-xml/

      And also configure CATALINA_OPTS. If you look in TOMCAT_HOME/bin for a file setenv.sh you can change the line to something like this:

      export CATALINA_OPTS="$CATALINA_OPTS -XX:MaxPermSize=256m -Xms64M -Xmx512M -Djava.awt.headless=true -javaagent:/path/to/jrebel/jrebel.jar -Drebel.remoting_plugin=true"
  4. A bit of a gotcha for jrebel users using the magnolia war overlay.

    Ensure the war overlay is put first (as shown above) or you'll get all sorts of problems with locating resources etc!

  5. I'm having a "funny" issue. When running with JRebel, IntelliJ+Tomcat can't find the info.magnolia.module.admininterface.setup.SimpleContentVersionHandler class. When running the same project in regular debug mode, no problem. Anyone else seen this ?

  6. If you accidentally install a jrebel plugin in intelliJ version which is too new for our activation server:
    - uninstall the plugin:
    . settings > plugins >
    . select jrebel
    . uninstall with the icon with the red arrow
    . restart intelliJ
    - download the appropriate* version from https://plugins.jetbrains.com/plugin/4441?pr=&showAllUpdates=true
    - install it
    . goto > settings > plugins
    . install plugin from disk (a button on the bottom)
    . select the downloaded zip (do not unzip before)
    . follow the instructions


    *) If you are using intelliJ v. 12, make sure to get a version for v. 12!
    Since plugin version 6 license server v. 3 is required; currently our version is lower. In that case take 5.6.3