How does the "addClassChangeListener" work?

Forum on this website is being phased out. New threads or replies cannot be posted. Existing content remains available for now in read only mode. You can contact technical support at

ZeroTurnaround Homepage Forums JRebel Support How does the "addClassChangeListener" work?


This topic contains 2 replies, has 2 voices, and was last updated by  Nicholas DiPiazza 2 months ago.

Viewing 3 posts - 1 through 3 (of 3 total)
  • Author
  • #67035

    Can you provide more details on how exactly JRebel SDK is intended to pick up an “addClassChangeListener”?

    The SDK example only provides a class called ReloadHelper, i.e. something like this:

    public class ReloadHelper {
      public static void addClassChangeListener(PluginManager pluginManager, Class<?> configClass) throws Exception {
        // Class event listeners are called when a class is reloaded by JRebel.
        // You can order the reload listeners using the priority parameter in the constructor.
        ReloaderFactory.getInstance().addClassReloadListener(configClass, new ClassEventListenerAdapter(0) {
          public void onClassEvent(int eventType, Class<?> klass) throws Exception {
            System.out.println("Need to reload plugin now.");

    But it appears the class is un-used. Does JRebel look through the plugin and find all static addClassChangeListener methods?

    This should be updated on the docs, and you should apply comments to the SDK code explaining this and add suppress warnings for the “unused” too so as to avoid confusion.



    Hi Nicholas,

    In the JRebel plugin demo the addClassChangeListener method is used in MemoryUsageServletCBP which instruments the init method to call it.
    This is a somewhat typical pattern in JRebel plugin development as it’s best to avoid putting as much code in strings as possible when doing Javassist instrumentation. Delegating to a static method in a helper class is much less error prone than “stringly-typed-code” as we call it.

    As you noticed this causes IDE-s to not realize where the class is used. To remedy this you can either explicitly declare the class every time it is used in a ClassBytecodeProcessor as follows:

    ctClass.getDeclaredMethod("init").insertAfter("" +
        ReloadHelper.class.getName() + ".addRequestListener(this);" +
        ReloadHelper.class.getName() + ".addClassChangeListener(this, ApplicationConfiguration.class);");

    Although this won’t help with “method is unused”, such helper classes explicitly comment that they are used within CBP-s so searching for class reference is enough.
    This method can clutter the stringly code a bit so an alternative is to just declare it once in the ClassPool imports:

    ctClass.getDeclaredMethod("init").insertAfter("" +
        "ReloadHelper.addRequestListener(this);" +
        "ReloadHelper.addClassChangeListener(this, ApplicationConfiguration.class);");

    Got it. Thanks!

Viewing 3 posts - 1 through 3 (of 3 total)

The forum ‘JRebel Support’ is closed to new topics and replies.