Skip to content

DevOps Day 69: Managing Plugins and Conquering "Dependency Hell"

Today's task was my first experience with managing the heart of Jenkins: its plugins. The goal was to extend Jenkins' capabilities by installing plugins for Git and GitLab, which are essential for any code-based CI/CD pipeline.

This turned into an incredibly valuable, real-world troubleshooting exercise. My first attempt at installation failed spectacularly due to a complex web of dependency conflicts—a situation often called "dependency hell." This document details my journey of diagnosing the root cause from the error logs and executing a multi-step solution to fix the environment and successfully install the required plugins.

Table of Contents


The Task

My objective was to add new functionality to my recently installed Jenkins server. The requirements were: 1. Log into the Jenkins UI. 2. Install two specific plugins: Git and GitLab. 3. Restart Jenkins to ensure the new plugins were correctly loaded and activated.


My Step-by-Step Solution

My path to success was not direct and required a significant troubleshooting phase. The final, correct process involved fixing the Jenkins environment first and then performing the installation.

Phase 1: Fixing the Dependency Issues

The initial installation failed, so I had to perform these corrective steps first.

  1. Manual Restart: I first logged into the Jenkins server via SSH (ssh root@jenkins...) and performed a manual restart to clear the failed state.
    sudo systemctl restart jenkins
    
  2. Update Plugin Metadata: After logging back into the UI, I went to Manage Jenkins > Plugins > Advanced settings and clicked the "Check now" button at the bottom. This forced Jenkins to download the latest list of plugins and their dependencies, which is key to resolving conflicts.
  3. Install All Available Updates: I navigated to the Updates tab in the Plugin Manager, selected all available updates, and installed them with a restart. This brought all my existing plugins to their latest versions, satisfying the requirements of the new plugins I wanted to install.

Phase 2: Installing the Required Plugins

With the environment now healthy, I could proceed with the original task.

  1. Login and Navigate: I logged into the Jenkins UI (admin / Adm!n321) and went to Manage Jenkins > Plugins.
  2. Select Plugins: I clicked on the Available plugins tab and used the search bar to find and select the checkboxes for the Git and GitLab plugins.
  3. Install and Restart: I clicked the install button and, on the installation page, I checked the crucial box: "Restart Jenkins when installation is complete and no jobs are running."
  4. Verification: After Jenkins restarted and I logged back in, I went to Manage Jenkins > Plugins > Installed plugins. I searched for Git and GitLab, and seeing them in this list was the final confirmation of success.

My Troubleshooting Journey: A Detective Story

This task was a perfect example of how a simple action can fail due to complex underlying issues.

  • Failure: A Cascade of Errors

    • Symptom: When I tried to install the Git and GitLab plugins, the installation page showed a long list of Failure statuses for many different plugins, not just the ones I selected.
    • Diagnosis: I carefully read through the error logs provided on the page. I found the "smoking gun" in the details for the Jersey 2 API plugin: Update required: JavaBeans Activation Framework (JAF) API (javax-activation-api 1.2.0-7) to be updated to 1.2.0-8 or higher
    • Conclusion: This single message told the whole story. The installation failed because of a "dependency conflict." The Jersey 2 API plugin (which GitLab needs) required a newer version of the JAF API plugin than what was currently installed. This one failure caused a chain reaction, leading all dependent plugins to fail as well. This is classic "dependency hell."
  • Solution: My solution was to stop fighting the installer and instead prepare the environment for it. By manually restarting, forcing an update check, and then installing all available updates for my existing plugins, I brought my Jenkins instance up to a healthy, up-to-date state. When I then tried to install Git and GitLab again, their dependency requirements were already met, and the installation completed without any issues.


Why Did I Do This? (The "What & Why")

- Jenkins Plugins: Jenkins' power comes from its massive library of plugins. These are add-ons that allow Jenkins to integrate with virtually any other tool in the DevOps toolchain (like Git, Docker, AWS, etc.). A fresh Jenkins installation is just a blank canvas; plugins are the paint. - Git and GitLab Plugins: - The Git Plugin is non-negotiable for a modern CI/CD pipeline. It provides the fundamental ability for Jenkins to clone source code from a Git repository to perform builds and tests. - The GitLab Plugin provides deeper, specific integration with GitLab. It enables features like "webhooks," where GitLab can instantly notify Jenkins to start a build the moment a developer pushes new code, making the CI process truly continuous. - Dependency Management: Plugins don't exist in a vacuum. Many plugins (like GitLab) rely on other, more fundamental plugins (like Git, Jersey 2 API, etc.) to do their job. Jenkins' Plugin Manager tries to handle these dependencies automatically, but as I saw, it can sometimes get stuck if the existing environment is out of date.


Deep Dive: Understanding Jenkins Plugin Dependencies

My troubleshooting journey was a crash course in how Jenkins handles its components.

[Image of a Jenkins plugin dependency graph]

  • A Web of Dependencies: A high-level plugin like GitLab doesn't just have one dependency; it has a whole tree of them. GitLab needs Git, which needs Git Client, which needs SSH Credentials, and so on.
  • The Point of Failure: The entire system is only as strong as its weakest link. In my case, a single, low-level API plugin (JAF API) was out of date. This prevented an intermediate plugin (Jersey 2 API) from installing, which in turn prevented the high-level plugin I actually wanted (GitLab) from installing.
  • The "Update Center": The Check now button I used is a powerful tool. It forces Jenkins to download the latest update-center.json file from the Jenkins update servers. This file is a giant catalog of all available plugins and, crucially, their exact dependency requirements. By forcing this update, I gave my Jenkins instance the "map" it needed to correctly resolve the conflicts.

Common Pitfalls

- Ignoring Dependency Errors: It's tempting to just see the "Failure" message and try again. The key to solving the problem was to actually click on the "Details" and read the error log to find the specific dependency conflict. - Network Issues: If the Jenkins server cannot connect to updates.jenkins.io, it won't be able to download plugins or resolve dependencies. This can sometimes be a corporate firewall or network configuration issue. - Forgetting to Restart: Many plugins require a restart to function correctly. Forgetting to check the "Restart" box can lead to strange behavior where the UI shows a plugin as installed, but it doesn't actually work yet.


Exploring the Commands and UI Used

- Manage Jenkins > Plugins: The central hub in the UI for adding, updating, and removing all plugins. - Available plugins tab: Where I went to find and select new plugins to install. - Updates tab: Where I went to update my existing plugins, which was the key to solving my dependency issues. - Installed plugins tab: My final verification step to confirm that the plugins were successfully installed and active. - sudo systemctl restart jenkins: The command-line tool I used to perform a clean, manual restart of the Jenkins service to clear the failed installation state.