# Jenkins Tool Management Architecture: ToolInstallation, ToolDescriptor, and DownloadFromUrlInstaller Explained

> Understand Jenkins tool management architecture. Learn how ToolInstallation, ToolDescriptor, and DownloadFromUrlInstaller automate tool installations and downloads for your CI/CD pipelines.

- Repository: [Jenkins/jenkins](https://github.com/jenkinsci/jenkins)
- Tags: architecture
- Published: 2026-07-28

---

**Jenkins tool management relies on an extensible descriptor-based architecture where `ToolInstallation` models a tool instance, `ToolDescriptor` registers it in the UI, and `DownloadFromUrlInstaller` handles automatic remote archive downloads.**

Jenkins automates the provisioning of build tools across distributed agents through a flexible, plugin-extensible framework. The architecture centers on the `ToolInstallation` and `ToolDescriptor` classes, paired with installer implementations such as `DownloadFromUrlInstaller`, to let administrators declare, configure, and auto-install everything from JDKs to custom binaries. Understanding these core classes—as implemented in the `jenkinsci/jenkins` repository—reveals how Jenkins resolves tool locations at runtime and keeps agents consistently provisioned.

## Core Components of the Jenkins Tool Management Architecture

### ToolInstallation

`ToolInstallation` in [`core/src/main/java/hudson/tools/ToolInstallation.java`](https://github.com/jenkinsci/jenkins/blob/main/core/src/main/java/hudson/tools/ToolInstallation.java) represents a concrete installation of a tool, storing its name, home directory, and optional properties. It implements both `Describable<ToolInstallation>` and `ExtensionPoint`, which allows every tool type to expose its own `ToolDescriptor`. The class provides node-specific resolution through `translate(Node, EnvVars, TaskListener)` and `preferredLocation`, and it stores a list of `ToolProperty` objects—most notably `InstallSourceProperty`.

### ToolDescriptor

`ToolDescriptor<T extends ToolInstallation>`, defined in [`core/src/main/java/hudson/tools/ToolDescriptor.java`](https://github.com/jenkinsci/jenkins/blob/main/core/src/main/java/hudson/tools/ToolDescriptor.java), acts as the descriptor for a concrete `ToolInstallation` subclass. It supplies UI metadata such as the display name and manages the list of configured installations via `getInstallations()`. Jenkins uses this descriptor to render the **Tool Configuration** page, and you can obtain registered descriptors through `ToolInstallation.all()`.

### InstallSourceProperty

`InstallSourceProperty`, found in [`core/src/main/java/hudson/tools/InstallSourceProperty.java`](https://github.com/jenkinsci/jenkins/blob/main/core/src/main/java/hudson/tools/InstallSourceProperty.java), is a `ToolProperty` that bundles one or more installers for a tool. It holds a `DescribableList<ToolInstaller, ...>` that the UI renders as **Auto-install** options. When attached to a `ToolInstallation`, each installer receives the owning tool reference through `installer.setTool(t)`.

### ToolInstaller

`ToolInstaller` in [`core/src/main/java/hudson/tools/ToolInstaller.java`](https://github.com/jenkinsci/jenkins/blob/main/core/src/main/java/hudson/tools/ToolInstaller.java) performs the actual installation of a tool on a node. Its abstract `performInstallation` method receives the target `ToolInstallation`, the node, and a logger. Each installer carries a label expression that restricts which agents it may run on through `appliesTo`, and implementations are discovered via `ToolInstallerDescriptor.all()`.

### ToolInstallerDescriptor

`ToolInstallerDescriptor<T extends ToolInstaller>`, located in [`core/src/main/java/hudson/tools/ToolInstallerDescriptor.java`](https://github.com/jenkinsci/jenkins/blob/main/core/src/main/java/hudson/tools/ToolInstallerDescriptor.java), is the descriptor for a `ToolInstaller`. It determines whether an installer is applicable to a given `ToolInstallation` type through `isApplicable(Class<? extends ToolInstallation>)`, which defaults to `true`. It also supplies UI helpers for label auto-completion and validation.

### DownloadFromUrlInstaller

`DownloadFromUrlInstaller` in [`core/src/main/java/hudson/tools/DownloadFromUrlInstaller.java`](https://github.com/jenkinsci/jenkins/blob/main/core/src/main/java/hudson/tools/DownloadFromUrlInstaller.java) is a concrete installer that downloads an archive from a URL and extracts it. It extends `ToolInstaller` and is configured with an **ID** that maps to an entry in the Jenkins update center JSON via the nested `Installable` class. It implements `isUpToDate` by checking a hidden `.installedFrom` marker file, and its `performInstallation` method downloads the archive, extracts it, optionally flattens a top-level directory, and writes the marker. The nested `DescriptorImpl` registers a `Downloadable` object so the update center can populate the list of available installables.

## How the Jenkins Tool Management Architecture Works

The framework follows a clear lifecycle from definition to execution.

1. **Definition** — A plugin or core module declares a concrete subclass of `ToolInstallation`. Its companion descriptor, extending `ToolDescriptor`, registers the installation type with Jenkins.

2. **Configuration** — In the *Global Tool Configuration* UI, an administrator creates an instance of that installation, providing a name and home path. Optionally, an `InstallSourceProperty` is added, exposing one or more installers.

3. **Installer selection** — The UI populates a drop-down with installers discovered through `ToolInstallerDescriptor.for_(MyToolInstallation.class)`. For many core tools, the default choice is a subclass of `DownloadFromUrlInstaller`.

4. **Execution** — When a build runs on a node, Jenkins calls `ToolInstallation.translateFor(node, log)`. This method first checks `ToolLocationNodeProperty` for node-specific overrides. It then iterates over `InstallSourceProperty.installers`, invoking any installer whose `appliesTo(node)` returns true. The installer's `performInstallation` method lazily provisions the tool only when `isUpToDate` indicates it is needed.

5. **Result** — The resolved `FilePath` for the tool's home directory on that node is returned, which subsequent build steps reference directly.

## Implementing a Custom Tool with DownloadFromUrlInstaller

The following snippets show how to wire a custom tool into the Jenkins tool management architecture. The first block defines the tool and its descriptor; the second shows a custom URL-based installer.

```java
// 1. Define a new ToolInstallation subclass
public class MyToolInstallation extends ToolInstallation
        implements NodeSpecific<MyToolInstallation>, EnvironmentSpecific<MyToolInstallation> {

    @DataBoundConstructor
    public MyToolInstallation(String name, String home, List<? extends ToolProperty<?>> properties) {
        super(name, home, properties);
    }

    @Override public MyToolInstallation forNode(Node node, TaskListener listener)
            throws IOException, InterruptedException {
        return (MyToolInstallation) translateFor(node, listener);
    }

    @Override public MyToolInstallation forEnvironment(EnvVars env) {
        return this; // no env-specific changes
    }
}

// 2. Provide a descriptor so Jenkins knows about the tool
@Extension
public static class DescriptorImpl extends ToolDescriptor<MyToolInstallation> {
    @Override public String getDisplayName() { return "My Custom Tool"; }
}

```

```java
public class MyToolInstaller extends DownloadFromUrlInstaller {
    @DataBoundConstructor
    public MyToolInstaller(@CheckForNull String id) {
        super(id);   // id must match an entry in the update-center JSON
    }

    @Extension
    public static final class DescriptorImpl extends DownloadFromUrlInstaller.DescriptorImpl<MyToolInstaller> {}
}

```

When a user selects **MyToolInstaller** for *My Custom Tool*, Jenkins performs the following actions according to the `jenkinsci/jenkins` source code:

- Loads the installable list from the update center using `Downloadable.get(getId())`.
- Selects the entry whose `id` matches the installer's configured `id`.
- Calls `performInstallation` to download and extract the archive onto the target node, verifying the `.installedFrom` marker to avoid redundant installs.

## Summary

- **`ToolInstallation`** defines a named tool instance and its properties, and translates itself for specific nodes.
- **`ToolDescriptor`** registers the tool type with Jenkins and drives the configuration UI.
- **`InstallSourceProperty`** groups one or more `ToolInstaller` instances under a single tool definition.
- **`ToolInstaller`** and **`ToolInstallerDescriptor`** handle the actual provisioning logic and applicability checks.
- **`DownloadFromUrlInstaller`** provides a ready-made implementation for fetching and extracting remote archives, keyed by update-center metadata.
- The architecture resolves tool locations at runtime through `translateFor`, respecting node overrides and lazy-installing binaries only when needed.

## Frequently Asked Questions

### What is the role of ToolInstallation in Jenkins?

`ToolInstallation` is the base class that models a specific tool instance, storing its name, home directory, and properties such as `InstallSourceProperty`. It implements `Describable<ToolInstallation>` so that each concrete tool type can expose its own `ToolDescriptor`, and it provides methods like `translateFor` to resolve node-specific paths at runtime.

### How does Jenkins decide which installer to use for a tool?

Jenkins discovers available installers through `ToolInstallerDescriptor.all()` and filters them by applicability using `isApplicable(Class<? extends ToolInstallation>)`. When a build requires the tool on a node, `InstallSourceProperty` iterates over its configured installers and invokes the first one whose `appliesTo` check matches the node's labels.

### What does DownloadFromUrlInstaller do under the hood?

`DownloadFromUrlInstaller` fetches an archive from a URL defined in the update-center JSON and extracts it on the target node. It writes a hidden `.installedFrom` marker file to track provenance, and its `isUpToDate` method skips reinstallation if the marker matches the current ID. The installer optionally pulls up a single top-level directory after extraction.

### Can a tool have both a manual home path and an automatic installer?

Yes. A `ToolInstallation` always has a home path, but when you attach an `InstallSourceProperty` containing installers, Jenkins can disregard or supplement that path. At runtime, `translateFor` evaluates node overrides first, then installers, returning the resolved `FilePath` that the build step ultimately uses.