繁体   English   中英

无法在具有接口的插件类支持的Java应用程序中公开自定义类,即Jar中的Jar

[英]Cannot expose custom class in Java application with interfaced plugin class support, Jar within a Jar

我有一个使用websocket通信的服务器/客户端设置,它们都是Spring Boot应用程序,用于通信的消息类保存在单独的项目“ CommonClasses”中。

Server和Client项目在其构建路径上都具有CommonClasses项目,使他们可以访问共享消息类型。

客户端将收到来自服务器的消息,并在响应之前对其进行操作。 迄今为止,客户可以执行的功能数量有限,但是其目的是向客户开放以设计自己的实现。 为此,有一个必须实例化的接口,我只需将客户端添加到新项目的类路径中,放入新的实现中,并在客户端中使用类路径加载器加载此新jar并调用即可完成此操作新方法。

如果我具有普通方法,则此方法有效,但是当我尝试实现先前传递了CommonClasses中详细说明的消息的实际接口时,此方法无效。

如果我解压缩客户端jar文件并将生成的CommonClasses jar文件添加到我的类路径中,则可以看到这些类,但是当我尝试将实例对象转换为我的Interface类型时,我得到了java.lang.ClassCastException。

我对堆栈溢出进行了研究,得出的结论是,尽管客户端接口和新项目中引用的接口具有相同的签名和项目,但它们被视为不同的对象。 都是因为我不得不从客户端jar中提取CommonClasses jar。

我有什么选择? 我知道我可以创建一个新接口并仅使用简单的Java类型并转换所有内容,但这将是昂贵的,并且如果可能的话,请避免这样做。 可以更改现有项目的构建过程,但如有可能,应避免。

到目前为止,这是我所拥有的:

    URL[] classLoaderUrls = new URL[]{new URL("file:C:\\customApplier.jar")};
    // Create a new URLClassLoader
    URLClassLoader urlClassLoader = new URLClassLoader(classLoaderUrls);
    // Load the target class
    Class<?> beanClass = urlClassLoader.loadClass("com.test.Applier");
    // Create a new instance from the loaded class
    Constructor<?> constructor = beanClass.getConstructor();
    ApplierIn ob = (ApplierIn)constructor.newInstance();

尝试强制转换为(ApplierIn)时引发异常。 感谢您的任何建议!

感谢@ Klaus-Groenbaek能够识别问题,它的确是一个不正确的类加载器。 所以我将其更改为:

    private static void addCustomJar(URL fileUrl) throws NoSuchMethodException, SecurityException, IllegalAccessException, IllegalArgumentException, InvocationTargetException {
    Method method = URLClassLoader.class.getDeclaredMethod("addURL", new Class[]{URL.class});
    method.setAccessible(true);
    method.invoke(ApplierIn.class.getClassLoader(), new Object[]{fileUrl});
}

为了将新的jar文件加载到我的应用程序中。 之后,事实证明,罐子中未包装的罐子不是问题!

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM