一种在Java中跨ClassLoader的方法调用的实现
内容导读
互联网集市收集整理的这篇技术教程文章主要介绍了一种在Java中跨ClassLoader的方法调用的实现,小编现在分享给大家,供广大互联网技能从业者学习和参考。文章包含1862字,纯文字阅读大概需要3分钟。
内容图文
![一种在Java中跨ClassLoader的方法调用的实现](/upload/InfoBanner/zyjiaocheng/1102/b3f50e33a2c543e8ba3b27c2e029fe0a.jpg)
ClassNotFoundException或者NoClassDefFoundError
在程序运行时我们可能遇到"ClassNotFoundException"或者"NoClassDefFoundError",遇到这样的问题时,当然,我们首先要检查我们的classpath的配置是否正确,需要的class是否已经按预期打包到运行时环境。但除了这些,我们还会遇到class已经被另外ClassLoader加载的情况,而且当前的ClassLoader层次被应用服务器控制,我们甚至无法改变。
以JBoss EAP 6为例,JBoss EAP 6开始使用了新的基于modules的类层次管理,对于已经有依赖声明的module之间才可以用正常方式调用,否则很难跨module调用。我们在(监控)项目中就遇到了web module需要访问message module的运行时信息,此时就必须访问真实的运行时来获取动态的数据,所以用冗余的方式加载目标类都是不能达到目标的。
ClassNotFoundException vs. NoClassDefFoundError
顺便提一下这两者的区别,细节区别就比较多了,简单来说,“ClassNotFoundException”一般是通过类名这个String尝试加载时失败报的,如Class.forName方法加载类,或者ClassLoader.loadClass、ClassLOader.findSystemClass也会出现同样的错误,而用其他方式试图显式加载类则会抛出NoClassDefFoundError。
基于接口编程的跨ClassLoader调用
在我们的项目中,由于module的隔离,“javax.jms.ConnectionFactory"或者“javax.jms.Queue”在当前的ClassLoader中都不可访问,最终我们通过如下的方式来实现:
图示说明:
- 当前工作上下文为ClassLoader1,目标上下文为ClassLoader2.
- 最终通过增加3个如图中砖红色的类,并通过Caller类的调用实现。
- ClassLoader-sub的实现要以ClassLoader2为parent(父加载器),ClassLoader-sub的必要性在于强制加载CallImpl类,并在实现中调用父加载器的基础类实现功能,类似一个适配器的模式。在我们的环境中,“javax.jms.ConnectionFactory"和“javax.jms.Queue”只在这一层可访问。
- 重要:Caller中的调用需要使用反射创建CallImpl的实例,并只能通过接口Call在Caller中引用,使用反射创建CallImpl时需要的ClassLoader-sub的父加载器可以通过JNDI查询ClassLoader2中的object。例如,我们的代码片段如:
String jndiName = getJNDIName(); InitialContext ctx = new InitialContext(); ClassList classList = new ClassList(false, null, null, Arrays.asList(CLASS_LIST)); ClassLoader helperLoader = new JMSCollectorClassLoader(ctx.lookup(jndiName).getClass().getClassLoader(), classList); Class helperClass = helperLoader.loadClass("CallImpl"); Constructor jmsQueueHelperConstructor = helperClass.getConstructor(String.class); Call mJmsQueueHelper = (Call) jmsQueueHelperConstructor.newInstance(jndiName);
其中,CLASS_LIST是需要ClassLoader-sub加载的CallImpl和其他辅助类的列表。
通过这个问题,可以明显的认识到“接口”的一个强大功能:隔绝底层实现的细节,只关心结果。
原文:http://www.cnblogs.com/1xin/p/6628018.html
内容总结
以上是互联网集市为您收集整理的一种在Java中跨ClassLoader的方法调用的实现全部内容,希望文章能够帮你解决一种在Java中跨ClassLoader的方法调用的实现所遇到的程序开发问题。 如果觉得互联网集市技术教程内容还不错,欢迎将互联网集市网站推荐给程序员好友。
内容备注
版权声明:本文内容由互联网用户自发贡献,该文观点与技术仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 gblab@vip.qq.com 举报,一经查实,本站将立刻删除。
内容手机端
扫描二维码推送至手机访问。