JVMを再起動する方法はありますか?実際に終了するのではなく、すべてのクラスを閉じてリロードし、メインから実行しますか?
あなたの最善の策は、おそらくループ内でJavaインタープリターを実行し、ただ終了することです。例えば:
#!/bin/sh
while true
do
Java MainClass
done
完全に再起動またはシャットダウンする機能が必要な場合は、終了ステータスをテストできます。
#!/bin/sh
STATUS=0
while [ $STATUS -eq 0 ]
do
Java MainClass
STATUS=$?
done
Javaプログラム内で、System.exit(0)を使用して「再起動」することを示し、System.exit(1)を使用して停止して停止したままにすることを示すことができます。 。
IBMのJVMには、「リセット可能」と呼ばれる機能があり、ユーザーが求めていることを効果的に実行できます。
IBM JVM以外は、可能だとは思いません。
実際の「再起動」ではありませんが、次のとおりです。
独自のクラスローダーを構築し、それを使用してすべてのクラス(ブートストラップを除く)をロードできます。次に、「再起動」する場合は、次のことを確認してください。
この手順は、Webサーバーでwebappを「ホットスワップ」する際に(ある程度)使用されます。
ただし、静的クラスメンバとJVM「グローバル」オブジェクト(制御されていないGCルートによってアクセスされるオブジェクト)は残ります。たとえば、Locale.setLocale()はLocaleの静的メンバーに影響します。 Localeクラスはシステムクラスローダーによってロードされるため、「再起動」されません。つまり、Locale.setLocale()で使用されていた古いLocaleオブジェクトは、明示的にクリーンアップされていなければ、後で使用可能になります。
さらにもう1つの方法は、クラスのインスツルメンテーションです。しかし、私はそれについてほとんど知らないので、私はアドバイスを提供することをheしています。
アプリケーションサーバーで作業している場合は、通常、組み込みのホットデプロイメントメカニズムが付属しており、アプリケーションを再デプロイすると、アプリケーション(Webアプリ、エンタープライズアプリ)のすべてのクラスが再ロードされます。
それ以外の場合は、商用ソリューションを検討する必要があります。 Java Rebel( http://www.zeroturnaround.com/javarebel/ )はそのようなオプションの1つです。
私の知る限り、そのような方法はありません。
それを行う方法がある場合、現在のロードされたコードに大きく依存して、保持されているすべてのリソースを適切に解放し、グレースフルリスタートを提供することに注意してください(ファイル、ソケット/ tcp/http /データベース接続、スレッドなどについて考えてください) )。
Jboss ASなどの一部のアプリケーションは、コンソールでCtrl + Cをキャプチャし、正常なシャットダウンを提供してすべてのリソースを閉じますが、これはアプリケーション固有のコードであり、JVM機能ではありません。
JavaXでは簡単です。標準関数 nohupJavax() または restart() を使用できます。
まあ、私は現在これを持っています、それは完全に動作し、完全にOSに依存しません。唯一動作する必要があるものは、パス/ etcなしでJavaプロセスを実行することですが、これも修正できると思います。
RunnableWithObjectとrestartMinecraft()以外の小さなコードはすべてstackoverflowからのものです。
次のように呼び出す必要があります。
restartMinecraft(getCommandLineArgs());
したがって、基本的には次のようになります。
はい、それは私のMinecraftプロジェクトから直接取得されます:)
コード:
Tools.isProcessExited()メソッド:
public static boolean isProcessExited(Process p) {
try {
p.exitValue();
} catch (IllegalThreadStateException e) {
return false;
}
return true;
}
Tools.restartMinecraft()メソッド:
public static void restartMinecraft(String args) throws IOException, InterruptedException {
//Here you can do shutdown code etc
Process p = Runtime.getRuntime().exec(args);
RunnableWithObject<Process> inputStreamPrinter = new RunnableWithObject<Process>() {
@Override
public void run() {
// TODO Auto-generated method stub
while (!Tools.isProcessExited(data)) {
try {
while (data.getInputStream().available() > 0) {
System.out.print((char) data.getInputStream().read());
}
} catch (IOException e) {
}
}
}
};
RunnableWithObject<Process> errorStreamPrinter = new RunnableWithObject<Process>() {
@Override
public void run() {
// TODO Auto-generated method stub
while (!Tools.isProcessExited(data)) {
try {
while (data.getErrorStream().available() > 0) {
System.err.print((char) data.getErrorStream().read());
}
} catch (IOException e) {
}
}
}
};
inputStreamPrinter.data = p;
errorStreamPrinter.data = p;
new Thread(inputStreamPrinter).start();
new Thread(errorStreamPrinter).start();
p.waitFor();
System.out.println("Minecraft exited. (" + p.exitValue() + ")");
System.exit(p.exitValue());
}
Tools.getCommandLineArgs()メソッド:
public static String getCommandLineArgs() {
String cmdline = "";
List<String> l = ManagementFactory.getRuntimeMXBean().getInputArguments();
cmdline += "Java ";
for (int i = 0; i < l.size(); i++) {
cmdline += l.get(i) + " ";
}
cmdline += "-cp " + System.getProperty("Java.class.path") + " " + System.getProperty("Sun.Java.command");
return cmdline;
}
Aaaaそして最後にRunnableWithObjectクラス:
package generic.minecraft.infinityclient;
public abstract class RunnableWithObject<T> implements Runnable {
public T data;
}
幸運を :)
JMXを使用して同様のことを行い、JMXを使用してモジュールを「アンロード」してから「リロード」します。舞台裏では、彼らは別のクラスローダーを使用していると確信しています。