如一楼所言,我猜想一下,根据java命名规范,你确定是Execute而不是execute?

解决方案 »

  1.   

    可以确定是Execute方法,我使用循环输出了被调用类的所有方法和每个方法中的参数,发现与我所输入的参数类型并没有两样,但程序执行就是有错误.真是想不明白了.
    另外,我在被调用类中import了javax.servlet.http.*,结果在初始化URLClassLoader时,一定要将servlet-api.jar也加入到URL路径中去,否则在classLoader时会报错,这难道是必须的吗?
    我的运行环境是Tomcat5.0.16,jdk1.4.2
      

  2.   

    被调用类的代码
    package com.userlibrary;
    import javax.servlet.http.*;
    import com.user.*;
    public class Demo
    {
    public Demo()
    {

    }

    public Boolean Execute( HttpServletResponse response , HttpServletRequest request , cuser CurUser )
    {
    try
    {
    System.out.print( request.getParameter( "username" ) );
    System.out.print( CurUser.CurrentUserName );
    }
    catch( Exception e )
    {
    return Boolean.FALSE;
    }
    return Boolean.TRUE;
    }
    }
      

  3.   

    这是调用代码
    URLClassLoader urlLoader = (URLClassLoader)this.getClass().getClassLoader();
    URL servlet = urlLoader.findResource( "../lib/serlet-api.jar" );//这句是必须的吗?
    URL[] u = { urlLoader.getURLs()[0] , servlet };
    URLClassLoader classLoader = new URLClassLoader( u );//没有上面那句的话,这句就会报错
    Class cls = classLoader.loadClass( "com.userlibrary.Demo" );
    Class[] ptypes = new Class[]{ HttpServletResponse.class , HttpServletRequest.class , cuser.class };
    Method main = cls.getDeclaredMethod( "Execute" , ptypes );//现在这里就出错了
    main.invoke( cls.newInstance() , new Object[]{ response , request , CurUser} )
      

  4.   

    现在我使用下面这个方法来读取类,后续语句不变,执行就没有问题.
    Class cls = Class.forName( "com.userlibrary.Demo" );真是百思不得其解,还望高人指点.
      

  5.   

    类似的怪问题,我也碰到过,至今不得其解曾经用过一个XML的DB, sonic eXtensive Information Server, 里面用到的一个class,和xerces里面的class重名,但属于不同package, 结果在指定classpath的时候,尽然哪个lib放前面,就去找哪个class,结果导致老是NoSuchMethod
      

  6.   

    补充一点,这个出错的class反编译出来的代码,有编译错误,其中的inner-class申明了一个non-final的static的field.所以让我更加困惑不已。
      

  7.   

    试试在调用部分做如下修改:
    URL url = new URL("../lib/serlet-api.jar");
    URL[] urls = new URL[]{url};
    URLClassLoader classLoader = new URLClassLoader(urls,this.getClass().getClassLoader());
    Class cls = classLoader.loadClass( "com.userlibrary.Demo" );
      

  8.   

    to rick_silver(杨若蝉):你的方法是可以的.
    主要就是URLClassLoader classLoader = new URLClassLoader( urls , this.getClass().getClassLoader() );这句的问题.我原先没有加this.getClass().getClassLoader()这个参数,所以执行不了.加了这个参数后,不但执行可以了.URL servlet = urlLoader.findResource( "../lib/serlet-api.jar" );这句也就不用加了.
    那能不能解释一下,加这个参数的作用是什么?(我的理解是把urls里要加载的类装载到this.getClass().getClassLoader()的执行环境中,使它们在同一环境中运行.)
    还希望能说明一下,Class.forName()也可以达到同样的效果,那这两种方法有什么区别,谁更好些(从代码上看Class.forName()方法要简洁些).
      

  9.   

    URLClassLoader(以下简称ucl)可以根据传入的URL定位资源,但是你调用的FindResource的方法可能不对,我的理解是这个方法只是用来获取某个类的URL,而不是一个类库的URL. 不知道你注意了没有,URLClassLoader有一个addURL方法,但是被声明为protected类型,我们不能调用,也就是说ucl的资源路径在创建实例的时候已经生成了,用findResource不能再添加,所以你那句
    URL servlet = urlLoader.findResource( "../lib/serlet-api.jar" );
    得出得URL应该是空的吧.
    如果要ucl包括指定的资源,需要在创建它的时候就指定,所以开始就创建一个URL作为构造函数的参数给它,是定位资源包的唯一手段.
    还有一个可能,就是每个类载入器一般都有一个父载入器,而他可能会从父载入器继承一些特性,这个我就没有试了,你可以试一下看把ucl构造函数中的this.getClass().getClassLoader()参数去掉,看行不行?
    以上是我的理解,不知对不对,大家给些意见
      

  10.   

    Class.forName方法是调用当前的类加载器创建类,只要在程序运行的classpath中存在该类所属资源包应该就可以调用成功,但是Class.forName的资源包指定是在程序启动时指定的,不可更改的,而ucl可以在运行期动态指定资源包进行类的加载,比Class.forName更加灵活一些吧
      

  11.   

    我最开始的错误就是因为在构造ucl时没有加this.getClass().getClassLoader()这个参数,所以必须加上URL servlet = urlLoader.findResource( "../lib/serlet-api.jar" );这句(这句话得出的servlet路径不为空).