java - Java Class.forName 的问题

标签 java reflection interface casting classcastexception

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

代码在不在 Web 应用程序的上下文中调用时有效(我通过将方法复制并粘贴到单独的程序中并从 main 调用它来测试它)。但是,当我运行/调试 Web 应用程序(我使用的是 NetBeans)时,代码失败。当我尝试将实例转换为 jar_file_dependencies.jar 中指定的接口(interface)时,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());
    }

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

非常感谢, 丹

最佳答案

简短的回答,不涉及太多繁琐的细节:gameJar 和 gameDependenciesJar 之一或两者可能包含 IMyClass 类/接口(interface)的定义。使用子类加载器时的经验法则是子类加载器应该包含任何“共享”类——这些应该只存在于父类加载器中。

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

关于java - Java Class.forName 的问题,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/4402712/

相关文章:

java - JAVA去除图像中的空白

java - 如何转换 PNG<->JPEG<->TIFF 图像

java - 如何在SPRING JPA查询结果中添加列名

c# - 如何递归获取命名空间内的所有命名空间

c++ - 转类 "Interfaceable"

java - 在 Spring Boot 中为接口(interface)使用 @Autowired 注解

c# - 您如何平衡框架/API 设计和 TDD

java - 如何访问 rx 中先前发射的数据?

java - 如何为 Java 类字段生成准确的泛型表达式?

java - 获取 Foo[].class 给定的 Foo.class