2011-01-14 5 views
5

ケーキが複数のJVMアプローチをどのように実装しているかを理解しようとしています。高レベルでは、ケーキは1つのJVMインスタンス(1つのJVMプロセス)があるnailgunに似ていると思っていました。新しいプロジェクトのJVMは、実際には新しいクラスローダーで評価されるクロージャー/異なるjar依存関係)、私の目には新しいJVMインスタンスではありません。しかし、What's the difference between Cake and Leiningen?から、単一のJVMインスタンスだけでなく、複数のJVM(ケーキ用とプロジェクト用)があることを意味します。永続的なJVM機能はケーキにどのように実装されていますか?

新しいJVMインスタンスが作成されている場合、高速化はどこから行われますか?私の理解では、新しいJVMの起動は、通常と同じ起動時のオーバーヘッドを招く新しいJVMプロセスを作成することを意味します。

もし存在しなければ、どのようにネイティブの依存関係が追加されますか?私が理解していることから、JVMはランタイムの前に渡されたコマンドライン引数からのネイティブ依存性しか知りません。私がこれを回避する方法を知っている唯一の方法は、Sun/Oracle JVM実装固有のハックです。

(let [clazz java.lang.ClassLoader 
     field (.getDeclaredField clazz "sys_paths")] 
    (.setAccessible field true) 
    (.set field clazz nil) 
    (System/setProperty "java.library.path" (apply str (interpose ";" native-paths)))) 

答えて

4

Cakeには、JVMを起動して管理するRubyスクリプトがあります。 RubyはJVMオーバーヘッドを持っていないので、RubyスクリプトはJVMを作成し、コマンドを実行するとRubyスクリプトはこれらのコマンドをJVMに委譲します。

2つのJVMが必要な理由は、ケーキの依存関係(ケーキJVM)がプロジェクトの依存関係(ベイクJVM)とは別のものだったからです。 cake replのようないくつかのコマンドは、プロジェクトのクラスパスを利用するために、ベークJVMで実行されます。

ただし、最新のバージョンでは、プロジェクトごとに1つのJVMしかありません。これは、同じJVM内の異なるクラスローダを使用して行うことができます。関連するライブラリはclasslojureです。

2つのJVMバージョンでも、JVMは永続的です。つまり、変更されたクラスパス(新しい依存関係などを追加する場合)のように、必要なときにのみ再生成されます。なぜコマンドが実行されるたびにJVMのオーバーヘッドが発生するのだろうと思うのか分かりません。考えられるのは、JVMを起動するすべてのコマンドではなく、すぐに多くのコマンドが実行されるということです。

+1

ありがとうございました。 OK、古いバージョンでは、プロジェクトごとに新しいJVMが作成されましたが、私は誤った印象を受けていました。もう1つのJVMインスタンスが存在するのはもっと爪に似ています。 nailgunメソッドのメソッドは、JVMの起動時間やセキュリティの問題を無視して、理想的でした。今はケーキを実装する方法ではないことが分かります。私はJVMの起動時間に関する利点を判断しようとしましたが、JVMを再起動または作成する必要がある状況ではなく、すべてのcakeコマンドごとに実行する必要がありました。 – bmillare

+0

classlojureはランタイムネイティブ依存関係の読み込みをサポートしていますか? – bmillare

2

Raynesが正しいです。ケーキ0.6.0以降、プロジェクトごとに1つのJVMがあります。 Cakeはメインクラスローダーで動作し、クラスローを使用してプロジェクトを別のクラスローダーにロードし、クラスパスが変更されたときにリロードします。すべてのプロジェクトで単一のJVMを共有するためのglobal〜/ .cake/configオプションについて説明しました。 classlojureを使ってこれを追加するのは難しいことではありません。このアプローチの主な問題は、ケーキタスクプラグインを別々に保つ方法です。おそらく、グローバルなケーキプロジェクトがメインのクラスローダーで実行され、各プロジェクトに2つのクラスローダー(ケーキ用とプロジェクト用)が用意されている可能性があります。

ネイティブ依存性に関して、classlojureは、JVMの起動後にクラスを追加することをサポートしていません。この機能を追加するパッチは、ネイティブライブラリパスが特定のクラスローダに対してローカルであり、同じJVM内のすべてのクラスローダで共有されていない限り、歓迎します。

+0

あなたが言いました最後の2つの要件は、残念ながら(私の知る限り)満たすことは基本的に不可能です。さらに、上記で与えたコードは、これが別のJVM実装で実行された場合には壊れてしまいます。 – bmillare

関連する問題