jarファイルからクラスを読み込むクラスローダー
id:NAT_programming:20060729の続き。jarファイルからクラスを読み込むクラスローダーなら、J2SEのAPIにありそうだと思って探してみたら、案の定ありました。java.net.URLClassLoaderクラスです。URLでjarファイルまたはクラスディレクトリを指定するクラスローダー。
一応、使いやすくするためにjarをFileで指定するサブクラスJarClassLoaderを作ってみた。
package nat.champloo.classloader; import java.io.File; import java.net.MalformedURLException; import java.net.URL; import java.net.URLClassLoader; /** * JARファイルからクラスを読み込むクラスローダー * @author NAT */ public class JarFileClassLoader extends URLClassLoader { /** * コンストラクタ * @param jarFiles クラスを読み込むJARファイルの配列 * @param parent 親となるクラスローダー * @throws MalformedURLException パスを URL として構文解析できない場合 */ public JarFileClassLoader(File[] jarFiles, ClassLoader parent) throws MalformedURLException { super(toURLs(jarFiles), parent); } /** * コンストラクタ * @param jarFile クラスを読み込むJARファイル * @param parent 親となるクラスローダー * @throws MalformedURLException パスを URL として構文解析できない場合 */ public JarFileClassLoader(File jarFile, ClassLoader parent) throws MalformedURLException { this(new File[]{jarFile}, parent); } private static URL[] toURLs(File[] jarFiles) throws MalformedURLException { URL[] urls = new URL[jarFiles.length]; for (int i = 0; i < jarFiles.length; i++) { urls[i] = jarFiles[i].toURL(); } return urls; } }
使用例とテストを兼ねたテストケースはこちら。
package nat.champloo.classloader; import junit.framework.TestCase;; public class JarClassLoaderTest extends TestCase { public void testLoadClass() throws Exception { // jarファイル"champloo.jar"からクラスを読み込む ClassLoader classLoader = new JarFileClassLoader( new File("champloo.jar"), getClass().getClassLoader()); Object a = classLoader.loadClass("nat.champloo.classloader.A").newInstance(); assertEquals("nat.champloo.classloader.A", a.getClass().getName()); assertEquals("A", a.toString()); } }
以前の例と同様に、jarファイル"champloo.jar"にはtoString()メソッドが"A"を返すクラスAが入っています。