如何实现基于Spring Core的独立Jar调用PCF上的Spring Batch作业?
Got it, let's walk through building this standalone Spring Core-based JAR invoker that triggers your Spring Batch jobs on Pivotal Cloud Foundry (PCF) when called via a Linux script. Since you're already using Spring Boot and TaskLauncher, we can adapt that approach to a leaner standalone setup—here's how to make it work:
First, you don't need a full Spring Boot app unless you want to leverage auto-configuration. For a minimal standalone JAR, stick to Spring Core plus the necessary cloud deployer dependencies. Add these to your build file (Maven example):
<dependencies> <dependency> <groupId>org.springframework</groupId> <artifactId>spring-context</artifactId> <version>5.3.24</version> <!-- Use a compatible version with your PCF setup --> </dependency> <dependency> <groupId>org.springframework.cloud</groupId> <artifactId>spring-cloud-deployer-cloudfoundry</artifactId> <version>2.8.4</version> </dependency> </dependencies>
Create a Spring configuration class to set up the CloudFoundryTaskLauncher bean, which handles communication with PCF. Avoid hardcoding credentials—use environment variables instead for security:
import org.springframework.cloud.deployer.spi.cloudfoundry.CloudFoundryTaskLauncher; import org.springframework.context.annotation.Bean; import org.springframework.context.annotation.Configuration; @Configuration public class PCFTaskConfig { @Bean public CloudFoundryTaskLauncher cloudFoundryTaskLauncher() { CloudFoundryTaskLauncher launcher = new CloudFoundryTaskLauncher(); // PCF connection details launcher.setApiEndpoint("https://api.your-pcf-instance.com"); launcher.setOrganization("your-org-name"); launcher.setSpace("your-space-name"); // Pull credentials from environment variables launcher.setUsername(System.getenv("PCF_USER")); launcher.setPassword(System.getenv("PCF_PASS")); launcher.setSkipSslValidation(false); // Disable only for internal, trusted PCF instances return launcher; } }
Create a main class that initializes the Spring context, accepts command-line arguments (like job name and parameters), and uses TaskLauncher to trigger the PCF-based Spring Batch job:
import org.springframework.context.annotation.AnnotationConfigApplicationContext; import org.springframework.cloud.deployer.spi.task.TaskLauncher; import org.springframework.cloud.deployer.spi.core.AppDeploymentRequest; import java.util.HashMap; import java.util.Map; public class BatchJobInvoker { public static void main(String[] args) { // Validate input if (args.length < 1) { System.err.println("Usage: java -jar batch-invoker.jar <batch-job-name> [job-parameters]"); System.exit(1); } String jobName = args[0]; String jobParams = args.length > 1 ? args[1] : ""; try (AnnotationConfigApplicationContext context = new AnnotationConfigApplicationContext(PCFTaskConfig.class)) { TaskLauncher taskLauncher = context.getBean(TaskLauncher.class); // Configure deployment request for your Spring Batch app Map<String, String> deploymentProps = new HashMap<>(); deploymentProps.put("spring.cloud.deployer.cloudfoundry.task.environment", String.format("SPRING_BATCH_JOB_NAME=%s,SPRING_BATCH_JOB_PARAMS=%s", jobName, jobParams)); // Optional: Set resource limits, app version, etc. deploymentProps.put("spring.cloud.deployer.cloudfoundry.memory", "1G"); AppDeploymentRequest request = new AppDeploymentRequest.Builder() .setApplicationName("your-batch-app-name") // Name of your deployed Spring Batch app on PCF .setDeploymentProperties(deploymentProps) .build(); // Launch the task String taskId = taskLauncher.launchTask(request); System.out.printf("Successfully triggered job '%s' with task ID: %s%n", jobName, taskId); } catch (Exception e) { System.err.printf("Failed to trigger job '%s': %s%n", jobName, e.getMessage()); e.printStackTrace(); System.exit(1); } } }
Use a build plugin to package all dependencies into a single JAR (so you don't need to manage classpath on the Linux server). For Maven, use the maven-assembly-plugin:
<build> <plugins> <plugin> <groupId>org.apache.maven.plugins</groupId> <artifactId>maven-assembly-plugin</artifactId> <version>3.4.2</version> <configuration> <archive> <manifest> <mainClass>com.yourpackage.BatchJobInvoker</mainClass> </manifest> </archive> <descriptorRefs> <descriptorRef>jar-with-dependencies</descriptorRef> </descriptorRefs> </configuration> <executions> <execution> <id>make-assembly</id> <phase>package</phase> <goals> <goal>single</goal> </goals> </execution> </executions> </plugin> </plugins> </build>
Write a bash script to set environment variables (for PCF credentials) and invoke the JAR. This makes it easy to call from cron or other automation tools:
#!/bin/bash # Set PCF credentials (store these securely in production, e.g., via vault or server env vars) export PCF_USER="your-pcf-username" export PCF_PASS="your-pcf-password" # Check for required job name argument if [ $# -lt 1 ]; then echo "Error: Missing batch job name" echo "Usage: $0 <batch-job-name> [job-parameters]" exit 1 fi # Invoke the standalone JAR java -jar /path/to/your/batch-invoker-jar-with-dependencies.jar "$1" "$2"
- Ensure your Spring Batch app is deployed as a task on PCF (use
cf push --taskor deploy via the cloud deployer API). - Adjust the
AppDeploymentRequestproperties to match your app's resource needs (memory, disk, environment variables). - For production, avoid hardcoding credentials in the script—use server environment variables or a secrets manager.
- You can extend the invoker to track task status using
taskLauncher.status(taskId)if you need to verify job completion.
内容的提问来源于stack exchange,提问作者TheNotSoTinyDreamer

