我正在通过在repl中检查它来玩别人的代码。
它一直调用System / exit,这会导致我的repl。这令人气愤。
在我可以访问的所有代码中,我都嘲笑了这些调用。
但它也调用了一些我没有源代码的库代码,包括java和clojure,这偶尔会导致退出。
有没有办法全局捕获这些调用,因此尝试调用它们不会杀死repl线程?理想情况下,它只会抛出异常。
我认为在java中我可以安装一个新的SecurityManager来实现这个效果,但我从来没有这样做过
这里似乎有一些东西: http://jroller.com/ethdsy/entry/disabling_system_exit
所以我想的是:
(System/setSecurityManager (SecurityManager.))
只有我需要附加
public void checkPermission( Permission permission ) {
if( "exitVM".equals( permission.getName() ) ) {
throw new ExitTrappedException() ;
}
}
到目前为止,我最好的拍摄是:
(System/setSecurityManager
(proxy [SecurityManager] []
(checkPermission [p]
(when (= "exitVM" (.getName p))
(throw (Exception. "exit"))))))
或者
(System/setSecurityManager
(proxy [SecurityManager] []
(checkExit [n] false)))
但他们俩都只是破坏了repl
或者有更好的方法吗?
答案 0 :(得分:2)
使用AspectJ并使用no op拦截对System.exit()的所有调用。
但你是对的,只是配置安全管理器会更安全。
答案 1 :(得分:1)
您还可以使用clj-sandbox来限制您不信任的代码。
答案 2 :(得分:1)
这个对我来说既适用于Clojures简单的REPL,也适用于Lein REPL
(def SM (proxy [SecurityManager] []
(checkPermission
[^java.security.Permission p]
(when (.startsWith (.getName p) "exitVM")
(throw (SecurityException. "exit"))))))
(System/setSecurityManager SM)
阿。甚至在Emacs的Cider REPL中也是如此。
名称实际上是“exitVM.n”,其中n是传递给System / exit的数字退出代码
我仍有一个问题需要扩展此安全管理器。令人惊讶的是,许多Clojure函数调用安全管理器,因此,当在其中使用时,给出一个无限循环,即StackOverflowException。
(对于后者,我提出了另一个问题:Security Manager in Clojure)
答案 3 :(得分:-1)