MXBeanインターフェースを作成することにより、JMXを使用してアプリケーションサーバーでリモート管理するためのメソッドと、それを実装するためのクラスを公開しました。このインターフェースには、サーバーに属性を設定するための操作と、属性の現在の値を取得するための操作が含まれています。たとえば、次の方法を取ります。
public interface WordManagerMXBean {
public void addWord(String word);
public WordsObject getWords();
public void removeWord(String word);
}
WordsObjectは、サーバーの状態に関するデータを取得するために使用される、カスタムのシリアル化可能なクラスです。次に、上記のインターフェイスを実装するWordManagerクラスもあります。次に、リソースを管理するためのJMXエージェントを作成します。
MBeanServer mbs = ManagementFactory.getPlatformMBeanServer();
ObjectName wordManagerName = new ObjectName("com.example:type=WordManager");
mbs.registerMBean(wordManager, wordManagerName);
これらのメソッドを呼び出すクライアントを作成しましたが、これは期待どおりに機能します。ただし、クライアントに返送できるユーザー定義の例外を追加して、この現在の構成を拡張したいと思います。だから私は私のインターフェースを次のようなものに変更したいと思います:
public interface WordManagerMXBean {
public void addWord(String word) throws WordAlreadyExistsException;
public WordsObject getWords();
public void removeWord(String word);
}
私のWordAlreadyExistsExceptionは次のようになります。
public class WordAlreadyExistsException extends Exception implements Serializable {
private static final long serialVersionUID = -9095552123119275304L;
public WordAlreadyExistsException() {
super();
}
}
クライアントでaddWord()メソッドを呼び出すときに、単語がすでに存在する場合はWordAlreadyExistsExceptionを返したいと思います。ただし、これを行うと、次のようなエラーが発生します。
java.rmi.UnmarshalException: Error unmarshaling return; nested exception is:
java.lang.ClassNotFoundException: com.example.WordAlreadyExistsException
WordAlreadyExistsException、WordsObject、およびWordManagerMXBeanインターフェースはすべて、クライアントとサーバーの両方で使用できる単一のjarファイルに含まれています。getWords()メソッドを呼び出すと、クライアントはWordsObjectを問題なく処理できます。ただし、上記のようなユーザー定義の例外がスローされた場合、クライアントは上記のエラーを出します。クライアントでこの例外を正しく処理するようにJMXを設定することは可能ですか?
いくつか検索した後、例外をラップするために使用されるMBeanExceptionクラスがあることに気付きました。このラッピングがエージェントによって自動的に実行されるのか、それとも自分でラッピングを実行するのかはわかりません。両方を試しましたが、どちらの場合もクライアントで同じエラーが発生します。
チェックされた例外とチェックされていない例外の両方でこれを試しましたが、同じエラーが発生します。
これに対する1つの解決策は、すべての標準Java例外が機能するため、一般的なエラー内でエラー文字列を返すことです。しかし、クライアントによる処理の実際の例外を取り戻したいと思います。
JMXでユーザー定義の例外を処理することは可能ですか?もしそうなら、どのようにアイデアはありますか?
編集:フルスタックトレースを含む
java.lang.reflect.UndeclaredThrowableException
at $Proxy4.addWord(Unknown Source)
at com.example.TestClient.addWord(TestClient.java:76)
at com.example.TestClient.execute(TestClient.java:56)
at java.lang.Thread.run(Thread.java:722
Caused by: java.rmi.UnmarshalException: Error unmarshaling return; nested exception is:
java.lang.ClassNotFoundException: com.example.WordAlreadyExistsException
at sun.rmi.transport.StreamRemoteCall.executeCall(StreamRemoteCall.java:245)
at sun.rmi.server.UnicastRef.invoke(UnicastRef.java:160)
at com.sun.jmx.remote.internal.PRef.invoke(Unknown Source)
at javax.management.remote.rmi.RMIConnectionImpl_Stub.invoke(Unknown Source)
at javax.management.remote.rmi.RMIConnector$RemoteMBeanServerConnection.invoke(RMIConnector.java:1017)
at javax.management.MBeanServerInvocationHandler.invoke(MBeanServerInvocationHandler.java:305)
... 6 more
Caused by: java.lang.ClassNotFoundException: com.example.WordAlreadyExistsException
at java.net.URLClassLoader$1.run(URLClassLoader.java:366)
at java.net.URLClassLoader$1.run(URLClassLoader.java:355)
at java.security.AccessController.doPrivileged(Native Method)
at java.net.URLClassLoader.findClass(URLClassLoader.java:354)
at java.lang.ClassLoader.loadClass(ClassLoader.java:423)
at java.lang.ClassLoader.loadClass(ClassLoader.java:356)
at java.lang.Class.forName0(Native Method)
at java.lang.Class.forName(Class.java:264)
at sun.rmi.server.LoaderHandler.loadClass(LoaderHandler.java:453)
at sun.rmi.server.LoaderHandler.loadClass(LoaderHandler.java:184)
at java.rmi.server.RMIClassLoader$2.loadClass(RMIClassLoader.java:637)
at java.rmi.server.RMIClassLoader.loadClass(RMIClassLoader.java:264)
at sun.rmi.server.MarshalInputStream.resolveClass(MarshalInputStream.java:216)
at java.io.ObjectInputStream.readNonProxyDesc(ObjectInputStream.java:1593)
at java.io.ObjectInputStream.readClassDesc(ObjectInputStream.java:1514)
at java.io.ObjectInputStream.readOrdinaryObject(ObjectInputStream.java:1750)
at java.io.ObjectInputStream.readObject0(ObjectInputStream.java:1347)
at java.io.ObjectInputStream.defaultReadFields(ObjectInputStream.java:1964)
at java.io.ObjectInputStream.readSerialData(ObjectInputStream.java:1888)
at java.io.ObjectInputStream.readOrdinaryObject(ObjectInputStream.java:1771)
at java.io.ObjectInputStream.readObject0(ObjectInputStream.java:1347)
at java.io.ObjectInputStream.readObject(ObjectInputStream.java:369)
at sun.rmi.transport.StreamRemoteCall.executeCall(StreamRemoteCall.java:243)
... 11 more