外部にあるjarファイルのクラスを動的に指定して使う検証
検証に使ったコードで、addClassPath2メソッドで動作できました。
package phone;
import java.io.File;
import java.lang.reflect.Method;
import java.net.MalformedURLException;
import java.net.URL;
import java.net.URLClassLoader;
import java.util.List;
// 外部にあるjarファイルのクラスを動的に指定して使うためのクラス
public class ExtLibLorder {
// 動的にClassPathを追加(リフレクションを使わないでjarファイルを登録する)
static void addClassPath1(File[] files) {
ClassLoader classLoader = Thread.currentThread().getContextClassLoader();
// URLに変換
URL[] urls = new URL[files.length];
for (int i = 0; i < urls.length; i++) {
try {
urls[i] = files[i].toURI().toURL();
} catch (MalformedURLException e) {
// 適宜例外処理
//throw new IllegalArgumentException(e);
e.printStackTrace();
}
}
URLClassLoader newClassLoader = URLClassLoader.newInstance(urls, classLoader);
Thread.currentThread().setContextClassLoader(newClassLoader);
try {
// -------------実験--------
Class cls = newClassLoader.loadClass("com.github.sarxos.webcam.Webcam");
Class.forName("com.github.sarxos.webcam.Webcam", true, newClassLoader);
// このメソッドは、上記は、可能であったが、次はできなかった。→ webcams = Webcam.getWebcams();
// よって、使っていない。
} catch (ClassNotFoundException e) {
e.printStackTrace();
}
}
// 成功したメソッド
public static void addClassPath2(File[] files) {
URLClassLoader sysloader = (URLClassLoader)ClassLoader.getSystemClassLoader();
Class sysclass = URLClassLoader.class;
try {
Method method = sysclass.getDeclaredMethod("addURL", new Class[]{URL.class});
method.setAccessible(true);
for(int i=0; i<files.length; i++)
method.invoke(sysloader, new Object[]{files[i].toURI().toURL()});
}
catch(Exception e) {
e.printStackTrace();
}
}
public static void main(String []args) {
// 以下のファイル群があるとして、そのクラスを利用する。(Webカメラを使うライブラリ)
File[] files = {//『http://webcam-capture.sarxos.pl/』
new File("lib/bridj-0.6.2.jar"),
new File("lib/slf4j-api-1.7.2.jar"),
new File("lib/webcam-capture-0.3.10.jar"),
};
System.out.println(files[0].getAbsolutePath() + " :"+ files[0].exists());
System.out.println(files[1].getAbsolutePath() + " :"+ files[1].exists());
System.out.println(files[2].getAbsolutePath() + " :"+ files[2].exists());
//ExtLibLorder.addClassPath1(files);// この手法ではできなった。
ExtLibLorder.addClassPath2(files);// これで、以下が可能になった。
List<com.github.sarxos.webcam.Webcam> webcams = com.github.sarxos.webcam.Webcam.getWebcams();
System.out.println(webcams.toString());
}
}