我本周需要将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

将Java类作为子进程运行相关推荐

  1. java 进程运行时间_将Java类作为子进程运行

    java 进程运行时间 我本周需要将Java类(而不是jar)作为子进程运行. 更确切地说,我想从测试内部产生一个新进程,而不是直接在测试内部(进程内)运行它. 我不认为这是幻想或复杂的事情. 但是, ...

  2. Java类的基本运行顺序

    我们以下面的类来说明一个基本的 Java 类的运行顺序: public class Demo{ private String name; private int age; public Demo(){ ...

  3. Java私塾跟我学系列——JAVA篇 第四章Java类和对象

    教学目标: i面向对象基础 i掌握对象的三大特性 i掌握Java类的构建 i掌握如何使用Java类 i理解引用类型 i理解按值传递和按引用传递 i深入理解变量 i掌握包装类 i理解类型转换 i理解Ja ...

  4. jaxb xml 生成 java_使用 JAXB 工具根据 Java 类生成 XML 模式

    使用 JAXB 工具根据 Java 类生成 XML 模式 2010-06-10 18:24:26|  分类: web service |字号 订阅 关键字: java to xml 使用 JAXB 工 ...

  5. java类的运行顺序_Java语言类的基本运行顺序

    本文主要向大家介绍了Java语言类的基本运行顺序,通过具体的代码向大家展示,希望对大家学习Java语言有所帮助.我们以下面的类来说明一个基本的 Java 类的运行顺序:1. public class  ...

  6. Java知多少(23)类的基本运行顺序

    我们以下面的类来说明一个基本的 Java 类的运行顺序: 1 public class Demo{ 2 private String name; 3 private int age; 4 public ...

  7. java加载并运行虚拟机_《深入理解Java虚拟机》- Java虚拟机是如何加载Java类的?...

    Java虚拟机是如何加载Java类的?  这个问题也就是面试常问到的Java类加载机制.在年初面试百战之后,菜鸟喜鹊也是能把这流程倒背如流啊!但是,也只是字面上的背诵,根本就是像上学时背书考试一样. ...

  8. Eclipse中将java类打成jar包形式运行

    记录一次帮助小伙伴将java类打成jar包运行 1.创建java project项目 file > new > project > java project 随便起一个项目名称,fi ...

  9. Dos下命令运行带有包名的Java类

    这几天在回顾原来的知识,发现知识一段时间不整理的话很多东西手生的很,今天刚刚想在dos下运行一个java类却出错了.Exception   in   thread   "main" ...

最新文章

  1. 浪潮小机装oracle数据库,浪潮ERP系统oracle双机热备安装文档 | 浪潮888博客
  2. 时间序列数据库——索引用ES、聚合分析时加载数据用什么?docvalues的列存储貌似更优优势一些...
  3. 基于java的餐饮管理系统_基于java的餐饮管理系统
  4. thinkphp5.0学习(九):TP5.0视图和模板
  5. 如何开始使用任何类型的数据? - 第1部分
  6. @Autowired注入为null的几种情况
  7. netty 多个 本地udp端口_如何在SpringBoot中,使用Netty实现远程调用?
  8. linux下的图形界面扫雷游戏(Gtk+2.0)
  9. iOS Mac终端 生成模拟器与真机都能运行的.a静态库
  10. 修改删除idea快捷键
  11. 智能陈桥五笔输入法 for linux,智能陈桥五笔官方版
  12. ios 边录音边放_ios中同时录音和播放
  13. CnPack 自动完成 回车时替换整个标识符
  14. 浅谈国内信息化项目的范围管控变更办法
  15. 60.(leaflet之家)leaflet虚线
  16. 安装系统之九 U盘装原版WIN8教程
  17. 【绝知此事要躬行】线性表之数组OJ
  18. QT quick中的登录界面(Rectangle,TextField文本框的使用)
  19. C语言吸引人眼球的题目,公众号文章标题如何吸引用户眼球,12个写出好标题的技巧...
  20. ng-content、ng-template、ng-container使用及区别

热门文章

  1. 【做题记录】[NOIP2011 提高组] 观光公交
  2. 【数论】【杜教筛】选数(P3172)
  3. 2017西安交大ACM小学期数据结构 [树状数组,极大值]
  4. 漫画:如何用栈实现队列
  5. 利用JEXL实现动态表达式编译
  6. 使用GZIP和Zip压缩Java数据流
  7. Oracle入门(十四.7)之良好的编程习惯
  8. mybatis思维导图,让mybatis不再难懂(二)
  9. 三个剩两个,两个剩一个,最后一个都没剩下。
  10. Ajax基本案例详解之$.post的实现