閲覧ありがとうございます。  
現在Javaのオンラインコンパイラを作成したいと思っています。  
作成するにあたり、どのように作成するのがモダンなのかを知りたく質問いたしました。

私の想定するオンラインコンパイラとは、いわゆるpaiza.ioのようなもので、  
ユーザーが入力を行ったプログラムをサーバーサイドで実行し、その結果を返却するものです。

私の実装イメージは以下の通りです。

  1. Webサーバー内で実行する（サンドボックス的な機能がある？）
  2. 仮想マシン上にファイルを配備し、実行する。その標準出力を何等かの形でサーバーと連携する
  3. なんらかのライブラリを用いる

2が有力なのかなと思っているのですが、貧弱なサーバーで実現したいので可能であれば１の方法を取りたいと思っています。  
参考となる情報を頂ければ幸いです。
CC BY-SA 4.0
2020-05-28T04:15:16.800
67066
2020-05-28T14:05:27.177
40363
question
java
オンラインコンパイラを作成するには
特に詳しいわけではないですが、私の聞いたことがある範囲で…

  * [Wandbox](https://wandbox.org/)
    * [Wandboxを支える技術](https://melpon.org/pub/wandbox) [#21](https://melpon.org/pub/wandbox#21)

> chrootを使って環境を閉じ込める

    * コード: <https://github.com/melpon/wandbox>
  * [AtCoder](https://atcoder.jp/) ジャッジサーバ 
    * <https://twitter.com/chokudai/status/1076367979686678529>

>
> ちなみに初期のAtCoderのジャッシサーバーはDockerとかなかったのでフルスクラッチで書いてて（cgroupsとかで制御してたはず？）、現行のAtCoderはLXCでやってるよ。
CC BY-SA 4.0
2020-05-28T05:10:08.233
67070
2020-05-28T05:19:05.953
2020-05-28T05:19:05.953
2808
2808
67066
answer
数年前ですが、ユーザがtextarea等に入力したコードを、サーバ側でコンパイルしてテストするシステムを作ったことがあります。

モダンかどうかは分かりませんが、そのときは、だいたい以下のような感じでやりました。

### コンパイルするとき

  * ユーザの入力コードを、ファイルに保存して`StandardJavaFileManager`を使ってコンパイラが読み書きできるようにする（その上のインタフェースを実装して全部オンメモリでやるのも良さそうですが、後述のPolicyのところで大変そうだったからファイルにしました）
  * `javax.tools.ToolProvider.getSystemJavaCompiler()`でコンパイラを取得
  * `JavaCompiler.CompilationTask compilation = compiler.getTask(...)`
  * `compilation.call()`とすると、先ほどのfileManagerで設定した場所にclassファイルが出力される（コンパイルエラーはJava例外としてcatchできる）

### 実行するとき

  * ファイルやネットワークアクセスを制限するための、javaのPolicyファイルを作っておく（参考 <https://docs.oracle.com/javase/jp/7/technotes/guides/security/PolicyFiles.html> ）
  * `java`コマンドの引数に`-Djava.security.policy=(ポリシーファイルのパス)`を指定
  * ユーザコードの場所等、ポリシーファイル内で可変にしたいところは、ポリシーファイル内でシステムプロパティーを参照するようにしておいて、その値も`java`コマンドの引数に`-Dsome.property.key=hoge`みたいにして渡す。

ご参考になれば幸いです。
CC BY-SA 4.0
2020-05-28T14:05:27.177
67087
2020-05-28T14:05:27.177
7572
67066
answer