【问题标题】:Problem with Java Class.forNameJava Class.forName 的问题
【发布时间】:2011-05-23 02:37:19
【问题描述】:

我正在尝试使用 Class.forName 在运行时从文件系统上的 .jar 文件动态加载类。我尝试加载的类在另一个 .jar 文件中实现了一个接口,因此我使用自己的 URLClassLoader 来引用这两个 .jar。

该代码在不在 Web 应用程序的上下文中调用时有效(我已通过将方法复制并粘贴到单独的程序中并从 main 调用它来测试这一点)。但是,当我运行/调试 Web 应用程序(我使用的是 NetBeans)时,代码会失败。当我尝试将实例强制转换为 jar_file_dependencies.jar 中指定的接口时,newInstance 方法会引发 ClassCastException。

如果有帮助,这里是相关代码:

       File gameJar = new File("C:\\file_path\\jar_file.jar");

       File gameDependenciesJar = new File("C:\\file_path\\jar_file_dependencies.jar");

        URLClassLoader cl = new URLClassLoader(new URL[]
                {
                    gameJar.toURI().toURL(),
                    gameDependenciesJar.toURI().toURL()
                });

        Class clazz = Class.forName("MyClass", true, cl);

        IMyClass myClass = (IMyClass)clazz.newInstance();

        System.out.println(game);

    } catch (Exception e)
    {
        System.out.println(e.getMessage());
    }

任何关于为什么此代码在一个程序而不是另一个程序中工作的建议将不胜感激。

非常感谢, 丹

【问题讨论】:

标签: java reflection interface casting classcastexception


【解决方案1】:

简短的回答,无需过多详细说明:gameJar 和 gameDependenciesJar 之一或两者可能包含 IMyClass 类/接口的定义。使用子类加载器时的经验法则是子类加载器应该包含任何“共享”类——这些应该只存在于父类加载器中。

部分解释:Web 应用程序类加载器通常具有与普通类加载器不同的委托策略。通常他们更喜欢孩子的班级而不是父母的班级。普通类加载器通常更喜欢父类而不是子类。在您的网络应用程序中,您最终得到了 IMyClass 类的 2 个单独定义(父类加载器中的一个定义,子类中的一个定义)。在您的普通应用程序中,子类加载器中的 IMyClass 定义被忽略,因此只加载了一个定义(在父类加载器中),一切都很顺利。

【讨论】:

    【解决方案2】:

    也许这会有所帮助,(未经测试)

    ClassLoader clsLoader = Thread.currentThread().getContextClassLoader();
    if (clsLoader == null) {
        clsLoader = this.getClass().getClassLoader();
    }
    
    URLClassLoader cl = new URLClassLoader(new URL[]
                    {
                        gameJar.toURI().toURL(),
                        gameDependenciesJar.toURI().toURL()
                    }, clsLoader);
    

    此外,您应该传递一个类的完整声明性名称MyClass,而不是在Class.forName() 中直接调用它MyClass

    例如

    Class clazz = Class.forName("com.xxxx.yyy.MyClass", true, cl);
    

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 2014-04-21
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2013-11-09
      相关资源
      最近更新 更多