@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, 2025, Oracle and/or its affiliates. All rights reserved. Use is subject to license terms. Documentation Redistribution Policyも参照してください。