Imagine a bacon-wrapped Ferrari. Still not better than our free technical reports.
See all our reports

How to use JRebel for speeding up Jenkins/Hudson plugin development

So I’ve been developing a Jenkins plugin for a whole week now, and the first few days were really tough for me – the turnaround time is just awful! At one point, I decided to make the effort to configure JRebel for this task (which is pretty easy for me, being on the JRebel team). What follows here is a quick guide for getting started developing Jenkins/Hudson plugins using JRebel. So let’s go!

The first step is to prepare your environment. Keep in mind that this is Jenkins/Hudson-specific, and you need to consult their Setting Up Environment page.

Once you have your environment setup you can create your plugin, but right now this is just an empty skeleton version.

$ mvn -cpu hpi:create
$ cd newly-created-directory
$ mvn package

The first build takes about 5 minutes, while maven downloads the internets. Once the command finishes, you can start up your own instance of Jenkins/Hudson and see the plugin in action. To run, execute the following command and navigate to http://localhost:8080/.

mvn hpi:run

Now you should see a Jenkins/Hudson installation with your plugin installed. The plugin does not do much at the moment – it only adds a new build step into the job that says “Hello World”. To try this out, we need to to create a job and add this step to the build cycle.

Result of the job run with Hello World plugin.

Next, lets open the project in our IDE and change the displaying logic. Let’s change the plugin to say “Good Day” instead of “Hello”. To see the difference in the browser, we have to build the project and again run mvn hpi:run, which actually takes quite a bit of time – 25 seconds on my machine. So every time we want to see the change we have to wait for half of a minute. Well, this is not an option for me (I don’t get paid by the hour) and I would prefer “taking five” when I want to, not when my machine dictates it.

I have configured JRebel in my IntelliJ IDEA. Next I will configure my plugin project to be run from the IDE and I will use the JRebel button to configure it.

IntelliJ IDEA configuration to run our Jenkins plugin

Now start the project with JRebel, change the greeting once again and compile class (Ctrl+Shift+F9 in IntelliJ). And Voila!

JRebel reloading the changed class.

Can you tell the difference? =)

Job result after reload.

So we’ve seen that JRebel can in fact be used to speed up your Jenkins/Hudson plugin development. And since many of these plugins are open source, you can save half your life by getting JRebel free! (See the OSS Developers part on our sales page)…

  • Frédéric Camblor

    Does it works for jelly scripts too ?

    I think they are not resulting in .class files … so I don’t think JRebel will use the same behaviour with this (maybe we should consider them as sort of configuration files).

  • Juri Timoshin

    You will have to add rebel.xml and configure it like here (see Configuring WARs section). That is – add “resources” folder to classpath element. Then jelly files will be automatically updated too.

  • Kohsuke Kawaguchi

    Note that Jelly scripts are reloaed live from the source folder automatically by Jenkins for you. No need for doing anything extra.

  • Kohsuke Kawaguchi

    Starting Jenkins 1.421, it’ll support JRebel better and allow you to reload more things, such as HTTP-bound methods like doXxx, changes to properties exposed to the remote API (via @Exported annotation.) See https://wiki.jenkins-ci.org/display/JENKINS/Developing+with+JRebel for more details.

  • Christopher

    Great article, thanks for the tip! Project managers can download Jenkins, together with enterprise support, from the new WANdisco uberApps Store. 

    Check out the video for info: http://www.ubersvn.com/videos/introducing-uberapps

  • When ever I use JRebel for Jenkins Development, I do get errors like this when ever it reloads a class:

    JRebel: Reloading class ‘org.jenkinsci.plugins.scriptler.builder.ScriptlerBuilder’.
    JRebel: An error occured in a JRebel plugin while handling a class reload event:
    java.lang.IllegalStateException: zip file closed
        at java.util.zip.ZipFile.ensureOpen(ZipFile.java:415)
        at java.util.zip.ZipFile.getEntry(ZipFile.java:160)
        at java.util.jar.JarFile.getEntry(JarFile.java:208)
        at java.util.jar.JarFile.getJarEntry(JarFile.java:191)
        at sun.misc.URLClassPath$JarLoader.getResource(URLClassPath.java:757)
        at sun.misc.URLClassPath.getResource(URLClassPath.java:169)
        at java.net.URLClassLoader$1.run(URLClassLoader.java:194)
        at java.security.AccessController.doPrivileged(Native Method)
        at java.net.URLClassLoader.findClass(URLClassLoader.java:190)
        at java.lang.ClassLoader.loadClass(ClassLoader.java:306)
        at java.lang.ClassLoader.loadClass(ClassLoader.java:247)
        at org.zeroturnaround.jrebel.groovy.GroovyClassEventListener.onClassEvent(GroovyClassEventListener.java:9)
        at com.zeroturnaround.javarebel.SDKReloaderImpl.doFireReloadListeners(JRebel:128)
        at com.zeroturnaround.javarebel.SDKReloaderImpl.firePendingReloadListeners(JRebel:68)
        at com.zeroturnaround.javarebel.SDKReloaderImpl.fireReloadListeners(JRebel:112)
        at com.zeroturnaround.javarebel.kP.reloadClass(JRebel:802)
        at com.zeroturnaround.javarebel.kP.checkReload(JRebel:337)
        at hudson.model.AbstractBuild$AbstractRunner.preBuild(AbstractBuild.java:724)
        at hudson.model.AbstractBuild$AbstractRunner.preBuild(AbstractBuild.java:719)
        at hudson.model.Build$RunnerImpl.doRun(Build.java:119)
        at hudson.model.AbstractBuild$AbstractRunner.run(AbstractBuild.java:459)
        at hudson.model.Run.run(Run.java:1376)
        at hudson.model.FreeStyleBuild.run(FreeStyleBuild.java:46)
        at hudson.model.ResourceController.execute(ResourceController.java:88)
        at hudson.model.Executor.run(Executor.java:230)

  • Arnel Pällo

    Try disabling the Groovy plugin in JRebel (-Drebel.groovy_plugin=false)

  • No – what is the difference?
    I’m trying to get our Dev group to look at this (I’m in OPS and tired of them complaining of 5 minute builds – where they check EVERYTHING out again after a minor change and rebuild with Hudson)
    So I need clearer time savings analysis – this is clearly a way for DEV for work smarter…
    thanks!

  • Hello, there

    It seems that lately Jenkins uses jetty for web container while doing plugin development

    I found it’s not working with jrebel

    plz help me out from this post in jrebel website, thx.

    http://zeroturnaround.com/forums/topic/jrebel-is-not-working-with-jenkins-plugin-development/