How Jenkins Manages Distributed Builds with Computer, Node, and JnlpSlaveAgentProtocol

Jenkins distributes builds across remote machines by representing each agent as a Computer instance and establishing a bi-directional remoting channel through the JNLP Slave-Agent Protocol.

Jenkins enables scalable continuous integration by delegating build workloads from the master to remote agents. In the jenkinsci/jenkins core codebase, this master-agent architecture is implemented through the interaction of Node, Computer, and JNLP launcher classes. Understanding how Jenkins distributed builds function at the source level helps administrators diagnose connectivity failures, secure agent secrets, and optimize executor allocation.

The Relationship Between Node, Slave, and Computer

When an administrator adds an agent in the Jenkins UI or via the REST API, Jenkins persists a hudson.model.Slave record that stores static configuration such as labels, remote filesystem root, and launch method. At runtime, Jenkins creates a corresponding Computer subclass—typically hudson.slaves.SlaveComputer defined in core/src/main/java/hudson/slaves/SlaveComputer.java—to represent the live execution environment. The abstract base class hudson.model.Computer in core/src/main/java/hudson/model/Computer.java defines executor management and channel state, while hudson.model.ComputerSet in core/src/main/java/hudson/model/ComputerSet.java aggregates every Computer for the scheduler and UI.

How JnlpSlaveAgentProtocol4 Establishes the Master-Agent Channel

The actual communication channel is provided by the JNLP Slave-Agent Protocol. On the master side, the modern implementation lives in jenkins.slaves.JnlpSlaveAgentProtocol4 at core/src/main/java/jenkins/slaves/JnlpSlaveAgentProtocol4.java. This class implements the default JNLP4-connect protocol, which superseded the legacy jenkins.slaves.JnlpSlaveAgentProtocol (JNLP1) now removed in recent Jenkins versions.

When an agent is configured to use JNLP, the master advertises a URL such as http://<master>/computer/<node>/jenkins-agent.jnlp. The file is generated by jenkins.slaves.EncryptedSlaveAgentJnlpFile in core/src/main/java/jenkins/slaves/EncryptedSlaveAgentJnlpFile.java and contains the master’s public key, the per-node agent secret, and the classpath jars required by the agent process. The helper class jenkins.slaves.DefaultJnlpSlaveReceiver in core/src/main/java/jenkins/slaves/DefaultJnlpSlaveReceiver.java validates the inbound connection and instantiates the remoting Channel once the agent authenticates.

Inside JNLPLauncher: Launching the Agent Process

The hudson.slaves.JNLPLauncher class in core/src/main/java/hudson/slaves/JNLPLauncher.java orchestrates the agent startup. Its launch(SlaveComputer c, TaskListener listener) method resolves the inbound URL, downloads the required jars, and constructs the command line that starts the agent JVM.

// Simplified flow in JNLPLauncher
public class JNLPLauncher extends ComputerLauncher {
    @Override public void launch(SlaveComputer c, TaskListener listener) throws IOException, InterruptedException {
        // 1. Resolve inbound URL (custom or default)
        URL inbound = getInboundAgentUrl(c);
        // 2. Download agent.jar (or use already‑installed copy)
        // 3. Start the Java process:
        //    java -jar agent.jar -jnlpUrl <inbound> -secret <secret>
        // 4. Attach the socket to the master’s Channel (remoting)
    }
}

After the remote JVM starts, it opens a TCP socket back to the master. On the master side, SlaveComputer accepts this socket and wraps it in a hudson.remoting.Channel, enabling remote procedure calls for build execution and log streaming.

The Remoting Channel and Executor Allocation

Once the socket is established, SlaveComputer creates the Channel that serves as the pipeline for all master-agent communication. The master’s Queue then assigns Executor objects to the Computer, dispatching build steps remotely over the channel. Because the channel is bi-directional, the master can stream console output, copy artifacts, and execute shell steps while the agent reports status back to the master.

Security, Secrets, and WebSocket Transport

Security for Jenkins distributed builds relies on a per-node agent secret embedded in the JNLP file and passed as the -secret argument. Administrators may also enforce SSL/TLS on the Jenkins master to encrypt traffic in transit.

Since Jenkins 2.263, agents can optionally upgrade the connection to a WebSocket channel, which simplifies firewall traversal by using standard HTTP ports. When launching with the -webSocket flag, the agent requests this upgrade, which the master honors when JNLPLauncher.DescriptorImpl.isWebSocketSupported() returns true. This transport reduces latency in environments that restrict raw TCP outbound connections.

Programmatic and Command-Line Agent Management

Administrators can provision JNLP agents via Groovy scripts or command-line tools.

To create a node programmatically:

import hudson.model.Node
import hudson.slaves.DumbSlave
import hudson.slaves.JNLPLauncher
import hudson.slaves.RetentionStrategy

def name = "remote‑linux"
def remoteFS = "/home/jenkins"
def numExecutors = 2
def mode = Node.Mode.NORMAL
def labels = "linux"

def launcher = new JNLPLauncher()               // defaults to JNLP4‑connect
def retention = RetentionStrategy.NOOP         // keep it always online

def slave = new DumbSlave(name, null, remoteFS,
                          numExecutors.toString(),
                          mode, labels,
                          launcher, retention,
                          Collections.emptyList())

Jenkins.instance.addNode(slave)
println "Node '${name}' added – start the agent with:\njava -jar agent.jar -jnlpUrl http://<master>/computer/${name}/jenkins-agent.jnlp -secret <secret>"

To launch the agent manually from the command line:


# 1. Download the agent jar from the master

curl -O http://jenkins.example.com/jnlpJars/agent.jar

# 2. Start the agent, letting it fetch the JNLP URL automatically

java -jar agent.jar -jnlpUrl http://jenkins.example.com/computer/my‑node/jenkins-agent.jnlp -secret <agent‑secret>

To use the WebSocket transport:

java -jar agent.jar -jnlpUrl http://jenkins.example.com/computer/my‑node/jenkins-agent.jnlp \
                    -webSocket -secret <agent‑secret>

Summary

  • Node/Slave stores static agent configuration, while Computer/SlaveComputer manages the live runtime state and executors.
  • JnlpSlaveAgentProtocol4 provides the default modern protocol for master-agent communication, replacing the legacy JNLP1 implementation.
  • JNLPLauncher.launch() constructs the agent command line, downloads required jars, and initiates the connection back to the master.
  • SlaveComputer wraps the inbound socket in a remoting Channel that the Jenkins Queue uses to dispatch builds and stream logs.
  • Security is enforced via a per-node secret and optional SSL/TLS; WebSocket mode (available since Jenkins 2.263) can improve connectivity through restrictive firewalls.

Frequently Asked Questions

What is the difference between a Node and a Computer in Jenkins?

A Node—concretely hudson.model.Slave—represents the static definition of an agent, including its labels, remote root directory, and launch method. A Computer—concretely hudson.slaves.SlaveComputer—is the runtime counterpart that tracks whether the agent is online, how many executors are idle, and holds the active remoting Channel.

How does JNLPLauncher differ from SSH-based launchers?

JNLPLauncher requires the agent to initiate the connection back to the master by requesting the JNLP file and opening a TCP socket. In contrast, SSH launchers such as hudson.plugins.sshslaves.SSHLauncher push the agent start command from the master to the remote host over SSH. JNLP is preferable when agents reside behind NAT or firewalls that block inbound SSH.

What JNLP protocol version does Jenkins use by default?

Modern Jenkins versions default to JNLP4-connect, implemented in jenkins.slaves.JnlpSlaveAgentProtocol4. The legacy jenkins.slaves.JnlpSlaveAgentProtocol (JNLP1) has been removed from recent releases.

Can a JNLP agent reconnect automatically if the network drops?

Yes. JNLPLauncher and the underlying remoting engine support automatic reconnection. If the TCP or WebSocket channel drops, the agent process can retry the connection using the same JNLP URL and secret until the master responds, minimizing manual intervention for transient network failures.

Have a question about this repo?

These articles cover the highlights, but your codebase questions are specific. Give your agent direct access to the source. Share this with your agent to get started:

Share the following with your agent to get started:
curl -s "https://instagit.com/install.md"

Works with
Claude Codex Cursor VS Code OpenClaw Any MCP Client

Maintain an open-source project? Get it listed too →