Plugin tutorial

Skip to end of metadata
Go to start of metadata

This document, together with the hello-world plugin, shows you how to get started with the plugin development.

Table of Contents

What Can Plugins Do?

Jenkins defines extensibility points, which are interfaces or abstract classes that model an aspect of a build system. Those interfaces define contracts of what need to be implemented, and Jenkins allows plugins to contribute those implementations. See this document for more about extension points.

In this document, we'll be implementing a Builder that says hello. (built-in builders include Ant, Maven, and shell script. Builders build a project.)

Setting Up Environment

To develop a plugin, you need Maven 3 (why?) and JDK 6.0 or later. If this is the first time you use Maven, make sure Maven can download stuff over the internet.

Nexus Users
If you are using the Nexus Maven Repository Manager, you can ignore these instructions, and instead, click here for instructions on how to add Jenkins build prerequisites and the proper settings.xml entries.

It may be helpful to add the following to your ~/.m2/settings.xml (Windows users will find them in %USERPROFILE%\.m2\settings.xml):

<settings>
  <pluginGroups>
    <pluginGroup>org.jenkins-ci.tools</pluginGroup>
  </pluginGroups>

  <profiles>
    <!-- Give access to Jenkins plugins -->
    <profile>
      <id>jenkins</id>
      <activation>
        <activeByDefault>true</activeByDefault> <!-- change this to false, if you don't like to have it on per default -->
      </activation>
      <repositories>
        <repository>
          <id>repo.jenkins-ci.org</id>
          <url>http://repo.jenkins-ci.org/public/</url>
        </repository>
      </repositories>
      <pluginRepositories>
        <pluginRepository>
          <id>repo.jenkins-ci.org</id>
          <url>http://repo.jenkins-ci.org/public/</url>
        </pluginRepository>
      </pluginRepositories>
    </profile>
  </profiles>
  <mirrors>
    <mirror>
      <id>repo.jenkins-ci.org</id>
      <url>http://repo.jenkins-ci.org/public/</url>
      <mirrorOf>m.g.o-public</mirrorOf>
    </mirror>
  </mirrors>
</settings>

This will let you use short names for Jenkins Maven plugins (i.e. hpi:create instead of org.jenkins-ci.tools:maven-hpi-plugin:1.61:create),
though this is unnecessary once you are already working in a plugin project (only useful for initial hpi:create).
Note that adding the Jenkins repositories in a profile like this is not really necessary since most (all?) plugins already define these repositories.
And the mirror declaration is probably unnecessary.

Creating a New Plugin

To start a new plugin, use the online skeleton generator, or use an IDE (below).
Alternatively, if you are more comfortable with Maven, run the following command:

$ mvn -U org.jenkins-ci.tools:maven-hpi-plugin:create

This will ask you a few questions, like the groupId (the Maven jargon for the package name) and the artifactId (the Maven jargon for your project name), then create a skeleton plugin from which you can start with. Make sure you can build this:

$ cd newly-created-directory
$ mvn package

Explanations:

-U means that Maven should update all relevant Maven plugins (check for plugin updates)
hpi: this prefix specifies that the Jenkins HPI Plugin is being invoked, a plugin that supports development of Jenkins plugins
create is the goal which creates the directory layout and the POM for your new Jenkins plugin and it adds it to the module list
package is a standard phase which compiles all sources, runs the tests and creates a package - when used by the HPI plugin it will create an *.hpi file

Building a Plugin

To build a plugin, run mvn install. This will create the file ./target/pluginname.hpi that you can deploy to Jenkins.

$ mvn install

Setting up a productive environment with your IDE

NetBeans

NetBeans users can use the IDE's Maven support to open the project directly.

As you navigate through the code, you can tell NetBeans to attach source code JAR files by clicking the "Attach" button that appears in the top of the main content window. This allows you to read the Jenkins core source code as you develop plugins. (Or just select Download Sources on the Dependencies node.)

You are advised to use the NetBeans plugin for Jenkins/Stapler development. This offers many Jenkins-specific features. Most visibly, create a new plugin using New Project » Maven » Jenkins Plugin, and use Run Project to test it.

IntelliJ IDEA

IntelliJ 7.0 (or later) users can load pom.xml directly from IDE, and you should see all the source code of libraries and Jenkins core all the way to the bottom. Consider installing IntelliJ IDEA plugin for Stapler to make the development easier.

IntelliJ defaults to downloading sources and JavaDocs on demand. So, to see the source, you may need to click the Download artifacts button in the Maven Projects tab.

Eclipse

Use Eclipse Juno (4.2) or later for the best experience.

As Jenkins plugins are Maven projects, Eclipse users have two ways to load a Jenkins plugin project. One is to use m2e, which tries to make Eclipse understand Maven "natively", and the other is to use Maven Eclipse plugin, which makes Maven generate Eclipse project definitions. At the moment, unless you have some prior experience with m2e, we currently recommend plugin developers to go with the Maven Eclipse plugin.

Eclipse users can run the following Maven command to generate Eclipse project files (the custom outputDirectory parameter is used to work around the lack of JSR-269 annotation processor support in Eclipse:)

$ mvn -DdownloadSources=true -DdownloadJavadocs=true -DoutputDirectory=target/eclipse-classes eclipse:eclipse

Once this command completes successfully, use "Import..." (under the File menu in Eclipse) and select "General" > "Existing Projects into Workspace".

Do not select "Existing Maven Projects", which takes you to the m2e route

See Jenkins plugin development with Eclipse for gotchas and other known Eclipse/Maven related issues with Jenkins plugin development.

See Eclipse alternative build setup for an alternative way of setting up the Eclipse build environment, that is a bit more technically involved than using maven, but can give faster build times.

Plugin Workspace Layout

The plugin workspace consists of the following major pieces:

pom.xml

Maven uses it for building your plugin.

src/main/java

Java source files of the plugin.

src/main/resources

Jelly/Groovy views of the plugin. See this document for more about it.

src/main/webapp

Static resources of the plugin, such as images and HTML files.

Source Code

Let's take a look at the source code. A plugin's main entry point is a PluginImpl class that extends from Plugin. Once Jenkins detects your plugin class (via its inheritance relationship from Plugin), it will create an instance, and invoke methods. A Plugin class is optional; a plugin may simply implement extensions:

Most of the time, a plugin class just registers extension points, and your main work involves implementing those extension points. See the source code for more about how a Builder is implemented and what it does.

Debugging a Plugin

NetBeans 6.7+ users can just hit Debug. For all others, run the following command to launch Jenkins with your plugin:
Convenient:

mvnDebug hpi:run

Unix:

$ export MAVEN_OPTS="-Xdebug -Xrunjdwp:transport=dt_socket,server=y,address=8000,suspend=n"
$ mvn hpi:run

Windows:

> set MAVEN_OPTS=-Xdebug -Xrunjdwp:transport=dt_socket,server=y,address=8000,suspend=n
> mvn hpi:run

If you open http://localhost:8080/jenkins in your browser, you should see the Jenkins page running in Jetty. The MAVEN_OPTS portion launches this whole thing with the debugger port 8000, so you should be able to start a debug session to this port from your IDE.

Once this starts running, keep it running. Jetty will pick up all the changes automatically.

  1. When you make changes to view files in src/main/resources or resource files in src/main/webapp, just hit F5 in your browser to see the changes.
  2. When you change Java source files, compile them in your IDE (NetBeans 6.7+: Debug > Apply Code Changes) and Jetty should automatically redeploy Jenkins to pick up those changes. There is no need to run mvn at all.
    MAVEN_OPTS can be used to specify all sorts of other JVM parameters, like -Xmx

Changing port

If you need to launch the Jenkins on a different port than 8080, set the port through the system property jetty.port.

$ mvn hpi:run -Djetty.port=8090

Setting context path

maven-hpi-plugin 1.65 or later (used by parent POM 1.401 or later) can set the context path by using a system property. On more recent versions of Jenkins the "/jenkins" prefix is added automatically.

$ mvn hpi:run -Dhpi.prefix=/jenkins

Changing code while debugging

Depending on what you change, you can see it in the running instance without restarting the whole Maven process:

  • Views: Groovy/Jelly views are re-compiled every time a browser requests a page, so just reload a page in the browser and you'll see the changes. This is also true for help files you write.
  • Java code: If you are debugging, JVM's hot swap feature can be used to reload code so long as you don't touch the method signature. Beyond that, you can hit ENTER in the Maven process and it'll reload the Jenkins webapp. See Developing with JRebel for how to get a JRebel license for OSS projects to improve this experience.
  • POM: If you change POM, you'll have to stop and restart Maven to see the changes.

Distributing a Plugin

To create a distribution image of your plugin, run the following Maven command:

$ mvn package

This should create target/*.hpi file. Other users can use Jenkins' web UI to upload this plugin to Jenkins (or place it in $JENKINS_HOME/plugins.)

Releasing a Plugin and Hosting a Plugin on jenkins-ci.org

If you got to this point, you should definitely consider hosting your plugin on jenkins-ci.org. Move on to this document for how to do that. This includes the instructions for releasing the plugin.

Using custom builds of plugins included in the Jenkins WAR

If you are building a patched version of one of the plugins in the Jenkins core, the deployment process is a bit different. This is because Jenkins will itself manage these plugins unless you tell it not to.

Deploying a custom build of a core plugin

  1. Stop Jenkins
  2. Copy the custom HPI file to $JENKINS_HOME/plugins
  3. Remove the previously expanded plugin directory
  4. Create an empty file called <plugin>.hpi.pinned - e.g. maven-plugin.hpi.pinned
  5. Start Jenkins

Other tips

  1. Consider running Maven like this mvn -o ... to avoid hitting repositories every time. This will make various operations considerably faster.
  2. Subscribe to the users' alias from here so that we can get in touch with you.
  3. When you bump up the version of Jenkins you depend on, make sure to run mvn clean once, in particular to delete target/work that Jetty uses. Newer versions may just use work, not target/work. Otherwise your Jetty may continue to pick up old left-over JAR files.
  4. If you have a high latency network connection to the Maven repository, you might find it faster to first run the build once on a server near to the maven repository, then rsync the .m2/repository folder across to your local computer
  5. The 'package' and 'install' targets will by default run many tests. You can add '-DskipTests' on the command-line to skip these (of course you should run the tests before committing any changes)
  6. The 'compiler:compile' goal is faster than 'compile', because it is a goal, rather than a lifecycle event, and therefore avoids certain earlier goals, such as setting up resources

Other resources

Besides this tutorial, there are other tutorials and examples available on line:

Labels

Edit
plugin plugin Delete
setup setup Delete
maven maven Delete
Enter labels to add to this page:
Please wait 
Looking for a label? Just start typing.

Add Comment