2015-12-05 11 views
8

アプリケーションクラスパスのクラスを除いて、システムクラスのみを読み込むJavaクラスローダを見つけたり作成したりしたいと思います。私の目標は、特定のJARファイルからロードするクラスローダーを構築し、システム専用のクラスローダーを使用してシステムクラスを解決し、アプリケーションによって定義されたクラスでJARファイルのクラスを汚染しないようにすることです。Javaシステムのみのクラスローダーが必要

これまで私はプライベートAPIを使用していないか、Java実装についての仮定をしていないシステムオンリーのクラスローダーを作成する方法を発見していません。私の現在の環境で動作するが、望ましくない仮定をする以下のコードを参照してください。

実装に依存しないシステムオンリーのクラスローダーを作成する方法がない場合は、理由はありませんか?私は悪い考えをしていますか?

private ClassLoader createJarClassLoader(File f) 
{ 
    ClassLoader systemClassLoader = ClassLoader.getSystemClassLoader(); 
    if (systemClassLoader instanceof URLClassLoader) { 
     URLClassLoader cl = (URLClassLoader) systemClassLoader; 
     URL[] urls = cl.getURLs(); 
     List<URL> wantedURLs = new ArrayList<>(); 
     for (URL u : urls) { 
      if (isSystemURL(u)) { 
       wantedURLs.add(u); 
      } 
     } 
     try { 
      wantedURLs.add(f.toURI().toURL()); 
     } catch (MalformedURLException ex) { 
      return null; 
     } 
     return new URLClassLoader(wantedURLs.toArray(new URL[0]), null); 
    } 
    return null; 
} 

private boolean isSystemURL(URL u) 
{ 
    return u.getPath().contains("/jre/"); 
} 
+2

なぜこれをやろうとしていますか?あなたは何を達成しようとしていますか? – jtahlborn

+0

@jtahlborn彼は非常に明確に理由を述べた: "私の目標は..." – qqilihq

+1

@qqilihq - いいえ、OPは "何"を達成しようとしていたのか "理由" – jtahlborn

答えて

1

親クラスローダーをブートストラップClassLoaderに設定する必要があります。 java.lang.StringオブジェクトのgetClassLoader()を呼び出して、ブートストラップClassLoaderを取得し、それをClassLoaderコンストラクタで使用します。

public class MyClassLoader extends URLClassLoader { 

    protected MyClassLoader(URL[] urls, ClassLoader parent) { 
     super(urls, parent); 
    } 

    static MyClassLoader getInstance(URL[] urls) { 
     ClassLoader parent = "".getClass().getClassLoader(); 
     return (new MyClassLoader(urls, parent)); 
    } 
} 

ブートストラップローダの表現は実装として記載され依存

いくつかの実装では、ブートストラップクラスローダを表すためにnullを使用してもよいです。このメソッド[getClassLoader]は、このクラスがブートストラップクラスローダによってロードされた場合、そのような実装ではnullを返します。

しかし、ClassLoaderコンストラクタの親ClassLoaderにも同じ言い回しが適用されます。つまり、この解決策は移植性があります。

+0

それはJDK 8で動作しますブートストラップクラスローダーがJavaプラットフォームのすべてのクラスを認識しているとは限りません。 JDK9用に計画されたモジュラーJDKでは、間違いなくそうはなりません。より興味深いのは、nullがClassLoaderコンストラクタに渡されるときの意味です。私はそれが何を意味するのか分かりませんが、Javaプラットフォームのクラスを正確に知っているクラスローダーを意味するように定義することもできます。 –

関連する問題