Azure Compute Batch Java
MicrosoftOfficialCreated by Microsoft
- Skill
- Tool integration
- Cloud and DevOps
- MIT
- No issues found
AutoGineer summary
Written by AutoGineer from the skill’s own files, not by the author
The Azure Batch SDK for Java provides a programmatic interface to interact with Azure Batch services. It enables developers to manage compute pools, define job schedules, and execute parallel or high-performance computing tasks across collections of virtual machine nodes. The library supports both synchronous and asynchronous client patterns and offers multiple authentication methods, including Microsoft Entra ID and shared key credentials.
What it does
- Creates and manages compute pools of virtual machines
- Defines and schedules batch jobs and individual tasks
- Supports task collection submission for efficient processing
- Provides monitoring for job progress and task execution status
- Enables node management including reboots and remote access
- Supports auto-scaling configurations for compute resources
When to use it
- When building Java applications that require large-scale parallel processing
- When automating high-performance computing workflows on Azure
- When you need to dynamically manage compute resources based on task volume
- When integrating batch job scheduling into existing Java services
Advantages
- Native Java support for Azure Batch service operations
- Flexible authentication options including Entra ID
- Support for both synchronous and asynchronous programming models
- Comprehensive control over task lifecycle and exit conditions
Usage examples
- “How do I create a new batch pool using the Java SDK?”
- The agent provides a code snippet using BatchPoolCreateParameters to define pool ID, VM configuration, and node counts, then calls createPool on the BatchClient.
- “Show me how to submit multiple tasks to an Azure Batch job in Java.”
- The agent demonstrates using createTaskCollection or createTasks to batch multiple BatchTaskCreateParameters objects into a single request.
- “How can I retrieve the output of a specific task in Azure Batch?”
- The agent shows how to use getTaskFile with the job ID, task ID, and file name to retrieve task output as BinaryData.
- “How do I authenticate the BatchClient using Entra ID?”
- The agent provides a code example using DefaultAzureCredentialBuilder to configure the BatchClientBuilder for secure authentication.
Install
Download the skill as a ZIP:
https://mp-staging.autogineer.com/agent-skills/microsoft/azure-compute-batch-java/downloadUnzip it into the cross-client skills folder of your project:
mkdir -p .agents/skills && unzip azure-compute-batch-java.zip -d .agents/skills
Documentation by Microsoft
Azure Batch SDK for Java
Client library for running large-scale parallel and high-performance computing (HPC) batch jobs in Azure.
Installation
<dependency>
<groupId>com.azure</groupId>
<artifactId>azure-compute-batch</artifactId>
<version>1.0.0-beta.5</version>
</dependency>Prerequisites
Azure Batch account
Pool configured with compute nodes
Azure subscription
Environment Variables
AZURE_BATCH_ENDPOINT=https://<account>.<region>.batch.azure.com # Required for all auth methods
AZURE_BATCH_ACCOUNT=<account-name> # Only required for shared key auth
AZURE_BATCH_ACCESS_KEY=<account-key> # Only required for shared key auth
AZURE_TOKEN_CREDENTIALS=prod # Required only if DefaultAzureCredential is used in productionClient Creation
With Microsoft Entra ID (Recommended)
import com.azure.compute.batch.BatchClient;
import com.azure.compute.batch.BatchClientBuilder;
import com.azure.core.credential.TokenCredential;
import com.azure.identity.AzureIdentityEnvVars;
import com.azure.identity.DefaultAzureCredentialBuilder;
import com.azure.identity.ManagedIdentityCredentialBuilder;
// Local dev: DefaultAzureCredential. Production: set AZURE_TOKEN_CREDENTIALS=prod or AZURE_TOKEN_CREDENTIALS=<specific_credential>
TokenCredential credential = new DefaultAzureCredentialBuilder()
.requireEnvVars(AzureIdentityEnvVars.AZURE_TOKEN_CREDENTIALS)
.build();
// Or use a specific credential directly in production:
// See https://learn.microsoft.com/java/api/overview/azure/identity-readme?view=azure-java-stable#credential-classes
// TokenCredential credential = new ManagedIdentityCredentialBuilder().build();
BatchClient batchClient = new BatchClientBuilder()
.credential(credential)
.endpoint(System.getenv("AZURE_BATCH_ENDPOINT"))
.buildClient();Async Client
import com.azure.compute.batch.BatchAsyncClient;
BatchAsyncClient batchAsyncClient = new BatchClientBuilder()
.credential(credential)
.endpoint(System.getenv("AZURE_BATCH_ENDPOINT"))
.buildAsyncClient();With Shared Key Credentials
import com.azure.core.credential.AzureNamedKeyCredential;
String accountName = System.getenv("AZURE_BATCH_ACCOUNT");
String accountKey = System.getenv("AZURE_BATCH_ACCESS_KEY");
AzureNamedKeyCredential sharedKeyCreds = new AzureNamedKeyCredential(accountName, accountKey);
BatchClient batchClient = new BatchClientBuilder()
.credential(sharedKeyCreds)
.endpoint(System.getenv("AZURE_BATCH_ENDPOINT"))
.buildClient();Key Concepts
| Concept | Description |
|---|---|
| Pool | Collection of compute nodes that run tasks |
| Job | Logical grouping of tasks |
| Task | Unit of computation (command/script) |
| Node | VM that executes tasks |
| Job Schedule | Recurring job creation |
Pool Operations
Create Pool
import com.azure.compute.batch.models.*;
batchClient.createPool(new BatchPoolCreateParameters("myPoolId", "STANDARD_DC2s_V2")
.setVirtualMachineConfiguration(
new VirtualMachineConfiguration(
new BatchVmImageReference()
.setPublisher("Canonical")
.setOffer("UbuntuServer")
.setSku("22_04-lts")
.setVersion("latest"),
"batch.node.ubuntu 22.04"))
.setTargetDedicatedNodes(2)
.setTargetLowPriorityNodes(0), null);Get Pool
BatchPool pool = batchClient.getPool("myPoolId");
System.out.println("Pool state: " + pool.getState());
System.out.println("Current dedicated nodes: " + pool.getCurrentDedicatedNodes());List Pools
import com.azure.core.http.rest.PagedIterable;
PagedIterable<BatchPool> pools = batchClient.listPools();
for (BatchPool pool : pools) {
System.out.println("Pool: " + pool.getId() + ", State: " + pool.getState());
}Resize Pool
import com.azure.core.util.polling.SyncPoller;
BatchPoolResizeParameters resizeParams = new BatchPoolResizeParameters()
.setTargetDedicatedNodes(4)
.setTargetLowPriorityNodes(2);
SyncPoller<BatchPool, BatchPool> poller = batchClient.beginResizePool("myPoolId", resizeParams);
poller.waitForCompletion();
BatchPool resizedPool = poller.getFinalResult();Enable AutoScale
BatchPoolEnableAutoScaleParameters autoScaleParams = new BatchPoolEnableAutoScaleParameters()
.setAutoScaleEvaluationInterval(Duration.ofMinutes(5))
.setAutoScaleFormula("$TargetDedicatedNodes = min(10, $PendingTasks.GetSample(TimeInterval_Minute * 5));");
batchClient.enablePoolAutoScale("myPoolId", autoScaleParams);Delete Pool
SyncPoller<BatchPool, Void> deletePoller = batchClient.beginDeletePool("myPoolId");
deletePoller.waitForCompletion();Job Operations
Create Job
batchClient.createJob(
new BatchJobCreateParameters("myJobId", new BatchPoolInfo().setPoolId("myPoolId"))
.setPriority(100)
.setConstraints(new BatchJobConstraints()
.setMaxWallClockTime(Duration.ofHours(24))
.setMaxTaskRetryCount(3)),
null);Get Job
BatchJob job = batchClient.getJob("myJobId", null, null);
System.out.println("Job state: " + job.getState());List Jobs
PagedIterable<BatchJob> jobs = batchClient.listJobs(new BatchJobsListOptions());
for (BatchJob job : jobs) {
System.out.println("Job: " + job.getId() + ", State: " + job.getState());
}Get Task Counts
BatchTaskCountsResult counts = batchClient.getJobTaskCounts("myJobId");
System.out.println("Active: " + counts.getTaskCounts().getActive());
System.out.println("Running: " + counts.getTaskCounts().getRunning());
System.out.println("Completed: " + counts.getTaskCounts().getCompleted());Terminate Job
BatchJobTerminateParameters terminateParams = new BatchJobTerminateParameters()
.setTerminationReason("Manual termination");
BatchJobTerminateOptions options = new BatchJobTerminateOptions().setParameters(terminateParams);
SyncPoller<BatchJob, BatchJob> poller = batchClient.beginTerminateJob("myJobId", options, null);
poller.waitForCompletion();Delete Job
SyncPoller<BatchJob, Void> deletePoller = batchClient.beginDeleteJob("myJobId");
deletePoller.waitForCompletion();Task Operations
Create Single Task
BatchTaskCreateParameters task = new BatchTaskCreateParameters("task1", "echo 'Hello World'");
batchClient.createTask("myJobId", task);Create Task with Exit Conditions
batchClient.createTask("myJobId", new BatchTaskCreateParameters("task2", "cmd /c exit 3")
.setExitConditions(new ExitConditions()
.setExitCodeRanges(Arrays.asList(
new ExitCodeRangeMapping(2, 4,
new ExitOptions().setJobAction(BatchJobActionKind.TERMINATE)))))
.setUserIdentity(new UserIdentity()
.setAutoUser(new AutoUserSpecification()
.setScope(AutoUserScope.TASK)
.setElevationLevel(ElevationLevel.NON_ADMIN))),
null);Create Task Collection (up to 100)
List<BatchTaskCreateParameters> taskList = Arrays.asList(
new BatchTaskCreateParameters("task1", "echo Task 1"),
new BatchTaskCreateParameters("task2", "echo Task 2"),
new BatchTaskCreateParameters("task3", "echo Task 3")
);
BatchTaskGroup taskGroup = new BatchTaskGroup(taskList);
BatchCreateTaskCollectionResult result = batchClient.createTaskCollection("myJobId", taskGroup);Create Many Tasks (no limit)
List<BatchTaskCreateParameters> tasks = new ArrayList<>();
for (int i = 0; i < 1000; i++) {
tasks.add(new BatchTaskCreateParameters("task" + i, "echo Task " + i));
}
batchClient.createTasks("myJobId", tasks);Get Task
BatchTask task = batchClient.getTask("myJobId", "task1");
System.out.println("Task state: " + task.getState());
System.out.println("Exit code: " + task.getExecutionInfo().getExitCode());List Tasks
PagedIterable<BatchTask> tasks = batchClient.listTasks("myJobId");
for (BatchTask task : tasks) {
System.out.println("Task: " + task.getId() + ", State: " + task.getState());
}Get Task Output
import com.azure.core.util.BinaryData;
import java.nio.charset.StandardCharsets;
BinaryData stdout = batchClient.getTaskFile("myJobId", "task1", "stdout.txt");
System.out.println(new String(stdout.toBytes(), StandardCharsets.UTF_8));Terminate Task
batchClient.terminateTask("myJobId", "task1", null, null);Node Operations
List Nodes
PagedIterable<BatchNode> nodes = batchClient.listNodes("myPoolId", new BatchNodesListOptions());
for (BatchNode node : nodes) {
System.out.println("Node: " + node.getId() + ", State: " + node.getState());
}Reboot Node
SyncPoller<BatchNode, BatchNode> rebootPoller = batchClient.beginRebootNode("myPoolId", "nodeId");
rebootPoller.waitForCompletion();Get Remote Login Settings
BatchNodeRemoteLoginSettings settings = batchClient.getNodeRemoteLoginSettings("myPoolId", "nodeId");
System.out.println("IP: " + settings.getRemoteLoginIpAddress());
System.out.println("Port: " + settings.getRemoteLoginPort());Job Schedule Operations
Create Job Schedule
batchClient.createJobSchedule(new BatchJobScheduleCreateParameters("myScheduleId",
new BatchJobScheduleConfiguration()
.setRecurrenceInterval(Duration.ofHours(6))
.setDoNotRunUntil(OffsetDateTime.now().plusDays(1)),
new BatchJobSpecification(new BatchPoolInfo().setPoolId("myPoolId"))
.setPriority(50)),
null);Get Job Schedule
BatchJobSchedule schedule = batchClient.getJobSchedule("myScheduleId");
System.out.println("Schedule state: " + schedule.getState());Error Handling
import com.azure.compute.batch.models.BatchErrorException;
import com.azure.compute.batch.models.BatchError;
try {
batchClient.getPool("nonexistent-pool");
} catch (BatchErrorException e) {
BatchError error = e.getValue();
System.err.println("Error code: " + error.getCode());
System.err.println("Message: " + error.getMessage().getValue());
if ("PoolNotFound".equals(error.getCode())) {
System.err.println("The specified pool does not exist.");
}
}Best Practices
Use Entra ID — Preferred over shared key for authentication
Use management SDK for pools —
azure-resourcemanager-batchsupports managed identitiesBatch task creation — Use
createTaskCollectionorcreateTasksfor multiple tasksHandle LRO properly — Pool resize, delete operations are long-running
Monitor task counts — Use
getJobTaskCountsto track progressSet constraints — Configure
maxWallClockTimeandmaxTaskRetryCountUse low-priority nodes — Cost savings for fault-tolerant workloads
Enable autoscale — Dynamically adjust pool size based on workload
Reference Links
Files
- ATTRIBUTION.mdAdded by AutoGineer979 B
- LICENSELicence file added by AutoGineer1.1 KiB
- SKILL.md11.6 KiB
- references/examples.md28.6 KiB
references/examples.md
Azure Batch Java SDK - Examples
Comprehensive code examples for the Azure Batch SDK for Java.
Table of Contents
Maven Dependency
Client Creation
Pool Operations
Job Operations
Task Operations
Node Operations
Job Schedule Operations
Error Handling
Complete Application Example
Maven Dependency
<dependency>
<groupId>com.azure</groupId>
<artifactId>azure-compute-batch</artifactId>
<version>1.0.0-beta.5</version>
</dependency>
<!-- For DefaultAzureCredential -->
<dependency>
<groupId>com.azure</groupId>
<artifactId>azure-identity</artifactId>
<version>1.14.2</version>
</dependency>Client Creation
With Microsoft Entra ID (Recommended)
import com.azure.compute.batch.BatchClient;
import com.azure.compute.batch.BatchClientBuilder;
import com.azure.identity.DefaultAzureCredentialBuilder;
String endpoint = System.getenv("AZURE_BATCH_ENDPOINT");
BatchClient batchClient = new BatchClientBuilder()
.credential(new DefaultAzureCredentialBuilder().build())
.endpoint(endpoint)
.buildClient();Async Client
import com.azure.compute.batch.BatchAsyncClient;
BatchAsyncClient batchAsyncClient = new BatchClientBuilder()
.credential(new DefaultAzureCredentialBuilder().build())
.endpoint(endpoint)
.buildAsyncClient();With Shared Key Credentials
import com.azure.core.credential.AzureNamedKeyCredential;
String accountName = System.getenv("AZURE_BATCH_ACCOUNT");
String accountKey = System.getenv("AZURE_BATCH_ACCESS_KEY");
AzureNamedKeyCredential sharedKeyCreds = new AzureNamedKeyCredential(accountName, accountKey);
BatchClient batchClient = new BatchClientBuilder()
.credential(sharedKeyCreds)
.endpoint(endpoint)
.buildClient();Pool Operations
Create Pool
import com.azure.compute.batch.models.*;
batchClient.createPool(new BatchPoolCreateParameters("myPoolId", "STANDARD_DC2s_v2")
.setVirtualMachineConfiguration(
new VirtualMachineConfiguration(
new BatchVmImageReference()
.setPublisher("Canonical")
.setOffer("UbuntuServer")
.setSku("22_04-lts")
.setVersion("latest"),
"batch.node.ubuntu 22.04"))
.setTargetDedicatedNodes(2)
.setTargetLowPriorityNodes(0)
.setTaskSlotsPerNode(4)
.setTaskSchedulingPolicy(new TaskSchedulingPolicy(ComputeNodeFillType.SPREAD)), null);
System.out.println("Pool created: myPoolId");Create Pool with Start Task
batchClient.createPool(new BatchPoolCreateParameters("myPoolWithStartTask", "STANDARD_D2s_v3")
.setVirtualMachineConfiguration(
new VirtualMachineConfiguration(
new BatchVmImageReference()
.setPublisher("Canonical")
.setOffer("0001-com-ubuntu-server-jammy")
.setSku("22_04-lts")
.setVersion("latest"),
"batch.node.ubuntu 22.04"))
.setTargetDedicatedNodes(2)
.setStartTask(new StartTask("apt-get update && apt-get install -y python3")
.setUserIdentity(new UserIdentity()
.setAutoUser(new AutoUserSpecification()
.setScope(AutoUserScope.POOL)
.setElevationLevel(ElevationLevel.ADMIN)))
.setMaxTaskRetryCount(2)
.setWaitForSuccess(true)), null);Create Pool with Application Packages
import java.util.Arrays;
batchClient.createPool(new BatchPoolCreateParameters("appPackagePool", "STANDARD_D2s_v3")
.setVirtualMachineConfiguration(
new VirtualMachineConfiguration(
new BatchVmImageReference()
.setPublisher("MicrosoftWindowsServer")
.setOffer("WindowsServer")
.setSku("2022-datacenter")
.setVersion("latest"),
"batch.node.windows amd64"))
.setTargetDedicatedNodes(2)
.setApplicationPackageReferences(Arrays.asList(
new ApplicationPackageReference("myApp").setVersion("1.0"),
new ApplicationPackageReference("myDependency").setVersion("2.0"))), null);Get Pool
BatchPool pool = batchClient.getPool("myPoolId");
System.out.println("=== Pool Details ===");
System.out.println("Pool ID: " + pool.getId());
System.out.println("State: " + pool.getState());
System.out.println("Allocation State: " + pool.getAllocationState());
System.out.println("VM Size: " + pool.getVmSize());
System.out.println("Current Dedicated Nodes: " + pool.getCurrentDedicatedNodes());
System.out.println("Current Low Priority Nodes: " + pool.getCurrentLowPriorityNodes());
System.out.println("Target Dedicated Nodes: " + pool.getTargetDedicatedNodes());List Pools
import com.azure.core.http.rest.PagedIterable;
PagedIterable<BatchPool> pools = batchClient.listPools();
System.out.println("=== Available Pools ===");
for (BatchPool p : pools) {
System.out.printf("Pool: %s, State: %s, Nodes: %d/%d%n",
p.getId(),
p.getState(),
p.getCurrentDedicatedNodes(),
p.getTargetDedicatedNodes());
}Resize Pool
import com.azure.core.util.polling.SyncPoller;
import java.time.Duration;
BatchPoolResizeParameters resizeParams = new BatchPoolResizeParameters()
.setTargetDedicatedNodes(4)
.setTargetLowPriorityNodes(2)
.setResizeTimeout(Duration.ofMinutes(15))
.setNodeDeallocationOption(BatchNodeDeallocationOption.TASK_COMPLETION);
SyncPoller<BatchPool, BatchPool> poller = batchClient.beginResizePool("myPoolId", resizeParams);
poller.waitForCompletion();
BatchPool resizedPool = poller.getFinalResult();
System.out.println("Pool resized. New target: " + resizedPool.getTargetDedicatedNodes());Enable AutoScale
String autoScaleFormula = """
// Target 1 dedicated node per 5 pending tasks
pendingTasks = $PendingTasks.GetSample(TimeInterval_Minute * 5);
$TargetDedicatedNodes = min(10, max(1, pendingTasks / 5));
$TargetLowPriorityNodes = 0;
""";
BatchPoolEnableAutoScaleParameters autoScaleParams = new BatchPoolEnableAutoScaleParameters()
.setAutoScaleEvaluationInterval(Duration.ofMinutes(5))
.setAutoScaleFormula(autoScaleFormula);
batchClient.enablePoolAutoScale("myPoolId", autoScaleParams);
System.out.println("AutoScale enabled");Disable AutoScale
batchClient.disablePoolAutoScale("myPoolId");
System.out.println("AutoScale disabled");Delete Pool
SyncPoller<BatchPool, Void> deletePoller = batchClient.beginDeletePool("myPoolId");
deletePoller.waitForCompletion();
System.out.println("Pool deleted");Job Operations
Create Job
batchClient.createJob(
new BatchJobCreateParameters("myJobId", new BatchPoolInfo().setPoolId("myPoolId"))
.setDisplayName("My Batch Job")
.setPriority(100)
.setConstraints(new BatchJobConstraints()
.setMaxWallClockTime(Duration.ofHours(24))
.setMaxTaskRetryCount(3))
.setOnAllTasksComplete(OnAllBatchTasksComplete.TERMINATE_JOB)
.setOnTaskFailure(OnBatchTaskFailure.NO_ACTION),
null);
System.out.println("Job created: myJobId");Create Job with Job Manager Task
batchClient.createJob(
new BatchJobCreateParameters("managedJobId", new BatchPoolInfo().setPoolId("myPoolId"))
.setJobManagerTask(new BatchJobManagerTask("manager", "python3 manage_tasks.py")
.setDisplayName("Job Manager")
.setKillJobOnCompletion(true)
.setRunExclusive(true)),
null);Get Job
BatchJob job = batchClient.getJob("myJobId", null, null);
System.out.println("=== Job Details ===");
System.out.println("Job ID: " + job.getId());
System.out.println("State: " + job.getState());
System.out.println("Priority: " + job.getPriority());
System.out.println("Pool: " + job.getPoolInfo().getPoolId());
System.out.println("Created: " + job.getCreationTime());List Jobs
PagedIterable<BatchJob> jobs = batchClient.listJobs(new BatchJobsListOptions());
System.out.println("=== Active Jobs ===");
for (BatchJob j : jobs) {
System.out.printf("Job: %s, State: %s, Pool: %s%n",
j.getId(),
j.getState(),
j.getPoolInfo().getPoolId());
}Get Task Counts
BatchTaskCountsResult counts = batchClient.getJobTaskCounts("myJobId");
System.out.println("=== Task Counts ===");
System.out.println("Active: " + counts.getTaskCounts().getActive());
System.out.println("Running: " + counts.getTaskCounts().getRunning());
System.out.println("Completed: " + counts.getTaskCounts().getCompleted());
System.out.println("Succeeded: " + counts.getTaskCounts().getSucceeded());
System.out.println("Failed: " + counts.getTaskCounts().getFailed());Update Job
BatchJobUpdateParameters updateParams = new BatchJobUpdateParameters()
.setPriority(200)
.setConstraints(new BatchJobConstraints()
.setMaxWallClockTime(Duration.ofHours(48)));
batchClient.updateJob("myJobId", updateParams);
System.out.println("Job updated");Terminate Job
BatchJobTerminateParameters terminateParams = new BatchJobTerminateParameters()
.setTerminationReason("Manual termination - job complete");
BatchJobTerminateOptions options = new BatchJobTerminateOptions().setParameters(terminateParams);
SyncPoller<BatchJob, BatchJob> poller = batchClient.beginTerminateJob("myJobId", options, null);
poller.waitForCompletion();
System.out.println("Job terminated");Delete Job
SyncPoller<BatchJob, Void> deletePoller = batchClient.beginDeleteJob("myJobId");
deletePoller.waitForCompletion();
System.out.println("Job deleted");Task Operations
Create Single Task
BatchTaskCreateParameters task = new BatchTaskCreateParameters("task1", "echo 'Hello World'");
batchClient.createTask("myJobId", task);
System.out.println("Task created: task1");Create Task with Resource Files
import java.util.Arrays;
BatchTaskCreateParameters task = new BatchTaskCreateParameters("processDataTask",
"python3 process.py input.csv output.csv")
.setResourceFiles(Arrays.asList(
new ResourceFile()
.setHttpUrl("https://storage.blob.core.windows.net/container/process.py?sasToken")
.setFilePath("process.py"),
new ResourceFile()
.setHttpUrl("https://storage.blob.core.windows.net/container/input.csv?sasToken")
.setFilePath("input.csv")))
.setOutputFiles(Arrays.asList(
new OutputFile("output.csv")
.setDestination(new OutputFileDestination()
.setContainer(new OutputFileBlobContainerDestination(
"https://storage.blob.core.windows.net/results?sasToken")
.setPath("results/output.csv")))
.setUploadOptions(new OutputFileUploadOptions()
.setUploadCondition(OutputFileUploadCondition.TASK_SUCCESS))));
batchClient.createTask("myJobId", task);Create Task with Exit Conditions
BatchTaskCreateParameters task = new BatchTaskCreateParameters("conditionalTask", "cmd /c exit 3")
.setExitConditions(new ExitConditions()
.setExitCodeRanges(Arrays.asList(
new ExitCodeRangeMapping(0, 0,
new ExitOptions().setJobAction(BatchJobActionKind.NONE)),
new ExitCodeRangeMapping(1, 5,
new ExitOptions().setJobAction(BatchJobActionKind.TERMINATE)),
new ExitCodeRangeMapping(6, 10,
new ExitOptions().setDependencyAction(DependencyActionKind.BLOCK))))
.setDefault(new ExitOptions()
.setJobAction(BatchJobActionKind.NONE)));
batchClient.createTask("myJobId", task);Create Task with User Identity
BatchTaskCreateParameters task = new BatchTaskCreateParameters("adminTask", "sudo apt-get update")
.setUserIdentity(new UserIdentity()
.setAutoUser(new AutoUserSpecification()
.setScope(AutoUserScope.TASK)
.setElevationLevel(ElevationLevel.ADMIN)));
batchClient.createTask("myJobId", task);Create Task Collection (up to 100)
List<BatchTaskCreateParameters> taskList = Arrays.asList(
new BatchTaskCreateParameters("task1", "echo Task 1"),
new BatchTaskCreateParameters("task2", "echo Task 2"),
new BatchTaskCreateParameters("task3", "echo Task 3"),
new BatchTaskCreateParameters("task4", "echo Task 4"),
new BatchTaskCreateParameters("task5", "echo Task 5")
);
BatchTaskGroup taskGroup = new BatchTaskGroup(taskList);
BatchCreateTaskCollectionResult result = batchClient.createTaskCollection("myJobId", taskGroup);
System.out.printf("Created %d tasks%n", result.getValue().size());Create Many Tasks (no limit)
import java.util.ArrayList;
List<BatchTaskCreateParameters> tasks = new ArrayList<>();
for (int i = 0; i < 1000; i++) {
tasks.add(new BatchTaskCreateParameters("task" + i,
String.format("python3 process.py --partition %d", i)));
}
batchClient.createTasks("myJobId", tasks);
System.out.printf("Created %d tasks%n", tasks.size());Create Task with Dependencies
// First, create prerequisite tasks
batchClient.createTask("myJobId", new BatchTaskCreateParameters("setup", "setup.sh"));
batchClient.createTask("myJobId", new BatchTaskCreateParameters("download", "download.sh"));
// Create dependent task
BatchTaskCreateParameters dependentTask = new BatchTaskCreateParameters("process", "process.sh")
.setDependsOn(new BatchTaskDependencies()
.setTaskIds(Arrays.asList("setup", "download")));
batchClient.createTask("myJobId", dependentTask);Get Task
BatchTask task = batchClient.getTask("myJobId", "task1");
System.out.println("=== Task Details ===");
System.out.println("Task ID: " + task.getId());
System.out.println("State: " + task.getState());
System.out.println("Command: " + task.getCommandLine());
if (task.getExecutionInfo() != null) {
System.out.println("Exit Code: " + task.getExecutionInfo().getExitCode());
System.out.println("Start Time: " + task.getExecutionInfo().getStartTime());
System.out.println("End Time: " + task.getExecutionInfo().getEndTime());
if (task.getExecutionInfo().getFailureInfo() != null) {
System.out.println("Failure: " + task.getExecutionInfo().getFailureInfo().getMessage());
}
}List Tasks
PagedIterable<BatchTask> tasks = batchClient.listTasks("myJobId");
System.out.println("=== Tasks ===");
for (BatchTask t : tasks) {
System.out.printf("Task: %s, State: %s%n", t.getId(), t.getState());
}Get Task Output
import com.azure.core.util.BinaryData;
import java.nio.charset.StandardCharsets;
// Get stdout
BinaryData stdout = batchClient.getTaskFile("myJobId", "task1", "stdout.txt");
System.out.println("=== stdout ===");
System.out.println(new String(stdout.toBytes(), StandardCharsets.UTF_8));
// Get stderr
BinaryData stderr = batchClient.getTaskFile("myJobId", "task1", "stderr.txt");
System.out.println("=== stderr ===");
System.out.println(new String(stderr.toBytes(), StandardCharsets.UTF_8));List Task Files
PagedIterable<BatchNodeFile> files = batchClient.listTaskFiles("myJobId", "task1");
System.out.println("=== Task Files ===");
for (BatchNodeFile file : files) {
System.out.printf("File: %s, Size: %d bytes%n",
file.getName(),
file.getProperties().getContentLength());
}Terminate Task
batchClient.terminateTask("myJobId", "task1", null, null);
System.out.println("Task terminated");Delete Task
batchClient.deleteTask("myJobId", "task1");
System.out.println("Task deleted");Node Operations
List Nodes
PagedIterable<BatchNode> nodes = batchClient.listNodes("myPoolId", new BatchNodesListOptions());
System.out.println("=== Compute Nodes ===");
for (BatchNode node : nodes) {
System.out.printf("Node: %s, State: %s, IP: %s%n",
node.getId(),
node.getState(),
node.getIpAddress());
}Get Node
BatchNode node = batchClient.getNode("myPoolId", "nodeId");
System.out.println("=== Node Details ===");
System.out.println("Node ID: " + node.getId());
System.out.println("State: " + node.getState());
System.out.println("IP Address: " + node.getIpAddress());
System.out.println("VM Size: " + node.getVmSize());
System.out.println("Total Tasks Run: " + node.getTotalTasksRun());
System.out.println("Running Tasks: " + node.getRunningTasksCount());Reboot Node
BatchNodeRebootParameters rebootParams = new BatchNodeRebootParameters()
.setNodeRebootOption(BatchNodeRebootOption.TASK_COMPLETION);
SyncPoller<BatchNode, BatchNode> rebootPoller =
batchClient.beginRebootNode("myPoolId", "nodeId", rebootParams);
rebootPoller.waitForCompletion();
System.out.println("Node rebooted");Get Remote Login Settings
BatchNodeRemoteLoginSettings settings = batchClient.getNodeRemoteLoginSettings("myPoolId", "nodeId");
System.out.println("=== Remote Login Settings ===");
System.out.println("IP Address: " + settings.getRemoteLoginIpAddress());
System.out.println("Port: " + settings.getRemoteLoginPort());
// SSH command
System.out.printf("SSH: ssh -p %d user@%s%n",
settings.getRemoteLoginPort(),
settings.getRemoteLoginIpAddress());Remove Node from Pool
BatchNodeRemoveParameters removeParams = new BatchNodeRemoveParameters(
Arrays.asList("nodeId1", "nodeId2"))
.setNodeDeallocationOption(BatchNodeDeallocationOption.TASK_COMPLETION)
.setResizeTimeout(Duration.ofMinutes(15));
batchClient.removeNodes("myPoolId", removeParams);
System.out.println("Nodes removal initiated");Job Schedule Operations
Create Job Schedule
import java.time.OffsetDateTime;
batchClient.createJobSchedule(new BatchJobScheduleCreateParameters("dailySchedule",
new BatchJobScheduleConfiguration()
.setRecurrenceInterval(Duration.ofHours(24))
.setDoNotRunUntil(OffsetDateTime.now().plusHours(1))
.setDoNotRunAfter(OffsetDateTime.now().plusDays(30)),
new BatchJobSpecification(new BatchPoolInfo().setPoolId("myPoolId"))
.setDisplayName("Daily Processing Job")
.setPriority(100)
.setConstraints(new BatchJobConstraints()
.setMaxTaskRetryCount(3))),
null);
System.out.println("Job schedule created: dailySchedule");Get Job Schedule
BatchJobSchedule schedule = batchClient.getJobSchedule("dailySchedule");
System.out.println("=== Job Schedule Details ===");
System.out.println("Schedule ID: " + schedule.getId());
System.out.println("State: " + schedule.getState());
System.out.println("Next Run: " + schedule.getExecutionInfo().getNextRunTime());
System.out.println("Recent Jobs: " + schedule.getExecutionInfo().getRecentJob());List Job Schedules
PagedIterable<BatchJobSchedule> schedules = batchClient.listJobSchedules();
System.out.println("=== Job Schedules ===");
for (BatchJobSchedule s : schedules) {
System.out.printf("Schedule: %s, State: %s%n", s.getId(), s.getState());
}Disable Job Schedule
batchClient.disableJobSchedule("dailySchedule");
System.out.println("Job schedule disabled");Enable Job Schedule
batchClient.enableJobSchedule("dailySchedule");
System.out.println("Job schedule enabled");Terminate Job Schedule
batchClient.terminateJobSchedule("dailySchedule");
System.out.println("Job schedule terminated");Delete Job Schedule
batchClient.deleteJobSchedule("dailySchedule");
System.out.println("Job schedule deleted");Error Handling
import com.azure.compute.batch.models.BatchErrorException;
import com.azure.compute.batch.models.BatchError;
try {
BatchPool pool = batchClient.getPool("nonexistent-pool");
} catch (BatchErrorException e) {
BatchError error = e.getValue();
System.err.println("=== Batch Error ===");
System.err.println("Error code: " + error.getCode());
System.err.println("Message: " + error.getMessage().getValue());
// Handle specific errors
switch (error.getCode()) {
case "PoolNotFound":
System.err.println("The specified pool does not exist.");
break;
case "JobNotFound":
System.err.println("The specified job does not exist.");
break;
case "TaskNotFound":
System.err.println("The specified task does not exist.");
break;
case "PoolQuotaReached":
System.err.println("Pool quota exceeded. Delete unused pools or request quota increase.");
break;
case "ActiveJobAndScheduleQuotaReached":
System.err.println("Job quota exceeded.");
break;
default:
System.err.println("Unexpected error: " + error.getCode());
}
// Show additional details if available
if (error.getValues() != null) {
for (var detail : error.getValues()) {
System.err.printf(" %s: %s%n", detail.getKey(), detail.getValue());
}
}
}Complete Application Example
import com.azure.compute.batch.BatchClient;
import com.azure.compute.batch.BatchClientBuilder;
import com.azure.compute.batch.models.*;
import com.azure.core.http.rest.PagedIterable;
import com.azure.core.util.BinaryData;
import com.azure.identity.DefaultAzureCredentialBuilder;
import java.nio.charset.StandardCharsets;
import java.time.Duration;
import java.util.*;
public class BatchJobRunner {
private final BatchClient client;
private final String poolId;
public BatchJobRunner(String poolId) {
this.client = new BatchClientBuilder()
.endpoint(System.getenv("AZURE_BATCH_ENDPOINT"))
.credential(new DefaultAzureCredentialBuilder().build())
.buildClient();
this.poolId = poolId;
}
public void ensurePoolExists() {
try {
BatchPool pool = client.getPool(poolId);
System.out.println("Pool exists: " + pool.getId());
} catch (BatchErrorException e) {
if ("PoolNotFound".equals(e.getValue().getCode())) {
createPool();
} else {
throw e;
}
}
}
private void createPool() {
System.out.println("Creating pool: " + poolId);
client.createPool(new BatchPoolCreateParameters(poolId, "STANDARD_D2s_v3")
.setVirtualMachineConfiguration(
new VirtualMachineConfiguration(
new BatchVmImageReference()
.setPublisher("Canonical")
.setOffer("0001-com-ubuntu-server-jammy")
.setSku("22_04-lts")
.setVersion("latest"),
"batch.node.ubuntu 22.04"))
.setTargetDedicatedNodes(2)
.setTaskSlotsPerNode(4), null);
// Wait for pool to be ready
waitForPoolReady();
}
private void waitForPoolReady() {
System.out.println("Waiting for pool to be ready...");
while (true) {
BatchPool pool = client.getPool(poolId);
if (pool.getAllocationState() == AllocationState.STEADY
&& pool.getCurrentDedicatedNodes() > 0) {
System.out.println("Pool is ready with " + pool.getCurrentDedicatedNodes() + " nodes");
break;
}
try {
Thread.sleep(10000);
} catch (InterruptedException e) {
Thread.currentThread().interrupt();
throw new RuntimeException(e);
}
}
}
public String runJob(String jobId, List<String> commands) {
// Create job
client.createJob(
new BatchJobCreateParameters(jobId, new BatchPoolInfo().setPoolId(poolId))
.setOnAllTasksComplete(OnAllBatchTasksComplete.TERMINATE_JOB),
null);
System.out.println("Job created: " + jobId);
// Create tasks
List<BatchTaskCreateParameters> tasks = new ArrayList<>();
for (int i = 0; i < commands.size(); i++) {
tasks.add(new BatchTaskCreateParameters("task" + i, commands.get(i)));
}
client.createTasks(jobId, tasks);
System.out.println("Created " + tasks.size() + " tasks");
// Wait for completion
waitForJobComplete(jobId);
return jobId;
}
private void waitForJobComplete(String jobId) {
System.out.println("Waiting for job to complete...");
while (true) {
BatchJob job = client.getJob(jobId, null, null);
if (job.getState() == BatchJobState.COMPLETED) {
System.out.println("Job completed");
break;
} else if (job.getState() == BatchJobState.DISABLED
|| job.getState() == BatchJobState.TERMINATING) {
throw new RuntimeException("Job failed or was terminated");
}
// Show progress
BatchTaskCountsResult counts = client.getJobTaskCounts(jobId);
System.out.printf("Progress: %d/%d tasks completed%n",
counts.getTaskCounts().getCompleted(),
counts.getTaskCounts().getActive() + counts.getTaskCounts().getRunning()
+ counts.getTaskCounts().getCompleted());
try {
Thread.sleep(5000);
} catch (InterruptedException e) {
Thread.currentThread().interrupt();
throw new RuntimeException(e);
}
}
}
public Map<String, String> getTaskOutputs(String jobId) {
Map<String, String> outputs = new HashMap<>();
PagedIterable<BatchTask> tasks = client.listTasks(jobId);
for (BatchTask task : tasks) {
try {
BinaryData stdout = client.getTaskFile(jobId, task.getId(), "stdout.txt");
outputs.put(task.getId(), new String(stdout.toBytes(), StandardCharsets.UTF_8));
} catch (Exception e) {
outputs.put(task.getId(), "Error: " + e.getMessage());
}
}
return outputs;
}
public void cleanup(String jobId) {
try {
client.beginDeleteJob(jobId).waitForCompletion();
System.out.println("Job deleted: " + jobId);
} catch (Exception e) {
System.err.println("Failed to delete job: " + e.getMessage());
}
}
public static void main(String[] args) {
BatchJobRunner runner = new BatchJobRunner("my-batch-pool");
try {
// Ensure pool exists
runner.ensurePoolExists();
// Run job with tasks
List<String> commands = Arrays.asList(
"echo 'Processing partition 1' && sleep 5",
"echo 'Processing partition 2' && sleep 5",
"echo 'Processing partition 3' && sleep 5",
"echo 'Processing partition 4' && sleep 5"
);
String jobId = "job-" + System.currentTimeMillis();
runner.runJob(jobId, commands);
// Get outputs
Map<String, String> outputs = runner.getTaskOutputs(jobId);
System.out.println("\n=== Task Outputs ===");
outputs.forEach((taskId, output) -> {
System.out.printf("%s: %s%n", taskId, output.trim());
});
// Cleanup
runner.cleanup(jobId);
} catch (Exception e) {
System.err.println("Error: " + e.getMessage());
e.printStackTrace();
}
}
}Environment Variables
AZURE_BATCH_ENDPOINT=https://<account>.<region>.batch.azure.com
AZURE_BATCH_ACCOUNT=<account-name>
AZURE_BATCH_ACCESS_KEY=<account-key>
# For DefaultAzureCredential
AZURE_CLIENT_ID=<service-principal-client-id>
AZURE_CLIENT_SECRET=<service-principal-secret>
AZURE_TENANT_ID=<tenant-id>Best Practices
Use Entra ID — Preferred over shared key for authentication
Use management SDK for pools —
azure-resourcemanager-batchsupports managed identitiesBatch task creation — Use
createTaskCollectionorcreateTasksfor multiple tasksHandle LRO properly — Pool resize, delete operations are long-running
Monitor task counts — Use
getJobTaskCountsto track progressSet constraints — Configure
maxWallClockTimeandmaxTaskRetryCountUse low-priority nodes — Cost savings for fault-tolerant workloads
Enable autoscale — Dynamically adjust pool size based on workload
Requirements and compatibility
Works with: Claude Code, Claude apps, OpenAI Codex, GitHub Copilot, Cursor, Gemini CLI, Kiro, OpenCode, Goose, Amp, Roo Code, JetBrains Junie, Factory Droid, Devin (ex-Windsurf), Mistral Vibe, OpenHands, Letta
“Works with” means the tool reads the open Agent Skills format; a skill written for one tool may use features others lack.
Needs: Needs Node.js
Security
No issues found by our static scan· No issues found
A static scan is not a guarantee. Skills are third-party content: review a skill before you let an agent use it.
Attribution and licence
- Created by
- Microsoft
- Publisher
- Microsoft (Official)
- Source
- microsoft/skills · .github/plugins/azure-sdk-java/skills/azure-compute-batch-java · commit 0696600
- Licence
- MIT License (redistribution allowed)
- LICENSE (added by AutoGineer from LICENSE)
- ATTRIBUTION.md (written by AutoGineer)
- Synced
AutoGineer is not affiliated with or endorsed by Microsoft.
Download ZIP
The ZIP holds the skill’s files, its licence files and an ATTRIBUTION.md. Download azure-compute-batch-java.zip