2016-06-25 3 views
0

코드 실행 후 잠재적으로 Java 코드가 중지 될 수 있도록 설정하려고합니다.Java를 줄 단위로 실행

나는 내 코드를 모두 스레드에 넣고 멈추고 싶을 때 Thread.interrupt()을 호출 할 생각이었다. 스레드 차단 메서드가 실행중인 경우에만이 메서드는 InterruptedException을 throw합니다 (예 : sleep, join, wait 등). 그렇지 않으면 그냥 중단 된 플래그를 설정하고 우리는 모든 라인 이후에 isInterrupted()을 통해 확인해야합니다.

그래서 지금은 오직 할 필요가 ... 다음 코드를 삽입입니다 코드의 모든 라인 후

if (myThread.isInterrupted()) { 
    System.exit(0); 
} 

. 내 Java 코드가 String에 저장되어있는 경우 코드 실행마다마다이 코드 행을 삽입 할 수 있습니까?

세미콜론에 분할 메서드를 사용하고 결과 배열의 모든 요소 사이에 스레드 코드를 삽입하는 것이 생각 났지만 예를 들어 루프의 끝에 세미콜론이 있기 때문에 작동하지 않습니다. 성명서. 나는 또한 코드 중괄호의 끝을 나타 내기 때문에 중괄호를 닫을 때도 나눠야한다고 생각한다.

편집 : 솔루션 시도가 :

final String javaCode = "if (myString.contains(\"foo\")) { return true; } int i = 0;"; 
final String threadDelimiter = "if (thisThread.isInterrupted()) { System.exit(0); }"; 
final StringBuffer sb = new StringBuffer(); 

for (int i = 0; i < javaCode.length(); i++) { 
    final char currChar = javaCode.charAt(i); 

    sb.append(currChar); 
    if ("{};".contains(currChar + "")) { 
     sb.append(threadDelimiter); 
    } 
} 

System.out.println(sb); 

이 코드는 거의 정확하지만, 세미콜론을 사용하여 루프의 모든 종류를 위해 작동하지 않을 것입니다. 또한 중괄호가없는 루프에서는 작동하지 않습니다.

+6

"코드를 실행 한 후에 잠재적으로 Java 코드를 중지하려고합니다. *"- 무엇을 ?? 왜? 뭔가 디버깅하려고합니까? 그렇다면 디버거를 사용하여 프로그램을 한 줄씩 일시 중지하고 단계별로 실행할 수 있습니다. 그렇지 않으면, 당신의 목표는 무엇입니까? 간단히'SIGINT '를 보내면 프로그램을 종료시킬 수있다. – dimo414

+1

왜 모든 코드 행 뒤에 * 할 것인가? 코드가 빠르게 실행되므로 중요한 부분 만 수행하면됩니다. 장기 실행 루프의 시작 부분 등. 중단되기 전에 다시 0.000001 초가 걸릴지는 중요하지 않습니다. 그렇습니까? * 참고 : 내 컴퓨터는 0.000001 초에 200 개의 간단한 문을 수행 할 수 있습니다. * – Andreas

+0

인터럽트 가능 자바 코드가 필요합니다. 장기 실행 자바 코드를 부여 받았기 때문에 일정 금액만큼 빨리 중지 할 수 있기를 바랍니다. 시간이지나갑니다. 또한, 나는 코드를 디버깅하려하지 않는다. 나는 실행할 코드를 받았고 어느 시점에서든 코드를 중단 할 수 있어야합니다. – Ogen

답변

4

우선, System.exit()을 트리거하는 것이 이러한 호출을 다른 스레드에 주입 한 다음 해당 스레드를 인터럽트 할 필요가 없다. System.exit()으로 전화를 걸어 otherThread.interrupt();라고 말하면 프로세스가 빨리 종료됩니다.

둘째로, 계획은 목표를 달성하지 못합니다. 아무 것도이 사항이 무기한 차단 프로그램의 표준 입력에 기록되지되고 있으며, 스레드 중단을 존중하지 않을 경우

new Scanner(System.in).next(); 

:이 문 주위에 당신의 인터럽트 당시 종료 코드를 추가하자. 스레드를 차단하게 만드는 비슷한 코드 스 니펫의 수많은 예제가 있습니다. 아무리 세분화되어 있더라도 중단 된 수표에 도달하지 못할 수 있습니다.

셋째, 소스 코드를 문자열로 조작하는 것은 광기가있는 경로입니다. 거기에 exist 안전한 구문을 조작 할 수있는 구조화 된 데이터 형식으로 Java 구문을 구문 분석하는 표준 도구. 의 경우 소스 코드 조작은 올바른 장비를 사용해야합니다.

넷째, 추가 명령을 주입하기 위해 소스 코드와 상호 작용해야하는 특별한 이유가 없습니다. 소스를 컴파일하고 bytecode injection을 사용하여 직접 명령을 주입하십시오. 바이트 코드는 Java 소스보다 훨씬 제한적인 구문을 가지고 있으므로 안전하게 추론하고 변형하는 것이 더 쉽습니다.

이 모든 것을 제쳐 놓고, 그러나, 당신은 단순히 당신의 목표는 자바 코드의 알 수없는 조각을 실행 만에 과정을 야기 할 수있다처럼 소리가이

을 수행 할 필요가 없습니다 언제든지 중지하십시오.이것은 입니다. 정확히 운영 체제에서 설계된 것으로서 프로세스 실행을 관리합니다. 이를 위해 POSIX는 몇 가지 표준을 제공합니다. signals 프로세스로 정상적으로 (또는 그렇게 우아하지 않게) 프로세스를 종료시킬 수 있습니다. SIGINT Java 프로세스를 보내기 - (Ctrl 키C) SIGTERM, 또는 SIGHUP하면 JVM 효과적으로 System.exit()을 트리거의 종료 시퀀스를 시작하게됩니다.

발생하는 두 가지 주요 단계가 있습니다 때 JVM shuts down : 등록 된 모든 종료 고리가있는 경우, 일부 지정되지 않은 순서로 시작하고 완료 될 때까지 동시에 실행할 수있는 첫 번째 단계에서

. 두 번째 단계에서는 종료하지 않고 종료 할 수있게 설정하면 실행되는 모든 초기화되지 않은 종료 기가 실행됩니다. 이 작업이 완료되면 가상 시스템이 중지됩니다. 즉

는만큼 당신이 prevent 당신이 registering malicious shutdown hooks에서 실행 중이거나 이러한 신호를 보내는 runFinalizersOnExit()를 호출하고있는 코드가 원인이됩니다 JVM은 즉시 종료합니다.

유스 케이스의 경우에도 허용되지 않는 경우 SIGKILL을 보내십시오. OS는 종료 훅이나 파이널 라이저를 실행할 기회없이 프로세스가 즉시 종료되도록합니다. JVM 내에서 Runtime.halt()으로 전화를해서 대략 동일한 작업을 수행 할 수도 있습니다.

+0

그러면 메인 스레드가 멈추지 않을까요? 전체 응용 프로그램이 실행을 멈추기를 원하지 않기 때문에 필자는 다음 Java 코드 조각을 계속 실행하고 싶습니다. 이 과정을 자신의 프로세스에서 실행해야한다는 의미입니까? – Ogen

+0

@Ogen 답변에 덧붙여 [어떻게 외부 Java 클래스를 동적으로 컴파일하고로드합니까?] (http://stackoverflow.com/a/21544850) 및 [Java 애플리케이션의 악성 코드에 대한 샌드 박스] (http://stackoverflow.com/a/502388) 또한 [자바 샌드 박스 라이브러리] (https://sourceforge.net/p/dw-sandbox/wiki/Java-Sandbox%200.3%20Documentation/)가 있습니다. 구성 가능한 최대 실행 시간. – Onur

+0

@Ogen 그렇습니다. 예를 들어, 격리 된 JVM에서 각 스 니펫을 실행해야합니다 (원래 예제 인 'System.exit()'도 주 스레드를 종료합니다). 이는 [sandboxing] (https://en.wikipedia.org/wiki/Sandbox_ (computer_security))이라는 표준 사례입니다. 진정으로 신뢰할 수없는 코드를 사용하면 프로세스가 아닌 격리 된 가상 시스템에서 각 코드 조각을 실행하는 것이 좋습니다. – dimo414