1

.classコンパイルされたコード ( ) Java を Java コード自体から実行するにはどうすればよいですか?

サーバー側でJavaコードをコンパイルして実行し、エンドユーザーに出力を提供するなど、一種の提供サービスを行っています。

誰でもこれを達成するアプローチを提案できますか?

import java.io.*;

public class demo {

    public static void main(String args[]) throws IOException, InterruptedException {
        int result;
        try {

            System.out.println("command output:");
            Process proc = Runtime.getRuntime().exec("java -cp . demoh");
            InputStream in = proc.getInputStream();
            result = proc.waitFor();

            BufferedInputStream buffer = new BufferedInputStream(proc.getInputStream());

            BufferedReader commandOutput = new BufferedReader(new InputStreamReader(buffer));
            System.out.print(commandOutput);

            String line = null;
            try {
                while ((line = commandOutput.readLine()) != null) {
                    System.out.print(line);
                    System.out.println("command output: " + line);
            }//end while
            commandOutput.close();

            } catch (IOException e) {
                //log and/or handle it  
            }
        } catch (IOException e) {
            System.err.println("IOException raised: " + e.getMessage());
        }
    }
}
4

6 に答える 6

1

ファイルがディスク上のどこかにある場合は.class、新しいプロセスを生成し、コマンド ラインからのように java コマンドを実行します。

Process p = Runtime.getRuntime().exec("java <java class file>");

いくつかのテストの後、次のコードが機能しました。

public static void main(String args[]) throws IOException, InterruptedException {
    int result;

    try {

        System.out.println("command output:");
        Process proc = Runtime.getRuntime().exec("java -cp . Test");

        InputStream errin = proc.getErrorStream();
        InputStream in = proc.getInputStream(); 
        BufferedReader errorOutput = new BufferedReader(new InputStreamReader(errin));
        BufferedReader output = new BufferedReader(new InputStreamReader(in));
        String line1 = null;
        String line2 = null;
        try {
            while ((line1 = errorOutput.readLine()) != null || 
                   (line2 = output.readLine()) != null) {                   
                if(line1 != null) System.out.print(line1);
                if(line2 != null) System.out.print(line2);               
            }//end while
            errorOutput.close();
            output.close();
        } catch (IOException e) {
            e.printStackTrace(); 
        }//end catc
        result = proc.waitFor();
    } catch (IOException e) {
        System.err.println("IOException raised: " + e.getMessage());
    }
}

ここで 2 つのことに注意してください。

  1. Java プロセスによって発生した実行時エラーは、入力ストリームではなくエラー ストリームに送信されるため、両方を読み取る必要があります。
  2. プロセスの実行中にストリームを読み取る必要があります。ストリームを読み取る前にプロセスが終了するのを待つと、プロセスの出力バッファーがいっぱいになり、親プロセスがデータを読み取るのを待っているのに対し、親プロセスは子プロセスが終了するのを待っているため、デッドロックが発生します。
于 2012-04-20T16:09:31.203 に答える
0

オプションの1つは、クラスローダーを使用してクラスのインスタンスを作成することです。クラスローダーはクラスをバイト配列として受け取り、そのインスタンスを作成して実行できます。JDKドキュメントでこのメソッドを参照してください。

于 2012-04-20T16:20:31.877 に答える
0

.jar ファイルを作成し、そのファイルをビルド パスに追加します。

于 2012-04-20T16:08:02.313 に答える
0

Java ソース ファイルをコンパイルし、クラスをロードし、インスタンスをインスタンス化し、クラス HelloWorld の toString() を出力するサンプル アプリを次に示します。クラスパスに tools.jar が必要になると思います。サンプル コードは、ソース ファイルが src フォルダーにあることを前提としています。.class ファイルはデフォルトでそこに生成されるため、クラスパスには src フォルダーが必要です。

Java コンパイラをより詳細に制御するには、javax.tools パッケージを参照してください。

package sourcerunner;

import java.io.IOException;
import java.util.concurrent.TimeUnit;
import javax.tools.JavaCompiler;
import javax.tools.ToolProvider;

public class SourceRunner {

    public static void main(String[] args) throws IOException, ClassNotFoundException, InstantiationException, IllegalAccessException, InterruptedException {
        JavaCompiler compiler = ToolProvider.getSystemJavaCompiler();

        compiler.run(System.in, System.out, System.err, "src/sourcerunner/HelloWorld.java");

        TimeUnit.SECONDS.sleep(1L);

        Class<?> cls = Class.forName("sourcerunner.HelloWorld");

        Object instance = cls.newInstance();

        System.out.println(instance);
    }
}

HelloWorld クラスは次のとおりです。

package sourcerunner;

public class HelloWorld {

    @Override
    public String toString() {
        return "Hello Java Compiler World.";
    }
}

上記のコードは非常に安全ではありません。コードを理解したら、新しい ClassLoader を使用してクラスをロードおよびインスタンス化するようにコードを変更します。ClassLoader に最小限の権限があることを確認してください。

于 2013-08-27T17:08:44.150 に答える
0

試す

Process process = Runtime.getRuntime().exec("java " + filePath); // without .class
Scanner output = new Scanner(process.getInputStream());
while (output.hasNext) {
   String token = output.next();
   ...
}
于 2012-04-20T16:09:50.800 に答える
0

Ant や Maven などのビルド/コンパイル ツールがまだたくさんあります。独自のツールを作成する前に確認してください。

于 2012-04-20T16:10:04.083 に答える