Запретить систему / выход в коде, к которому у меня нет доступа - PullRequest
7 голосов
/ 11 февраля 2011

Я играю с чужим кодом, изучая его в ответе.

Он продолжает вызывать 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)))

Но они оба просто уничтожают реплику

Или есть лучший способ сделать это?

Ответы [ 4 ]

2 голосов
/ 11 февраля 2011

Используйте AspectJ и перехватывайте все вызовы System.exit () без операции.

Но вы правы, просто настройка менеджера безопасности была бы более разумной.

1 голос
/ 09 января 2014

Этот работает для меня как в Clojures simple REPL, так и в REPL Lein, тоже

(def SM (proxy [SecurityManager] [] 
          (checkPermission 
            [^java.security.Permission p] 
            (when (.startsWith (.getName p) "exitVM") 
              (throw (SecurityException. "exit")))))) 

(System/setSecurityManager SM)

Ах.Даже в Cider REPL в Emacs.

На самом деле это имя "exitVM.n", где n - это числовой код выхода, переданный в System / exit

. У меня все еще есть проблема с расширением этогоменеджер по безопасности.Удивительно, что многие функции Clojure вызывают диспетчер безопасности, и, следовательно, при использовании внутри него дают бесконечный цикл, иначе StackOverflowException.

(Для последнего я открыл другой вопрос: Менеджер безопасности в Clojure )

1 голос
/ 13 февраля 2011

Вы также можете использовать clj-sandbox для ограничения кода, которому вы не доверяете.

0 голосов
/ 11 февраля 2011
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...