有 Java 编程相关的问题?

你可以在下面搜索框中键入要查询的问题!

java取消动态CallyLoaded可调用项我没有编写

我有一些代码可以从一个目录中的几个JAR动态加载类。因为JAR中的代码是不可信的,所以我希望通过“沙箱化”来保护主应用程序,使其免受编码错误或恶意动态类的攻击。我试图做的一件事是“时间框”不受信任代码的执行,如果执行时间太长(例如,因为它卡在无限循环中),就将其杀死。我试图使用Callable和Future实现这一点,不是因为我想并行运行任务(我不想),而是想利用已完成的工作来提供返回值、捕获异常和取消运行任务。然而,当我在一些测试代码上运行它时,我发现调用Future。cancel(true)似乎没有取消任务

我在StackOverflow上看到了几个关于为什么会发生这种情况的问题(such as this one),答案总是一样的:cancel(true)通过在运行可调用函数的线程上调用interrupt()来工作,这要求在取消生效之前,在可中断()的操作(例如thread.sleep()上取消的任务块)。因为我不控制代码的执行,所以不能保证它会这样做,所以我不能确定我是否取消了它

有没有什么方法可以让我运行动态加载的代码,然后在执行过程中杀死它并确保它死掉,即使它永远不会阻塞可中断的操作

// Assume: ExecutorService pool, Callable<T> task,
//  long timeout, TimeUnit timeUnit
Future<T> future = pool.submit(task);
T result;

try {
    result = future.get(timeout, timeUnit);
    // do something with result
} catch (TimeoutException ex) {
    future.cancel(true);
    // handle timeout
} catch (ExecutionException ex) {
    // handle exeception thrown by task
} catch (InterruptedException ex) {
    // handle InterruptedException
}

共 (2) 个答案

  1. # 1 楼答案

    Thread.stopThread.destroy旁边,为了实现最终的沙盒,可以在带有Process p = Runtime.getRuntime().exec( cmd );的子进程中生成一个完整的JVM。这个过程真的可以被Process.destroy if necessary.破坏

    要简化流程创建,请使用ProcessBuilder。另外,查看可用的教程(this one is in french)来执行流程,等待完成(使用waitFor),并管理流

    我在一个需要将ps文档转换为pdf的产品中看到了它的工作原理。我们正在转储ps文件,执行ps2pdf,然后读取输出文件

    赞成/反对Process

    • (+)将真正的沙箱放入一个单独的进程中
    • (-)双方的沟通 JVM更难处理
    • (-)使应用程序的部署复杂化 (JVM的路径、选项、当前目录等)

    请注意Thread.stopThread.destroy(我不确定它是否已实际实现)是不受鼓励的,因为它们在锁获取和释放方面是不安全的。确保您阅读了Why Are Thread.stop, Thread.suspend, Thread.resume and Runtime.runFinalizersOnExit Deprecated?如果在单独线程中运行的不受信任模块没有弄乱应用程序的锁,最坏的情况是它自己的锁,那么Thread.stop可能仍然是最好的选择

    赞成/反对Thread.stop

    • (+)易于使用
    • (+)可信和不可信代码之间的通信很容易
    • (-)不赞成
    • (-)在某些非常特殊的情况下可能不安全,必须首先进行评估
  2. # 2 楼答案

    取消,或者说线程中断,机制基本上是协作的,您无法中断恶意任务。你唯一的选择是Thread.stop()他们,这是非常危险的,原因很多