From 090a66e327adf2d2ba916d0f157724171aea2b51 Mon Sep 17 00:00:00 2001 From: Noriaki Ando Date: Thu, 26 Aug 2021 16:56:31 +0900 Subject: [PATCH 1/5] jar file loadpath issue jar file loadpath issue https://openrtm.org/openrtm/ja/content/openrtm-users-02802-java%E7%89%88%E3%81%AErtcd%E3%81%AE%E5%8B%95%E4%BD%9C%E3%81%AB%E3%81%A4%E3%81%84%E3%81%A6 --- .../src/jp/go/aist/rtm/RTC/ModuleManager.java | 9 ++++++++- 1 file changed, 8 insertions(+), 1 deletion(-) 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..88c63173 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 @@ -361,7 +361,14 @@ private String getModuleName(String name){ int point = name.lastIndexOf(extensions[ic]); name = name.substring(0, point); if(extensions[ic].equals(".jar")){ - name = name+"."+name; + try{ + addClassPath(url, args[0]); + if(args.length == 2){ + name = args[1]; + } + } + catch (Exception ex) { + } } break; } From ffc646de43560bd532102bdaddafe7c527c8c740 Mon Sep 17 00:00:00 2001 From: n-ando Date: Thu, 5 Aug 2021 12:00:00 +0900 Subject: [PATCH 2/5] . --- .../src/jp/go/aist/rtm/RTC/ModuleManager.java | 73 ++++++++++++++----- 1 file changed, 54 insertions(+), 19 deletions(-) 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 88c63173..d3527dec 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 @@ -203,6 +203,7 @@ public String load(final String moduleName) throws Exception { rtcout.println(Logbuf.PARANOID, "Is moduleName AbsolutePath ? " + file.exists()); if(file.exists()){ // When moduleName is AbsolutePath. + if(!m_absoluteAllowed) { throw new IllegalArgumentException( "Absolute path is not allowed"); @@ -238,12 +239,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,19 +301,27 @@ 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; - + try { 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 +330,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,9 +361,14 @@ 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; @@ -352,24 +377,18 @@ private Class getClassFromName(URLClassLoader url, /** * {@.ja モジュール名作成する。} *

- * {@.ja 拡張子を削除する。拡張子jarの場合はモジュール名を付加する} + * {@.ja 拡張子を削除する。} */ private String getModuleName(String name){ + rtcout.println(Logbuf.TRACE, + "getModuleNmae(" + name + ", urlClassLoader)"); String extensions[] = {".class", ".jar"}; - for(int ic=0;ic " + name); break; } } @@ -395,7 +414,22 @@ private URLClassLoader createURLClassLoader(String parent){ } /** - * {@.ja モジュールのアンロード。} + * + */ + 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} * *

@@ -442,7 +476,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); From ec1f10cc5a2e64b0bb899b8bbab0b1e5f625d2b1 Mon Sep 17 00:00:00 2001 From: n-ando Date: Fri, 6 Aug 2021 12:00:00 +0900 Subject: [PATCH 3/5] . --- .../src/jp/go/aist/rtm/RTC/ModuleManager.java | 29 +++++++++++++++++-- 1 file changed, 27 insertions(+), 2 deletions(-) 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 d3527dec..e79e87e3 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 @@ -375,9 +375,11 @@ private Class getClassFromName(URLClassLoader url, } /** - * {@.ja モジュール名作成する。} + * {@.ja 名称から拡張子を除去する。} + * {@.en Strip extension from name.} *

- * {@.ja 拡張子を削除する。} + * {@.ja モジュール名にファイル名が指定された際に拡張子を除去する。} + * {@.en Strip extension from name when a file name specified.} */ private String getModuleName(String name){ rtcout.println(Logbuf.TRACE, @@ -414,7 +416,30 @@ private URLClassLoader createURLClassLoader(String parent){ } /** + * {@.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 From a4a887ee1399bd7cbfaad7444f77a9459f0a6919 Mon Sep 17 00:00:00 2001 From: n-ando Date: Sat, 7 Aug 2021 12:00:00 +0900 Subject: [PATCH 4/5] . --- jp.go.aist.rtm.RTC/src/jp/go/aist/rtm/RTC/ModuleManager.java | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) 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 e79e87e3..ae63f231 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 @@ -203,7 +203,6 @@ public String load(final String moduleName) throws Exception { rtcout.println(Logbuf.PARANOID, "Is moduleName AbsolutePath ? " + file.exists()); if(file.exists()){ // When moduleName is AbsolutePath. - if(!m_absoluteAllowed) { throw new IllegalArgumentException( "Absolute path is not allowed"); @@ -305,7 +304,7 @@ private Class getClassFromName(URLClassLoader url, "getClassFromName(url, " + name + ", holder)"); String separator = System.getProperty("file.separator"); Class target = null; - + try { target = url.loadClass(name); holder.value = name; From 9aaafe5583bc9821a103fb6b078ef621a232a570 Mon Sep 17 00:00:00 2001 From: n-ando Date: Thu, 5 Aug 2021 12:00:00 +0900 Subject: [PATCH 5/5] . --- .../src/jp/go/aist/rtm/RTC/ModuleManager.java | 10 ++++++---- 1 file changed, 6 insertions(+), 4 deletions(-) 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 ae63f231..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 @@ -922,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; @@ -1290,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.} @@ -1326,5 +1324,9 @@ private Vector recursiveDirectory(Vector paths){ } return result; } - + /** + * private variables + */ + private Logbuf rtcout; + private ArrayList m_modprofs = new ArrayList(); }