01.02.2015 Views

Ken Cavanaugh - The Gmbal project

Ken Cavanaugh - The Gmbal project

Ken Cavanaugh - The Gmbal project

SHOW MORE
SHOW LESS

Create successful ePaper yourself

Turn your PDF publications into a flip-book with our unique Google optimized e-Paper software.

<strong>Gmbal</strong><br />

Sustaining TOI<br />

<strong>Ken</strong> <strong>Cavanaugh</strong><br />

Friday, December 11, 2009<br />

1


Outline<br />

MBeans<br />

AMX<br />

Review of <strong>Gmbal</strong> API<br />

Use in GF and CORBA<br />

Build and release details<br />

Implementation packages and overview<br />

Debugging tips<br />

Current tests<br />

Friday, December 11, 2009<br />

2


MBeans<br />

Management interface defined in JMX<br />

<strong>Gmbal</strong> is a convenient way to create MBeans<br />

<strong>Gmbal</strong> creates MBeans that are:<br />

Open MBeans (dynamic MBeans with Open data)<br />

AMX compliant<br />

Have Model MBean metadata<br />

Are JDK 5 compliant<br />

JDK 6 has significant JMX changes<br />

Still supporting JDK 5 while <strong>Gmbal</strong>’s customers require it<br />

Friday, December 11, 2009<br />

3


AMX<br />

AMX MBeans are GlassFish v3’s version of MBeans<br />

AMX is an interface specification: <strong>Gmbal</strong> is an implementation of AMX<br />

AMX requirements:<br />

ObjectNames have a very specific form that defines a parent/child<br />

hierarchy<br />

A number of required attributes for metadata<br />

Several required MBean attributes:<br />

Parent<br />

Name<br />

Children<br />

Friday, December 11, 2009<br />

4


<strong>Gmbal</strong> API: Annotations<br />

8 basic annotations:<br />

@ManagedObject and @ManagedData<br />

@ManagedAttribute<br />

@ManagedOperation and @ParameterNames<br />

@NameValue<br />

@Description<br />

@AMXMetadata<br />

5 specialized annotations:<br />

@InheritedAttribute and @InheritedAttributes<br />

@IncludeSubclass<br />

@DescriptorKey and @DescriptorFIelds<br />

Friday, December 11, 2009<br />

5


<strong>Gmbal</strong> API: Interface and Factory<br />

One interface (ManagedObjectManager) that handles registration and<br />

related operations.<br />

One concrete class (ManagedObjectManagerFactory) to obtain<br />

ManagedObjectManagers.<br />

Friday, December 11, 2009<br />

6


ManagedObjectManager API:<br />

registration<br />

public interface ManagedObjectManager {<br />

NotificationEmitter getRoot() ;<br />

NotificationEmitter createRoot() ;<br />

NotificationEmitter createRoot( Object obj ) ;<br />

NotificationEmitter createRoot( Object obj, String name ) ;<br />

NotificationEmitter register( Object obj ) ;<br />

NotificationEmitter registerAtRoot( Object obj ) ;<br />

NotificationEmitter registerAtRoot( Object obj, String name ) ;<br />

NotificationEmitter register( Object parent, Object obj ) ;<br />

NotificationEmitter register( Object parent, Object obj, String name ) ;<br />

void unregister( Object obj ) ;<br />

}<br />

• Each MOM must have 1 root<br />

• Unregister when needed<br />

• Name required unless object has @NameValue method<br />

Friday, December 11, 2009<br />

7


Deferred and Suspended<br />

Registration<br />

Registration with the MBean server does not alway happen<br />

immediately<br />

MOM has a suspend/resume API to allow program to defer<br />

registration until some later point (usually after all init has completed)<br />

Problem: as soon as an MBean is registered, it can (and will!) be<br />

called asynchronously (AMX validator always runs)<br />

Can suspend before any MBeans created, then resume after all init<br />

completes<br />

MOM created by createFederated may have deferred registration<br />

Can’t create MOM root until root parent exists (AMX requirement)<br />

Transparent to <strong>Gmbal</strong> client in most ways<br />

Note that AMX is NOT started in GFv3 by default<br />

All of this is handled in the JMXRegistrationManager<br />

Friday, December 11, 2009<br />

8


ManagedObjectManager API:<br />

miscellaneous<br />

public interface ManagedObjectManager {<br />

void suspendJMXRegistration() ;<br />

void resumeJMXRegistration() ;<br />

ObjectName getObjectName( Object obj ) ;<br />

Object getObject( ObjectName oname ) ;<br />

void stripPrefix( String... str )<br />

String getDomain() ;<br />

MBeanServer getMBeanServer() ;<br />

void setMBeanServer( MBeanServer server ) ;<br />

ResourceBundle getResourceBundle() ;<br />

void setResourceBundle( ResourceBundle rb ) ;<br />

void addAnnotation( AnnotatedElement element, Annotation annotation )<br />

}<br />

Suspend/resume to deal with registration in constructor problem<br />

Access object name object mapping for registered objects<br />

set/get MBeanServer and description resource bundle<br />

stripPrefix and addAnnotations discussed later<br />

Friday, December 11, 2009<br />

9


ManagedObjectManager API:<br />

Debugging<br />

interface ManagedObjectManager {<br />

public enum RegistrationDebugLevel { NONE, NORMAL, FINE } ;<br />

void setRegistrationDebugLevel( RegistrationDebugLevel level ) ;<br />

}<br />

void setRuntimeDebug( boolean flag ) ;<br />

void setTypelibDebug( int level ) ;<br />

void setJMXRegistrationDebug( boolean flag ) ;<br />

String dumpSkeleton( Object obj ) ;<br />

void suppressDuplicateRootReport( boolean suppressReport ) ;<br />

Several different tracing capabilities<br />

Tracing when MBeans are constructed<br />

FINE adds<br />

Tracing when MBean methods are invoked<br />

Tracing for type evaluation in typelib<br />

Tracing for registration of MBean with JMX<br />

Dump the skeleton for any registered object<br />

Control reporting of duplicate setRoot calls<br />

Friday, December 11, 2009<br />

10


ManagedObjectManagerFactory<br />

public final class ManagedObjectManagerFactory {<br />

public static ManagedObjectManager createStandalone( String domain ) { ... }<br />

}<br />

public static ManagedObjectManager createFederated( ObjectName rootParentName ) { ... }<br />

• Only concrete class in the API<br />

• createStandalone(String) takes a domain used in all ObjectNames from<br />

this ManagedObjectManager.<br />

• Typically used in standalone case<br />

• createFederated(rootParentName) takes an AMX-compliant ObjectName<br />

which is the parent of the ManagedObjectManager’s root<br />

• Typically used in GFv3 case<br />

Friday, December 11, 2009<br />

11


Use of <strong>Gmbal</strong><br />

In GlassFish v3<br />

Annotations used along with GF probes<br />

Used to create MBeans for GF monitoring<br />

In CORBA<br />

Create MBeans directly for management API<br />

ORB MBean Hierarchy:<br />

gmbal root (amx parent in GlassFish)<br />

various internal APIs are available as MBean<br />

I’ll talk about this more in the CORBA TOI<br />

Lloyd will talk about tools for viewing AMX MBeans in GFv3<br />

Friday, December 11, 2009<br />

12


Workspace and Artifacts<br />

Project is at http://kenai.com/<strong>project</strong>s/gmbal<br />

Currently master is the gmbal repository at http://kenai.com/hg/<br />

gmbal~master (tag is VERSION-3.0.0-b023)<br />

Artifacts are all available in Maven at http://download.java.net/<br />

maven/2/org/glassfish/gmbal<br />

Current valid artifacts:<br />

Group ID Artifact ID Current Version<br />

(in GF 3.0-FCS)<br />

org.glassfish.gmbal gmbal-api-only 3.0.0-b023<br />

org.glassfish.gmbal gmbal-api-only-source 3.0.0-b023<br />

org.glassfish.gmbal gmbal 3.0.0-b023<br />

org.glassfish.gmbal gmbal-source 3.0.0-b023<br />

Friday, December 11, 2009<br />

13


Build and Integration Process<br />

Make a clone of the repository at https://hg.kenai.com/hg/<br />

gmbal~master<br />

use -r option for a specific version (e.g. -r 3.0-FCS)<br />

hg tags command will display all versions<br />

Build with “ant all”<br />

To make a new release:<br />

edit build.properties<br />

change build.int to the new build version<br />

or if necessary the other gmbal.* properties for different versions<br />

hg commit/hg tag /hg push<br />

“ant release” to release to maven repository<br />

Friday, December 11, 2009<br />

14


<strong>Gmbal</strong> Implementation: Packages<br />

<strong>Gmbal</strong> API:<br />

org.glassfish.gmbal<br />

org.glassfish.gmbal.util<br />

<strong>Gmbal</strong> impl:<br />

org.glassfish.gmbal.generic<br />

org.glassfish.gmbal.logex<br />

org.glassfish.gmbal.typelib<br />

org.glassfish.gmbal.impl<br />

Tools and test support:<br />

org.glassfish.gmbal.tools.argparser<br />

org.glassfisdh.gmbal.tools.file<br />

org.glassfish.gmbal.main<br />

Friday, December 11, 2009<br />

15


<strong>Gmbal</strong> API packages<br />

org.glassfish.gmbal<br />

previously discussed annotations<br />

previously discussed ManagedObjectManager and<br />

ManagedObjectManagerFactory<br />

org.glassfish.gmbal.util<br />

Contains GenericConstructor<br />

GenericConstructor( final Class type, String className,<br />

final Class... signature )<br />

T create( Object... args )<br />

ManagedObjectManagerFactory creates instances of<br />

GenericConstructor for the createFederated and createStandalone<br />

method in ManagedObjectManagerImpl<br />

Decouples interface from implementation<br />

gmbal-api-only has just the org.glassfish.gmbal and<br />

org.glassfish.gmbal.util package<br />

Friday, December 11, 2009<br />

16


org.glassfish.gmbal.generic<br />

Provides interfaces that represent functions<br />

Also algorithms that operate on functions (things like map, fold,<br />

find)<br />

Provides debugging facilities<br />

DprintUtil for method tracing<br />

OperationTracer for gathering context information for exceptions<br />

MethodMonitor to tie this together<br />

Facet accessor to provide limited dynamic inheritance<br />

Construct MBean with standard AMX attributes and application<br />

specific attributes<br />

Generic support for printing out arbitrary objects<br />

Uses annotations to control printing behavior<br />

Friday, December 11, 2009<br />

17


org.glassfish.gmbal.logex<br />

Uses an annotated interface to generate exceptions and log messages<br />

Also supports I18N for messages<br />

Example:<br />

@ExceptionWrapper( idPrefix="GMBALTLIB", resourceBundle = "org.glassfish.gmbal.logex.LogStrings" )<br />

public interface Exceptions {<br />

static final Exceptions self = WrapperGenerator.makeWrapper( Exceptions.class ) ;<br />

// Allow 100 exceptions per class<br />

static final int EXCEPTIONS_PER_CLASS = 100 ;<br />

// TypeEvaluator<br />

static final int TYPE_EVALUATOR_START = 1 ;<br />

@Message( "Internal error in TypeEvaluator" )<br />

@Log( id=TYPE_EVALUATOR_START + 0 )<br />

IllegalStateException internalTypeEvaluatorError( @Chain Exception exc ) ;<br />

}<br />

@Message( "evaluateType should not be called with a Method ({0})" )<br />

@Log( id=TYPE_EVALUATOR_START + 1 )<br />

IllegalArgumentException evaluateTypeCalledWithMethod( Object type ) ;<br />

Friday, December 11, 2009<br />

18


org.glassfish.gmbal.typelib<br />

Converts the standard java Class/java.lang.reflect.Type hierarchy into<br />

an internal form for <strong>Gmbal</strong>.<br />

Main interfaces:<br />

EvaluatedType (parent)<br />

EvaluatedDeclaration (types that can have annotations)<br />

EvaluatedFieldDeclaration<br />

EvaluatedMethodDeclaration<br />

EvaluatedClassDeclaration<br />

EvaluatedArrayType<br />

TypeEvaluator<br />

Main implementation class<br />

Provides public static EvaluatedType<br />

getEvaluatedType( Class ) method<br />

No need for Java’s type variables and wildcard types: these are<br />

evaluated out of the result (which is the whole reason for doing this)<br />

Friday, December 11, 2009<br />

19


org.glassfish.gmbal.typelib<br />

Evaluated generic types (replaces type variables with types) so that<br />

<strong>Gmbal</strong> can easily use type information to generate open types<br />

Example:<br />

@ManagedData<br />

public interface Bar {<br />

@ManagedAttribute<br />

String getName() ;<br />

}<br />

@ManagedAttribute<br />

String getAddress() ;<br />

@ManagedData<br />

public interface Foo {<br />

@ManagedAttribute<br />

List getElems() ;<br />

}<br />

@ManagedObject<br />

public interface Baz {<br />

@ManagedAttribute<br />

Foo getFoo()<br />

}<br />

Foo is annotated as @ManagedData<br />

Needs to be OpenData<br />

But we can’t tell what type T is in Foo<br />

Baz has an instance of Foo with T<br />

instantiated to Bar<br />

Note that Foo also has an instance of the<br />

standard List, with is declared with its own<br />

type variable T (see java.util.List)<br />

Typelib replaces all type variables with the<br />

values to which they are bound<br />

It is a bit tricky due to the need to handle<br />

complex recursive references to types<br />

Friday, December 11, 2009<br />

20


org.glassfish.gmbal.impl<br />

<strong>The</strong> main implementation package<br />

Classes:<br />

ManagedObjectManagerInternal (interface for MOM used in impl<br />

package)<br />

ManagedObjectManagerImpl<br />

MBeanSkeleton (contains most of the implementation for a specific<br />

MBean)<br />

MBeanImpl (actually class used to represent MBean)<br />

MBeanTree (containment hierarchy of MBeans)<br />

JMXRegistrationManager (manages MBean registrations)<br />

TypeConverter(Impl) (handle java type open type conversions)<br />

AttributeDescriptor (main implementation of attributes)<br />

AMXImpl (implements AMX attributes)<br />

Friday, December 11, 2009<br />

21


Tools and test support<br />

org.glassfish.gmbal.tools.argparser<br />

Attribute driven command line parser<br />

org.glassfish.gmbal.tools.file<br />

General purpose file and directory processing tools from CORBA<br />

Used here to generate resource bundle for logex exception<br />

wrappers<br />

org.glassfish.gmbal.main<br />

Provides ProfileMain, which is used for simple performance testing<br />

None of this code is delivered in the OSGi bundles for <strong>Gmbal</strong><br />

Friday, December 11, 2009<br />

22


Construction and Registration 1<br />

ManagedObjectManagerImpl data:<br />

MBeanTree (maintains registration of all MBeans for this MOM)<br />

skeletonMap (maps class to skeleton)<br />

typeConverterMap (maps class to type converter)<br />

Registration starts at ManagedObjectManagerImpl.register( Object<br />

parent, Object obj, String name )<br />

get the MBeanImpl corresponding to the parent<br />

construct the MBean for obj<br />

register the MBean in the tree<br />

Friday, December 11, 2009<br />

23


Construction and Registration 2<br />

ConstructMBean<br />

Use typelib to get an EvaluatedType for the class of obj<br />

get a skeleton for the evaluated type<br />

Analyzes the annotations for attributes and operations<br />

gets the TypeConverters for all attribute and operation types<br />

Constructs the JMX metadata for all types, attributes, and<br />

operations<br />

construct AMX Metadata<br />

construct MBeanImpl<br />

Friday, December 11, 2009<br />

24


Attributes and Operations<br />

MBeanImpl implements the dynamic MBean interface by delegating to<br />

the MBeanSkeleton<br />

MBeanImpl implements the FacetAccessor interface<br />

MBeanSkeleton uses the appropriate AttributeDescriptor for<br />

attribute get/set<br />

<strong>The</strong> AttributeDescriptor uses the FacetAccessor interface to get/set<br />

the actual attribute value (either from a method or a field)<br />

<strong>The</strong> AttributeDescriptor also uses the TypeConverter to convert to/<br />

from the OpenType as needed<br />

Friday, December 11, 2009<br />

25


Debugging: MethodMonitor<br />

Most of the code in typelib and impl uses the MethodMonitor<br />

Allows internal tracing of method entry, exit, and other interesting<br />

points in the method<br />

Currently used for two purposes:<br />

To record interesting context in the OperationTracer<br />

To hook in DprintUtil for support of debug flags, which are<br />

controlled by the debug methods<br />

Friday, December 11, 2009<br />

26


Example of OperationTracer<br />

INFO: GMBAL406: registering MBean extern:pp=/gmbal-root/AMXClientTest$MyManagedClass[Root]/AMXClientTest<br />

$MyManagedClass[Child],type=AMXClientTest$MyManagedClass,name=GrandChild-2<br />

CONTEXT:<br />

( 0): register(org.glassfish.gmbal.impl.AMXClientTest$MyManagedClass@1d2b9b7,org.glassfish.gmbal.impl.AMXClientTest<br />

$MyManagedClass@19c0bd6,)<br />

( 1): register(MBeanImpl[type=AMXClientTest$MyManagedClass,name=Child,oname=extern:pp=/gmbal-root/AMXClientTest<br />

$MyManagedClass[Root],type=AMXClientTest$MyManagedClass,name=Child],org.glassfish.gmbal.impl.AMXClientTest<br />

$MyManagedClass@19c0bd6,MBeanImpl[type=AMXClientTest$MyManagedClass,name=GrandChild-2,oname=extern:pp=/gmbal-root/<br />

AMXClientTest$MyManagedClass[Root]/AMXClientTest$MyManagedClass[Child],type=AMXClientTest<br />

$MyManagedClass,name=GrandChild-2])<br />

java.lang.RuntimeException: StackTrace<br />

at org.glassfish.gmbal.logex.WrapperGenerator.makeException(WrapperGenerator.java:220)<br />

at org.glassfish.gmbal.logex.WrapperGenerator.handleFullLogging(WrapperGenerator.java:361)<br />

at org.glassfish.gmbal.logex.WrapperGenerator.access$300(WrapperGenerator.java:93)<br />

at org.glassfish.gmbal.logex.WrapperGenerator$1.invoke(WrapperGenerator.java:434)<br />

at $Proxy16.registeringMBean(Unknown Source)<br />

at org.glassfish.gmbal.impl.MBeanImpl.register(MBeanImpl.java:303)<br />

at org.glassfish.gmbal.impl.JMXRegistrationManager.register(JMXRegistrationManager.java:193)<br />

at org.glassfish.gmbal.impl.MBeanTree.register(MBeanTree.java:376)<br />

at org.glassfish.gmbal.impl.ManagedObjectManagerImpl.register(ManagedObjectManagerImpl.java:713)<br />

at org.glassfish.gmbal.impl.ManagedObjectManagerImpl.register(ManagedObjectManagerImpl.java:724)<br />

at org.glassfish.gmbal.impl.AMXClientTest.initializeMom(AMXClientTest.java:195)<br />

at org.glassfish.gmbal.impl.AMXClientTest.setUp(AMXClientTest.java:176)<br />

•This is taken from a test case which is registering an MBean<br />

•<strong>The</strong> context indicates the data being registered<br />

•( 0): This is the main register method discussed previously<br />

•( 1): This is the MBeanTree register call<br />

•Here we see a fully constructed MBean being registered under<br />

the parent<br />

•This gives information not available in the stack trace<br />

•<strong>The</strong> OperationTracer is avilable for all <strong>Gmbal</strong> exceptions<br />

Friday, December 11, 2009<br />

27


<strong>The</strong> debug methods<br />

<strong>Gmbal</strong> has a number of methods that can be set to display more<br />

information<br />

<strong>The</strong>re is no general user-exposed API for this<br />

But note that some of the <strong>Gmbal</strong> debug can be enabled using the<br />

ORB debug flags within the ORB<br />

All of the debug flags enabled various MethodMonitor calls which<br />

print out information in a method:<br />

On entry: ($thread): (GMBAL).impl..-><br />

Info: ($thread): (GMBAL).impl..::<br />

On exit: ($thread): (GMBAL).impl..


<strong>Gmbal</strong> tests<br />

<strong>Gmbal</strong> has an extensive test suite in the <strong>project</strong><br />

tests use the same package names as source, but are in a different<br />

directory (standard NB <strong>project</strong> layout)<br />

Main test is in org.glassfish.gmbal.JmxaTest (old name)<br />

Emma reports pretty good code coverage<br />

block 69%<br />

class 78%<br />

line 69%<br />

method 69%<br />

Hudson job is at http://hudson.sfbay/view/corba/gmbal<br />

Unfortunately the job is currently broken<br />

Friday, December 11, 2009<br />

29


Common Errors in Using <strong>Gmbal</strong><br />

Just a few examples<br />

I don’t have time to do complete documentation on these<br />

Examples:<br />

Registering the same object twice<br />

Unregistering an object that was previously unregistered<br />

Passing something to a register method that cannot represent an<br />

MBean (e.g. no @ManagedObject annotation)<br />

Putting @ManagedAttribute on a method that is not a valid<br />

attribute (e.g. return non-void and takes an argument)<br />

Annotating object with @AMXMetadata( isSingleton = true ) and<br />

then creating more than one instance<br />

Forgetting @NameValue on an object registered without a name<br />

Friday, December 11, 2009<br />

30

Hooray! Your file is uploaded and ready to be published.

Saved successfully!

Ooh no, something went wrong!