This repository has been archived by the owner on Sep 6, 2018. It is now read-only.
-
Notifications
You must be signed in to change notification settings - Fork 4
/
Copy pathFunctionalSpec.html
1789 lines (1770 loc) · 79.1 KB
/
FunctionalSpec.html
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
360
361
362
363
364
365
366
367
368
369
370
371
372
373
374
375
376
377
378
379
380
381
382
383
384
385
386
387
388
389
390
391
392
393
394
395
396
397
398
399
400
401
402
403
404
405
406
407
408
409
410
411
412
413
414
415
416
417
418
419
420
421
422
423
424
425
426
427
428
429
430
431
432
433
434
435
436
437
438
439
440
441
442
443
444
445
446
447
448
449
450
451
452
453
454
455
456
457
458
459
460
461
462
463
464
465
466
467
468
469
470
471
472
473
474
475
476
477
478
479
480
481
482
483
484
485
486
487
488
489
490
491
492
493
494
495
496
497
498
499
500
501
502
503
504
505
506
507
508
509
510
511
512
513
514
515
516
517
518
519
520
521
522
523
524
525
526
527
528
529
530
531
532
533
534
535
536
537
538
539
540
541
542
543
544
545
546
547
548
549
550
551
552
553
554
555
556
557
558
559
560
561
562
563
564
565
566
567
568
569
570
571
572
573
574
575
576
577
578
579
580
581
582
583
584
585
586
587
588
589
590
591
592
593
594
595
596
597
598
599
600
601
602
603
604
605
606
607
608
609
610
611
612
613
614
615
616
617
618
619
620
621
622
623
624
625
626
627
628
629
630
631
632
633
634
635
636
637
638
639
640
641
642
643
644
645
646
647
648
649
650
651
652
653
654
655
656
657
658
659
660
661
662
663
664
665
666
667
668
669
670
671
672
673
674
675
676
677
678
679
680
681
682
683
684
685
686
687
688
689
690
691
692
693
694
695
696
697
698
699
700
701
702
703
704
705
706
707
708
709
710
711
712
713
714
715
716
717
718
719
720
721
722
723
724
725
726
727
728
729
730
731
732
733
734
735
736
737
738
739
740
741
742
743
744
745
746
747
748
749
750
751
752
753
754
755
756
757
758
759
760
761
762
763
764
765
766
767
768
769
770
771
772
773
774
775
776
777
778
779
780
781
782
783
784
785
786
787
788
789
790
791
792
793
794
795
796
797
798
799
800
801
802
803
804
805
806
807
808
809
810
811
812
813
814
815
816
817
818
819
820
821
822
823
824
825
826
827
828
829
830
831
832
833
834
835
836
837
838
839
840
841
842
843
844
845
846
847
848
849
850
851
852
853
854
855
856
857
858
859
860
861
862
863
864
865
866
867
868
869
870
871
872
873
874
875
876
877
878
879
880
881
882
883
884
885
886
887
888
889
890
891
892
893
894
895
896
897
898
899
900
901
902
903
904
905
906
907
908
909
910
911
912
913
914
915
916
917
918
919
920
921
922
923
924
925
926
927
928
929
930
931
932
933
934
935
936
937
938
939
940
941
942
943
944
945
946
947
948
949
950
951
952
953
954
955
956
957
958
959
960
961
962
963
964
965
966
967
968
969
970
971
972
973
974
975
976
977
978
979
980
981
982
983
984
985
986
987
988
989
990
991
992
993
994
995
996
997
998
999
1000
<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN">
<html>
<head>
<!--
DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS HEADER.
Copyright (c) 2008-2018 Oracle and/or its affiliates. All rights reserved.
The contents of this file are subject to the terms of either the GNU
General Public License Version 2 only ("GPL") or the Common Development
and Distribution License("CDDL") (collectively, the "License"). You
may not use this file except in compliance with the License. You can
obtain a copy of the License at
https://oss.oracle.com/licenses/CDDL+GPL-1.1
or LICENSE.txt. See the License for the specific
language governing permissions and limitations under the License.
When distributing the software, include this License Header Notice in each
file and include the License file at LICENSE.txt.
GPL Classpath Exception:
Oracle designates this particular file as subject to the "Classpath"
exception as provided by Oracle in the GPL Version 2 section of the License
file that accompanied this code.
Modifications:
If applicable, add the following below the License Header, with the fields
enclosed by brackets [] replaced by your own identifying information:
"Portions Copyright [year] [name of copyright owner]"
Contributor(s):
If you wish your version of this file to be governed by only the CDDL or
only the GPL Version 2, indicate your decision by adding "[Contributor]
elects to include this software in this distribution under the [CDDL or GPL
Version 2] license." If you don't indicate a single choice of license, a
recipient has the option to distribute your version of this file under
either the CDDL, the GPL Version 2 or to extend the choice of license to
its licensees as provided above. However, if you add GPL Version 2 code
and therefore, elected the GPL Version 2 license, then the option applies
only if the new code is made subject to such option by the copyright
holder.
-->
<!--
Document : FunctionalSpec
Created on : Nov 17, 2008, 4:25:47 PM
Author : ken
-->
<title>GMBAL Functional Spec</title>
<meta http-equiv="content-type" content="text/html; charset=UTF-8">
<style type="text/css" title="Amaya theme">
/* Modern style for Amaya Editor Lite */
/* default rules for the whole document */
body {
font-size: 12pt;
font-family: Helvetica, Arial, sans-serif;
font-weight: normal;
font-style: normal;
color: black;
background-color: white;
line-height: 1.2em;
margin-left: 4em;
margin-right: 2em;
}
/* paragraphs */
pre {
color: Green;
}
p {
padding: 0;
margin-top: 1em;
margin-bottom: 1em;
text-align: left;
}
/* headings */
h1 {
font-size: 180%;
font-weight: bold;
font-style: normal;
font-variant: small-caps;
text-align: left;
padding: 0;
margin-top: 1.7em;
margin-bottom: 1.7em;
}
h2 {
font-size: 150%;
font-weight: bold;
font-style: normal;
padding: 0;
margin-top: 1.5em;
margin-bottom: 1.1em;
}
h3 {
font-size: 130%;
font-weight: bold;
font-style: normal;
padding: 0;
margin-top: 1.3em;
margin-bottom: 1.1em;
}
h4 {
font-size: 110%;
font-weight: bold;
font-style: normal;
padding: 0;
margin-top: 1.1em;
margin-bottom: 1.1em;
}
h5 {
font-size: 100%;
font-weight: bold;
font-style: italic;
padding: 0;
margin-top: 1em;
margin-bottom: 1em;
}
h6 {
font-size: 100%;
font-weight: normal;
font-style: italic;
padding: 0;
margin-top: 1em;
margin-bottom: 1em;
}
/* divisions */
div {
padding: 0;
margin-top: 0em;
margin-bottom: 0em;
}
/* lists */
ul, ol {
padding: 0 0 0 3em;
margin-top: 1em;
margin-bottom: 1em;
}
ul ul, ol ol, ul ol, ol ul {
margin-top: 1em;
margin-bottom: 1em;
}
li {
padding: 0;
margin-top: 1em;
margin-bottom: 1em;
text-align: left;
}
li p {
margin-top: 1em;
margin-bottom: 1em;
}
dl {
padding: 0;
margin-top: 1em;
margin-bottom: 1em;
margin-left: 1em;
}
dl dl {
margin-top: 0em;
margin-bottom: 0em;
}
dt {
padding: 0;
font-weight: bold;
margin-top: .3em;
margin-bottom: .3em;
}
dd {
padding: 0;
margin-top: .3em;
margin-left: 3em;
margin-bottom: .3em;
}
dl p {
margin-top: .3em;
margin-bottom: .3em;
}
/* inline */
strong {
font-weight: bold;
}
em {
font-style: italic;
}
code {
font-family: Courier New, Courier, monospace;
}
ins {
background-color: yellow;
text-decoration: underline;
}
del {
text-decoration: line-through;
}
/* anchors */
a[href] {
color: blue;
text-decoration: underline;
}
/* end */
</style>
</head>
<body>
<h1>GlassFish MBean Annotation Library (gmbal)</h1>
<h1>Functional Specification</h1>
by Ken Cavanaugh<br>
Version 1.0 (for GlassFish v3 FCS)<span
style="background-color: rgb(250, 255, 221);"></span><br>
12/11/09<span style="background-color: rgb(255, 249, 200);"></span><br>
<h2>1. Introduction</h2>
<p>The GlassFish MBean Annotation Library (gmbal, pronounced as in
"gumball")
is a runtime annotation processor that creates Open MBeans. This is
useful for
creating a management API for existing code with minimal effort.
It is
intended to be applied to existing modules (which may be OSGi bundles
in
GlassFish v3, or any other packaging model including standard jar
files), but
could be used anywhere that it is desired to combine the definition of
the
management API with the module API and implementation.</p>
<p>Note that gmbal is not limited to use in GlassFish. Gmbal is
completely independent of GlassFish, and may be used in a context where
GlassFIsh is not present. However, when a gmbal-enabled module in used
in
GlassFish V3, that module will automatically be manageable using
GlassFish V3
admin tools.</p>
<p>There are really two parts to creating a management API for a
module:
instrumenting the module implementation, and providing a client
interface that
may be accessed remotely. This is closely related to the AMX work in
GFv3. AMX defines the interface for AMX MBeans, and provides
tools and libraries for clients accessing AMX MBeans. Gmbal is a
library that provides a mechanism for implementing AMXv3-compliant
MBeans.<br>
</p>
<h3>1.1. Alignment with related projects</h3>
JMX is also defining similar annotations in JSR 255 for JDK 7.
The JSR 255 spec is available at the download <a
href="http://jcp.org/aboutJava/communityprocess/edr/jsr255/index.html">page</a>.
Gmbal is mostly aligned with the JSR 255
annotations.
<br>
<br>
The similarities include:<br>
<ul>
<li><a href="gmbal/javadoc/org/glassfish/gmbal/ManagedAttribute.html">@ManagedAttribute</a>
is the same, except that gmbal allows overriding the id.</li>
<li><a href="gmbal/javadoc/org/glassfish/gmbal/ManagedOperation.html">@ManagedOperation</a>
is the same, except that gmbal allows overriding the id.</li>
<li><a href="gmbal/javadoc/org/glassfish/gmbal/DescriptorKey.html">@DescriptorKey</a>
is the same.</li>
<li><a href="gmbal/javadoc/org/glassfish/gmbal/DescriptorFields.html">@DescriptorFields</a>
is the same.</li>
<li><a href="gmbal/javadoc/org/glassfish/gmbal/Description.html">@Description</a>
is similar to JSR 255, but does not support a bundleBaseName attribute.
The bundle is set in gmbal through the
ManagedObjectManager.setResourceBundle call.<br>
</li>
</ul>
Differences:<br>
<ul>
<li>The packaging is necessarily different: org.glassfish.gmbal for
gmbal, javax.management for JSR 255.</li>
<li>Gmbal uses <a
href="gmbal/javadoc/org/glassfish/gmbal/ManagedObject.html">@ManagedObject</a>
instead of @MBean (part of JSR 255) or <a
href="http://java.sun.com/javase/6/docs/api/javax/management/MXBean.html">@MXBean</a>.</li>
<li>Gmbal only supports attribute change notifications, so
the @NotificationInfo annotation (from JSR 255) does not exist in
Gmbal. See "<a href="#3.2.3._register_and_registerAtRoot">register
and registerAtRoot</a>" for a discussion on notification support.<br>
</li>
<li>Gmbal has an <a
href="gmbal/javadoc/org/glassfish/gmbal/ManagedData.html">@ManagedData</a>
annotation to define the mapping of data types into CompositeData,
while JSR 255 follows MXBeans and simply assumes that all methods that
follow the JavaBeans patterns define read-only attributes.</li>
<li>Gmbal supports an <a
href="gmbal/javadoc/org/glassfish/gmbal/MBeanType.html">@AMXMetadata</a>
annotation, but this is really just an extension to the descriptor
annotation mechanism borrowed from JMX ModelMBeans. The
@AMXMetadata annotation is provided to support AMX-specific metadata.</li>
<li>Gmbal includes <a
href="gmbal/javadoc/org/glassfish/gmbal/ParameterNames.html">@ParameterNames</a>
to provide reasonable names for the arguments on MBean
operations. JSR 255 does not currently have such a mechanism,
because JDK 7 will have an extension to Java reflection that captures
the argument names on methods.</li>
<li>Gmbal includes <a
href="gmbal/javadoc/org/glassfish/gmbal/ObjectNameKey.html">@NameValue</a>
to make it easy to define the value of the "name" field in the
ObjectName. This makes registration of object as MBeans slightly
simpler.</li>
<li>Gmbal includes <a
href="gmbal/javadoc/org/glassfish/gmbal/IncludeSubclass.html">@IncludeSubclass</a>,
which allows limited (and closed) polymorphism for CompositeData.
This partially solves the problem of mapping a group of types sharing
type Base that appear as (for example) attributes with type
List<Base>.</li>
<li>Gmbal includes <a
href="gmbal/javadoc/org/glassfish/gmbal/InheritedAttribute.html">@InheritedAttribute</a>(<a
href="gmbal/javadoc/org/glassfish/gmbal/InheritedAttributes.html">s</a>)
to allow using methods inherited from super classes or super interfaces
that cannot be annotated as attribute and operations.</li>
<li>Gmbal is more limited currently in mapping OpenType -> Java
type than JMX is, as this does not seem to be a feature that we need.<br>
</li>
</ul>
Note that there are two complimentary ways to define MBeans: MXBeans
and
annotations. MXBeans are somewhat more convenient to use in cases
where EVERY
method in a class or interface is part of the management interface,
whereas
annotations are more convenient for adding a management interface to
existing
code. But both mechanisms share most of the same rules for MXBean
mapping from
Java types to Open types as discussed in "<a
href="#4.3._OpenType_mapping_">OpenType Mapping</a>".<br>
<br>
AMX in GlassFish v3 is being generalized to define exactly what an
MBean must
do to be manageable in the GlassFish v3 admin tools (see Lloyd's <a
href="https://glassfish.dev.java.net/nonav/v3/admin/planning/V3Changes/V3_AMX_SPI.html">GlassFish
V3 AMX SPI</a> specification). Gmbal will follow all mandatory and most
of the
optional requirements of this specification so that any module that
uses gmbal
to define MBeans will automatically participate in the GFv3 admin tools
when run in a GFv3 container. However, this will not prevent
the use of
gmbal in these same modules as a standalone MBean definition library.<br>
<br>
This last point needs a little more explanation. The main
interface that
matters for running in or out of a GFv3 container is
ManagedObjectManagerFactory.create<span style="font-style: italic;">XXX</span>
(<span style="font-style: italic;">XXX</span> is either Standalone or
Federated).
The createStandalone method is needed for running outside of GFv3, and
takes
the domain name as an argument. createFedederated must be called inside
of
GFv3, and this requires the AMXv3-compliant ObjectName of the
ManagedObjectManager root
MBean's
parent. Calling the appropriate method is probably best handled
in most cases
by having an OSGi bundle for a module that is responsible for
integrating the
module into GFv3. <br>
<br>
For example, the orb-iiop bundle integrates the standalone ORB bundles
into GFv3. orb-iiop handles
registration of all of the GFv3-specific interceptors and other
initialization
when the GFv3 ORB instance is created. orb-iiop will also need to set
the ORB property com.sun.corba.ee.ORBGmbalRootParentName to the string
representation of the ObjectName of the ORB's gmbal root parent.
The ORB will then use this property to call either createStandalone (if
it is not set) or createFederated (with the value of the property as
the ObjectName passed into the call).<br>
<h3>1.2. Similar projects</h3>
Besides JSR 255 (discussed in the previous section), there are at least
two other
projects that also define MBeans using annotations.<br>
<br>
The Spring project also defines a set of <a
href="http://static.springframework.org/spring/docs/2.0.x/reference/jmx.html#jmx-interface-annotations">annotations</a>
to use for creating
MBeans. Eamonn McManus has pointed to this as one of the starting
points for JSR 255 in a blog <a
href="http://weblogs.java.net/blog/emcmanus/archive/2007/08/defining_mbeans.html">post</a>
from August 2007. JSR 255 and Spring share the @ManagedAttribute
and @ManagedOperation annotations, but the Spring annotations
include a description fields, whereas JSR 255 has moved the description
into a separate annotation (as I have
in gmbal as well).<br>
<br>
The WebObject project from INRIA in France has created the <a
href="http://spoon.gforge.inria.fr/SpoonJMX/Main">SpoonJMX</a>
project, which
also allows the use of annotations to define MBeans. SpoonJMX uses
@ManagedResource to define an MBean class. It
uses @ManagedAttribute and @ManagedOperation as in the other
systems. SpoonJMX defines a @ObjectKeyName annotation,
which I have adopted for use in gmbal as well under the name of
@NameValue. SpoonJMX also
defines more attributes on the annotations than
either gmbal or JSR 255.<br>
<h2>2. The Management Data Model</h2>
Gmbal supports a simple hierarchical model of management data as
defined in JSR
77 and AMX.<br>
<img style="width: 730px; height: 507px;" alt="Gmbal Class Diagram"
src="Gmbal.png"><br>
The components of the data model are as follows:<br>
<ul>
<li>A ManagedObjectManager acts as a container for all state related
to a particular usage of gmbal. This includes:
<ul>
<li>A domain to use for all ObjectNames created in this
ManagedObjectManager.</li>
<li>A rootParentName, which is the ObjectName of the parent of
the ManagedObjectManager.</li>
<li>A root object, which represents the top of the tree of MBean
managed by the ManagedObjectManager.<br>
</li>
</ul>
</li>
<li>From a POJO with annotations, an MBeanImpl is constructed, which
implements the dynamic MBean API. This dynamic MBean is
associated with additional classes:
<ul>
<li>0 or more Attributes, which may be getters or setters or both
(note that AMX will give as at least Name, Parent, and Children
attributes).<br>
</li>
<li>0 or more Operations, which may be invoked.</li>
<li>Metadata, represented by ModelMBeanInfoSupport (so that
metadata Descriptors are available on JDK 5 as well as JDK 6). The
Metadata is extensible through the use of the @DescriptorKey and
@DescriptorField meta-annotations.<br>
</li>
<li>A single parent MBeanImpl, which may be null (this is one end
of the contains relation).</li>
<li>0 or more child MBeanImpls (this is the other end of the
contains relation).</li>
<li>Following AMXv3, the ObjectName of the MBean will contain 3
name/value pairs:</li>
<ul>
<li>pp, which is the AMXv3 parent path, or the path name of the
parent of this MBean</li>
<li>type, which is derived from the Class using annotations or
other mechanisms</li>
<li>name, which is derived either from the registration call,
or a method on the object. The name is absent in the case of a
singleton. In any case, the type and name (if present) must be
unique within the scope of the parent.<br>
</li>
</ul>
</ul>
</li>
<li>Attributes and Operations have ids, which are generally derived
from the name of the annotated method as discussed <a
href="#4.1._Processing_of_method_names_for_IDs">here</a>, but the id
may also be specified in the @<a
href="gmbal/javadoc/org/glassfish/gmbal/ManagedAttribute.html">ManagedAttribute</a>
and @<a href="gmbal/javadoc/org/glassfish/gmbal/ManagedOperation.html">ManagedOperation</a>
annotations, as well as in the @<a
href="gmbal/javadoc/org/glassfish/gmbal/InheritedAttribute.html">InheritedAttribute</a>
annotation.<br>
</li>
</ul>
Note that all values consumed or produced by Attributes and Operations
are
instances of OpenTypes.<br>
<br>
This diagram is a simplification of the actual implementation of
gmbal. In
particular, the metadata, attributes, and operations are
maintained in a
MBeanSkeleton
class, which is shared by all MBeanImpls for instances of the same
class. The TypeConverter
that handles conversion between Java types and the corresponding
OpenType is also
not
included here.<br>
<h2>3. Interfaces</h2>
Javadocs are <a href="gmbal/javadoc/index.html">available</a> as part
of the
gmbal project. <br>
<br>
There are basically 3 elements to the gmbal API:<br>
<ol>
<li>class ManagedObjectManagerFactory, which provides factory methods
for creating instance of the ManagedObjectManager interface.</li>
<li>interface ManagedObjectManager, which provides
register/deregister methods (and a number of other capabilities).</li>
<li>A number of annotations.<br>
</li>
</ol>
Here is a summary of the annotations:<br>
<table style="text-align: left; width: 100%;" border="1" cellpadding="2"
cellspacing="2">
<tbody>
<tr>
<td style="vertical-align: top; font-weight: bold;">Annotation
Class<br>
</td>
<td style="vertical-align: top; font-weight: bold; width: 20%;">Annotation
Fields<br>
</td>
<td style="vertical-align: top; font-weight: bold;">Applicable
Element Type<br>
</td>
<td style="vertical-align: top;"><span style="font-weight: bold;">Relation
to JSR 255</span><br>
</td>
<td style="vertical-align: top; font-weight: bold;">Purpose<br>
</td>
</tr>
<tr>
<td style="vertical-align: top;">@ManagedObject<br>
</td>
<td style="vertical-align: top;">none<br>
</td>
<td style="vertical-align: top;">Class or Interface<br>
</td>
<td style="vertical-align: top;">255 uses @MXBean<br>
</td>
<td style="vertical-align: top;">Defines a class whose instances
are processed into MBeans.<br>
</td>
</tr>
<tr>
<td style="vertical-align: top;">@ManagedData<br>
</td>
<td style="vertical-align: top;">String name (defaults to class
name)<br>
</td>
<td style="vertical-align: top;">Class or Interface<br>
</td>
<td style="vertical-align: top;">MXBeans assume all methods are
in CompositeData<br>
</td>
<td style="vertical-align: top;">Defines a class whose instances
are process into Open data for Open Mbeans.<br>
</td>
</tr>
<tr>
<td style="vertical-align: top;">@ManagedAttribute<br>
</td>
<td style="vertical-align: top;">String id (defaults to value
from Method name)<br>
</td>
<td style="vertical-align: top;">Method or field<br>
</td>
<td style="vertical-align: top;">Same<br>
</td>
<td style="vertical-align: top;">Defines a method or field that
represents
an attribute either in ManagedData or ManagedObject<br>
</td>
</tr>
<tr>
<td style="vertical-align: top;">@ManagedOperation<br>
</td>
<td style="vertical-align: top;">String id (defaults to value
from Method name)<br>
Impact impact (defaults to UNKNOW; Impact enum corresponds to
MBeanOperationInfo impact values)<br>
</td>
<td style="vertical-align: top;">Method<br>
</td>
<td style="vertical-align: top;">Same<br>
</td>
<td style="vertical-align: top;">Defines a method that represents
an operation in ManagedObject <br>
</td>
</tr>
<tr>
<td style="vertical-align: top;">@Description<br>
</td>
<td style="vertical-align: top;">String value<br>
<br>
String key (the key to use in a generated resource bundle; default ""
means to derive key from name of annotated element)<br>
</td>
<td style="vertical-align: top;">Class, Interface, Method,
or Field<br>
</td>
<td style="vertical-align: top;">Same (but JSR 255 includes I18N)<br>
</td>
<td style="vertical-align: top;">Defines the descriptive text
associated with a Class, Interface, or Method. This may require I18N,
as discussed <a href="#4.2._I18N_support">here</a>.<br>
</td>
</tr>
<tr>
<td style="vertical-align: top;">@IncludeSubclass<br>
</td>
<td style="vertical-align: top;">Class[] value<br>
</td>
<td style="vertical-align: top;">Class or Interface for
ManagedData<br>
</td>
<td style="vertical-align: top;">N/A<br>
</td>
<td style="vertical-align: top;">Lists subclasses of the
annotated class that should also be scanned for annotations which are
included only on instances of the appropriate type<br>
</td>
</tr>
<tr>
<td style="vertical-align: top;">@NameValue<br>
</td>
<td style="vertical-align: top;">none<br>
</td>
<td style="vertical-align: top;">Method<br>
</td>
<td style="vertical-align: top;">N/A<br>
</td>
<td style="vertical-align: top;">Defines a method (must be a
getter) whose result is the value of the name attribute in the
ObjectName of the MBean for an instance of the class<br>
</td>
</tr>
<tr>
<td style="vertical-align: top;">@ParameterNames<br>
</td>
<td style="vertical-align: top;">String[] value (defaults to "")
(if present, must have same length as number of arguments in the
annotated method)<br>
</td>
<td style="vertical-align: top;">Method<br>
</td>
<td style="vertical-align: top;">N/A (JSR 255 will take this
information from reflection, which will make arg names available in JDK
7)<br>
</td>
<td style="vertical-align: top;">Defines the method names to be
used on an MBean operation. If this annotation is not present or has
the default value, the names will be arg<span
style="font-style: italic;">Num, </span>where <span
style="font-style: italic;">Num</span> is the position of the argument
starting from 0<br>
</td>
</tr>
<tr>
<td style="vertical-align: top;">@InheritedAttribute<br>
</td>
<td style="vertical-align: top;">
<ul>
<li>String description</li>
<li>String id (default "" which means take from method name)</li>
<li>String methodName (default "" which means use id)</li>
</ul>
one of methodName or id must NOT be ""<br>
<br>
</td>
<td style="vertical-align: top;">Class or Interface<br>
</td>
<td style="vertical-align: top;">N/A<br>
</td>
<td style="vertical-align: top;">Defines a method inherited from
a class that cannot be annotated as an attribute. See "<a
href="#3.2.8._addAnnotation">addAnnotation</a>" for a discussion of
the use of this annotation.<br>
</td>
</tr>
<tr>
<td style="vertical-align: top;">@InheritedAttributes<br>
</td>
<td style="vertical-align: top;">InheritedAttribute[] value<br>
</td>
<td style="vertical-align: top;">Class or Interface<br>
</td>
<td style="vertical-align: top;">N/A<br>
</td>
<td style="vertical-align: top;">Allows including multiple
inherited attributes<br>
</td>
</tr>
<tr>
<td style="vertical-align: top;">@AMXMetadata<br>
</td>
<td style="vertical-align: top;">
<ul>
<li>boolean isSingleton() (true if only one MBean of this
type is allowed as a child of another MBean)</li>
<li>String group() (value is the group for this mbean, defaults
to "other")</li>
<li>String[] subTypes() (value is the list of allowable types
for children of this bean)</li>
<li>String genericInterfaceName() (used in AMX proxy
construction)<br>
</li>
<li> boolean immutableInfo() (true if the MBeanInfo
can never change)</li>
<li>String interfaceClassName() (also used in AMX proxy
construction)<br>
</li>
<li>String type() (the type to use in an ObjectName or in an
admin CLI path expression: defaults to class name, but see
also <a href="#filterPrefix">stripPrefix</a>)</li>
</ul>
(This is just an application of @DescriptorKey, with a little
special support in the gmbal implementation)<br>
</td>
<td style="vertical-align: top;">Class or Interface<br>
</td>
<td style="vertical-align: top;">N/A (but JMX supports
descriptors; see below)<br>
</td>
<td style="vertical-align: top;">Adds GFv3 and AMX specific
metadata to be defined for MBeans (see "<a
href="#4.4._Metadata_support_">Metadata Support</a>" for more details).<br>
</td>
</tr>
<tr>
<td style="vertical-align: top;">@DescriptorKey<br>
</td>
<td style="vertical-align: top;">String value<br>
</td>
<td style="vertical-align: top;">Annotation method<br>
</td>
<td style="vertical-align: top;">same as JSR 255<br>
</td>
<td style="vertical-align: top;">Define metadata that can be
added to any MBean (see "<a href="#4.4._Metadata_support_">Metadata
Support</a>" for details)<br>
</td>
</tr>
<tr>
<td style="vertical-align: top;">@DescriptorField<br>
</td>
<td style="vertical-align: top;">String value (must be name=value)<br>
</td>
<td style="vertical-align: top;">Class, Interface, or Method<br>
</td>
<td style="vertical-align: top;">same as JSR 255<br>
</td>
<td style="vertical-align: top;">Define metadata directly on
MBean (See "<a href="#4.4._Metadata_support_">Metadata Support</a>" for
details)<br>
</td>
</tr>
</tbody>
</table>
<br>
Note that @ManagedAttribute and @Description may be used on fields.
There is however a limitation: any such field MUST be final, and have a
known immutable type. This is necessary to guarantee that access
to the field is safe in the presence of multiple thread. The
legal types are basically the SimpleTypes from JMX OpenType, with a
couple of additions:<br>
<ul>
<li>The primitives (boolean, byte, char, short, int, long, float,
double) and the corresponding java.lang wrapper classes (Boolean, Byte,
Character, Short, Integer, Long, Float, Double).</li>
<li>String</li>
<li>BigDecimal, BigInteger</li>
<li>Date</li>
<li>ObjectName</li>
<li>Class</li>
<li>Number</li>
<li>Object<br>
</li>
</ul>
<h3>3.1. The ManagedObjectManagerFactory</h3>
The ManagedObjectManagerFactory is primarily used to create
ManagedObjectManagers. It is the only concrete class in the gmbal
API, which is defined in the package org.glassfish.gmbal.
Obviously the implementation has other concrete classes, but these are
contained in subpackages under org.glassfish.gmbal.<br>
<h4>3.1.1. getMethod</h4>
This is a simple wrapper around Class.getDeclaredMethod that converts
the
checked exceptions from getDeclaredMethod into unchecked
exceptions. It is
intended for use with the <a href="#addAnnotation">addAnnotation</a>
method.<br>
<h4><a name="3.1.2._create"></a>3.1.2. create</h4>
There are two versions of create: createStandalone( String ) and
createFederated( ObjectName ).
createStandalone( String ) is used to create a standalone hierarchy:
the String is the
domain to use for all ObjectNames created from the resulting
ManagedObjectManager. In this version, the root has no parent.<br>
<br>
createFederated( ObjectName ) is used to create a hierarchy of MBeans
that are rooted
under a parent MBean that is not managed by the created instance of
ManagedObjectManager. In this case, the parent of the
ManagedObjectManager is
identified by the object name (called the rootParentName) that is
passed to the
create call. Note that the root parent MBean MUST be managed by
the same
MBeanServer as the ManagedObjectManager. The ObjectName MUST be
an AMX-compliant ObjectName: in particular, it MUST define pp, type,
and
name attributes.<br>
<br>
Note that createFederated must obey the parent-child restriction in
AMX. That is, a child cannot be created<br>
before its parent has been created. It is possible that the root
parent ObjectName passed to createFederated does not correspond to a
valid MBean in the MBeanServer at the time that createFederated is
called. In this case, the Gmbal ManagedObjectManager
created by the createFederated call must defer registration of its
MBeans until after the root parent has been registered. The MOM
monitors the root parent in the MBeanServer, registering and
de-registering all MBeans in the mom's tree as the root parent is
registered and de-registered.<br>
<br>
For examples of the usage of these methods, see "<a
href="#4.6._Using_Gmbal_">Using Gmbal</a>".<br>
<h3>3.2. The ManagedObjectManager</h3>
The ManagedObjectManager is the main API for gmbal. It contains a
tree of
MBeans with a single root,<br>
which may optionally be federated into a large MBean hierarchy.<br>
<br>
The most important methods are createRoot, register, and
unregister. Any
application of gmbal must use these methods. For examples of the
usage of the key methods, see "<a href="#4.6._Using_Gmbal_">Using Gmbal</a>".<br>
<h4>3.2.1. createRoot</h4>
There are several methods to create a root in the
ManagedObjectManager.
createRoot() creates a root that simply acts as an AMX container.
Its type
and name are both set to GMBALROOT.<br>
<br>
createRoot( Object ) and createRoot( Object, String ) both use the
given object
as the root, and just as in the register methods, these methods create
an MBean
from the Object using the annotations on its class. The createRoot(
Object )
method will derive the name from the object itself by calling the
@NameValue method from the class. If no such method is
available, the
name is set to the type value. The second method allows the name
to specified
explicitly. This can be useful in case where either
@NameValue is not
used, or there are multiple ManagedObjectManager instances with the
same root
type that share the same parent. In this case, it is essential
that each root
have a distinct name.last. There is also a createRoot() method,
which creates a simple internal root that only provides the required
AMXv3 attributes.<br>
<br>
createRoot may only be called when the ManagedObjectManager does not
already
contain a root. This is true immediately after a
ManagedObjectManagerFactory.create call, or after unregistering the
root.<br>
<h4>3.2.2. getRoot</h4>
getRoot returns the current root of the ManagedObjectManager. If
no root is
available, getRoot throws an IllegalStateException.<br>
<h4><a name="3.2.3._register_and_registerAtRoot"></a>3.2.3. register
and registerAtRoot</h4>
There are two forms of register: register( Object parent, Object obj )
and
register( Object parent, Object obj, String name ). The first
form obtains
the name from obj (by using @NameValue),
the second allows explicit specification of the name. The
returned result is
an instance
of NotificationEmitter that may be used to register a
NoticationListener to
listen for attribute change notifications on the
MBean that was created for obj. <br>
<br>
There are also two forms of registerAtRoot: registerAtRoot( Object obj
) and
registerAtRoot( Object obj, String name). These methods are
exactly
equivalent to mom.register( mom.getRoot(), obj ) and mom.register(
mom.getRoot(), obj, name ). <br>
<br>
All of these methods can only be called after a successful createRoot
call.<br>
<h4><a name="3.2.4._unregister"></a>3.2.4. unregister</h4>
unregister( Object ) unregisters an object that was previously
registered. It
also deletes any children of the object in depth-first order.
Unregister
removes the generated MBean from the ManagedObjectManager and also
unregisters
the MBean from the ManagedObjectManager's MBeanServer.<br>
<br>
Unregister can only be called after a successful createRoot call.<br>
<h4>3.2.5. getObject/getObjectName</h4>
The register methods return a NotificationEmitter which can be used to
register
a NotificationListener to listen for attribute change events. But
sometimes
access to the ObjectName is needed. getObjectName returns the
ObjectName that
was created for an object that was passed to the register method.
getObject
is used to handle the opposite case: going from the ObjectName to the
registered Object. Note that in both case the registered Object
is the
implementation object passed to a register method, NOT the internally
created
dynamic MBean (which is not directly provided).<br>
<br>
These methods can only be called after a successful createRoot call.<br>
<h4>3.2.6. stripPrefix and stripPackagePrefix<a name="filterPrefix"></a></h4>
A type prefix is simply a prefix of a fully qualified Java class name.
By
default, the MBean ObjectName type field is set to the full qualified
class
name of the implementation class, stripped of the longest type prefix
of the
class name. For example, in CORBA the type prefixes are set to:<br>
<br>
<div style="margin-left: 40px;">
com.sun.corba.se<br>
com.sun.corba.se.spi<br>
com.sun.corba.se.spi.orbutil<br>
com.sun.corba.se.impl<br>
com.sun.corba.se.impl.orbutil<br>
<br>
</div>
This helps keep the ObjectNames to a reasonable length.
Applications of gmbal
are also free to specify the exact type name to use through an
annotation.<br>
<br>
stripPackagePrefix is used to indicate that ALL package prefixes should
be removed from the class name for the default type.<br>
<br>
These methods may only be called before a successful createRoot call.<br>
<h4>3.2.7. <a name="MBeanServer_and_ResourceBundle"></a>MBeanServer
and
ResourceBundle</h4>
Accessors (getter and setter) are provided for the MBeanServer and the
ResourceBundle.<br>
<br>
The MBeanServer is used for all register and unregister operations in
the
ManagedObjectManager instance. It defaults to the<br>
platform MBeanServer.<br>
<br>
The ResourceBundle is used to internationalize all descriptions.
If set, the
description value is used as a key in the resource bundle,<br>
otherwise the description value is taken as the actual description.<br>
<h4><a name="3.2.8._addAnnotation"></a>3.2.8. <a name="addAnnotation"></a>addAnnotation</h4>
The best way to explain this method is to start with an example.
CORBA
defines a class org.omg.PortableServer.Servant. The
definition of Servant is a standard, and so I cannot add annotations to
the
source code for Servant. Gmbal is flexible enough that we can put
the annotation almost anywhere, so what are the possible
subclasses of Servant? Mostly one subclass is used in GlassFish for
dynamic RMI-IIOP: ReflectiveTie,
but others are possible, including Ties generated by the idlj
compiler. We also cannot add non-standard
annotations to standard-compliant code generated by a code generator.<br>
<br>
This becomes an issue when adding annotations to things like the ORB's
POA,
which has a method:<br>
<pre>@ManagedData<br>Servant get_servant() { ... }<br></pre>
that I would like to use as an attribute. How should gmbal
represent Servant
in this case? I may want to represent the Servant as ManagedData,
using one or more methods (such as byte[]
_object_id()) on the Servant as attributes, but there is no place that
I can put an annotation for this.<br>
<br>
The solution I have adopted in gmbal is to allow annotations to be
added on
"dummy" classes, and then use ManagedObjectManager.addAnnotation
to add the annotation to the appropriate
type. For example, the above example can be handled by:<br>
<pre>@ManagedData<br>@InheritedAttributes( {<br> @InheritedAttribute( methodName="_object_id", id="objectId",<br> description="The Object Id for this Servant" ),<br> ... // several other methods<br>} )<br>public interface DummyServant {}<br><br>mom.addAnnotation( Servant.class, <br> DummyServant.class.getAnnotation( ManagedObject.class ) ) ;<br>mom.addAnnotation( Servant.class, <br> DummyServant.class.getAnnotation( InheritedAttributes.class ) ) ;<br></pre>
This behaves exactly as if the annotations on DummyServant were on
Servant,
allowing the appropriate annotation processing to take place.<br>
<br>
InheritedAttribute can also be used when it is desired to use a method
inherited from a super class as an attribute or operation. This
is useful in the case where the superclass is
a class that for whatever reason cannot be modified with an
annotation. For example, the GlassFish v3 ORB defines an
interface TaggedProfileTemplate (in com.sun.corba.se.spi.ior) as
follows:<br>
<pre>@ManagedData<br>@Description( "A template for creating a TaggedProfile" ) <br>@IncludeSubclass( { com.sun.corba.se.spi.ior.iiop.IIOPProfileTemplate.class } )<br>@InheritedAttribute( description="List of TaggedComponents for this template",<br> methodName="iterator", id="TaggedComponents" )<br>public interface TaggedProfileTemplate extends List<TaggedComponent>, <br> Identifiable, WriteContents, MakeImmutable<br>{ <br> ... <br>}<br></pre>