分类
Java

远程执行 Java 代码

本文是《深入理解 Java 虚拟机》中的一个实战,看完后照着敲的代码,简单地封装了一个 Servlet, 只需引入 Maven 并配置一下这个 Servlet 就可以实现浏览器端上传 Java 代码,远程动态执行。

关于书上的这部分代码,就不贴了,大家可以直接看书,没有书的可以参考这篇文章:
http://blog.csdn.net/coslay/article/details/49564789
主要原理就是,编译好的字节码,我们把其中对 System 类的引用移花接木到我们自己写的一个 HackSystem 类上,这样,就可以拿到所有往 stdout 输出的内容了,然后显示在网页上。

另一部分就是动态编译上传的 Java 代码,用的是 JDK 自带的 JavaCompiler. 网上搜到的最简单的用法,都是先有一个文件,然后像本地允许 javac 命令一样,将文件名传给 Compiler 输出文件也保存在文件系统中。不过我不太想把代码写到文件中,在内存里就好了,编译好的字节码也不必写入 class 文件,我能拿到 byte 字节流就行。于是搜到了另一篇文章:
http://blog.csdn.net/whuqin/article/details/49818309
主要就是自自定义一个 JavaFileManager 和两个 SimpleJavaFileObject( 一个用字符串表示 Java 源代码的 JavaSourceFileObject, 一个用 byte 数组表示 class 文件的 JavaClassFileObject)

这样我们再写个简单的 Servlet, 获取上传的代码,用自定义的编译器工具编译一下,得到字节码流,然后用书里的代码处理一下,替换掉 sout. 就 OK 了。
具体代码可以在 GitHub 找到,或者引入 Maven:

<!-- https://mvnrepository.com/artifact/com.youthlin/debug -->
<dependency>
    <groupId>com.youthlin</groupId>
    <artifactId>debug</artifactId>
    <version>1.1.1</version>
</dependency>

然后在 web.xml 里配置:

    <servlet>
        <servlet-name>debug</servlet-name>
        <servlet-class>com.youthlin.debug.web.DebugServlet</servlet-class>
    </servlet>
    <servlet-mapping>
        <servlet-name>debug</servlet-name>
        <url-pattern>/debug.do</url-pattern>
    </servlet-mapping>

即可在项目中看到:

上传要执行的 Java 代码及显示执行结果
上传要执行的 Java 代码及显示执行结果


另外,之前博客中提到的 自己实现一个 Mini MVC 框架 MVC 框架也支持了文件上传了,上图中的文件上传功能就是 这个 Mini-MVC 自带的。可以引用 Maven 品尝:

<dependency>
  <groupId>com.youthlin</groupId>
  <artifactId>mini-mvc</artifactId>
  <version>1.1.1</version>
</dependency>

项目代码在 https://github.com/YouthLin/mini-framework 示例代码可以在 https://github.com/YouthLin/examples/tree/master/example-mini-mvc 找到


“远程执行 Java 代码”上的2条回复

发表回复

您的邮箱地址不会被公开。 必填项已用 * 标注

[/鼓掌] [/难过] [/调皮] [/白眼] [/疑问] [/流泪] [/流汗] [/撇嘴] [/抠鼻] [/惊讶] [/微笑] [/得意] [/大兵] [/坏笑] [/呲牙] [/吓到] [/可爱] [/发怒] [/发呆] [/偷笑] [/亲亲]