本文将详细解释如何使用JavaRuntime。文章内容质量较高,边肖将分享给大家参考。希望你看完这篇文章后有所了解。
00-1010最近在做项目框架,需要在框架结束时关闭服务器连接,清除框架的一些锁文件。在这里,我想到了shutdownhook,并学习了Runtime的用法。
前言
演示示例,证明程序正常结束时会调用。如果杀-9,肯定不会叫。
publicclassShutdownHookTest {
publicationstativitmain(String[]args){ 0
system . out . println('==================application start=================');
Runtime.getRuntime()。addshuttdowhook(new thread(()-{ 0
system . out . println('-hook 1-');
}));
Runtime.getRuntime()。addshuttdowhook(new thread(()-{ 0
system . out . println('-hook 2-');
}));
system . out . println('==================application end================');
}
}正常操作结束,结果如下。
===============应用程序启动=====================
================应用程序结束====================
-钩子1 -
钩子2
进程已完成,退出代码为0
如果暂停,请单击下图左下角的红色方形图标停止运行应用程序。
因此,shutdownhook已被执行。
Shutdownhook可以处理删除文件、关闭连接等操作。当程序正常结束时。
1. shutdownhook
2. exec执行
演示示例如下,例如ls
publicclassShutdownHookTest {
publicationstatinvitmain(String[]args)throwsInt
erruptedException, IOException {
Process process = Runtime.getRuntime().exec("ls");
try (InputStream fis = process.getInputStream();
InputStreamReader isr = new InputStreamReader(fis);
BufferedReader br = new BufferedReader(isr)) {
String line;
while ((line = br.readLine()) != null) {
System.out.println(line);
}
}
}
}
结果如下
而正常执行结果
但是这个方法有远程执行风险,即在浏览器端通过这个方法执行特定指令,比如执行rm -rf *,结果就很……
2.2 管道符
但是遇见管道符之后就会失效,什么办法解决,sh -c,但是不能直接用,否则获取到的是TTY窗口信息
public static void main(String[] args) throws IOException { Process process = Runtime.getRuntime().exec("sh -c ps aux|grep java"); try (InputStream fis = process.getInputStream(); InputStreamReader isr = new InputStreamReader(fis); BufferedReader br = new BufferedReader(isr)) { String line; while ((line = br.readLine()) != null) { System.out.println(line); } } }
结果????
sh -c的参数要分离,不然runtime会认为是一个参数
2.3源码分析
跟踪代码,使用ProcessImpl来执行指令
public Process exec(String[] cmdarray, String[] envp, File dir) throws IOException { return new ProcessBuilder(cmdarray) .environment(envp) .directory(dir) .start(); }
ProcessBuilder
// Only for use by ProcessBuilder.start() static Process start(String[] cmdarray, java.util.Map<String,String> environment, String dir, ProcessBuilder.Redirect[] redirects, boolean redirectErrorStream) throws IOException { assert cmdarray != null && cmdarray.length > 0; // Convert arguments to a contiguous block; it's easier to do // memory management in Java than in C. byte[][] args = new byte[cmdarray.length-1][]; int size = args.length; // For added NUL bytes for (int i = 0; i < args.length; i++) { args[i] = cmdarray[i+1].getBytes(); size += args[i].length; } byte[] argBlock = new byte[size]; int i = 0; for (byte[] arg : args) { System.arraycopy(arg, 0, argBlock, i, arg.length); i += arg.length + 1; // No need to write NUL bytes explicitly } int[] envc = new int[1]; byte[] envBlock = ProcessEnvironment.toEnvironmentBlock(environment, envc); int[] std_fds; FileInputStream f0 = null; FileOutputStream f1 = null; FileOutputStream f2 = null; try { if (redirects == null) { std_fds = new int[] { -1, -1, -1 }; } else { std_fds = new int[3]; if (redirects[0] == Redirect.PIPE) std_fds[0] = -1; else if (redirects[0] == Redirect.INHERIT) std_fds[0] = 0; else { f0 = new FileInputStream(redirects[0].file()); std_fds[0] = fdAccess.get(f0.getFD()); } if (redirects[1] == Redirect.PIPE) std_fds[1] = -1; else if (redirects[1] == Redirect.INHERIT) std_fds[1] = 1; else { f1 = new FileOutputStream(redirects[1].file(), redirects[1].append()); std_fds[1] = fdAccess.get(f1.getFD()); } if (redirects[2] == Redirect.PIPE) std_fds[2] = -1; else if (redirects[2] == Redirect.INHERIT) std_fds[2] = 2; else { f2 = new FileOutputStream(redirects[2].file(), redirects[2].append()); std_fds[2] = fdAccess.get(f2.getFD()); } } return new UNIXProcess (toCString(cmdarray[0]), argBlock, args.length, envBlock, envc[0], toCString(dir), std_fds, redirectErrorStream); } finally { // In theory, close() can throw IOException // (although it is rather unlikely to happen here) try { if (f0 != null) f0.close(); } finally { try { if (f1 != null) f1.close(); } finally { if (f2 != null) f2.close(); } } } }
new UNIXProcess 环境
/** * java.lang.Process subclass in the UNIX environment. * * @author Mario Wolczko and Ross Knippel. * @author Konstantin Kladko (ported to Linux and Bsd) * @author Martin Buchholz * @author Volker Simonis (ported to AIX) */ final class UNIXProcess extends Process {
3. 总结
Runtime用处非常多,偏底层
比如gc调用
加载jar文件
Runtime功能强大,但需要合理利用,很多攻击是通过Runtime执行的漏洞
但是使用shutdownhook还是很方便的,用来做停止任务的后续处理。
关于Java Runtime的使用方法是什么就分享到这里了,希望
内容来源网络,如有侵权,联系删除,本文地址:https://www.230890.com/zhan/147373.html