Warning: file_get_contents(/data/phpspider/zhask/data//catemap/8/design-patterns/2.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181

Warning: file_get_contents(/data/phpspider/zhask/data//catemap/6/mongodb/12.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Websphere 如何安全地处理JMX远程客户端中缺少的本地类_Websphere_Rmi_Jmx_Classnotfoundexception_Corba - Fatal编程技术网

Websphere 如何安全地处理JMX远程客户端中缺少的本地类

Websphere 如何安全地处理JMX远程客户端中缺少的本地类,websphere,rmi,jmx,classnotfoundexception,corba,Websphere,Rmi,Jmx,Classnotfoundexception,Corba,我一直在玩一个可编程的远程JMX客户机,连接到WebSphereApplicationServer的MBean服务器。到目前为止还不错,我可以使用适当的JMXServiceURL进行连接,并从我的bean订阅通知 但是-如果一个bean发送一个通知,其中包含一个不在本地类路径上的类,那么它就会产生一个很好的堆栈跟踪: SEVERE: Failed to fetch notification, stopping thread. Error is: java.rmi.RemoteException:

我一直在玩一个可编程的远程JMX客户机,连接到WebSphereApplicationServer的MBean服务器。到目前为止还不错,我可以使用适当的JMXServiceURL进行连接,并从我的bean订阅通知

但是-如果一个bean发送一个通知,其中包含一个不在本地类路径上的类,那么它就会产生一个很好的堆栈跟踪:

SEVERE: Failed to fetch notification, stopping thread. Error is: java.rmi.RemoteException: CORBA NO_IMPLEMENT 1330646337 No; nested exception is: 
    org.omg.CORBA.NO_IMPLEMENT: The sender's class RMI:com.mycompany.MyWeirdClass:143EC4C84209B825:EAD08F0965BC6044 is not present on the local classpath, and the class is not marked as truncatable, so it cannot be unmarshaled.  vmcid: OMG  minor code: 1  completed: No
java.rmi.RemoteException: CORBA NO_IMPLEMENT
... more frames ...
其最终原因是:

Caused by: java.lang.ClassNotFoundException: com.mycompany.MyWeirdClass
    at com.ibm.rmi.util.RepositoryId.loadClass(RepositoryId.java:675)
    at com.ibm.rmi.util.RepositoryId.checkClassCache(RepositoryId.java:644)
    ...
看起来它在IBM代码的深处爆炸,似乎没有任何地方我可以做任何事情;有问题的通知从未到达我的NotificationListener


所以,;我能做些什么来处理这种情况,而不让我收到进一步的通知?

我可以想出4种方法来解决这个问题,按复杂度的升序排列(我认为):

将类库添加到客户端类路径

陈述显而易见的,但尽量全面

修改通知

考虑修改服务器生成的通知,将com.mycompany.MyWeirdClass实例交换为格式化字符串。如果对象复杂,请考虑使用XML或JSON。如果您可以修改通知发送方来封送实例,那么这可能是最简单的方法。如果没有,您可以修改com.mycompany.MyWeirdClass类(应该是,对吗?),并添加一个返回实例字符串表示形式的方法

远程类加载器

在WebSphere应用程序中实现一个HTTP服务器,该服务器返回包含com.mycompany.MyWeirdClass类及其所有依赖项的JAR。(从技术上讲,HTTP服务器可以在任何地方,只要它提供正确的类。)让我们假设JAR在http://classloader.mycompany.com/Weird.jar。现在,使用添加的系统属性启动客户端,如下所示:

java .....  -D-Djava.rmi.server.codebase=http://classloader.mycompany.com/Weird.jar ...
import com.sun.jmx.mbeanserver.DefaultMXBeanMappingFactory;
import com.sun.jmx.mbeanserver.MXBeanMapping;
final MXBeanMapping mapping = 
   DefaultMXBeanMappingFactory.DEFAULT.mappingForType(
      com.mycompany.MyWeirdClass.class, 
      DefaultMXBeanMappingFactory.DEFAULT
   );
private Object writeReplace() throws ObjectStreamException {
   try {
      return mapping.toOpenValue(this);
   } catch (Exception ex) {
      throw new RuntimeException(ex);
   }
}
这里有一个HTTP服务器实现的示例,用于提供动态类加载

将类实现为JMX OpenType

实现这一点最常用的方法是将类设为,或者可以实现或扩展。如果您不介意使用com.sun类,java运行时(1.6+)将包含一个为您创建复合数据实例的类,因此此实用程序可以与上述解决方案之一配合使用。例如,实现writeReplace跟踪如下:

java .....  -D-Djava.rmi.server.codebase=http://classloader.mycompany.com/Weird.jar ...
import com.sun.jmx.mbeanserver.DefaultMXBeanMappingFactory;
import com.sun.jmx.mbeanserver.MXBeanMapping;
final MXBeanMapping mapping = 
   DefaultMXBeanMappingFactory.DEFAULT.mappingForType(
      com.mycompany.MyWeirdClass.class, 
      DefaultMXBeanMappingFactory.DEFAULT
   );
private Object writeReplace() throws ObjectStreamException {
   try {
      return mapping.toOpenValue(this);
   } catch (Exception ex) {
      throw new RuntimeException(ex);
   }
}