- PR -

URLClassLoaderとgetMethodについて

投稿者投稿内容
てま
会議室デビュー日: 2007/06/15
投稿数: 2
投稿日時: 2007-06-15 21:06
てまです。
ぬし&ベテランの皆様ありがとうございます
nagise様のヒントを元に以下のコードをScreenControlクラスに追加してみました
コード:
package loader;
import java.lang.reflect.*;
import java.net.URL;
import java.net.URLClassLoader;
import java.io.*;
public class ScreenControl extends Thread {
        public void run(){
                URL baseURL = null;
                File baseDir = null;
                try{
                        baseDir = (new File( "D:\My Program\classLoad\\classes\" )).getCanonicalFile();
                        baseURL = baseDir.toURI().toURL();
                } catch (Exception e){
                        e.printStackTrace();
                }
                URLClassLoader loader = new URLClassLoader( new URL[]{baseURL} );                        
                Class<?> clazz;
                Class<?> dmyClazz;     // <-追加 !!!!!!!
                try {
                        clazz = loader.loadClass("loader.OptionClass");
                        dmyClazz = loader.loadClass("loader.DummyViews");     // <-追加 !!!!!!!
                } catch (ClassNotFoundException e) {
                        e.printStackTrace();
                        return;
                }                
                
             //           ↓追加 !!!!!!!
                ClassLoader cloader1 ;
                ClassLoader cloader2 ;
                ClassLoader cloader3 ;
                ClassLoader cloader4 ;
                cloader1 = int.class.getClassLoader();
                cloader2 = String.class.getClassLoader();
                cloader3 = DummyViews.class.getClassLoader();
                cloader4 = dmyClazz.getClassLoader();
                System.out.println("ClassLoader1="+cloader1);
                System.out.println("ClassLoader2="+cloader2);
                System.out.println("ClassLoader3="+cloader3);
                System.out.println("ClassLoader4="+cloader4);
                //           ↑ここまで !!!!!!!
                
                Method calc1;
                Method calc2;
                Method calc3;
                Object object = null;
                try{
                        object = clazz.newInstance();
                } catch (Exception e){
                        e.printStackTrace();return;
                }
                try {
                        calc1 = clazz.getMethod("calc", new Class[]{int.class});
                        calc2 = clazz.getMethod("calc", new Class[]{String.class});
                        calc3 = clazz.getMethod("calc", new Class[]{DummyViews.class});
                } catch (SecurityException e2) {
                        e2.printStackTrace();return;
                } catch (NoSuchMethodException e2) {
                        e2.printStackTrace();return;
                }
                Object ret1 = null; //戻り値
                Object ret2 = null; //戻り値
                Object ret3 = null; //戻り値
                try {
                        ret1 = calc1.invoke(object, new Object[]{ 3 });
                        ret2 = calc2.invoke(object, new Object[]{ "3" });
                        ret3 = calc3.invoke(object, new Object[]{ new DummyViews(3)});
                        //  = object.メソッド((int)1); と同じ
                } catch (IllegalArgumentException e3) {
                        e3.printStackTrace();return;
                } catch (IllegalAccessException e3) {
                        e3.printStackTrace();return;
                } catch (InvocationTargetException e3) {
                        e3.getCause().printStackTrace();return;
                } 
                System.out.println("ret1="+ret1);
                System.out.println("ret2="+ret2);
                System.out.println("ret3="+ret3);
        }
}



面白い結果がでました
[Javaコマンド]
D:\My Program\classLoad\classes>java loader.TestMain
ClassLoader1=null
ClassLoader2=null
ClassLoader3=sun.misc.Launcher$AppClassLoader@a90653
ClassLoader4=sun.misc.Launcher$AppClassLoader@a90653
ret1=12
ret2=12
ret3=12

[Swing]
D:\My Program\classLoad\classes>java loader.JFrameTest
ClassLoader1=null
ClassLoader2=null
ClassLoader3=sun.misc.Launcher$AppClassLoader@a90653
ClassLoader4=sun.misc.Launcher$AppClassLoader@a90653
ret1=12
ret2=12
ret3=12

[IEプラグイン]
ClassLoader1=null
ClassLoader2=null
ClassLoader3=sun.plugin.security.PluginClassLoader@73a34b
ClassLoader4=java.net.URLClassLoader@92bbba
java.lang.NoSuchMethodException: loader.OptionClass.calc(loader.DummyViews)
at java.lang.Class.getMethod(Unknown Source)
at loader.ScreenControl.run(ScreenControl.java:67)
at loader.RootInit.init(RootInit.java:12)
at sun.applet.AppletPanel.run(Unknown Source)
at java.lang.Thread.run(Unknown Source)

ご指摘のとおりでした
ブラウザプラグインのときのみ
前者のDummyViewsと後者のDummyViewsは別々のクラスローダーから取得されています
よってinvokeメソッドを次のように変えて解決することができました
<前>
ret3 = calc3.invoke(object, new Object[]{ new DummyViews(3)});
<↓後>
Constructor cot = dmyClazz.getConstructor( new Class[]{int.class} );
ret3 = calc3.invoke(object, new Object[]{ cot.newInstance( new Object[]{ 3 })});

出処がたとえ同じクラスでも、取得経路が違えば異なるクラスと判断することがわかりました

スキルアップ/キャリアアップ(JOB@IT)