java 进程运行时间_将Java类作为子进程运行
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列表后,它們將傳遞到ProcessBuilder 。 ProcessBuilder獲取此列表,并使用其中包含的每個值來生成命令。 command列表中的每個值都由ProcessBuilder用空格分隔。 它的構造函數還有其他重載,其中之一包含一個字符串,您可以在其中手動定義整個命令。 這消除了您手動管理在命令字符串中添加參數的需要。
子進程以其IO傳遞到執行它的進程開始。 查看生成的所有stdout和stderr都是必需的。 inheritIO是一種便捷方法,也可以通過調用鏈接以下代碼來實現(也配置子inheritIO的stdin ):
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 進程運行時間
總結
以上是生活随笔為你收集整理的java 进程运行时间_将Java类作为子进程运行的全部內容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: java设计模式适配器模式_Java中的
- 下一篇: java美元兑换,(Java实现) 美元