diff --git a/jp.go.aist.rtm.RTC/src/jp/go/aist/rtm/RTC/ModuleManager.java b/jp.go.aist.rtm.RTC/src/jp/go/aist/rtm/RTC/ModuleManager.java index 131b6f97..41abc125 100644 --- a/jp.go.aist.rtm.RTC/src/jp/go/aist/rtm/RTC/ModuleManager.java +++ b/jp.go.aist.rtm.RTC/src/jp/go/aist/rtm/RTC/ModuleManager.java @@ -238,12 +238,17 @@ public String load(final String moduleName) throws Exception { "getParent = " + file.getParent()); if(file.isAbsolute()){ URLClassLoader url = createURLClassLoader(file.getParent()); - rtcout.println(Logbuf.PARANOID, "url =" + url); + if (fullClassName.endsWith(".jar")) { + rtcout.println(Logbuf.PARANOID, "addURL(" + fullClassName + ")"); + addClassPath(url, fullClassName); + } + + rtcout.println(Logbuf.PARANOID, "url = " + url); if(url!=null){ String name = file.getName(); name = getModuleName(name); - rtcout.println(Logbuf.PARANOID, "name =" + name); + rtcout.println(Logbuf.PARANOID, "name = " + name); StringHolder packageModuleName = new StringHolder(); target = getClassFromName(url,name,packageModuleName); module_path = packageModuleName.value; @@ -295,6 +300,8 @@ public String load(final String moduleName) throws Exception { private Class getClassFromName(URLClassLoader url, String name, StringHolder holder){ + rtcout.println(Logbuf.TRACE, + "getClassFromName(url, " + name + ", holder)"); String separator = System.getProperty("file.separator"); Class target = null; @@ -302,12 +309,18 @@ private Class getClassFromName(URLClassLoader url, target = url.loadClass(name); holder.value = name; } catch (java.lang.NoClassDefFoundError e) { + rtcout.println(Logbuf.PARANOID, + "NoClassDefFound Error exception: getClassFromName => loadClass("+name+") failed."); String messagetString = e.getMessage(); + rtcout.println(Logbuf.PARANOID, + "Exception messageString => " + messagetString); String key = "wrong name: "; int index = messagetString.indexOf(key); String packageName = messagetString.substring(index+key.length(), messagetString.length()-1); + rtcout.println(Logbuf.PARANOID, + "Estimated packageName => " + packageName); URL[] urls = url.getURLs(); java.util.ArrayList al = new java.util.ArrayList(java.util.Arrays.asList(urls)); @@ -316,15 +329,21 @@ private Class getClassFromName(URLClassLoader url, String stringUrl = new String(); try{ stringUrl = urls[ic].toURI().getPath(); + rtcout.println(Logbuf.PARANOID, + "stringUrl => " + stringUrl); } catch(Exception ex){ continue; } int pointer = packageName.lastIndexOf(name); String stringPackageName = packageName.substring(0, pointer); + rtcout.println(Logbuf.PARANOID, + "stringPackageName => " + stringPackageName); if(stringUrl.endsWith(stringPackageName)){ int point = stringUrl.lastIndexOf(stringPackageName); stringPath = stringUrl.substring(0, point); + rtcout.println(Logbuf.PARANOID, + "stringPath => " + stringPath); File path = new File(stringPath); try{ URI uri = path.toURI(); @@ -341,28 +360,36 @@ private Class getClassFromName(URLClassLoader url, packageName = packageName.replace("/","."); packageName = packageName.trim(); - + rtcout.println(Logbuf.PARANOID, "Re-tring getClassFromName"); target = getClassFromName(url,packageName,holder); } catch (Exception e) { + rtcout.println(Logbuf.PARANOID, + "Unknown exception: getClassFromName => loadClass("+name+") failed."); + String messagetString = e.getMessage(); + rtcout.println(Logbuf.PARANOID, + "Exception messageString => " + messagetString); // } return target; } /** - * {@.ja モジュール名作成する。} + * {@.ja 名称から拡張子を除去する。} + * {@.en Strip extension from name.} *

- * {@.ja 拡張子を削除する。拡張子jarの場合はモジュール名を付加する} + * {@.ja モジュール名にファイル名が指定された際に拡張子を除去する。} + * {@.en Strip extension from name when a file name specified.} */ private String getModuleName(String name){ + rtcout.println(Logbuf.TRACE, + "getModuleNmae(" + name + ", urlClassLoader)"); String extensions[] = {".class", ".jar"}; - for(int ic=0;ic " + name); break; } } @@ -388,7 +415,45 @@ private URLClassLoader createURLClassLoader(String parent){ } /** - * {@.ja モジュールのアンロード。} + * {@.ja クラスパスの追加} + * {@.en Addd class path} + * + *

+ * {@.ja クラスパスに path を追加し実行中に新たな class や jar を + * ロードできるようにする。addURL()メソッドはprotectedのため、直接 + * コールできないのでこのような実装になっている。Java9以降では動作しない。} + * {@.en Adding the path to the classpath to load new classes and + * jar files in runtime. Since addURL() method is protected and + * cannot be called directry, implemented as follows. This scheme + * does not work after Java9.} + * + * @param classLoader + * {@.ja クラスローダー。URLClassLoaderでなければならない。} + * {@.en A class loader. It shall URLClassLoader.} + * @param path + * {@.ja CLASSPATHに追加するパス。} + * {@.en A path to be added to CLASSPATH.} + * @throws ReflectiveOperationException + * {@.ja リフレクション操作が機能しなかった場合にスローされます。} + * {@.en Thrown when the reflection operation doesn't work.} + * @throws MalformedURLException + * {@.ja 不正な形式のURLの場合にスローされます。} + * {@.en Thrown when the malformed URL is specified.} + */ + private void addClassPath(ClassLoader classLoader, String path) + throws ReflectiveOperationException, MalformedURLException + { + if (classLoader instanceof URLClassLoader) { + // URLClassLoaderであることが前提 + Method method = + URLClassLoader.class.getDeclaredMethod("addURL", URL.class); + method.setAccessible(true); + // ロードするURLを追加する + method.invoke(classLoader, new File(path).toURI().toURL()); + } + } + /** + * {@.ja モジュールのロード。} * {@.en Load and intialize the module} * *

@@ -435,7 +500,8 @@ public String load(final String moduleName, final String methodName) } String module_path = load(moduleName); - + rtcout.println(Logbuf.TRACE, + "load(" + moduleName + ") => " + module_path + "done"); Method initMethod = symbol(module_path,methodName); @@ -856,7 +922,7 @@ protected void addNewFile(final String fpath, * {@.en This class is used to filter directory listings * in the list method of class File.} */ - private class FilePathFilter implements FilenameFilter{ + private class FilePathFilter implements FilenameFilter { private String m_regex = new String(); public FilePathFilter(String str) { m_regex = str; @@ -1224,8 +1290,6 @@ public boolean accept(java.io.File dir, String name) { return false; } } - private Logbuf rtcout; - private ArrayList m_modprofs = new ArrayList(); /** * {@.ja 指定したパス以下に存在するディレクトリを探索する} * {@.en Searches the directory which exists in below of designated paths.} @@ -1260,5 +1324,9 @@ private Vector recursiveDirectory(Vector paths){ } return result; } - + /** + * private variables + */ + private Logbuf rtcout; + private ArrayList m_modprofs = new ArrayList(); }