当前位置: 首页 > news >正文

使用 Apache Commons Exec 管理外部进程

在这里插入图片描述

😄 19年之后由于某些原因断更了三年,23年重新扬帆起航,推出更多优质博文,希望大家多多支持~
🌷 古之立大事者,不惟有超世之才,亦必有坚忍不拔之志
🎐 个人CSND主页——Micro麦可乐的博客
🐥《Docker实操教程》专栏以最新的Centos版本为基础进行Docker实操教程,入门到实战
🌺《RabbitMQ》本专栏主要介绍使用JAVA开发RabbitMQ的系列教程,从基础知识到项目实战
🌸《设计模式》专栏以实际的生活场景为案例进行讲解,让大家对设计模式有一个更清晰的理解
💕《Jenkins实战》专栏主要介绍Jenkins+Docker+Git+Maven的实战教程,让你快速掌握项目CI/CD,是2024年最新的实战教程
如果文章能够给大家带来一定的帮助!欢迎关注、评论互动~

使用 Apache Commons Exec 管理外部进程

  • 前言
  • 为什么选择 Apache Commons Exec?
  • 基本用法
  • 高级特性
  • 结语

前言

在现代软件开发中,经常需要从 Java 应用程序中启动和管理外部进程。Apache Commons Exec 提供了一个简单且强大的 API,用于管理和控制外部进程。本文将详细介绍如何使用 Apache Commons Exec 管理外部进程,包括其优势、基本用法以及一些高级特性。

在这里插入图片描述

为什么选择 Apache Commons Exec?

Java 原生的 java.lang.ProcessBuilderjava.lang.Runtime.exec() 方法虽然能够启动外部进程,但在处理复杂场景(如超时、流控制和并发管理)时显得力不从心。Apache Commons Exec 提供了以下优势:

  • 简化 API提供更为简洁和易用的接口。
  • 超时控制支持设置超时时间,防止进程无限期挂起。
  • 流处理提供对标准输入、输出和错误流的灵活处理。
  • 可靠的进程销毁在超时或异常情况下能够可靠地销毁进程。

基本用法

首先,引入 Apache Commons Exec 依赖:目前最新版本为 1.4.0

<dependency><groupId>org.apache.commons</groupId><artifactId>commons-exec</artifactId><version>1.4.0</version>
</dependency>

以下是一个基本示例,演示如何使用 Apache Commons Exec 启动一个简单的外部进程:

import org.apache.commons.exec.CommandLine;
import org.apache.commons.exec.DefaultExecutor;
import org.apache.commons.exec.ExecuteException;public class BasicExecExample {public static void main(String[] args) {//不带参数 查看ip指令 博主是MacOS系统//CommandLine cmdLine = CommandLine.parse("ifconfig");//带参数CommandLine cmdLine = new CommandLine("ping");cmdLine.addArgument("www.baidu.com");//设置执行器DefaultExecutor executor = new DefaultExecutor();try {//执行命令executor.execute(cmdLine);} catch (ExecuteException e) {System.err.println("Execution failed: " + e.getMessage());} catch (IOException e) {System.err.println("IO error: " + e.getMessage());}}
}

执行效果

在这里插入图片描述

高级特性

超时控制
使用 ExecuteWatchdog 来设置进程的最大执行时间。如果超时,进程将被自动终止:

import org.apache.commons.exec.ExecuteWatchdog;public class TimeoutExecExample {public static void main(String[] args) {//模拟执行时间CommandLine cmdLine = new CommandLine("ping");cmdLine.addArgument("www.baidu.com");DefaultExecutor executor = new DefaultExecutor();ExecuteWatchdog watchdog = new ExecuteWatchdog(10000); // 10秒超时executor.setWatchdog(watchdog);try {executor.execute(cmdLine);} catch (ExecuteException e) {System.err.println("Execution failed: " + e.getMessage());} catch (IOException e) {System.err.println("IO error: " + e.getMessage());}}
}

可以看到当 ping 指令在执行10秒后进程自动终止

在这里插入图片描述

流处理
通过 PumpStreamHandler 可以处理进程的标准输出和错误输出。以下示例展示了如何将输出重定向到文件:

import org.apache.commons.exec.PumpStreamHandler;import java.io.FileOutputStream;
import java.io.IOException;public class StreamHandlerExample {public static void main(String[] args) {CommandLine cmdLine = new CommandLine("ping");cmdLine.addArgument("www.baidu.com");DefaultExecutor executor = new DefaultExecutor();try (FileOutputStream outputStream = new FileOutputStream("output.log");FileOutputStream errorStream = new FileOutputStream("error.log")) {PumpStreamHandler streamHandler = new PumpStreamHandler(outputStream, errorStream);executor.setStreamHandler(streamHandler);int exitValue = executor.execute(cmdLine);System.out.println("Exit value: " + exitValue);} catch (IOException e) {System.err.println("IO error: " + e.getMessage());}}
}

带环境变量的执行
你可以为外部进程设置特定的环境变量:

import java.util.HashMap;
import java.util.Map;public class EnvVarsExample {public static void main(String[] args) {CommandLine cmdLine = new CommandLine("env");DefaultExecutor executor = new DefaultExecutor();Map<String, String> env = new HashMap<>();env.put("MY_VAR", "some_value");try {int exitValue = executor.execute(cmdLine, env);System.out.println("Exit value: " + exitValue);} catch (ExecuteException e) {System.err.println("Execution failed: " + e.getMessage());} catch (IOException e) {System.err.println("IO error: " + e.getMessage());}}
}

异步执行
Commons Exec还支持异步执行命令。这对于不需要即时等待命令完成的场景非常有用,比如在后台运行某个长时间的任务。这里我们模拟一下mysql数据库备份

    public static void main(String[] args) {CommandLine cmdLine = CommandLine.parse("bash your-database-backup.sh");DefaultExecutor executor = new DefaultExecutor();executor.setExitValue(1);try {executor.execute(cmdLine, new ExecuteResultHandler() {@Overridepublic void onProcessComplete(int exitValue) {System.out.println("数据库备份完成,退出值:" + exitValue);}@Overridepublic void onProcessFailed(ExecuteException e) {System.err.println("数据库备份失败:" + e.getMessage());}});} catch (ExecuteException e) {System.err.println("Execution failed: " + e.getMessage());} catch (IOException e) {System.err.println("IO error: " + e.getMessage());}}

结语

Apache Commons Exec 提供了一个功能强大且灵活的 API,用于管理和控制外部进程。通过简化的 API、超时控制、流处理和环境变量设置,开发者可以更轻松地集成和管理外部进程。在实际应用中,合理使用这些特性可以显著提升应用程序的稳定性和可维护性。

通过以上示例,相信你已经对 Apache Commons Exec 有了基本了解和实践经验。下一章节我们就使用 Apache Commons Exec 自动化脚本执行实现 MySQL 数据库备份,让大家有更深入的理解。


在这里插入图片描述

相关文章:

  • 【计算机网络】——概述(图文并茂)
  • oracle中的INTERVAL函数学习总结
  • 50etf期权上市时间是什么时候?50etf期权对应的标的
  • 2022年全国职业院校技能大赛高职组“信息安全管理与评估”赛项第三阶段任务书
  • GolangFoundation
  • CSS学习笔记目录
  • 安装Lubuntu24.04
  • C# list集合
  • 卷积神经网络-奥特曼识别
  • # 详解 JS 中的事件循环、宏/微任务、Primise对象、定时器函数,以及其在工作中的应用和注意事项
  • Swoole 协程调度机制
  • 构建 VPC 并启动 Web 服务器
  • ADB安装教程
  • 修改python环境包的内容后如何及时更新到内存
  • 零拷贝(Zero Copy)
  • Create React App 使用
  • egg(89)--egg之redis的发布和订阅
  • HTTP中GET与POST的区别 99%的错误认识
  • idea + plantuml 画流程图
  • iOS仿今日头条、壁纸应用、筛选分类、三方微博、颜色填充等源码
  • JAVA 学习IO流
  • RxJS 实现摩斯密码(Morse) 【内附脑图】
  • SpringBoot几种定时任务的实现方式
  • underscore源码剖析之整体架构
  • Vue UI框架库开发介绍
  • 记录一下第一次使用npm
  • 系统认识JavaScript正则表达式
  • 【运维趟坑回忆录】vpc迁移 - 吃螃蟹之路
  • Nginx实现动静分离
  • 策略 : 一文教你成为人工智能(AI)领域专家
  • 交换综合实验一
  • 资深实践篇 | 基于Kubernetes 1.61的Kubernetes Scheduler 调度详解 ...
  • #[Composer学习笔记]Part1:安装composer并通过composer创建一个项目
  • $NOIp2018$劝退记
  • (16)UiBot:智能化软件机器人(以头歌抓取课程数据为例)
  • (二)Pytorch快速搭建神经网络模型实现气温预测回归(代码+详细注解)
  • (附源码)springboot“微印象”在线打印预约系统 毕业设计 061642
  • (附源码)ssm旅游企业财务管理系统 毕业设计 102100
  • (佳作)两轮平衡小车(原理图、PCB、程序源码、BOM等)
  • (蓝桥杯每日一题)平方末尾及补充(常用的字符串函数功能)
  • (入门自用)--C++--抽象类--多态原理--虚表--1020
  • (十二)devops持续集成开发——jenkins的全局工具配置之sonar qube环境安装及配置
  • (原創) 博客園正式支援VHDL語法著色功能 (SOC) (VHDL)
  • (转)C语言家族扩展收藏 (转)C语言家族扩展
  • (转)GCC在C语言中内嵌汇编 asm __volatile__
  • .360、.halo勒索病毒的最新威胁:如何恢复您的数据?
  • .bat批处理出现中文乱码的情况
  • .cn根服务器被攻击之后
  • .net开发时的诡异问题,button的onclick事件无效
  • //解决validator验证插件多个name相同只验证第一的问题
  • /boot 内存空间不够
  • :O)修改linux硬件时间
  • @property括号内属性讲解
  • @RequestBody与@ResponseBody的使用
  • [android] 看博客学习hashCode()和equals()