将Java类作为子进程运行

我本周需要将Java类(而不是jar)作为子进程运行。 更准确地说,我想从测试内部产生一个新进程,而不是直接在测试内部运行(进程内)。 我不认为这是幻想或复杂的事情。 但是,这不是我以前不需要做的事,也不知道要编写的确切代码。

幸运的是,稍后有一个快速的Google和一些Stack Overflow帖子。 我找到了所需的答案 。 尽管有答案,但为了我自己和你自己的利益,我在这里重写了它。

 class JavaProcess { private JavaProcess() { } public static int exec(Class clazz, List<String> jvmArgs, List<String> args) throws IOException, InterruptedException { String javaHome = System.getProperty( "java.home" ); String javaBin = javaHome + File.separator + "bin" + File.separator + "java" ; String classpath = System.getProperty( "java.class.path" ); String className = clazz.getName(); List<String> command = new ArrayList<>(); command.add(javaBin); command.addAll(jvmArgs); command.add( "-cp" ); command.add(classpath); command.add(className); command.addAll(args); ProcessBuilder builder = new ProcessBuilder(command); Process process = builder.inheritIO().start(); process.waitFor(); return process.exitValue(); }  } 

该静态函数将要执行的Class与所有JVM参数以及该类的main方法期望的参数一起使用。 可以访问两组参数可以完全控制子流程的执行。 例如,您可能想以低堆空间执行您的类,以查看它在内存压力下如何应对(这是我需要的)。

注意,要使此方法起作用,您要执行的类需要具有一个main方法。 这很重要。

访问Java可执行文件的路径(存储在javaBin )允许您使用与主应用程序相同的Java版本执行子javaBin 。 如果将javaBin替换为"java" ,则存在使用计算机的默认Java版本执行子javaBin的风险。 很多时候那可能很好。 但是,在某些情况下可能不希望这样做。

将所有命令添加到command列表后,它们将传递到ProcessBuilderProcessBuilder获取此列表,并使用其中包含的每个值来生成命令。 command列表中的每个值都由ProcessBuilder用空格分隔。 它的构造函数还有其他重载,其中之一包含一个字符串,您可以在其中手动定义整个命令。 这消除了您手动管理在命令字符串中添加参数的需要。

子进程以其IO传递到执行它的进程开始。 查看生成的所有stdoutstderr都是必需的。 inheritIO是一种便捷方法,也可以通过调用链接以下代码来实现(也配置子inheritIOstdin ):

 builder .redirectInput(ProcessBuilder.Redirect.INHERIT) .redirectOutput(ProcessBuilder.Redirect.INHERIT) .redirectError(ProcessBuilder.Redirect.INHERIT); 

最后, waitFor告诉执行线程等待所生成的子进程完成。 该过程是否成功结束或错误都无关紧要。 只要子流程以某种方式完成。 主要执行可以继续进行。 进程如何完成由其exitValue详细说明。 例如, 0通常表示成功执行,而1详细说明无效语法错误。 还有许多其他退出代码,它们在不同的应用程序中可能会有所不同。

调用exec方法如下所示:

 JavaProcess.exec(MyProcess. class , List.of( "-Xmx200m" ), List.of( "argument" )) 

它执行以下命令(或其附近的命令):

 /Library/Java/JavaVirtualMachines/jdk- 12.0 . 1 .jdk/Contents/Home/bin/java -cp /playing-around- -blogs MyProcess for -blogs MyProcess "argument" 

我剪掉了很多包含classpath的路径,以使其更加简洁。 您的外观可能会比这更长。 这实际上取决于您的应用程序。 上面命令中的路径是运行它所需的最低要求(显然是为我的机器定制的)。

exec方法相当灵活,有助于描述发生的情况。 尽管,如果您希望使其具有更大的延展性和适用性,但我建议从该方法返回ProcessBuilder本身。 允许您在多个地方重用这段代码,同时提供配置IO重定向的灵活性,以及​​决定是在后台还是在块中运行子流程并等待其完成的能力。 这看起来像:

 public static ProcessBuilder exec(Class clazz, List<String> jvmArgs, List<String> args) { String javaHome = System.getProperty( "java.home" ); String javaBin = javaHome + File.separator + "bin" + File.separator + "java" ; String classpath = System.getProperty( "java.class.path" ); String className = clazz.getName(); List<String> command = new ArrayList<>(); command.add(javaBin); command.addAll(jvmArgs); command.add( "-cp" ); command.add(classpath); command.add(className); command.addAll(args); return new ProcessBuilder(command);  } 

通过使用这两个功能中的一个(或两个),您现在可以运行应用程序的类路径中存在的任何类。 在我的情况下,这对于在集成测试中生成子流程非常有用,而无需预先构建任何jar。 这样就可以控制JVM参数,例如子进程的内存,如果直接在现有进程内部运行,则这些子进程将无法配置。

翻译自: https://www.javacodegeeks.com/2019/07/running-java-class-subprocess.html

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

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

光猫的分类及应用范围有哪些?

光猫也称为单端口光端机&#xff0c;是针对特殊用户环境而设计的产品&#xff0c;它利用一对光纤进行单E1或单V.35或单10BaseT点到点式的光传输终端设备。该设备作为本地网的中继传输设备&#xff0c;适用于基站的光纤终端传输设备以及租用线路设备。而对于多口的光端机一般会直…

关于光模块用单模光纤和多模光纤小知识

通过对光纤的认知&#xff0c;我们了解到光纤是通过导光来传输信号、不导电、不怕雷击&#xff0c;所以也不需要用接地保护&#xff0c;我们按光在光纤中的传输模式分为&#xff1a;多模光纤和单模光纤。对于我们使用者来说&#xff0c;你把多模和单模名称由来记住就可以了。接…

硬盘序列号示例_序列化代理模式示例

硬盘序列号示例有些书极大地改变了你的生活。 其中一本书是Joshua Bloch撰写的“ Effective Java” 。 在下面您可能会发现一些小的实验&#xff0c;该实验的灵感来自于本书的第11章“串行化”。 假设我们有一个为继承而设计的类&#xff0c;它本身不是可序列化的 &#xff0c…

什么是光纤转换器?光纤转换器转换类别介绍

光纤转换器是RS-232/422/485串行数据通过光纤的远距离传输&#xff0c;可以完成串口到光纤的转换&#xff0c;并且可以延长串行通信信号的传输距离。那么&#xff0c;光纤转换器转换类别有哪些呢&#xff1f;接下来我们就跟随飞畅科技的小编一起来详细了解下吧&#xff01; 光纤…

H2数据库的Spring Boot

在本快速教程中&#xff0c;我们将引导一个由内存H2数据库支持的简单Spring Boot应用程序。 我们将使用Spring Data JPA与我们的数据库进行交互。 项目设置&#xff1a; 首先&#xff0c;让我们使用Spring Initializr生成我们的项目模板&#xff1a; 单击“生成项目”链接后&…

集线器,交换机,路由器工作层次的区别

集线器&#xff08;Hub&#xff09;、交换机&#xff08;Switch&#xff09;与路由器&#xff08;Router&#xff09;号称是网络硬件三剑客&#xff0c;一直以来都是网络界的活跃分子&#xff0c;但让非常多初入网络之门的菜鸟恼火的是&#xff0c;它们三者不仅外观相似&#x…

什么是协议网桥?

网桥&#xff08;Bridge&#xff09;是早期的两端口二层网络设备&#xff0c;用来连接不同网段。网桥的两个端口分别有一条独立的交换信道&#xff0c;不是共享一条背板总线&#xff0c;可隔离冲突域。网桥比集线器&#xff08;Hub&#xff09;性能更好&#xff0c;集线器上各端…

网桥是怎么分类的?具体有哪些分类?

网桥也叫桥接器&#xff0c;是连接两个局域网的一种存储/转发设备&#xff0c;它能将一个大的LAN分割为多个网段&#xff0c;或将两个以上的LAN互联为一个逻辑LAN&#xff0c;使LAN上的所有用户都可访问服务器。那么&#xff0c;网桥具体是怎么分类的&#xff0c;有哪些类别呢&…

c++返回指针时候注意提防_编写干净的测试–提防魔术

c返回指针时候注意提防很难为干净的代码找到一个好的定义&#xff0c;因为我们每个人都有自己的单词clean的定义。 但是&#xff0c;有一个似乎是通用的定义&#xff1a; 简洁的代码易于阅读。 这可能会让您感到有些惊讶&#xff0c;但我认为该定义也适用于测试代码。 使测试尽…

无线网桥的特点及应用方案

无线网桥顾名思义就是无线网络的桥接&#xff0c;它利用无线传输方式实现在两个或多个网络之间搭起通信的桥梁&#xff1b;无线网桥从通信机制上分为电路型网桥和数据型网桥。那么&#xff0c;无线网桥的特点及应用方案有哪些呢&#xff1f;接下来我们就一起来看看吧&#xff0…

Spring WebClient的单元测试

WebClient引用其Java文档是Spring Framework的 非阻塞&#xff0c;反应式客户端执行HTTP请求&#xff0c;通过底层HTTP客户端库&#xff08;如Reactor Netty&#xff09;公开流利的&#xff0c;反应式API 。 在我当前的项目中&#xff0c;我广泛使用WebClient进行服务到服务…

以太网的光猫和光纤的光猫有什么区别吗?

光调制解调器&#xff0c;光猫也称为单端口光端机&#xff0c;是针对特殊用户环境而研发的一种三件一套的光纤传输设备。该设备采用大规模集成芯片&#xff0c;电路简单&#xff0c;功耗低&#xff0c;可靠性高&#xff0c;具有完整的告警状态指示和完善的网管功能。光猫可以分…

SFP光模块基本概念及使用注意事项详解

光模块(optical module)由光电子器件、功能电路和光接口等组成&#xff0c;光电子器件包括发射和接收两部分。简单的说&#xff0c;光模块的作用就是光电转换&#xff0c;发送端把电信号转换成光信号&#xff0c;通过光纤传送后&#xff0c;接收端再把光信号转换成电信号。现在…

Java中的状态设计模式

在本教程中&#xff0c;我们将探讨另一种流行的行为设计模式-状态设计模式。 当我们使用可以存在于多个状态的对象时&#xff0c;状态设计模式的知识变得非常有用。 当对象的行为取决于其当前状态时&#xff0c;我们应该主要使用它。 这种模式有助于我们避免在该类的方法中对对…

串口服务器工作方式及常见异常故障问题排除方法介绍

串口设备联网服务器就像一台带CPU、实时操作系统和TCP/IP协议的微型电脑&#xff0c;方便在串口和网络设备中传输数据。您可以在世界任何位置通过网络&#xff0c;用您的计算机来存取&#xff0c;管理和配置远程的设备。但是我们在实际使用串口服务器的过程中&#xff0c;难免会…

E1立体声卡侬头(XLR) 音频编解码器产品介绍

FCA系列音频编解码器是一种采用数字处理芯片及大规模FPGA、数字编解码转换和时钟恢复技术方法设计的基于E1(2M)通道传输立体声广播信号的广播传送设备系统&#xff0c;它可以借助目前成熟可靠的E1传输系统网&#xff0c;建立起数字立体声广播传送系统网络&#xff0c;实现广播传…

E1视音频编解码器应用方案详细说明

E1音频编解码器&#xff0c;是采用数字处理芯片及大规模FPGA、数字编解码转换和时钟恢复技术方法设计的。适用于广播节目源传输的设备。音频编码器是将输入的立体声音频信号&#xff0c;经A/D数字编解码变换或数据格式转换后&#xff0c;重新成帧&#xff0c;形成串行数据流&am…

java请求接口示例_Java 8:功能接口示例

java请求接口示例为了支持Java 8中的lambda表达式&#xff0c;他们引入了Functional Interfaces。 具有单一抽象方法的接口可以称为功能接口。 Runnable&#xff0c;Comparator&#xff0c;Cloneable是功能接口的一些示例。 我们可以使用Lambda表达式实现这些功能接口。 例如…

Java中的外观设计模式

立面是指建筑物的外观。 当穿过街道时&#xff0c;我们所看到的只是建筑物的外观。 该图面抽象了建筑物的所有复杂实施细节。 同样&#xff0c; 外观设计模式旨在为子系统中的一组接口提供统一的接口。 这个统一的接口对客户端隐藏了子系统的复杂性。 它属于结构模式类别。 J…

串口服务器介绍及产品特点详解

串口服务器提供串口转网络功能&#xff0c;能够将RS-232/485/422串口转换成TCP/IP网络接口&#xff0c;实现RS-232/485/422串口与TCP/IP网络接口的数据双向透明传输。使得串口设备能够立即具备TCP/IP网络接口功能&#xff0c;连接网络进行数据通信&#xff0c;极大的扩展串口设…