1

asmを使用してプロキシパターンを実装します。
例:
元のクラスはtest.service.Serviceです。

public class ProxyFactory{
    public static Object generateProxy(Class<?> argument){
        //do generate use asm. 
        //generate a proxyClass that extends argument
        //and override the sayHello() method
        //and than invoke System.out.println("anything") before we call super.sayHello()
        Class<?> class = proxyClass;
        return class.newInstance();
    }
}


public class Service implements IService{
    @Override
    public List<String> sayHello(){
        List<String> list = new ArrayList<String>();
        list.add("stackoverflow user");
        return list;
    }
}

public class Action extends ActionSupport{

     private IService service = ProxyFactory.generateProxy(Service.class);

}

私がこのアクションを要求すると、例外になります:

java.lang.reflect.InvocationTargetException
at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
... at java.lang.Thread.run(Thread.java:619)
原因:java.lang.NoClassDefFoundError:test.service。
java.lang.ClassLoader.defineClass1(ネイティブメソッド)でのサービス
...
... 40 more
原因:java.lang.ClassNotFoundException:test.service.Service
at java.net.URLClassLoader $ 1.run(URLClassLoader.java:200 )
at java.security.AccessController.doPrivileged(Native Method)
...
at java.lang.ClassLoader.loadClass(ClassLoader.java:252)
at java.lang.ClassLoader.loadClassInternal(ClassLoader.java:320)
... 43もっと

上記のコードはすべて、アプリケーションとして実行すれば機能する可能性があるため、Tomcatクラスローダーの問題のようです。誰かがそれを解決するのを手伝ってくれませんか。
感謝

4

1 に答える 1

0

実際、自分で解決してください。予想どおり、問題はクラスローダーが原因です。
これはコードの前です:

byte[] b = class byte code...
ClassLoder loader = ClassLoader.getSystemClassLoader();
Class<?> cls = Class.forName("java.lang.ClassLoader");
java.lang.reflect.Method method = cls.getDeclaredMethod(
                "defineClass", new Class[] { String.class, byte[].class,
                        int.class, int.class });
method.setAccessible(true);
Object[] args = new Object[] { sc.getName(), b, new Integer(0),
                    new Integer(b.length) };
clazz = (Class<?>) method.invoke(loader, args);


そして今、 ClassLoader.getSystemClassLoader()の代わりにThread.currentThread()。getContextClassLoader()を使用しています。

これは、tomcatクラスローダーを使用してクラスを定義できるため、Web
アプリケーションクラス「test.service.Service」を見つけることができることを意味します。

于 2012-05-29T01:11:11.370 に答える