質問

Java プロセス内から Java プロセスの CLASSPATH を変更するにはどうすればよいですか?


あなたが私に「なぜあなたはそれをしたいのですか?」と尋ねる前にすぐに説明します。

Clojure REPL を実行している場合、CLASSPATH にさらに多くの jar をロードする必要があるのが一般的です。 クロージュア Clojure 自体を再起動せずに実行したいと考えています (これは、Emacs 上の Slime で使用する場合には実際には選択肢ではありません)。

それが理由ですが、私はこの質問が「変な言語」「変なエディタ」というタグ付けされて、答えを持っているかもしれない大多数の Java 開発者に無視されることを望みません。

役に立ちましたか?

解決

2017 年第 4 四半期の更新:として コメントした 以下により vda8888, 、Java 9 では、システム java.lang.ClassLoader はもうありません java.net.URLClassLoader.

見る "Java 9 移行ガイド:最も一般的な 7 つの課題"

先ほど説明したクラス ローディング戦略は新しいタイプで実装されており、Java 9 ではアプリケーション クラス ローダーもそのタイプです。
つまり、 URLClassLoader もう、たまには (URLClassLoader) getClass().getClassLoader() または (URLClassLoader) ClassLoader.getSystemClassLoader() シーケンスは実行されなくなります。

java.lang.ModuleLayer に影響を与えるために使用される代替アプローチになります。 モジュールパス (クラスパスの代わりに)。たとえば「」を参照してください。Java 9 モジュール - JPMS の基本".


Java 8 以下の場合:

一般的なコメント:

システムのクラスパスを変更することはできません (動作が保証されている移植可能な方法で、以下を参照)。代わりに、新しい ClassLoader を定義する必要があります。

クラスローダーは階層的な方法で動作します...したがって、クラス X への静的参照を行うクラスは、X と同じ ClassLoader または子 ClassLoader にロードする必要があります。以前にそうしなかった場合、カスタム ClassLoader を使用してシステム ClassLoader リンクによってコードを適切にロードすることはできません。したがって、見つけた追加コードに加えて、メイン アプリケーション コードがカスタム ClassLoader で実行されるように手配する必要があります。
(そうは言っても、 ひび割れたすべて コメントでこの例について言及しています を延長する URLClassLoader)

また、独自の ClassLoader を作成せず、代わりに URLClassLoader を使用することを検討することもできます。次の URL を使用して URLClassLoader を作成します。 ない 親クラスローダーの URL 内。

URL[] url={new URL("file://foo")};
URLClassLoader loader = new URLClassLoader(url);

より完全なソリューション だろう:

ClassLoader currentThreadClassLoader
 = Thread.currentThread().getContextClassLoader();

// Add the conf dir to the classpath
// Chain the current thread classloader
URLClassLoader urlClassLoader
 = new URLClassLoader(new URL[]{new File("mtFile").toURL()},
                      currentThreadClassLoader);

// Replace the thread classloader - assumes
// you have permissions to do so
Thread.currentThread().setContextClassLoader(urlClassLoader);

JVM システム クラスローダーが URLClassLoader であると仮定すると (すべての JVM に当てはまらない可能性があります)、リフレクションを使用して実際にシステム クラスパスを変更することもできます。(しかし、それはハックです;)):

public void addURL(URL url) throws Exception {
  URLClassLoader classLoader
         = (URLClassLoader) ClassLoader.getSystemClassLoader();
  Class clazz= URLClassLoader.class;

  // Use reflection
  Method method= clazz.getDeclaredMethod("addURL", new Class[] { URL.class });
  method.setAccessible(true);
  method.invoke(classLoader, new Object[] { url });
}

addURL(new File("conf").toURL());

// This should work now!
Thread.currentThread().getContextClassLoader().getResourceAsStream("context.xml");

他のヒント

あなたができるとは思わない-正しいこと(私は信じる)は、新しいパスで新しいクラスローダーを作成することだ。あるいは、クラスパス(ローダーの)を動的に変更できる独自のクラスローダーを作成することもできます。

を使用して調べることができます。 java.net.URLClassLoader 。元々クラスパスになかったクラスをプログラムでロードすることができますが、それが正確に必要かどうかはわかりません。

以下の2つのリンクからわかるように、VonCが提供する方法が最適と思われますが、これらの投稿のいくつかを確認し、「Java Dynamic Classpath」をグーグルで検索してください。または" Java Dynamic Class Loading"そこからいくつかの情報を見つけます。

より詳細に投稿しますが、VonCはほとんど仕事をしました。

動的からクラスとJarファイルの読み込み

サンフォーラムの投稿も確認してください。

String s="java  -classpath abcd/ "+pgmname+" "+filename;   
Process pro2 = Runtime.getRuntime().exec(s); 
BufferedReader in = new BufferedReader(new InputStreamReader(pro2.getInputStream()));

は、Javaプログラムでクラスパスを変更する例です

ライセンス: CC-BY-SA帰属
所属していません StackOverflow
scroll top