3 分ごとにクラスを実行する単純な Java プログラムを作成しようとしています。これらのクラスを呼び出すために Timer と TimerTask を使用しています。
import java.io.IOException;
import java.util.ArrayList;
import java.util.Date;
import java.util.List;
import java.util.Timer;
import java.util.TimerTask;
public class Receiver
{
public static void main(String[] args)
{
System.out.println("Time now is -> " + new Date());
Timer timer = new Timer();
TimerTask task = new ReceiverTask();
timer.scheduleAtFixedRate(task, 0, 180000);
}
}
class DPGReceiverTask extends TimerTask
{
private ArrayList<TaskArgs> m_tasks = new ArrayList<TaskArgs>();
public ReceiverTask()
{
m_tasks.add(new TaskArgs("com.comp.Receiver", new String[] { "ARG1", "ARG2"}));
}
public void run()
{
System.out.println("Receiver Started!");
String classpath = "D:/Receiver;D:/Receiver/lib/*";
int i = 0;
ArrayList<Process> processes = new ArrayList<Process>();
for (TaskArgs task: m_tasks)
{
try
{
List<String> command = new ArrayList<String>();
command.add(System.getProperty("java.home") + "/bin/java");
command.add("-classpath");
command.add(classpath);
command.add(task.Name);
String[] args = task.Args;
for (String arg : args)
{
command.add(arg);
}
Process process = new ProcessBuilder(command).start();
processes.add(process);
}
catch (IOException e)
{
e.printStackTrace();
}
}
try
{
for (Process process : processes)
{
int exitCode = process.waitFor();
}
}
catch (InterruptedException e)
{
e.printStackTrace();
}
}
}
public class TaskArgs
{
public TaskArgs(String name, String[] args)
{
Name = name;
Args = args;
}
public String Name;
public String[] Args;
}
winsw
次にJavaを実行するbatファイルを実行するサービスを実装して作成しました。
receiverTask.bat
java -classpath ReceiverService.jar Receiver
receiverTask.xml
<service>
<id>receiverTask</id>
<name>receiverTask</name>
<description>receiver Service</description>
<executable>receiverTask.bat</executable>
<logpath>D:\winsw\logs\Service</logpath>
<log mode="roll-by-time">
<pattern>yyyyMMdd</pattern>
</log>
<depend>Spooler</depend>
<startargument>run</startargument>
<stopargument>stop</stopargument>
</service>
この現在の実装には 2 つの問題があります。
- 現在の Java が終了しているかどうかに関係なく、Timer は 3 分後に別のプロセスを開始します。
- サービス (winsw - Java サービス ラッパー) を停止しても、java.exe または cmd.exe を実行しているプロセスは停止しません。
プロセスを強制終了するために destroy メソッドを追加しようとしましたが、これで本当によいのでしょうか?
...
try
{
for (Process process : processes)
{
Timer t = new Timer();
TimerTask killer = new TimeoutProcessKiller(process);
t.schedule(killer, 178000);
int exitCode = process.waitFor();
killer.cancel();
}
}
public class TimeoutProcessKiller extends TimerTask
{
private Process p;
public TimeoutProcessKiller(Process p)
{
this.p = p;
}
public void run()
{
p.destroy();
}
}
誰か提案はありますか?