java本地命令执行
Runtime

就一个构造方法,是private的,只能在Runtime类中实例化,但是可以使用静态方法getRuntime获取到Runtime对象,通过Runtime对象的方法exec执行命令
exec返回一个Process对象
调用链(windows)
1 2 3 4 5
| Runtime.exec() ->ProcessBuilder.start() -> ProcessImpl.start() -> new ProcessImpl()
|
linux是将ProcessImpl的start换成forkAndExec
Runtime.exec直接执行,或在jdk8以下反射执行
1 2
| System.out.println(org.apache.commons.io.IOUtils.toString(Runtime.getRuntime().exec("ls").getInputStream()));
|
ProcessBuilder
类跟方法start都是public的,直接用,也是返回Process对象
1
| System.out.println(org.apache.commons.io.IOUtils.toString(new ProcessBuilder("whoami").start().getInputStream()));
|
ProcessImpl
类是default权限,只能在java8以下反射获取,并调用static的start
1 2 3 4 5 6
| Class<?> clazz = Class.forName("java.lang.ProcessImpl"); String[] cmds = new String[]{"whoami"}; Method method = clazz.getDeclaredMethod("start", String[].class, Map.class, String.class, ProcessBuilder.Redirect[].class, boolean.class); method.setAccessible(true); Process e = (Process) method.invoke(null, cmds, null, null, null, false); System.out.println(org.apache.commons.io.IOUtils.toString(e.getInputStream()));
|
Jni命令执行
java中native方法是底层c/c++实现的(jni就是java与c/c++地层交流的api)
自己编写native方法测试
创建test2.java
java测试
1 2 3 4 5 6 7 8
| package test; public class test2 { public static native String nativeMethod(String str); public static void main(String[] args) throws Exception { System.load("D:\\download\\untitled1\\test\\cmd.dll"); System.out.println(test2.nativeMethod("ls / -al")); } }
|
1
| javac -cp . test2.java -h . //-h选项用来在指定目录生成test_test2.h
|
编写test_test2.cpp
java与c/c++通信参考(https://blog.csdn.net/qq_25722767/article/details/52557235)
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36
|
#include "test_test2.h" #include <string> #include <cstdio> using namespace std;
JNIEXPORT jstring JNICALL Java_test_test2_nativeMethod(JNIEnv *env, jclass jclass, jstring str) { if (str == NULL) { return NULL; }
const char *c_str = env->GetStringUTFChars(str, NULL); if (c_str == NULL) { return NULL; }
FILE *fp = popen(c_str, "r"); env->ReleaseStringUTFChars(str, c_str);
if (fp == NULL) { return NULL; }
string output; char buffer[1024];
while (fgets(buffer, sizeof(buffer), fp) != NULL) { output += buffer; } pclose(fp);
return env->NewStringUTF(output.c_str()); }
|
编译命令
1 2 3
| g++ -shared -o cmd.dll test_test2.cpp -I"%JAVA_HOME%/include" -I"%JAVA_HOME%/include/win32" -static -static-libgcc -static-libstdc++ -Wl,--add-stdcall-alias
#-static尽量静态编译
|