2013-04-11 3 views
6

Мой главный поток создал новую тему И когда новый поток вызовет System.exit(-1), моя основная тема будет закрыта. Как я могу обработать код выхода и сохранить основной поток в живых?System.exit в Java Thread

PS. новый поток вызовет некоторый метод в другом файле .jar, поэтому я не могу его изменить.

+0

ли этот метод реагировать на перерывы? У вас есть способ заставить его выйти? – assylias

+2

Err, не закончится ли JVM в конце концов? Независимо от прерываний? – Thihara

+2

@Thihara Вопрос выглядит следующим образом: как остановить эту нить, не останавливая основной поток. Конечно, System.exit завершит JVM, и, похоже, OP это понимает. Но на самом деле я вижу, что это также можно понимать как: новый поток вызывает System.exit, и я хочу, чтобы это не было сделано. Это неясно ... – assylias

ответ

2

класс:

public class MySecurityManager extends SecurityManager { 
    @Override 
    public void checkPermission(Permission perm) { 
    } 

    @Override 
    public void checkPermission(Permission perm, Object context) { 
    } 

    @Override 
    public void checkCreateClassLoader() { 
    } 

    @Override 
    public void checkAccess(Thread t) { 
    } 

    @Override 
    public void checkAccess(ThreadGroup g) { 
    } 

    @Override 
    public void checkExit(int status) { 
     throw new SecurityException("not allow to call System.exit"); 
    } 

    @Override 
    public void checkExec(String cmd) { 
    } 

    @Override 
    public void checkLink(String lib) { 
    } 

    @Override 
    public void checkRead(FileDescriptor fd) { 
    } 

    @Override 
    public void checkRead(String file) { 
    } 

    @Override 
    public void checkRead(String file, Object context) { 
    } 

    @Override 
    public void checkWrite(FileDescriptor fd) { 
    } 

    @Override 
    public void checkWrite(String file) { 
    } 

    @Override 
    public void checkDelete(String file) { 
    } 

    @Override 
    public void checkConnect(String host, int port) { 
    } 

    @Override 
    public void checkConnect(String host, int port, Object context) { 
    } 

    @Override 
    public void checkListen(int port) { 
    } 

    @Override 
    public void checkAccept(String host, int port) { 
    } 

    @Override 
    public void checkMulticast(InetAddress maddr) { 
    } 

    @Override 
    public void checkPropertiesAccess() { 
    } 

    @Override 
    public void checkPropertyAccess(String key) { 
    } 

    @Override 
    public boolean checkTopLevelWindow(Object window) { 
     return super.checkTopLevelWindow(window); 
    } 

    @Override 
    public void checkPrintJobAccess() { 
    } 

    @Override 
    public void checkSystemClipboardAccess() { 
    } 

    @Override 
    public void checkAwtEventQueueAccess() { 
    } 

    @Override 
    public void checkPackageAccess(String pkg) { 
    } 

    @Override 
    public void checkPackageDefinition(String pkg) { 
    } 

    @Override 
    public void checkSetFactory() { 
    } 

    @Override 
    public void checkMemberAccess(Class<?> clazz, int which) { 
    } 

    @Override 
    public void checkSecurityAccess(String target) { 
    } 
} 


на startop:

System.setSecurityManager(new MySecurityManager()); 
+0

это работает! ~ JVM выбрасывает исключение без выхода – Dozer

5

Вы не можете.

Terminates the currently running Java Virtual Machine. The argument serves as a status code; by convention, a nonzero status code indicates abnormal termination.

Это Javadoc.

Таким образом, метод прервет всю JVM. Не только нить ....

+0

* Вы не можете. * Это неверно, большая часть java-безопасности/кода, чувствительного к ОС, может быть предотвращена с помощью SecurityManager, это встроенная функциональность с самого начала Java. – bestsss

+0

О да, это проскользнуло мне ... Но только потому, что я не знал об этом ... Спасибо за информацию. – Thihara

5

Ваш вопрос очень неясен, но если вызов System.exit завершается успешно, ОС прекратит ваше приложение.

Если вы хотите, чтобы System.exit не удался, вы можете установить диспетчер безопасности и предотвратить это. Помимо этого вы можете обработать код через пользовательский загрузчик классов и удалить вызов.

Редактировать: если вы идете в w/Security manager, скорее всего, бросая SecurityException, будет завершен поток. Если это не так - обмануть и бросить ThreadDeath. Если это еще не так - просто держите нить, например. for(;;) Thread.sleep(10000); Последний протекает поток и его ресурсы, но, по крайней мере, не будет убивать ваше приложение.

link to similar question

+0

Я думаю, что «менеджер безопасности» может удовлетворить мои потребности, я попробую. – Dozer

0

Использование Java SecurityManager, чтобы сохранить основной поток от выхода и запустить другой код резьбы с SecurityManager.

Редактировать: Примите идею от Tomcat или другого сервера, как они управляют кодом, например <% System.exit(1); %>, в JSP.

+0

Вы не можете запускать * другие темы * w/security manager, это глобально. Вы можете обнаружить потоки в менеджере, но это другое. – bestsss

Смежные вопросы