2016-06-25 3 views
0

コード実行後に潜在的に停止するようにJavaコードを設定しようとしています。Javaを1行ずつ実行しています

スレッド内にすべてのコードを入れて、それを停止したいときにThread.interrupt()を呼び出すことを考えていました。スレッドブロッキングメソッドが実行されている場合(sleepjoinwaitなど)、このメソッドによってコードにはInterruptedExceptionがスローされます。それ以外の場合は、中断したフラグを設定するだけで、すべての行の後にisInterrupted()でチェックする必要があります。

だから今、私がする必要があるすべては...コードのすべての行の後

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

を次のコードを挿入しています。私のJavaコードがStringに格納されている場合、コードの実行のたびにこの行のコードを挿入するにはどうすればよいですか?

私はsplitメソッドをセミコロンで使用し、結果の配列内のすべての要素の間にスレッドコードを挿入することを考えていましたが、forループが機能しないため、forループは終わりを表しません。ステートメント。コードステートメントの終わりを表すので、中括弧も閉じなければならないと思います。

EDIT:ソリューションの試み:

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

なぜコードを1行おきにしたいのですか?コードは高速で実行されるため、重要なポイントとなります。長時間実行されるループの開始時などに実行されます。中断される前に0.000001秒かかるかどうかは問題ではありませんか? *参考:私のマシンは0.000001秒で200個の簡単なステートメントを実行できます。* – Andreas

+0

私は割込み可能なJavaコードを必要としています。私は長時間実行しているJavaコードを与えられています。時間が経過してる。また、私はコードをデバッグしようとしていません。実行するコードが与えられており、いつでも中断する必要があります。 – Ogen

答えて

4

最初に、System.exit()をトリガーすることが目的ならば、そのような呼び出しを別のスレッドに注入してそのスレッドを中断する必要はありません。 System.exit()に電話をしてotherThread.interrupt();と呼ぶと、処理はすぐに終了します。

第2に、あなたの計画はあなたの目標を達成しません。あなたはこの文の周りにあなたの割り込み、その後、終了コードを追加したとします

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

何もこの文は無期限にブロックし、スレッドの中断を尊重しませんプログラムの標準入力に書き込まされていない場合。同様のコードスニペットには、スレッドをブロックする数多くの例があります。どのように細かく注入しても、中断された小切手には到達できません。

第3に、ソースコードを文字列として操作することは、狂気が存在するパスダウンです。そこにはexist Java構文を安全に操作できる構造化データ型に解析するための標準ツールがあります。 でなければならない場合は、ソースコード操作で適切な機器を使用してください。

第4に、追加のコマンドを単に注入するためにソースコードと対話する必要がある特別な理由はありません。ソースをコンパイルし、bytecode injectionを使用して直接コマンドを注入してください。バイトコードはJavaソースよりも構文がはるかに制限されているため、安全性を理由づけて変更するのは簡単です。

ことのすべてを脇に、しかし、あなたは単にあなたの目標は、Javaコードのいくつかの未知のスニペットを実行したがために、プロセスを引き起こすことができるようにすることですようですね。この

のいずれかを実行する必要はありません。いつでも停止できます。これはです。正確にはオペレーティングシステムが設計したもので、プロセスの実行を管理するものです。そのために、POSIXはいくつかの標準規格を提供しています。あなたはプロセスに正常に(あるいはそうではなくて)そのプロセスを終了させることができます。 JavaプロセスSIGINTはCtrl - C)を送信する、SIGTERM、またはSIGHUPはJVMが効果System.exit()をトリガー、そのシャットダウンシーケンスを開始します。

起こる二つの重要なステップがありますときJVM shuts down:すべての登録済みシャットダウンフックが、もしあれば、いくつかの不特定の順序で起動し、終了するまで同時に実行することが許可されている第1段階で

。第2段階では、ファイナライズ時にファイナライズが有効になっていれば、すべての呼び出されないファイナライザが実行されます。これが完了すると、仮想マシンは停止します。言い換えれば

は、限り、あなたは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)また、[javaサンドボックスライブラリ](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

関連する問題