@Documented @Retention(value=RUNTIME) @Target(value=TYPE) public @interface MXBean
インタフェースに対して、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の概念を使用すると、javax.management.openmbean
により定義された、定義済みの型セットだけを参照するMBeanを簡単にコーディングできます。この方法なら、リモート・クライアントを含むクライアントは、MBeanの型を示すモデル固有のクラスにアクセスしなくても、MBeanを利用できます。
この概念は、Standard MBeanの概念と比べて、理解しやすいものです。ここでは、管理対象オブジェクトをStandard MBeanおよびMXBeanとして表現する方法について説明します。
Standard MBean | MXBean |
---|---|
public interface MemoryPoolMBean { String getName(); MemoryUsage getUsage(); // ... } |
public interface MemoryPoolMXBean { String getName(); MemoryUsage getUsage(); // ... } |
上記の記述から、定義は非常に類似していることがわかります。唯一の相違点は、インタフェースの命名規則として、Standard MBeanではSomethingMBean
を使用するのに対して、MXBeanではSomethingMXBean
を使用するという点です。
この管理対象オブジェクトでは、MemoryUsage
型のUsage
という名前の属性があります。この種の属性の特徴は、データ項目セットの一貫したスナップショットを提供する点です。たとえば、メモリー・プール内の現在の使用済みメモリー容量や、現在のメモリー・プールの最大値を含めることができます。これらが別の項目になっていると、getAttribute
を個別に呼び出して項目を取得するため、さまざまな時点の一貫性のない値を取得する可能性があります。max
値よりも大きいused
値を取得する可能性もあります。
このため、次のようにMemoryUsage
を定義できます。
Standard MBean | MXBean |
---|---|
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() {...} } |
public class MemoryUsage { // standard JavaBean conventions with getters @ConstructorProperties({"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にリンクするための、@ConstructorProperties
注釈が追加されています。この点については、あとで詳しく説明します。
MemoryUsage
は、モデル固有クラスです。Standard MBeanでは、MemoryUsage
クラスが不明な場合、MBeanサーバーのクライアントはUsage
属性にアクセスできません。クライアントが、JMX技術に基づくジェネリック・コンソールである場合を考えてみましょう。この場合、コンソールは、接続先の各アプリケーションのモデル固有クラスを使って設定する必要があります。Java言語で記述されていないクライアントの場合、問題は一層難しくなります。この場合、MemoryUsage
の内容についてクライアントに知らせる方法がない可能性があります。
このような場合に、MXBeanはStandard MBeanと異なります。管理インタフェースの定義方法はほとんど同じですが、MXBeanフレームワークでは、モデル固有クラスがJavaプラットフォームの標準クラスに変換されます。配列および標準javax.management.openmbean
パッケージのCompositeData
クラスとTabularData
クラスを使用することで、標準クラスだけを使用して任意の複雑さのデータ構造を構築できます。
この点は、2つのモデルのクライアントを比較することでより明確になります。
Standard MBean | MXBean |
---|---|
String name = (String)
mbeanServer. |
String name = (String) mbeanServer. |
String
などの単純な型の属性の場合、コードは同じです。ただし、複雑な型の属性の場合、Standard MBeanのコードではクライアントがモデル固有クラスMemoryUsage
を認識する必要があるのに対し、MXBeanのコードでは非標準クラスは必要ありません。
ここに示すクライアント・コードでは、MXBeanクライアントの方がいくらか複雑になっています。ただし、クライアントがモデル(ここでは、MemoryPoolMXBean
インタフェースとMemoryUsage
クラス)を実際に認識している場合は、プロキシの構築が可能です。モデルが事前にわかる場合には、Standard MBeanを使用するかMXBeanを使用するかに関係なく、この方法で管理対象オブジェクトとのやり取りを行うことをお勧めします。
Standard MBean | MXBean |
---|---|
MemoryPoolMBean proxy =
JMX. |
MemoryPoolMXBean proxy =
JMX. |
MemoryPoolオブジェクトの実装の動作は、Standard MBeanでもMXBeanでも同様です。
Standard MBean | MXBean |
---|---|
public class MemoryPool implements MemoryPoolMBean { public String getName() {...} public MemoryUsage getUsage() {...} // ... } |
public class MemoryPool implements MemoryPoolMXBean { public String getName() {...} public MemoryUsage getUsage() {...} // ... } |
MBean ServerへのMBeanの登録の動作は、どちらの場合も同じです。
Standard MBean | MXBean |
---|---|
{
MemoryPoolMBean pool = new MemoryPool();
mbeanServer. |
{
MemoryPoolMXBean pool = new MemoryPool();
mbeanServer. |
MXBeanは、MBeanの一種です。MXBeanオブジェクトは、MBeanサーバーに直接登録することも、StandardMBean
の引数として使用し、結果のMBeanをMBeanサーバーに登録することもできます。
MBeanServer
インタフェースのregisterMBean
やcreateMBean
メソッドを使ってオブジェクトをMBeanサーバーに登録すると、MBeanの型を判別するためにオブジェクトのクラスが検査されます。
DynamicMBean
インタフェースを実装する場合、MBeanはDynamic MBeanです。StandardMBean
クラスはこのインタフェースを実装します。このため、これはStandardMBean
クラスを使って作成されたStandard MBeanまたはMXBeanに適用されます。SMXBean
のインタフェース(S
は空ではない文字列であり、注釈@MXBean(false)
を含まない); および/または@MXBean(true)
または単に@MXBean
という注釈を含むインタフェース。MemoryPoolMXBean
です。
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
は関係ありません。)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
のサブクラスのインスタンスです。たとえば、Java型List<String>
について考えてみましょう。
List<String>
)はArrayType
(1,
SimpleType.STRING
)
であり、1次元のString
配列を表します。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 (下記を参照) |
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<
E>
やSet<
E>
(List<String>
やSet<ObjectName>
など)のマッピング方法は、同じ要素型の配列(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
を実装する別のクラスです。
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
の型名は、次の型名ルールに従って決定されます。
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の規則とは異なります。Standard MBeanまたはMXBeanインタフェースではgetOwner
メソッドはOwner
という名前の属性を定義し、Java BeanまたはマップされたCompositeType
ではgetOwner
メソッドはowner
という名前のプロパティまたは項目を定義します。
2つのメソッドが同じ項目名を生成する場合(getOwner
とisOwner
、getOwner
とgetowner
など)、型の変換は不可能です。
公開型がCompositeType
の場合、対応するマップされたJava型(opendata(J))はCompositeData
になります。Jのインスタンスから、上記のCompositeType
に対応するCompositeData
へのマッピングは、次のように実行されます。最初に、JがCompositeDataView
インタフェースを実装する場合、そのインタフェースのtoCompositeData
メソッドが呼び出されて、変換が実行されます。それ以外の場合は、項目ごとにgetterを呼び出して対応する公開データ型に変換することにより、CompositeData
が構築されます。これにより、次のようなgetterが、
List<String> getNames()
名前「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
J from(CompositeData cd)
メソッドを持つ場合、そのメソッドを呼び出すことでJのインスタンスが再構築されます。
それ以外で、JがConstructorProperties
注釈を含む1つ以上のpublicコンストラクタを持つ場合は、これらのコンストラクタの1つ(常に同じコンストラクタである必要はない)を呼び出して、Jのインスタンスが再構築されます。これらのすべての注釈は、コンストラクタが持つパラメータと同じだけの文字列をリストに含める必要があります。各文字列はJのgetterに対応するプロパティの名前にします。このgetterの型は、対応するコンストラクタ・パラメータと同じにする必要があります。ConstructorProperties
注釈に記述されていないgetterが存在するとしても、それはエラーではありません。これらは、オブジェクトの再構築には不要な情報に関連したメソッドである可能性があります。
Jのインスタンスは、CompositeData
から再構築された適切な項目を使ってコンストラクタを呼び出すことで再構築されます。このCompositeData
は、一部の項目が存在していなかった以前のバージョンのJに由来するものである可能性があります。このため、呼び出されるコンストラクタは、CompositeData
内に実在する項目に基づいて実行時に決定されます。コンストラクタが適用可能になるのは、ConstructorProperties
注釈に記載されたすべてのプロパティがCompositeData
内に項目として存在する場合です。適用可能なコンストラクタが存在しない場合は、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は再構築不可能です。
ルール2は、java.beans
パッケージが含まれないJava SEのサブセット・プロファイルには適用できません。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 );
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; }
@ConstructorProperties
注釈を含むpublicコンストラクタ:
public class NamedNumber { public int getNumber() {return number;} public String getName() {return name;} @ConstructorProperties({"number", "name"}) public NamedNumber(int number, String name) { this.number = number; this.name = name; } private final int number; private final String name; }
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; }
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は、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)の値になります。次にこの定義を示します。
Class.getName()
により返される値になります("int"
、"java.lang.String"
など)。
"[]"
を付加したものになります。たとえば、genericstring(int[]
)は"int[]"
、genericstring(List<String>[][]
)は"java.util.List<java.lang.String>[][]"
になります。
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」。
修飾子と型 | オプションの要素と説明 |
---|---|
boolean |
value
注釈付きインタフェースがMXBeanインタフェースである場合、trueになります。
|
バグまたは機能を送信
詳細なAPIリファレンスおよび開発者ドキュメントについては、Java SEのドキュメントを参照してください。そのドキュメントには、概念的な概要、用語の定義、回避方法、有効なコード例などの、開発者を対象にしたより詳細な説明が含まれています。
Copyright© 1993, 2014, Oracle and/or its affiliates. All rights reserved.