What Is Jenkins?
If you never heard about Jenkins, or it is just something that you didn't understand exactly what is it useful for, this article is for you. In the next few minutes, we will have an overview of Jenkins meant to introduce you this comprehensive tool dedicated to automating any kind of project.
Basically, Jenkins is an open source project written in Java and dedicated to sustaining continuous integration practices (CI). The tasks that Jenkins can solve are related to project automation, or, more exactly, Jenkins is fully able to automate build, test, and integrate our projects. For example, in this article you will see how to chain GitHub->Jenkins->Payara Server to obtain a simple CI environment for a Hello World Spring-based application (don't worry, you don't need to know Spring).
So, let's delve a little in the Jenkins goals. We begin with the installation of Jenkins 2, continue with major settings/configurations, install specific plug-ins, and finish with a quick start example of automating a Java Web application.
In this article, we will assume the following:
- You know how to create a public GitHub account and repository.
- You know how to link your favorite IDE (code editor) to a GitHub repository (clone a repository).
- You know how to install and start Payara Server with its default settings.
Download and Install Jenkins 2
To download Jenkins, simply access the official Jenkins Web site (https://jenkins.io/) and press the button labeled Download Jenkins, as seen in Figure 1:
Figure 1: Download Jenkins
We go for the weekly release, which is listed oin the right side. Simply expand the menu button from Figure 1 and choose the distribution compatible with your system (OS) and needs. For example, we will choose to install Jenkins under Windows 7 (64-bit), as you can see from Figure 2:
Figure 2: Select a distribution compatible with the system
Notice that, even if the name is 2.5.war, for Windows we will download a specific installer. After download, you should obtain a ZIP archive named jenkins-2.5.zip. Simply un-zip this archive in a convenient location on your computer. You should see a MSI file named jenkins.msi. So, double-click this file to proceed with the very simple installation steps. Basically, the installation should go pretty smoothly and should be quite intuitive; we installed Jenkins in the D:\jenkins 2.5 folder. At the end, Jenkins will be automatically configured as a Windows service and will be listed in the Services application, as in Figure 3:
Figure 3: Jenkins as a Windows service
Beside setting Jenkins as a service, you will notice that the default browser was automatically started, as shown in Figure 4:
Figure 4: Unlock Jenkins
Well, this is the self-explanatory login page of Jenkins, so simply act accordingly to unlock Jenkins. In our case, the initialAdminPassword was 9d9f510d8ef043e98f7c574b3ea8adc0. Don't bother about typing this password; simply use copy-paste. After you click the Continue button, you can see the page from Figure 5:
Figure 5: Install Jenkins plug-ins
Because we are using Jenkins for the first time, we prefer to go with the default set of plug-ins. Later on, we can install more plug-ins, so you don't have to worry that you didn't install a specific plug-in at this step. Notice that installing suggested plug-ins may take a while, depending on your Internet connection (network latency), so be patient and wait for Jenkins to finish this job for you. While this job is in progress, you should see a verbose monitoring that reveals the progress status, plug-ins names, and the dependencies downloaded for those plug-ins. See Figure 6:
Figure 6: Monitoring plug-ins installation progress
You can use this time to spot some commonly used plug-ins, such as Git, Gradle, Pipeline, Ant, and so forth.
After this job is done, it is time to set an admin user of Jenkins. You need to have at least an admin, so fill up the requested information accordingly (Figure 7):
Figure 7: Create the first Jenkins admin
If you press Continue as admin, Jenkins will automatically log you in with these credentials and you will see the Jenkins dashboard. If you press the Save and Finish button, you will not be logged in automatically and you will see the page from Figure 8:
Figure 8: Start using Jenkins
If you choose Save and Finish (or whenever you are not logged in), you will be prompted to log in via a simple form, as in Figure 9:
Figure 9: Log in to Jenkins as admin
After login, you should see the Jenkins dashboard, as in Figure 10:
Figure 10: Jenkins dashboard
So far, you have successfully downloaded, installed, and started Jenkins. Let's go farther and see several useful and common configurations.
Modify the Jenkins Home Directory (JENKINS_HOME)
To work as expected, Jenkins needs a home directory and implicitly some disk space. In Windows (on a 64-bit machine), by default, the Jenkins home directory (JENKINS_HOME) is the place where you have installed Jenkins. In our case, this is D:\jenkins 2.5. If you take a quick look into this folder, you will notice several sub-folders and files, such as the /jobs folder, used for storing jobs configurations; a /plugins folder, used for storing installed plug-ins or the jenkins.xml file containing some Jenkins configurations. So, in this folder, you will store Jenkins stores plug-ins, jobs, workspace, users, and so on.
Now, let's suppose that we want to modify the Jenkins folder from D:\jenkins 2.5 in C:\JenkinsData. To accomplish this task, we need to follow several steps:
- Ensure that Jenkins is not running. You can stop it from the Servicesapplication or from the command prompt, as in Figure 11:
Figure 11: Stopping Jenkins from the command prompt
- Open for edit the jenkins.xml file located in D:\jenkins 2.5.
- Edit the following entry:
<env name="JENKINS_HOME" value="%BASE%"/>
<env name="JENKINS_HOME" value=" C:\JenkinsData"/>
- Manually create the folder C:\JenkinsData and copy into it everything from D:\jenkins 2.5except the files and folders from Figure 12:
Figure 12: Files and folders that should not be copied in the new JENKINS_HOME
- Start the Jenkins service from the Servicesapplication or from the command prompt, as in Figure 13:
Figure 13: Starting Jenkins from the command prompt
- Now, you can easily navigate to http://localhost:8080/systemInfo (or from the Jenkins dashboard, Manage Jenkins | System Information and notice that JENKINS_HOME is not set as C:\JenkinsData):
Figure 14: Check the JENKINS_HOME value
|Note: Under Windows, most probably you will want to store data under the ProgramData folder. You can easily find the environment variable for this folder, but usually it is %ProgramData% and points to the C:\ProgramData location. So, if you want this path, simply adjust jenkins.xmlas:
<env name="JENKINS_HOME" value="%ProgramData%"/>
Modify Default Port (8080)
By default, Jenkins will start on port 8080. In case that you are using this port for another application (for example, application servers as Payara, Wildfly, and the like), you will want to manually set another port for Jenkins. This can be accomplished by following these steps:
- Ensure that Jenkins is not running.
- Edit the jenkins.xml file and locate the <arguments/> tag.
- Find the --httpPort=8080 argument and modify it. For example, we have set the port to 9011:
<arguments>-Xrs -Xmx256m -Dhudson.lifecycle= hudson.lifecycle.WindowsServiceLifecycle -jar "%BASE%\jenkins.war" --httpPort=9011 --webroot="%BASE%\war"</arguments>
- Restart Jenkins and access localhost:9011.
Allocate More Memory to Jenkins
By default, Jenkins will use 256MB, as you can see in jenkins.xml. To allocate more memory, simply adjust the corresponding argument. For example, let's give ir 8192MB:
<arguments>-Xrs -Xmx8192m -Dhudson.lifecycle= hudson.lifecycle.WindowsServiceLifecycle -jar "%BASE%\jenkins.war" --httpPort=9011 --webroot="%BASE%\war"</arguments>
You also may want to adjust the perm zone or other JVM memory characteristics by adding more arguments:
<arguments>-Xrs -XX:PermSize=512m -XX:MaxPermSize=2048m -Xmn128m -Xms1024m -Xmx8192m -Dhudson.lifecycle= hudson.lifecycle.WindowsServiceLifecycle -jar "%BASE%\jenkins.war" --httpPort=9011 --webroot="%BASE%\war"</arguments>
Please find more Jenkins parameters here.
Jenkins and Winstone
Winstone is part of Jenkins; therefore, you can take advantage of settings such as --handlerCountStartup (set the number of worker threads to spawn at startup; default, 5) or --handlerCountMax (set the max number of worker threads to allow; default,d 300).
Administrating Jenkins Plug-ins
Remember that when we have installed Jenkins we chosen the default set of plug-ins. Moreover, remember that we said that Jenkins allows us to install more plug-ins later from the dashboard. Well, it is time to see how to deal with Jenkins plug-ins.
List Installed Plug-ins
To see what plug-ins are installed in your Jenkins instance, simply select the Manage Jenkins | Administration plugins | Installed tab. See Figure 15:
Figure 15: See the installed plug-ins
Install a New Plug-in
Installing a new plug-in is pretty simple. Select the Manage Jenkins | Administration plugins | Available tab. Locate the desired plug-in(s) (notice that Jenkins will provide a huge list of plug-ins, so you better use the search filter feature), tick the desired plug-in(s), and click one of the available options listed at the bottom of the page. Jenkins will do the rest for you. See Figure 16:
Figure 16: Install a new plug-in
For example, later in this article we will need to instruct Jenkins to deploy the application WAR on a Payara Server. To accomplish this, we can install a plug-in named Deploy Plugin. So, in the Available tab, we have used the filter feature and typed deploy. This will bring us, on screen, the plug-in as in Figure 17. (If you don't use the filter, you will have to manually search through hundreds of available plug-ins, which will be time-consuming.) Therefore, simply tick it and install it without restart:
Figure 17: Install Deploy plug-in
After installation, this plug-in will be listed under the Installed tab.
Global Tool Configuration
Before defining a job for Jenkins, it is a good practice to take a look to the global tool configuration (Manage Jenkins | Global Tool Configuration). Depending on what types of jobs you want to run, Jenkins needs to know where to find additional tools, such as JDK, Git, Gradle, Ant, Maven, and so forth. Each of these tools can be installed automatically by Jenkins once you tick the Install automatically checkbox. For example, in Figure 18, you can see that Jenkins will install Maven automatically:
Figure 18: Install Maven under Jenkins
But, if you already have Maven installed locally, you can un-tick the Install automatically checkbox and instruct Jenkins where to find Maven locally via the MAVEN_HOME environment variable. Either way, you have to specify a name to this Maven installation. For example, type Maven as the name and keep this in mind because you will need it later.
Each tool can be installed automatically, or you can simply instruct Jenkins where to find it locally via environment variables (for JDK, JAVA_HOME; for Git, GIT_HOME; for Gradle, GRADLE_HOME; for Ant, ANT_HOME, and for Maven, MAVEN_HOME). Moreover, each tool needs a name used to identify it and refer it later when you start defining jobs. This is useful when you have multiple installation of the same tool. In case that a required variable is not available, Jenkins will show this via an error message. For example, let's say that we decided to instruct Jenkins to use the local Git distribution. But, we don't have GIT_HOME set, so here it is what Jenkins will report:
Figure 19: Install Git under Jenkins
This means that we need to set GIT_HOME accordingly or choose the Install automatically option. Once you set GIT_HOME, the error will disappear. So, before assigning jobs to Jenkins, take your time and ensure that you have successfully accomplished global tool configuration. This is a very important aspect!
Let's Define a Jenkins Job
Because this is the first Jenkins job, we will keep it very simple. Practically, what we will do is to implement a simple CI project for a Hello World Spring application. This application is available here. Don't worry if you don't know Spring; it is not mandatory!
Furthermore, you have to link the repository (you can fork to this repository) to your favorite IDE (for example, NetBeans, Eclipse, and so on) in such a way that you can easily push changes to GitHub. How you can accomplish this is beyond this article's goal, but if you choose NetBeans, you can find the instructions here.
So, we are supposing that you have Jenkins installed/configured and the application is opened in your favorite IDE and linked to GitHub. The next thing to do is to install Payara Server with its default settings and start it. By default, it should start on port 8080 with admin capabilities on port 4848.
Our next goal is to obtain the following automation: at each three-minute interval, Jenkins will take the code from GitHub, compile it, and the resulted WAR will be deployed on Payara Server.
Define a New Jenkins Job
Open Jenkins in a browser and click New Item or Create a new job, as in Figure 20:
Figure 20: Create a new job in Jenkins
As you will see, there are several types of jobs (projects) available. We will choose the most popular one, which is freestyle project and we will name it HelloSpring:
Figure 21: Select a job type and name it
After you press the Ok button, Jenkins will open the configuration panel for this type of job. First, we will provide a simple description of the project, as in Figure 22 (this is optional):
Figure 22: Describe your new job
Specify GitHub Project URL
Because this is a project hosted on GitHub, we need to inform Jenkins about its location. For this, on the General tab, tick the GitHub project checkbox and provide the project URL (without the tree/master or tree/branch part):
Figure 23: Set the project URL
Configure Source Code Management
The next step consists of configuring the Git repository that contains our application in the Source Code Management tab. This means that we have to tick the Git checkbox and specify the repository URL, the credentials used for access, and the branches to build, as in Figure 24:
Figure 24: Configure Git repository
Trigger Application Build
Further, let's focus on the Build Triggers tab. As you can see, Jenkins provides several options for choosing the moment when the application should be built. Most probably, you will want to choose the Build when a change is pushed to GitHub option, but for this we need to have a Jenkins instance visible on the Internet. This is needed for GitHub, which will use a webhook to inform Jenkins whenever a new commit is available. You also may go for the Poll SCM option, which will periodically check for changes before triggering any build. Only when changes to the previous version are detected, the build will be triggered. But, for now, we go for the Build periodically option, which will build the project periodically without checking for changes. We set this cron service to run at every three minutes:
Figure 25: Build project periodically
The schedule can be configured based on the instructions provided by Jenkins if you press the little question mark icon listed in the right of the Schedule section. By the way, don't hesitate to use those question marks whenever they are available because they provide really useful information.
To build the project, Jenkins need to know how to do it. Our application is a simple Maven Web application and pom.xml is in the root of the application. So, on the Build tab, select the Invoke top-level Maven targets option from the Add build step drop-box. Furthermore, instruct Jenkins about the Maven distribution (remember that we have configured a Maven instance under the name Maven earlier in the Global Tool Configuration section) and about the goals you want to be executed (for example, clean and package):
Figure 26: Configure Maven distribution and goals
Deploy after Build
So far, so good! Finally, if the application is successfully built, we want to delegate Jenkins to deploy it on Payara Server (remember that we have installed the Deploy Plugin earlier, especially for this task). This is a post-build action that can be configured on the Post-Build Actions tab. From the Add post-build action drop-box, select the Deploy war/ear to a container item.
Figure 27: Add a post-build action
This will open a dedicated wizard where we have to configure at least the Payara Server location and the credentials for accessing it:
Figure 28: Configure Payara Server for deployment
Click the Save button and everything is done. Jenkins will report the new job on the dashboard:
Figure 29: The job was set
Fire a Build Manually or Wait for cron to Run
Now, you can try to fire a manual build or wait for the cron to run the build every three minutes. For a manual build, simply click the project name from Figure 29, and on Build Now, as in Figure 30:
Figure 30: Running a build now
Each build is listed under the Build History section and can be in one of three stages: in progress, success, or failure. You easily can identify the status of your builds:
Figure 31: Build status
Most probably, if the build failed, you want to see what just happened. For this, simply click the specific build and afterwards on Console Output, as in Figure 32:
Figure 32: Check build output
Note: In Windows 7 (and not only) you may encounter an error, as in Figure 33:
All you have to do is to provide access for writing in the C:\Windows\Temp folder via the Properties wizard:
Figure 34: Providing access for writing to the folder
Run the Application
If the build is successfully accomplished, the application is deployed on Payara Server and it is available on the Applications tab of the admin console. From there, you easily can launch it, as in Figure 35:
Figure 35: Run the application
It looks like our small project works like a charm! Further, do some modifications in the application, push it on GitHub, wait for the Jenkins cron to run, and notice how the modifications are reflected in your browser after refresh.
Well, to further the project, you can try to add more functionalities, like a JIRA account, GitHub webhook, and the like.