別のJavaアプリケーションを実行するバッチファイルを実行する必要があります。正常に実行されるかどうかは気にしません。エラーをキャプチャする必要はありません。
ProcessBuilder でこれを行うことは可能ですか?エラーをキャプチャしないとどうなりますか?
ただし、私の要件は、別のJavaアプリケーションを実行することです。
Runtime.getRuntime().exec()
アプローチは、すぐにわかるように非常に面倒です。
Apache Commons Exec プロジェクトを見てください。 Runtime.getRuntime().exec()
およびProcessBuilder
APIの使用に関連する多くの一般的な問題の方法を抽象化します。
次のように簡単です:
String line = "myCommand.exe";
CommandLine commandLine = CommandLine.parse(line);
DefaultExecutor executor = new DefaultExecutor();
executor.setExitValue(1);
int exitValue = executor.execute(commandLine);
はい、ProcessBuilderを使用して可能です。
ProcessBuilderの例:
import Java.io.*;
import Java.util.*;
public class CmdProcessBuilder {
public static void main(String args[])
throws InterruptedException,IOException
{
List<String> command = new ArrayList<String>();
command.add(args[0]);
ProcessBuilder builder = new ProcessBuilder(command);
Map<String, String> environ = builder.environment();
final Process process = builder.start();
InputStream is = process.getInputStream();
InputStreamReader isr = new InputStreamReader(is);
BufferedReader br = new BufferedReader(isr);
String line;
while ((line = br.readLine()) != null) {
System.out.println(line);
}
System.out.println("Program terminated!");
}
}
以下の例を確認してください。
http://www.rgagnon.com/javadetails/Java-0014.html
http://www.Java-tips.org/Java-se-tips/Java.util/from-runtime.exec-to-processbuilder.html
バッチ命令またはその他のアプリケーションを使用して実行できます
Runtime.getRuntime().exec(cmd);
また、次のコードを使用して、実行して戻りコードを取得するのを待つことができます(正しく実行されたかどうかを確認するため)。
Process p = Runtime.getRuntime().exec(cmd);
p.waitFor();
int exitVal = p.exitValue();
さまざまな種類の呼び出しの完全な説明がここにあります http://www.rgagnon.com/javadetails/Java-0014.html
ProcessBuilder
を使用してリモートアプリケーションを実行する方法の例を次に示します。入出力やエラーを気にしないので、次のようにできます。
_List<String> args = new ArrayList<String>();
args.add ("script.bat"); // command name
args.add ("-option"); // optional args added as separate list items
ProcessBuilder pb = new ProcessBuilder (args);
Process p = pb.start();
p.waitFor();
_
waitFor()
メソッドは、プロセスが終了するまで待機してから続行します。このメソッドはプロセスのエラーコードを返しますが、気にしないので、この例には入れませんでした。
ProcessBuilder
を使用してコマンドを実行する方法を知っていると仮定します。
Javaからコマンドを実行すると、常にプロセスからstdoutおよびstderrストリームを読み取る必要があります。そうしないと、stdoutまたはstderrブロックを書き込むためにバッファがいっぱいになり、プロセスを続行できません。
私はこれが古いスレッドであることを知っていますが、ルートレベルのアクセスを除いてこのスレッドがOPと同じことをしようとしているのを見つけたので、実装を入れる価値があるかもしれませんが、実際には解決策が見つかりませんでした探していました。以下のメソッドは、エラーチェックに関係なく、またはコマンドが正常に実行された場合でもコマンドを実行するためだけに使用される静的ルートレベルシェルを作成します。
Android作成した懐中電灯アプリを使用して、LEDを異なるレベルの明るさに設定できます。すべてのエラーチェックとその他の毛羽立ちを取り除くことで、指定したLEDに切り替えることができますわずか3msの明るさレベルで、LightTones(ライト付きのRingTones)への扉を開きます。アプリ自体の詳細については、こちらをご覧ください: http://forum.xda-developers.com/showthread.php ?t = 2659842
以下は、クラス全体です。
public class Shell {
private static Shell rootShell = null;
private final Process proc;
private final OutputStreamWriter writer;
private Shell(String cmd) throws IOException {
this.proc = new ProcessBuilder(cmd).redirectErrorStream(true).start();
this.writer = new OutputStreamWriter(this.proc.getOutputStream(), "UTF-8");
}
public void cmd(String command) {
try {
writer.write(command+'\n');
writer.flush();
} catch (IOException e) { }
}
public void close() {
try {
if (writer != null) { writer.close();
if(proc != null) { proc.destroy(); }
}
} catch (IOException ignore) {}
}
public static void exec(String command) { Shell.get().cmd(command); }
public static Shell get() {
if (Shell.rootShell == null) {
while (Shell.rootShell == null) {
try { Shell.rootShell = new Shell("su"); //Open with Root Privileges
} catch (IOException e) { }
}
}
return Shell.rootShell;
}
}
次に、アプリ内の任意の場所でコマンドを実行します(たとえば、LEDの明るさを変更する)。
Shell.exec("echo " + bt.getLevel() + " > "+ flashfile);
以下のスニペットコードは、ProcessBuilderを使用して外部Javaプログラムをコンパイルおよび実行するために記述されています。これは、外部プログラムを実行する方法と同じです。 OS環境でJava_HOMEを設定する必要があります。 more を参照
package com.itexpert.exam;
import Java.io.BufferedReader;
import Java.io.IOException;
import Java.io.InputStream;
import Java.io.InputStreamReader;
public class JavaProcessBuilder {
/**
* Provide absolute Java file path
*/
private static final String Java_FILE_LOCATION = "D:\\Test.Java";
public static void main(String args[]) throws IOException{
String command[] = {"javac",Java_FILE_LOCATION};
ProcessBuilder processBuilder = new ProcessBuilder(command);
Process process = processBuilder.start();
/**
* Check if any errors or compilation errors encounter then print on Console.
*/
if( process.getErrorStream().read() != -1 ){
print("Compilation Errors",process.getErrorStream());
}
/**
* Check if javac process execute successfully or Not
* 0 - successful
*/
if( process.exitValue() == 0 ){
process = new ProcessBuilder(new String[]{"Java","-cp","d:\\","Test"}).start();
/** Check if RuntimeException or Errors encounter during execution then print errors on console
* Otherwise print Output
*/
if( process.getErrorStream().read() != -1 ){
print("Errors ",process.getErrorStream());
}
else{
print("Output ",process.getInputStream());
}
}
}
private static void print(String status,InputStream input) throws IOException{
BufferedReader in = new BufferedReader(new InputStreamReader(input));
System.out.println("************* "+status+"***********************");
String line = null;
while((line = in.readLine()) != null ){
System.out.println(line);
}
in.close();
}
}
Apache commons execライブラリよりも優れたライブラリがあることがわかりました。 Java Secure Shell(JSch)を使用してジョブを実行できます。
同じ問題がありました。 JSchを使用してこの問題を解決しました。 Apache commonsには、異なるサーバーでコマンドを実行する際にいくつかの問題がありました。さらに、JSchはInputStreamsの結果とエラーを返しました。もっとエレガントだと思いました。サンプルソリューションはこちらにあります: http://wiki.jsch.org/index.php?Manual%2FExamples%2FJschExecExample
import Java.io.InputStream;
import Java.io.BufferedReader;
import Java.io.InputStreamReader;
import org.Apache.commons.exec.*;
import com.jcraft.*;
import com.jcraft.jsch.JSch;
import com.jcraft.jsch.Session;
import com.jcraft.jsch.ChannelExec;
import Java.util.Arrays;
import Java.util.List;
import Java.util.ArrayList;
import Java.util.HashMap;
public class exec_linux_cmd {
public HashMap<String,List<String>> exec_cmd (
String USERNAME,
String PASSWORD,
String Host,
int port,
String cmd)
{
List<String> result = new ArrayList<String>();
List<String> errors = new ArrayList<String>();
HashMap<String,List<String>> result_map = new HashMap<String,List<String>>();
//String line = "echo `eval hostname`";
try{
JSch jsch = new JSch();
/*
* Open a new session, with your username, Host and port
* Set the password and call connect.
* session.connect() opens a new connection to remote SSH server.
* Once the connection is established, you can initiate a new channel.
* this channel is needed to connect and remotely execute the program
*/
Session session = jsch.getSession(USERNAME, Host, port);
session.setConfig("StrictHostKeyChecking", "no");
session.setPassword(PASSWORD);
session.connect();
//create the excution channel over the session
ChannelExec channelExec = (ChannelExec)session.openChannel("exec");
// Gets an InputStream for this channel. All data arriving in as messages from the remote side can be read from this stream.
InputStream in = channelExec.getInputStream();
InputStream err = channelExec.getErrStream();
// Set the command that you want to execute
// In our case its the remote Shell script
channelExec.setCommand(cmd);
//Execute the command
channelExec.connect();
// read the results stream
BufferedReader reader = new BufferedReader(new InputStreamReader(in));
// read the errors stream. This will be null if no error occured
BufferedReader err_reader = new BufferedReader(new InputStreamReader(err));
String line;
//Read each line from the buffered reader and add it to result list
// You can also simple print the result here
while ((line = reader.readLine()) != null)
{
result.add(line);
}
while ((line = err_reader.readLine()) != null)
{
errors.add(line);
}
//retrieve the exit status of the remote command corresponding to this channel
int exitStatus = channelExec.getExitStatus();
System.out.println(exitStatus);
//Safely disconnect channel and disconnect session. If not done then it may cause resource leak
channelExec.disconnect();
session.disconnect();
System.out.println(exitStatus);
result_map.put("result", result);
result_map.put("error", errors);
if(exitStatus < 0){
System.out.println("Done--> " + exitStatus);
System.out.println(Arrays.asList(result_map));
//return errors;
}
else if(exitStatus > 0){
System.out.println("Done -->" + exitStatus);
System.out.println(Arrays.asList(result_map));
//return errors;
}
else{
System.out.println("Done!");
System.out.println(Arrays.asList(result_map));
//return result;
}
}
catch (Exception e)
{
System.out.print(e);
}
return result_map;
}
//CommandLine commandLine = CommandLine.parse(cmd);
//DefaultExecutor executor = new DefaultExecutor();
//executor.setExitValue(1);
//int exitValue = executor.execute(commandLine);
public static void main(String[] args)
{
//String line = args[0];
final String USERNAME ="abc"; // username for remote Host
final String PASSWORD ="abc"; // password of the remote Host
final String Host = "3.98.22.10"; // remote Host address
final int port=22; // remote Host port
HashMap<String,List<String>> result = new HashMap<String,List<String>>();
//String cmd = "echo `eval hostname`"; // command to execute on remote Host
exec_linux_cmd ex = new exec_linux_cmd();
result = ex.exec_cmd(USERNAME, PASSWORD , Host, port, cmd);
System.out.println("Result ---> " + result.get("result"));
System.out.println("Error Msg ---> " +result.get("error"));
//System.out.println(Arrays.asList(result));
/*
for (int i =0; i < result.get("result").size();i++)
{
System.out.println(result.get("result").get(i));
}
*/
}
}
編集1:Unixで実行されているプロセス(長時間実行されている場合)を見つけるには、ps -aux | grep Java
。プロセスIDは、実行中のUNIXコマンドとともにリストされる必要があります。
戻り値を気にしない場合は、単にRuntime.getRuntime().exec("path.to.your.batch.file");
を使用できます
単純に Runtime.exec() を使用できます