使用 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() {
                @Override
                public void onProcessComplete(int exitValue) {
                    System.out.println("数据库备份完成,退出值:" + exitValue);
                }

                @Override
                public 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 数据库备份,让大家有更深入的理解。


在这里插入图片描述

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:/a/664854.html

如若内容造成侵权/违法违规/事实不符,请联系我们进行投诉反馈qq邮箱809451989@qq.com,一经查实,立即删除!

相关文章

基于 Apache Doris 的实时/离线一体化架构,赋能中国联通 5G 全连接工厂解决方案

作者&#xff1a;田向阳&#xff0c;联通西部创新研究院 大数据专家 共创&#xff1a;SelectDB 技术团队 导读&#xff1a; 数据是 5G 全连接工厂的核心要素&#xff0c;为支持全方位的数据收集、存储、分析等工作的高效进行&#xff0c;联通 5G 全连接工厂从典型的 Lambda 架…

使用PNP管控制MCU是否需要复位

这两台用到一款芯片带电池&#xff0c;希望电池还有电芯片在工作的时候插入电源不要给芯片复位&#xff0c;当电池没电&#xff0c;芯片不在工作的时候&#xff0c;插入电源给芯片复位所以使用一个PNP三极管&#xff0c;通过芯片IO控制是否打开复位&#xff0c;当芯片正常工作的…

在长窗口时代,RAG技术是否仍然必要?

自从谷歌推出 Gemini 1.5 Pro&#xff0c;行业内部对于 RAG 的讨论就不绝于耳。 Gemini 1.5 Pro 的性能确实令人瞩目。根据谷歌公布的技术文档&#xff0c;该系统能够稳定处理长达 100 token 的内容&#xff0c;相当于一小时的视频、十一小时的音频、超过三万行的代码或七十万…

Spring Cloud Alibaba-09-Seata分布式事务

Lison <dreamlison163.com>, v1.0.0, 2024.5.03 Spring Cloud Alibaba-09-Seata分布式事务 文章目录 Spring Cloud Alibaba-09-Seata分布式事务分布式事务基础事务本地事务分布式事务分布式事务的场景 分布式事务的解决方案全局事务可靠消息服务最大努力通知TCC事务 Se…

Java实现数据结构---数组

文章目录 概念存储原理数组的操作完整代码 概念 数组是&#xff08;Array&#xff09;是有限个相同类型的变量所组成的有序集合&#xff0c;数组中的每一个变量为称为元素。数组是最简单、最常用的数据结构。 数组下标从零开始。 存储原理 数组用一组连续的内存空间来存储一…

蓝桥杯第17135题 不完整的算式 C++ Java Python

目录 题目 思路和解题方法 步骤 1&#xff1a;识别缺失的部分 步骤 2&#xff1a;根据已知条件计算或推断 步骤 3&#xff1a;处理特殊情况和验证 c 代码 Java 版本 Python 版本&#xff08;仅供参考&#xff09; 代码和解题细节&#xff1a; 题目 题目链接&#xff…

STM32自己从零开始实操03:输出部分原理图

一、继电器电路 1.1指路 延续使用 JZC-33F-012-ZS3 继电器&#xff0c;设计出以小电流撬动大电流的继电器电路。 &#xff08;提示&#xff09;电路需要包含&#xff1a;三极管开关电路、续流二极管、滤波电容、指示灯、输出部分。 1.2数据手册重要信息提炼 联系排列&…

神经网络与深度学习——第3章 线性模型

本文讨论的内容参考自《神经网络与深度学习》https://nndl.github.io/ 第3章 线性模型 线性模型 线性模型&#xff08;Linear Model&#xff09;是机器学习中应用最广泛的模型&#xff0c;指通过样本特征的线性组合来进行预测的模型&#xff0c;给定一个 D D D维样本 x [ x …

解锁 GPT-4o 背后数据带来的情绪价值

GPT-4o 可以说已经是一个富有情感、通人性的智能语音助手&#xff0c;或者更准确地说&#xff0c;是一个越来越接近人类交互的 “新物种”。这个强大的模型同时具备文本、图片、视频和语音理解和合成方面的能力&#xff0c;甚至可以被视为 GPT-5 的一个未完成版。 01 富有情感的…

lipo制作通用版本静态库

文章目录 目的了解多架构的maclipo如何利用lipo编译通用版本静态库lipo 命令整理扩展目的 主要是使用lipo命令在macOS上创建通用版本的静态库(.a文件),来支持多种架构,如arm64,x86_64。 学习目的: 了解mac 不同架构arm64, x86_64了解lipo命令了解多架构的mac 随着appl…

Linux - 文件管理高级1

0.管道 | 将前面命令的标准输出传递给管道作为后面的标准输入 1.文件查找 find find 进行文件查找时&#xff0c;默认进行递归查找&#xff0c;会查找隐藏目录下的文件 1.1 用法 # find 查找路径 查找条件... -type // 文件类型 f 普通文件 b 设备 d …

数据目录用处如此之大?四个步骤教你构建数据目录

在数字化浪潮的推动下&#xff0c;数据已成为企业决策的核心。然而&#xff0c;随着数据量的爆炸性增长&#xff0c;如何高效地管理和利用这些宝贵的数据资产&#xff0c;成为了一个日益严峻的挑战。企业需要一个强大的工具来组织、索引和解释其数据&#xff0c;以便快速发现和…

代理IP怎么检测?如何判断IP好坏?

当我们的数字足迹无处不在&#xff0c;隐私保护显得愈发重要。而代理IP就像是我们的隐身斗篷&#xff0c;让我们在各项网络业务中更加顺畅。 我们常常看到别人购买了代理IP服务后&#xff0c;用在线检测网站检查IP&#xff0c;相当于一个”售前检验““售后质检”的作用。但是…

图书管理系统——Java实现

文章目录 Java实现图书管理系统问题分析框架搭建业务实现项目测试代码演示BookioperationUserMain&#xff08;默认包&#xff09; Java实现图书管理系统 学习了前六篇的SE语法&#xff0c;我们现在要用它们实现一个简单的图书管理系统项目&#xff0c;深入了解各个知识点的应…

【CH32V305FBP6】4. systick 配置

配置 main.c void SYSTICK_Init_Config(u_int64_t ticks) {SysTick->SR & ~(1 << 0);//clear State flagSysTick->CMP ticks - 1;SysTick->CNT 0;SysTick->CTLR 0xF;NVIC_SetPriority(SysTicK_IRQn, 15);NVIC_EnableIRQ(SysTicK_IRQn); }中断计数 …

算法-扫描线

目录 什么是扫描线算法&#xff1f; 扫描线简单应用 更多的扫描线 什么是扫描线算法&#xff1f; 在计算几何中&#xff0c;扫描线算法&#xff08;scan line algorithm&#xff09;一般用来解决几何图形的面积交并&#xff0c;周长交并问题&#xff0c;扫描线算法的核心思想…

Day 8:1461. 检查一个字符串是否包含所有长度为 K 的二进制子串

Leetcode 1461. 检查一个字符串是否包含所有长度为 K 的二进制子串 给你一个二进制字符串 s 和一个整数 k 。如果所有长度为 k 的二进制字符串都是 s 的子串&#xff0c;请返回 true &#xff0c;否则请返回 false 。 截取每个长度为 k 的字符串&#xff0c;加入 Set 中&#x…

wpf listbox实现选中动画

效果如下&#xff1a; 参考&#xff1a;https://github.com/WPFDevelopersOrg/WPFDevelopers/blob/master/src/WPFDevelopers.Samples.Shared/Controls/NavigateMenu/NavigateMenu.xaml 实现上述效果的前台代码&#xff1a; <Windowx:Class"ListBox.MainWindow"…

数据隐私新篇章:Facebook如何保护用户信息

随着数字化时代的到来&#xff0c;数据隐私保护成为了社交媒体平台和用户共同关注的焦点。作为全球最大的社交网络之一&#xff0c;Facebook一直致力于保护用户的隐私和数据安全。本文将深入探讨Facebook在数据隐私保护方面的措施和实践&#xff0c;以及其如何开启数据隐私的新…

C++系列-类模板

&#x1f308;个人主页&#xff1a;羽晨同学 &#x1f4ab;个人格言:“成为自己未来的主人~” 类模板的定义格式&#xff1a; #define _CRT_SECURE_NO_WARNINGS #include<iostream> using namespace std; template<class T> class Stack { public:Stack(size_…