インタフェースに対して、MXBeanインタフェースである、またはMXBeanインタフェースではないというマークを明示的に付けるための注釈です。 デフォルトでは、インタフェースがpublicで、SomethingMXBean
のように名前の末尾がMXBean
の場合、MXBeanインタフェースです。 次に示すインタフェースは、MXBeanインタフェースです。
public interface WhatsitMXBean {} @MXBean public interface Whatsit1Interface {} @MXBean(true) public interface Whatsit2Interface {}
次に示すインタフェースは、MXBeanインタフェースではありません。
interface NonPublicInterfaceNotMXBean{} public interface Whatsit3Interface{} @MXBean(false) public interface MisleadingMXBean {}
MXBean仕様
MXBeanの概念を使用すると、javax.management.openmbean
により定義された、定義済みの型セットだけを参照するMBeanを簡単にコーディングできます。 この方法なら、リモート・クライアントを含むクライアントは、MBeanの型を示すモデル固有のクラスにアクセスしなくても、MBeanを利用できます。
この概念は、Standard MBeanの概念と比べて、理解しやすいものです。 ここでは、管理対象オブジェクトをStandard MBeanおよびMXBeanとして表現する方法について説明します。
Standard MBean
public interface MemoryPoolMBean { String getName(); MemoryUsage getUsage(); // ... }
MXBean
public interface MemoryPoolMXBean { String getName(); MemoryUsage getUsage(); // ... }
上記の記述から、定義は非常に類似していることがわかります。 唯一の相違点は、インタフェースの命名規則として、Standard MBeanではSomethingMBean
を使用するのに対して、MXBeanではSomethingMXBean
を使用するという点です。
この管理対象オブジェクトでは、MemoryUsage
型のUsage
という名前の属性があります。 この種の属性の特徴は、データ項目セットの一貫したスナップショットを提供する点です。 たとえば、メモリー・プール内の現在の使用済みメモリー容量や、現在のメモリー・プールの最大値を含めることができます。 これらが別の項目になっていると、getAttribute
を個別に呼び出して項目を取得するため、さまざまな時点の一貫性のない値を取得する可能性があります。 max
値よりも大きいused
値を取得する可能性もあります。
このため、次のようにMemoryUsage
を定義できます。
Standard MBean
public class MemoryUsage implements Serializable { // standard JavaBean conventions with getters public MemoryUsage(long init, long used, long committed, long max) {...} long getInit() {...} long getUsed() {...} long getCommitted() {...} long getMax() {...} }
MXBean
public class MemoryUsage { // standard JavaBean conventions with getters @ConstructorParameters({"init", "used", "committed", "max"}) public MemoryUsage(long init, long used, long committed, long max) {...} long getInit() {...} long getUsed() {...} long getCommitted() {...} long getMax() {...} }
MXBeanではMemoryUsage
にSerializable
のマークを付ける必要がないことを除けば、どちらの場合も定義は同じです(ただし、Serializableのマークを付けることは可能)。 一方、コンストラクタ・パラメータを対応するgetterにリンクする@ConstructorParameters
注釈を追加しました。 この点については、あとで詳しく説明します。
MemoryUsage
は、モデル固有クラスです。 Standard MBeanでは、MemoryUsage
クラスが不明な場合、MBeanサーバーのクライアントはUsage
属性にアクセスできません。 クライアントが、JMX技術に基づくジェネリック・コンソールである場合を考えてみましょう。 この場合、コンソールは、接続先の各アプリケーションのモデル固有クラスを使って設定する必要があります。 Java言語で記述されていないクライアントの場合、問題は一層難しくなります。 この場合、MemoryUsage
の内容についてクライアントに知らせる方法がない可能性があります。
このような場合に、MXBeanはStandard MBeanと異なります。 管理インタフェースの定義方法はほとんど同じですが、MXBeanフレームワークでは、モデル固有クラスがJavaプラットフォームの標準クラスに変換されます。 配列および標準javax.management.openmbean
パッケージのCompositeData
クラスとTabularData
クラスを使用することで、標準クラスだけを使用して任意の複雑さのデータ構造を構築できます。
この点は、2つのモデルのクライアントを比較することでより明確になります。
Standard MBean
String name = (String)
mbeanServer.getAttribute
(objectName, "Name");
MemoryUsage usage = (MemoryUsage)
mbeanServer.getAttribute(objectName, "Usage");
long used = usage.getUsed();
MXBean
String name = (String) mbeanServer.getAttribute
(objectName, "Name");CompositeData
usage = (CompositeData) mbeanServer.getAttribute(objectName, "Usage"); long used = (Long) usage.get
("used");
String
などの単純な型の属性の場合、コードは同じです。 ただし、複雑な型の属性の場合、Standard MBeanのコードではクライアントがモデル固有クラスMemoryUsage
を認識する必要があるのに対し、MXBeanのコードでは非標準クラスは必要ありません。
ここに示すクライアント・コードでは、MXBeanクライアントの方がいくらか複雑になっています。 ただし、クライアントがモデル(ここでは、MemoryPoolMXBean
インタフェースとMemoryUsage
クラス)を実際に認識している場合は、プロキシの構築が可能です。 モデルが事前にわかる場合には、Standard MBeanを使用するかMXBeanを使用するかに関係なく、この方法で管理対象オブジェクトとのやり取りを行うことをお勧めします。
Standard MBean
MemoryPoolMBean proxy =
JMX.newMBeanProxy
(
mbeanServer,
objectName,
MemoryPoolMBean.class);
String name = proxy.getName();
MemoryUsage usage = proxy.getUsage();
long used = usage.getUsed();
MXBean
MemoryPoolMXBean proxy =
JMX.newMXBeanProxy
(
mbeanServer,
objectName,
MemoryPoolMXBean.class);
String name = proxy.getName();
MemoryUsage usage = proxy.getUsage();
long used = usage.getUsed();
MemoryPoolオブジェクトの実装の動作は、Standard MBeanでもMXBeanでも同様です。
Standard MBean
public class MemoryPool implements MemoryPoolMBean { public String getName() {...} public MemoryUsage getUsage() {...} // ... }
MXBean
public class MemoryPool implements MemoryPoolMXBean { public String getName() {...} public MemoryUsage getUsage() {...} // ... }
MBean ServerへのMBeanの登録の動作は、どちらの場合も同じです。
Standard MBean
{
MemoryPoolMBean pool = new MemoryPool();
mbeanServer.registerMBean
(pool, objectName);
}
MXBean
{
MemoryPoolMXBean pool = new MemoryPool();
mbeanServer.registerMBean
(pool, objectName);
}
MXBeanの定義
MXBeanは、MBeanの一種です。 MXBeanオブジェクトは、MBeanサーバーに直接登録することも、StandardMBean
の引数として使用し、結果のMBeanをMBeanサーバーに登録することもできます。
MBeanServer
インタフェースのregisterMBean
やcreateMBean
メソッドを使ってオブジェクトをMBeanサーバーに登録すると、MBeanの型を判別するためにオブジェクトのクラスが検査されます。
- クラスが
DynamicMBean
インタフェースを実装する場合、MBeanはDynamic MBeanです。StandardMBean
クラスはこのインタフェースを実装します。このため、これはStandardMBean
クラスを使って作成されたStandard MBeanまたはMXBeanに適用されます。 - それ以外で、クラスがStandard MBeanの命名規則に一致する場合、MBeanはStandard MBeanです。
- 上記のいずれにも当てはまらない場合は、MXBeanの可能性があります。 次のインタフェースがあるかどうか、オブジェクトにより実装されたインタフェースのセットが検査されます。
- クラス名が
SMXBean
のインタフェース(S
は空ではない文字列であり、注釈@MXBean(false)
を含まない); および/または @MXBean(true)
または単に@MXBean
という注釈を含むインタフェース。
MemoryPoolMXBean
です。 - クラス名が
- これらの条件に当てはまるものがない場合、MBeanは無効であり、登録を試みると
NotCompliantMBeanException
が生成されます。
MXBeanインタフェース内でメソッドのパラメータまたは戻り値の型として示されるすべてのJava型が、次のルールに従って変換可能である必要があります。 また、パラメータが次の定義に従って再構築可能である必要があります。
上記のルールに準拠しないMXBeanを構築しようとすると、例外がスローされます。
命名規則
MXBean内のメソッドには、Standard MBean内のメソッドと同じ命名規則が適用されます。
T getN()
メソッド(T
はvoid
ではないJava型、N
は空でない文字列)は、N
という名前の読取り可能な属性が存在することを示します。 属性のJava型および公開型は、次のマッピング・ルールに従って決定されます。Object
から継承したfinal Class getClass()
メソッドは、getterの検索時には無視されます。boolean isN()
メソッドは、Java型boolean
および公開型SimpleType.Boolean
の読取り可能属性N
が存在することを示します。void setN(T x)
メソッドは、書込み可能属性N
が存在することを示します。 属性のJava型および公開型は、次のマッピング・ルールに従って決定されます。 (パラメータの名前x
は関係ありません。)- ほかのすべてのメソッドは、メソッドと同じ名前の演算が存在することを示します。 戻り値および各パラメータのJava型および公開型は、次のマッピング・ルールに従って決定されます。
getN
およびisN
のルールにより、getterの概念がまとめて定義されます。 setN
のルールにより、setterの概念が定義されます。
同名のgetterが2つ存在するか、同名のsetterが2つ存在するとエラーになります。 同名のgetterとsetterが存在する場合は、両方のT
型を同じにします。 この場合、属性は読み取り/書込み属性になります。 getterとsetterのいずれか一方が1つだけ存在する場合、属性はそれぞれ読取り専用または書込み専用になります。
型マッピング・ルール
javax.management.openmbean
パッケージで定義されているように、MXBeanはOpen MBeanの一種です。 これは、属性、演算パラメータ、および演算の戻り値がすべて、公開型 (つまりOpenType
の4つの標準サブクラス)を使って記述可能でなければならないことを意味します。 MXBeanでは、Java型を公開型にマッピングすることでこれを実現します。
すべてのJava型Jで、MXBeanマッピングの記述に次の情報が使用されます。
- 対応する公開型であるopentype(J)。 これは、
OpenType
のサブクラスのインスタンスです。 - マップされたJava型opendata(J)。これはどのopentype(J)についても、1つのopendata(J)に対しては常に同じです。 これはJavaクラスです。
- 値をJ型からopendata(J)型に変換する方法。
- 値をopendata(J)型からJ型に変換する方法(可能な場合)。
たとえば、Java型List<String>
について考えてみましょう。
- 公開型、opentype(
List<String>
)はArrayType
(1,
SimpleType.STRING
)
であり、1次元のString
配列を表します。 - マップされたJava型、opendata(
List<String>
)はString[]
です。 List<String>
は、List.toArray(new String[0])
を使ってString[]
に変換できます。String[]
は、Arrays.asList
を使ってList<String>
に変換できます。
Jからopentype(J)を派生させるマッピング・ルールが存在しない場合、JをMXBeanインタフェース内のメソッド・パラメータまたは戻り値の型にすることはできません。
opendata(J)をJに再変換する方法がある場合、Jは再構築可能であると言います。 MXBeanインタフェース内のすべてのメソッド・パラメータは、再構築可能である必要があります。これは、MXBeanフレームワークがメソッドを呼び出す際に、これらのパラメータをopendata(J)からJに変換する必要があるためです。 JMX.newMXBeanProxy
により生成されたプロキシでは、これは、再構築可能でなければならないMXBeanインタフェース内のメソッドの戻り値です。
null値を使用できないプリミティブJava型を除く、すべてのJava型と公開型で、null値が許可されます。 J型をopendata(J)型に変換したり、opendata(J)型をJ型に変換したりする場合は、null値とnull値がマッピングされます。
次の表に、型マッピング・ルールの概要を示します。
Java型J | opentype(J) | opendata(J) |
---|---|---|
int 、boolean など(8つのプリミティブJava型) |
SimpleType.INTEGER 、SimpleType.BOOLEAN など |
Integer 、Boolean など(対応するboxed型) |
Integer 、ObjectName など( SimpleType の適用範囲内の型) |
対応するSimpleType |
J、同じ型 |
int[] など (プリミティブ型の1ディメンション配列) |
ArrayType.getPrimitiveArrayType(int[].class) など |
J、同じ型 |
E[] (非プリミティブ要素型Eの配列、 int[][] を含む。Eはint[] ) |
ArrayType.getArrayType( opentype(E)) |
opendata(E)[] |
List< E> Set< E> SortedSet< E> (下記を参照) |
E[] に対するものと同じ |
E[] に対するものと同じ |
列挙E (Java内で enum E {...} として宣言される) |
SimpleType.STRING |
String |
Map< K,V> SortedMap< K,V> |
TabularType (下記を参照) |
TabularData (下記を参照) |
レコード・クラス | 可能な場合にはCompositeType (下記を参照) |
CompositeData (下記参照) |
MXBeanインタフェース | SimpleType.OBJECTNAME (下記を参照) |
ObjectName (下記を参照) |
その他の型 | 可能な場合にはCompositeType (下記を参照) |
CompositeData (下記参照) |
以降のセクションでは、これらのルールについて詳しく説明します。
プリミティブ型のマッピング
8つのプリミティブJava型(boolean
、byte
、short
、int
、 long
、float
、double
、char
)は、java.lang
から Boolean
、Byte
などの対応するboxed型にマッピングされます。公開型は、対応するSimpleType
です。 このため、opentype( long
)はSimpleType.LONG
に、opendata(long
)は java.lang.Long
になります。
long[]
などのプリミティブ型の配列は、公開型として直接表現できます。 従って、openType( long[]
)は ArrayType.getPrimitiveArrayType(long[].class)
であり、opendata( long[]
)は long[]
です。
JMX API内の演算はプリミティブではなく常にJavaオブジェクト上で実行されるため、実際には、プレーンなint
と Integer
の違いなどが明確になることはありません。 ただし、配列で違いが明らかになります。
コレクションのマッピング(List<
E>
など)
List<String>
または Set<ObjectName>
のようなList<
E >
または Set<
E >
は、String[]
または ObjectName[]
のような同じ要素型の配列と同じ方法でマッピングされます。
SortedSet<
E>
もE[]
と同じ方法でマッピングされます。ただし、これが変換可能なのは、EがComparable
を実装するクラスまたはインタフェースである場合のみです。 このため、SortedSet<String>
やSortedSet<Integer>
は変換可能ですが、 SortedSet<int[]>
やSortedSet<List<String>>
は変換不可能です。 SortedSet
インスタンスの変換は、null以外のcomparator()
が存在すると、IllegalArgumentException
をスローして失敗します。
List<
E>
はjava.util.ArrayList<
E>
として、Set<
E>
はjava.util.HashSet<
E>
として、SortedSet<
E>
はjava.util.TreeSet<
E>
としてそれぞれ再構築されます。
マップのマッピング(Map<
K,V>
など)
Map<
K,V>
または SortedMap<
K,V>
( Map<String,ObjectName>
など)は、公開型TabularType
を持ち、TabularData
にマッピングされます。 TabularType
には、key
およびvalue
という名前の2つの項目が含まれます。 key
の公開型はopentype(K)、value
の公開型はopentype(V)です。 TabularType
のインデックスは、単一の項目key
です。
たとえば、 Map<String,ObjectName>
のTabularType
は、次のようなコードを使って構築できます。
String typeName = "java.util.Map<java.lang.String, javax.management.ObjectName>"; String[] keyValue = new String[] {"key", "value"}; OpenType[] openTypes = new OpenType[] {SimpleType.STRING, SimpleType.OBJECTNAME}; CompositeType rowType = new CompositeType(typeName, typeName, keyValue, keyValue, openTypes); TabularType tabularType = new TabularType(typeName, typeName, rowType, new String[] {"key"});
typeName
は、次に詳述する型名ルールに従って決定されます。
SortedMap<
K,V>
は同じ方法でマッピングされます。ただし、これが変換可能なのは、KがComparable
を実装するクラスまたはインタフェースである場合のみです。 このため、SortedMap<String,int[]>
は変換可能ですが、SortedMap<int[],String>
は変換不可能です。 SortedMap
インスタンスの変換は、null以外のcomparator()
が存在すると、 IllegalArgumentException
をスローして失敗します。
Map<
K,V>
はjava.util.HashMap<
K,V>
として、SortedMap<
K,V>
はjava.util.TreeMap<
K,V>
としてそれぞれ再構築されます。
TabularData
はインタフェースです。 Map<
K,V>
を公開データとして表現するのに使用される具象クラスはTabularDataSupport
、またはTabularDataSupport
として直列化する TabularData
を実装する別のクラスです。
レコードのマッピング
「レコード」クラスJは、componentsがすべてオープン・タイプに変換可能な場合にのみCompositeType
に変換できます。 それ以外の場合は、変換できません。 コンポーネントを持たないレコードは変換できません。
レコード・クラスのCompositeType
へのマッピング
すべてのコンポーネントがオープン・タイプに変換可能なレコードは、それ自体がCompositeType
に変換できます。 レコード・クラスは、次のようにCompositeType
に変換されます。
CompositeType
のタイプ名はレコード・クラスの名前です。- レコードgetterは、「レコード・コンポーネント」のアクセサです。
- タイプがTのレコード・コンポーネントごとに、
CompositeType
のアイテムはレコード・コンポーネントと同じ名前になり、そのタイプは前述の「タイプ・マッピング・ルール」で定義されているopentype(T)になります。
レコード・クラスのインスタンスのCompositeData
へのマッピング
CompositeType
に対応するレコード・クラスのインスタンスからCompositeData
へのマッピングは、「その他のタイプ」に指定されているものと同じです。
CompositeData
からのレコード・クラスのインスタンスの再構築
レコードは、その標準コンストラクタを使用して再構築されます。 標準コンストラクタでは、@javax.management.ConstructorParameters
または@java.beans.ConstructorProperties
注釈が存在する必要はありません。 これらの注釈が標準コンストラクタに存在する場合は、無視されます。
レコード・クラスJのインスタンスをCompositeData
から再構築する方法の詳細は、次の「CompositeData
からのJavaタイプまたはレコード・クラスJのインスタンスの再構築」を参照してください。
MXBeanインタフェースのマッピング
MXBeanインタフェース、またはMXBeanインタフェース内部で参照される型は、別のMXBeanインタフェースJを参照できます。 この場合、opentype(J)はSimpleType.OBJECTNAME
、opendata(J)はObjectName
です。
たとえば、次のような2つのMXBeanインタフェースが存在する場合を考えましょう。
public interface ProductMXBean { public ModuleMXBean[] getModules(); } public interface ModuleMXBean { public ProductMXBean getProduct(); }
ModuleMXBean
インタフェースを実装するオブジェクトは、そのgetProduct
メソッドから、ProductMXBean
インタフェースを実装するオブジェクトを返します。 ModuleMXBean
オブジェクトと返される ProductMXBean
オブジェクトの両方を、同じMBeanサーバーのMXBeanとして登録する必要があります。
ModuleMXBean.getProduct()
メソッドは、Product
という名前の属性を定義します。 この属性の公開型はSimpleType.OBJECTNAME
です。対応するObjectName
値は、参照されるProductMXBean
がMBeanサーバー内で登録される名前になります。
ModuleMXBean
用のMXBeanプロキシを作成して、そのgetProduct()
メソッドを呼び出す場合、別のMXBeanプロキシを作成することにより、プロキシがObjectName
をProductMXBean
に再度マッピングします。 より正式には、JMX.newMXBeanProxy(mbeanServerConnection, objectNameX, interfaceX)
で作成されたプロキシがobjectNameY
を別のMXBeanインタフェースである interfaceY
にマップする必要がある場合は、 JMX.newMXBeanProxy(mbeanServerConnection, objectNameY, interfaceY)
を使用します。 この実装では、同じパラメータを使ってJMX.newMXBeanProxy
を呼び出すことで、以前に作成されたプロキシが返されることがあります。また、新規プロキシが作成されることもあります。
ModuleMXBean
インタフェースを次のように変更することで、逆マッピングを実行できます。
public interface ModuleMXBean { public ProductMXBean getProduct(); public void setProduct(ProductMXBean c); }
setProduct
メソッドの存在は、Product
属性が読み取り/書込みであることを示します。 以前と同様に、この属性の値はObjectName
になります。 この属性を設定する場合は、ObjectName
をsetProduct
メソッドで必要なProductMXBean
オブジェクトに変換します。 このオブジェクトは、同じMBeanサーバー内の指定されたObjectName
のMXBeanプロキシになります。
ModuleMXBean
用のMXBeanプロキシを作成してそのsetProduct
メソッドを呼び出す場合、プロキシはそのProductMXBean
引数をObjectName
に再度マッピングします。 これが機能するのは、引数が実際に、同じ MBeanServerConnection
内のProductMXBean
に対応する別のプロキシである場合のみです。 プロキシは、別のプロキシから返されることがあります(たとえば、ModuleMXBean.getProduct()
はProductMXBean
用のプロキシを返す)。また、JMX.newMXBeanProxy
により作成されることも、MBeanServerInvocationHandler
またはサブクラスである呼出しハンドラを持つProxy
を使って作成されることもあります。
2つの異なるObjectName
に同じMXBeanが登録されていると、別のMXBeanからそのMXBeanへの参照があいまいになります。 このため、MBeanサーバーに登録済のMXBeanオブジェクトを、別の名前で同じMBeanサーバーに登録しようとすると、InstanceAlreadyExistsException
がスローされます。 一般に、1つのMBeanオブジェクトを複数の名前で登録することは避けてください。特に、NotificationBroadcaster
であるMBeanでは、正しく動作しません。
その他の型のマッピング
JavaクラスやインタフェースJが上記の表に示したそのほかのルールに当てはまらない場合、次に示すように、MXBeanフレームワークによりCompositeType
へのマッピングが試みられます。 このCompositeType
の型名は、次の型名ルールに従って決定されます。
JavaタイプJのCompositeType
へのマッピング
getterのクラスは、上記の規則を使って検査されます。 (getterはpublicインスタンス・メソッドでなければならない。) getterが存在しないか、getterの型が変換不可能な場合、Jは変換不可能です。
1つ以上のgetterが存在し、どのgetterにも変換可能な型が存在する場合、opentype(J)は各getter用の項目を1つ保持する CompositeType
です。 次のgetterの場合、
T getName()
CompositeType
内の項目はname
と呼ばれ、opentype(T)型を持ちます。 たとえば、次の項目の場合、
String getOwner()
項目はowner
と呼ばれ、公開型 SimpleType.STRING
を持ちます。 次のgetterの場合、
boolean isName()
CompositeType
内の項目はname
と呼ばれ、SimpleType.BOOLEAN
型を持ちます。
最初の文字(コード・ポイント)が、小文字に変換されることに留意してください。 これはJava Beansの規則に従っています。歴史的な理由から、これはStandard MBeanの規則とは異なります。 標準のMBeanまたはMXBeanインタフェースでは、メソッドgetOwner
はOwner
という属性を定義し、Java BeanまたはマップされたCompositeType
ではメソッド getOwner
がowner
というプロパティまたはアイテムを定義します。
2つのメソッドが同じアイテム名(たとえば、 getOwner
およびisOwner
、またはgetOwner
および getowner
)を生成する場合、その型は変換可能ではありません。
Javaタイプまたはレコード・クラスJのインスタンスからCompositeData
へのマッピング
公開型がCompositeType
の場合、対応するマップされたJava型(opendata(J))はCompositeData
になります。 Jのインスタンスから、上記のCompositeType
に対応するCompositeData
へのマッピングは、次のように実行されます。 最初に、JがCompositeDataView
インタフェースを実装する場合、そのインタフェースのtoCompositeData
メソッドが呼び出されて、変換が実行されます。 それ以外の場合は、項目ごとにgetterを呼び出して対応する公開データ型に変換することにより、CompositeData
が構築されます。 これにより、次のようなgetterが、
List<String> getNames()
(または、レコードの場合はList<String> names()
)
名前「names
」および公開型ArrayType(1, SimpleType.STRING)
の項目にマッピングされます。 CompositeData
への変換によりgetNames()
が呼び出され、生成されたList<String>
が項目「names
」のString[]
に変換されます。
CompositeData
はインタフェースです。 型をオープン・データとして表現するために使用される具象クラスは、CompositeDataSupport
、または CompositeDataSupport
として直列化される CompositeData
を実装する別のクラスです。
CompositeData
からのJavaタイプまたはレコード・クラスJのインスタンスの再構築
opendata(J)がJava型JのCompositeData
である場合、JのインスタンスをCompositeData
から再構築可能であるか、Jは再構築不可能であるかのどちらかになります。 CompositeData
内のいずれかの項目が再構築不可能である場合、Jも再構築不可能です。
指定した任意のJに関して、CompositeData
からJのインスタンスを再構築する方法を決定する際、次のルールが適用されます。 リスト内で適用可能な最初のルールが使用されます。
Jが
public static
Jfrom(CompositeData cd)
メソッドを持つ場合、そのメソッドを呼び出すことでJのインスタンスが再構築されます。それ以外の場合、Jが
Record
クラスで、レコード標準コンストラクタが適用可能な場合、Jのインスタンスはレコードの標準コンストラクタを呼び出して再構築されます。 標準コンストラクタ(該当する場合)は、CompositeData
から適切な再構築アイテムを使用してコールされます。 レコード・コンポーネントで指定されたすべてのプロパティがCompositeData
に存在する場合は、標準コンストラクタはapplicableです。それ以外の場合、Jに
@javax.management.ConstructorParameters
または@java.beans.ConstructoProperties
注釈を持つ少なくとも1つのパブリック・コンストラクタがある場合、Jのインスタンスを再構築するために、これらのコンストラクタの1つ(必ずしも常に同じではない)が呼び出されます。 コンストラクタに@javax.management.ConstructorParameters
と@java.beans.ConstructorProperties
の両方が付いている場合、@javax.management.ConstructorParameters
が使用され、@java.beans.ConstructorProperties
は無視されます。 これらのすべての注釈は、コンストラクタが持つパラメータと同じだけの文字列をリストに含める必要があります。各文字列はJのgetterに対応するプロパティの名前にします。このgetterの型は、対応するコンストラクタ・パラメータと同じにする必要があります。@ConstructorParameters
または@ConstructorProperties
注釈(これらは、オブジェクトを再構成するために必要とされない情報)に記載されていないゲッターが存在することは誤りではありません。Jのインスタンスは、
CompositeData
から再構築された適切な項目を使ってコンストラクタを呼び出すことで再構築されます。 呼び出されるコンストラクタは、このCompositeData
がすべてのアイテムが存在しない以前のバージョンのJから来る可能性があるので、実際にCompositeData
に存在するアイテムに基づいて実行時に決定されます。@ConstructorParameters
または@ConstructorProperties
注釈に指定されたすべてのプロパティがCompositeData
のアイテムとして存在する場合、コンストラクタはapplicableです。 適用可能なコンストラクタが存在しない場合は、Jを再構築する試みは失敗します。プロパティを任意に組み合せる場合は、次のいずれかが当てはまります。(a)適用可能なコンストラクタが存在しない、(b)適用可能なコンストラクタが1つだけ存在する、(c)適用可能なコンストラクタの1つが、他の適用可能な各コンストラクタが指定したプロパティの適切なスーパー・セットを指定する。 (つまり、選択するコンストラクタに関してあいまいさは存在しないことになります。) この条件がtrueでない場合、Jは再構築可能ではありません。
それ以外で、Jが引数のないpublicコンストラクタを持ち、型がTで名前がNのJ内の各getterに対して同じ名前と型の対応するsetterが存在する場合は、Jのインスタンスが引数のないコンストラクタを使って構築され、setterが
CompositeData
から再構築された項目を使って呼び出されて値が復元されます。 たとえば、
public List<String> getNames()
メソッドが存在する場合、このルールが適用される
public void setNames(List<String> names)
メソッドも存在する必要があります。CompositeData
がJの以前のバージョンに基づく場合、一部の項目が存在しない可能性があります。 この場合、対応するsetterは呼び出されません。それ以外で、Jがgetter以外のメソッドを持たないインタフェースである場合、Jのインスタンスは、
Proxy
を使って構築されます。その際、変換対象のCompositeData
を利用するCompositeDataInvocationHandler
が使用されます。それ以外の場合、Jは再構築不可能です。
java.beans.ConstructorProperties
が(例えば、java.desktopモジュールが読み込み不可能な場合や、ランタイム・イメージにjava.desktopモジュールが含まれていない場合)でない場合、ルール2は適用されません。 java.beans
パッケージが含まれないランタイムを対象とするときに、コンパイル時と実行時の環境に不一致があることにより、JがpublicコンストラクタおよびConstructorProperties
注釈を使用してコンパイルされる場合、別のルールが適用されないかぎり、Jは再構築不可能になります。
次の例では、int
および String
で構成される NamedNumber
型をコーディングするいくつかの方法を示します。 いずれの場合でも、CompositeType
は次のようになります。
CompositeType
( "NamedNumber", // typeName "NamedNumber", // description new String[] {"number", "name"}, // itemNames new String[] {"number", "name"}, // itemDescriptions new OpenType[] {SimpleType.INTEGER, SimpleType.STRING} // itemTypes );
- static
from
メソッド:public class NamedNumber { public int getNumber() {return number;} public String getName() {return name;} private NamedNumber(int number, String name) { this.number = number; this.name = name; } public static NamedNumber from(CompositeData cd) { return new NamedNumber((Integer) cd.get("number"), (String) cd.get("name")); } private final int number; private final String name; }
- レコード:
public record NamedNumber(int number, String name) {}
@ConstructorParameters
注釈付きのパブリック・コンストラクタ:public class NamedNumber { public int getNumber() {return number;} public String getName() {return name;} @ConstructorParameters({"number", "name"}) public NamedNumber(int number, String name) { this.number = number; this.name = name; } private final int number; private final String name; }
- 各getter用のsetter:
public class NamedNumber { public int getNumber() {return number;} public void setNumber(int number) {this.number = number;} public String getName() {return name;} public void setName(String name) {this.name = name;} public NamedNumber() {} private int number; private String name; }
- getterのみを持つインタフェース:
public interface NamedNumber { public int getNumber(); public String getName(); }
データのコレクションを表現するだけのクラスは、通常、不変にしておくことをお薦めします。 不変クラスのインスタンスは、構築後に変更することはできません。 CompositeData
自体は不変であることに留意してください。 不変であることには多数の利点があります。特にスレッドの安全性やセキュリティ面で大きなメリットがあります。 このため、setterの使用は、可能な場合は避けるようにしてください。
再帰型
再帰(自己参照)型をMXBeanインタフェース内で使用することはできません。 これは、CompositeType
の不変性によるものです。 たとえば、次の型は自身を参照するため、属性の型になることはできません。
public interface Node { public String getName(); public int getPriority(); public Node getNext(); }
このような再帰型を書き換えて、再帰型でなくすることはいつでも可能です。 それには、新しい型を導入することが必要な場合があります。 たとえば、
public interface NodeList { public List<Node> getNodes(); } public interface Node { public String getName(); public int getPriority(); }
MXBeanに対応したMBeanInfoの内容
MXBeanは、Open MBeanの一種です。 ただし、互換性を保つために、MBeanInfo
はOpenMBeanInfo
ではありません。 特に、属性、パラメータ、オペレーションの戻り値の型がint
などのプリミティブ型またはvoid
(戻り値の型)である場合、属性、パラメータ、オペレーションはそれぞれMBeanAttributeInfo
、MBeanParameterInfo
、MBeanOperationInfo
で表されます。これらのgetType()
または getReturnType()
はプリミティブ名(「int
」など)を返します。 前述のマッピング・ルールで、opendataマッピングがラップされる型(Integer
など)と指定される場合でも、これは当てはまります。
MXBeanのMBeanInfo.getConstructors()
が返すpublicコンストラクタの配列(MBeanサーバーに直接登録される)には、そのMXBeanのpublicコンストラクタがすべて含まれます。 MXBeanのクラスがpublicではない場合、コンストラクタもpublicでないとみなされます。 StandardMBean
クラスを使って構築されるMXBeanに対して返されるリストは、Standard MBeanと同じ方法で取得されます。 MXBeanの構築方法に関係なく、コンストラクタ・パラメータはMXBeanマッピング・ルールの影響を受けず、対応するOpenType
を持ちません。
MBeanサーバー内に直接登録されるMXBeanがNotificationBroadcaster
インタフェースを実装しない場合、そのMXBeanのMBeanInfo.getNotifications()
が返す通知型の配列は空になります。 それ以外の場合、これは、MXBeanの登録時にNotificationBroadcaster.getNotificationInfo()
を呼び出した結果になります。 その後、このメソッドの結果が変わっても、MBeanInfo.getNotifications()
の結果は変わりません。 StandardMBean
またはStandardEmitterMBean
クラスを使って構築されるMXBeanに対して返されるリストは、Standard MBeanと同じ方法で取得されます。
MBeanInfo
に含まれるすべてのMBeanAttributeInfo
、MBeanParameterInfo
、およびMBeanOperationInfo
オブジェクトのDescriptor
は、上記のマッピング・ルールで指定されたOpenType
を値とするフィールドopenType
を持ちます。 このため、getType()
が「int
」であっても、getDescriptor().getField("openType")
はSimpleType.INTEGER
になります。
これらの各オブジェクトのDescriptor
も、MXBeanインタフェース内に表示されるJava型を表す文字列であるoriginalType
フィールドを持ちます。 この文字列の書式については、下記の「型名」セクションを参照してください。
MBeanInfo
のDescriptor
は、文字列「true
」を値とするmxbean
フィールドを持ちます。
型名
MXBean内のメソッド・パラメータや戻り値のマップされていない型Tを文字列として表現することが必要な場合があります。 Tがジェネリック型でない場合、この文字列はClass.getName()
により返される値になります。 それ以外の場合、これはgenericstring(T)の値になります。次にこの定義を示します。
- Tがジェネリック型でも配列型でもない場合、genericstring(T)は
Class.getName()
により返される値になります("int"
、"java.lang.String"
など)。 - Tが配列E[]である場合、genericstring(T)はgenericstring(E)のあとに
"[]"
を付加したものになります。 たとえば、genericstring(int[]
)は"int[]"
、genericstring(List<String>[][]
)は"java.util.List<java.lang.String>[][]"
になります。 - それ以外の場合、Tは、
List<String>
などのパラメータ化された型になります。genericstring(T)はClass.getName()
により返されるパラメータ化された型の完全指定名、左山括弧("<"
)、genericstring(A) (Aは最初の型パラメータ)、2番目の型パラメータBが存在する場合は", "
(カンマと空白文字1つ)とgenericstring(B)、および右山括弧(">"
)で構成されます。
メソッドがint[]
を返す場合は、これは、 Class.getName()
により返される文字列"[I"
で表されます。ただし、メソッドがList<int[]>
を返す場合、これは文字列 "java.util.List<int[]>"
で表されます。
例外
Java型から公開型へのマッピングで問題が発生すると、OpenDataException
により通知されます。 これは、getterを持たないjava.util.Random
などの型を参照する場合など、MXBeanインタフェースの分析中に発生することがあります。 また、インスタンスの変換中(MXBean内のメソッドからの戻り値またはMXBeanプロキシ内のメソッドへのパラメータ)に発生することもあります。たとえば、SortedSet
がnull以外の Comparator
を持つ場合に、SortedSet<String>
から String[]
に変換するときに発生します。
公開型から Java型へのマッピングで問題が発生すると、InvalidObjectException
により通知されます。 これは、再構築可能な型が必須のコンテキストで、上記のルールに従うと再構築可能ではない型を参照する場合など、MXBeanインタフェースの分析中に発生することがあります。 また、該当する名前のEnum定数が存在しない状況でStringからEnumへの変換を行う場合のように、インスタンスの変換中(MXBean内のメソッドへのパラメータまたはMXBeanプロキシ内のメソッドからの戻り値)に発生することもあります。
コンテキストに応じて、OpenDataException
またはInvalidObjectException
を、RuntimeMBeanException
やUndeclaredThrowableException
などの別の例外内にラップできます。 スローされる各例外で、条件Cがtrueになります。「eは OpenDataException
またはInvalidObjectException
(必要に応じて)。あるいはe.getCause()
のCはtrue」。
- 導入されたバージョン:
- 1.6
-
オプション要素のサマリー
オプションの要素
-
要素の詳細
-
value
boolean value注釈付きインタフェースがMXBeanインタフェースである場合、trueになります。- 戻り値:
- 注釈付きインタフェースがMXBeanインタフェースである場合はtrue
- デフォルト:
- true
-