Simple Custom JMX MBeans with WebLogic 12c and Spring

Using the Spring framework bundled with WebLogic 12 the programming of JMX MBeans becomes as easy as writing a simple POJO within a web application. After coding the MBean as a POJO all that is left to do is creating the Spring configuration file and editing the web.xml deployment decriptor:

– Firstly you have to add the Spring <listener> to the web.xml deployment descriptor with the web.xml to get Spring started.

– Secondly create the applicationContext.xml for Spring in the WEB-INF subdirectory. Declare the Spring bean and let Spring export it to the platform MBean server.

– Thirdly deploy the web application and test it with JConsole, WLST or j4psh.

For your convinience I already built an example. You can download the deployable SimpleJMX.war file or the complete NetBeans project.

You can see the application in action, including the involved files and the deployment in the following screencast:

How to access custom MBeans from WLST is shown in the second part:

The third part is showing how to retrieve MBean attributes from a JSP:

WebLogic Scripting Tool on Capsaicin: j4psh JMX Shell with Syntax Highlighting, Wildcards and Tab-Completion

[This posting will be a part of my upcoming WebLogic 12c book]

Kudos Oracle! Over a year ago I mentioned in my Oracle Middleware and Cloud Computing book that developing WebLogic Scripting Tool (WLST) scripts with vi or Notepad++ is so 80’ies. It took you only a couple of months to respond with an Eclipse facet. Now everyone can use the bundled Eclipse with OEPE for WLST scripting . Thanks for that – even if you had it on your to-do list anyway ;)

WLST itself is a fantastic tool to interactively explore WebLogic MBean world with all their attributes, operations, and relationships (it’s described here – did I mention that this post is not for the beginners?). WLST is using its own proprietary syntax to navigate to MBeans though.

Are you willing to look beyond your own backyard? Ready to move to real MBean names? Then let’s spice it up.

 

j4psh JMX Shell

j4psh is a JMX shell which is using standard MBean names, provides syntax highlighting together with code completion and even wildcard patterns! In j4psh you will be using similar command as in WLST. Here is an incomplete list of the most useful commands:

  • connect, to connect to an Java EE server with the jolokia.war deployed or using the Java agent
  • pwd, to find out the current MBean name or domain
  • cd, to navigate to an MBean or domain
  • ls, to list MBean details (works with * and can be restricted as “ls -a” for attributes and “ls -o” for operations).
  • cat, to display attribute values

Unlike WLST, where every command is basically a Python method, the j4psh syntax is as easy as it gets.

 

 

For the bigger picture how j4psh can be downloaded, installed and how nicely it fits into the  Jolokia open source project see my previous posting.

 

Screencasts

In my opinion j4psh is easiest to understand when seen in action, so here are two examples of j4psh sessions.

 

1.) Basic usage of j4psh with WebLogic. The JMX “HelloWord”: enabling verbose garbage collection without server restart.

 

2.) Advanced Usage of j4psh with WebLogic: How to find the right MBean for a JDBC connection? Retrieve JMX attributes from JDBC connection pool, then use the MBean Name for the same RESTful request.

 

Give it a try! It’s free anyway. And let me know what you think!
And by the way, after writing about open source Jolokia, I am now determined to grow a real Jolokia plant myself…

Update: Many thanks to the Jolokia team ;) for the plant!!


RESTful WebLogic Monitoring of Servers, Applications, JDBC and JMS with Jolokia

[This posting will be a part of my upcoming WebLogic 12c book]

This article is part II of III. Make sure you read part I explaining the basics of monitoring WebLogic with WLST, the WebLogic 12c REST-ful management API and the open source framework Jolokia.

There will be a part III in a few of days, explaining how to use j4psh with WebLogic. j4psh is a JMX shell that resembles WLST in interactive mode but includes features such as syntax highlighting and tab-completion of commands and MBean names. j4psh is highly useful to interactively find out the correct MBean names used for the requests below.

WebLogic with Jolokia

Did you ever wonder how to retrieve the configuration values for a WebLogic managed server, runtime data of a JDBC connection pool or the number of messages in a particular JMS queue with a fast and simple HTTP GET?

The examples show typical use cases for monitoring a WebLogic domain with the following configuration:

– Admin server running at localhost:7001
– Managed server with name surf1 running at localhost:7003
– JDBC datasource with the name emergencyDB and associated connection pool (target set to surf1)
– JMS configuration with a JMS server surfJMS running on managed server surf1, a module surfJMSModule containing a queue name jms/ShippingRequestQueue (target of JMS server is surf1, JMS module subdeployment set to surfJMS)
– A deployment of a web service with the name SubmitOrder and target AdminServer and surf1.

An installation of Jolokia with target set to all server of the domain is recommended to follow the examples in this part.

 

General: List Configuration Details of Managed Server with Name surf1

http://localhost:7001/jolokia/read/com.bea:Name=surf1,Type=Server?ignoreErrors=true

Note, that without the ?ignoreErrors=true parameter the request would fail with an “NoAccessRuntimeException” because you cannot access the SSL keystore passphrases without proper authentication. Authentication is easily possible, but beyond of the scope of this article.

{ "request" : { "mbean" : "com.bea:Name=surf1,Type=Server",
      "type" : "read"
    },
  "status" : 200,
  "timestamp" : 1334778534,
  "value" : { "AcceptBacklog" : 300,
      "AddWorkManagerThreadsByCpuCount" : false,
      "AdminReconnectIntervalSeconds" : 10,
      "AdministrationPort" : 9002,
      "AdministrationPortEnabled" : false,
      "AdministrationProtocol" : "t3s",
      "AutoKillIfFailed" : false,
      "AutoMigrationEnabled" : false,
      "AutoRestart" : true,
      "COM" : { "objectName" : "com.bea:Name=surf1,Server=surf1,Type=COM" },
      "COMEnabled" : false,
      "CandidateMachines" : [  ],
      "ClasspathServletDisabled" : false,
      "ClientCertProxyEnabled" : false,
      "Cluster" : { "objectName" : "com.bea:Name=surfCluster,Type=Cluster" },
      "ClusterRuntime" : null,
      "ClusterWeight" : 100,
      "CoherenceClusterSystemResource" : null,
      "CompleteCOMMessageTimeout" : -1,
      "CompleteHTTPMessageTimeout" : -1,
      "CompleteIIOPMessageTimeout" : -1,
      "CompleteMessageTimeout" : 60,
      "CompleteT3MessageTimeout" : -1,
      "ConnectTimeout" : 0,
      "ConsensusProcessIdentifier" : -1,
      "ConsoleInputEnabled" : false,
      "CustomIdentityKeyStoreFileName" : null,
      "CustomIdentityKeyStorePassPhrase" : "ERROR: Access to sensitive attribute in clear text is not allowed due to the setting of ClearTextCredentialAccessEnabled attribute in SecurityConfigurationMBean. Attr: CustomIdentityKeyStorePassPhrase, MBean name: com.bea:Name=surf1,Type=Server (class weblogic.management.NoAccessRuntimeException)",
      "CustomIdentityKeyStorePassPhraseEncrypted" : "ERROR: Access not allowed for subject: principals=[], on ResourceType: Server Action: read, Target: CustomIdentityKeyStorePassPhraseEncrypted (class weblogic.management.NoAccessRuntimeException)",
      "CustomIdentityKeyStoreType" : null,
      "CustomTrustKeyStoreFileName" : null,
      "CustomTrustKeyStorePassPhrase" : "ERROR: Access to sensitive attribute in clear text is not allowed due to the setting of ClearTextCredentialAccessEnabled attribute in SecurityConfigurationMBean. Attr: CustomTrustKeyStorePassPhrase, MBean name: com.bea:Name=surf1,Type=Server (class weblogic.management.NoAccessRuntimeException)",
      "CustomTrustKeyStorePassPhraseEncrypted" : "ERROR: Access not allowed for subject: principals=[], on ResourceType: Server Action: read, Target: CustomTrustKeyStorePassPhraseEncrypted (class weblogic.management.NoAccessRuntimeException)",
      "CustomTrustKeyStoreType" : null,
      "DGCIdlePeriodsUntilTimeout" : 5,
      "DataSource" : { "objectName" : "com.bea:Name=surf1,Server=surf1,Type=DataSource" },
      "DefaultFileStore" : { "objectName" : "com.bea:Name=surf1,Server=surf1,Type=DefaultFileStore" },
      "DefaultIIOPPassword" : "ERROR: Access to sensitive attribute in clear text is not allowed due to the setting of ClearTextCredentialAccessEnabled attribute in SecurityConfigurationMBean. Attr: DefaultIIOPPassword, MBean name: com.bea:Name=surf1,Type=Server (class weblogic.management.NoAccessRuntimeException)",
      "DefaultIIOPPasswordEncrypted" : "ERROR: Access not allowed for subject: principals=[], on ResourceType: Server Action: read, Target: DefaultIIOPPasswordEncrypted (class weblogic.management.NoAccessRuntimeException)",
      "DefaultIIOPUser" : null,
      "DefaultInternalServletsDisabled" : false,
      "DefaultProtocol" : "t3",
      "DefaultSecureProtocol" : "t3s",
      "DefaultTGIOPPassword" : "ERROR: Access to sensitive attribute in clear text is not allowed due to the setting of ClearTextCredentialAccessEnabled attribute in SecurityConfigurationMBean. Attr: DefaultTGIOPPassword, MBean name: com.bea:Name=surf1,Type=Server (class weblogic.management.NoAccessRuntimeException)",
      "DefaultTGIOPPasswordEncrypted" : "ERROR: Access not allowed for subject: principals=[], on ResourceType: Server Action: read, Target: DefaultTGIOPPasswordEncrypted (class weblogic.management.NoAccessRuntimeException)",
      "DefaultTGIOPUser" : "guest",
      "ExecuteQueues" : [  ],
      "ExpectedToRun" : true,
      "ExternalDNSName" : null,
      "ExtraEjbcOptions" : null,
      "ExtraRmicOptions" : null,
      "FederationServices" : { "objectName" : "com.bea:Name=surf1,Server=surf1,Type=FederationServices" },
      "GatheredWritesEnabled" : false,
      "GracefulShutdownTimeout" : 0,
      "HealthCheckIntervalSeconds" : 180,
      "HealthCheckStartDelaySeconds" : 120,
      "HealthCheckTimeoutSeconds" : 60,
      "HostsMigratableServices" : true,
      "HttpTraceSupportEnabled" : false,
      "HttpdEnabled" : true,
      "IIOP" : { "objectName" : "com.bea:Name=surf1,Server=surf1,Type=IIOP" },
      "IIOPEnabled" : true,
      "IIOPTxMechanism" : "ots",
      "IdleConnectionTimeout" : 65,
      "IdleIIOPConnectionTimeout" : -1,
      "IdlePeriodsUntilTimeout" : 4,
      "IgnoreSessionsDuringShutdown" : false,
      "InstrumentStackTraceEnabled" : true,
      "InterfaceAddress" : null,
      "JDBCLLRTableName" : null,
      "JDBCLoggingEnabled" : false,
      "JDBCLoginTimeoutSeconds" : 0,
      "JMSDefaultConnectionFactoriesEnabled" : true,
      "JMSThreadPoolSize" : 15,
      "JNDITransportableObjectFactoryList" : [  ],
      "JTAMigratableTarget" : { "objectName" : "com.bea:Name=surf1,Server=surf1,Type=JTAMigratableTarget" },
      "JavaCompiler" : "javac",
      "JavaCompilerPostClassPath" : null,
      "JavaCompilerPreClassPath" : null,
      "JavaStandardTrustKeyStorePassPhrase" : "ERROR: Access to sensitive attribute in clear text is not allowed due to the setting of ClearTextCredentialAccessEnabled attribute in SecurityConfigurationMBean. Attr: JavaStandardTrustKeyStorePassPhrase, MBean name: com.bea:Name=surf1,Type=Server (class weblogic.management.NoAccessRuntimeException)",
      "JavaStandardTrustKeyStorePassPhraseEncrypted" : "ERROR: Access not allowed for subject: principals=[], on ResourceType: Server Action: read, Target: JavaStandardTrustKeyStorePassPhraseEncrypted (class weblogic.management.NoAccessRuntimeException)",
      "KernelDebug" : { "objectName" : "com.bea:Name=surf1,Server=surf1,Type=ServerDebug" },
      "KeyStores" : "DemoIdentityAndDemoTrust",
      "ListenAddress" : "",
      "ListenDelaySecs" : 0,
      "ListenPort" : 7003,
      "ListenPortEnabled" : true,
      "ListenThreadStartDelaySecs" : 60,
      "ListenersBindEarly" : false,
      "Log" : { "objectName" : "com.bea:Name=surf1,Server=surf1,Type=Log" },
      "LogRemoteExceptionsEnabled" : false,
      "LoginTimeoutMillis" : 5000,
      "LowMemoryGCThreshold" : 5,
      "LowMemoryGranularityLevel" : 5,
      "LowMemorySampleSize" : 10,
      "LowMemoryTimeInterval" : 3600,
      "MSIFileReplicationEnabled" : false,
      "Machine" : null,
      "ManagedServerIndependenceEnabled" : true,
      "MaxCOMMessageSize" : -1,
      "MaxHTTPMessageSize" : -1,
      "MaxIIOPMessageSize" : -1,
      "MaxMessageSize" : 10000000,
      "MaxOpenSockCount" : -1,
      "MaxT3MessageSize" : -1,
      "MessageIdPrefixEnabled" : false,
      "MessagingBridgeThreadPoolSize" : 5,
      "MuxerClass" : null,
      "NMSocketCreateTimeoutInMillis" : 180000,
      "Name" : "surf1",
      "NativeIOEnabled" : true,
      "NetworkAccessPoints" : [  ],
      "Notes" : null,
      "OutboundEnabled" : false,
      "OutboundPrivateKeyEnabled" : false,
      "OverloadProtection" : { "objectName" : "com.bea:Name=surf1,Server=surf1,Type=OverloadProtection" },
      "Parent" : { "objectName" : "com.bea:Name=surfandconsulting,Type=Domain" },
      "PeriodLength" : 60000,
      "PreferredSecondaryGroup" : null,
      "ReliableDeliveryPolicy" : null,
      "ReplicationGroup" : null,
      "ReplicationPorts" : null,
      "RestartDelaySeconds" : 0,
      "RestartIntervalSeconds" : 3600,
      "RestartMax" : 2,
      "ReverseDNSAllowed" : false,
      "SSL" : { "objectName" : "com.bea:Name=surf1,Server=surf1,Type=SSL" },
      "ScatteredReadsEnabled" : false,
      "SelfTuningThreadPoolSizeMax" : 400,
      "SelfTuningThreadPoolSizeMin" : 1,
      "ServerDebug" : { "objectName" : "com.bea:Name=surf1,Server=surf1,Type=ServerDebug" },
      "ServerDiagnosticConfig" : { "objectName" : "com.bea:Name=surf1,Server=surf1,Type=WLDFServerDiagnostic" },
      "ServerLifeCycleTimeoutVal" : 30,
      "ServerStart" : { "objectName" : "com.bea:Name=surf1,Server=surf1,Type=ServerStart" },
      "ServerVersion" : "unknown",
      "SingleSignOnServices" : { "objectName" : "com.bea:Name=surf1,Server=surf1,Type=SingleSignOnServices" },
      "SocketBufferSizeAsChunkSize" : false,
      "SocketReaders" : -1,
      "StagingDirectoryName" : "/u01/domains/surfandconsulting/servers/surf1/stage",
      "StagingMode" : "stage",
      "StartupMode" : "RUNNING",
      "StartupTimeout" : 0,
      "StuckThreadMaxTime" : 600,
      "StuckThreadTimerInterval" : 60,
      "SystemPasswordEncrypted" : "ERROR: Access not allowed for subject: principals=[], on ResourceType: Server Action: read, Target: SystemPasswordEncrypted (class weblogic.management.NoAccessRuntimeException)",
      "TGIOPEnabled" : true,
      "ThreadPoolPercentSocketReaders" : 33,
      "TimedOutRefIsolationTime" : 0,
      "TransactionLogFilePrefix" : "./",
      "TransactionLogFileWritePolicy" : "Direct-Write",
      "TransactionLogJDBCStore" : { "objectName" : "com.bea:Name=surf1,Server=surf1,Type=TransactionLogJDBCStore" },
      "TunnelingClientPingSecs" : 45,
      "TunnelingClientTimeoutSecs" : 40,
      "TunnelingEnabled" : false,
      "Type" : "Server",
      "UploadDirectoryName" : "./servers/surf1/upload",
      "Use81StyleExecuteQueues" : false,
      "UseConcurrentQueueForRequestManager" : false,
      "UseFusionForLLR" : false,
      "VerboseEJBDeploymentEnabled" : "false",
      "VirtualMachineName" : "surfandconsulting_surf1",
      "WebServer" : { "objectName" : "com.bea:Name=surf1,Server=surf1,Type=WebServer" },
      "WebService" : { "objectName" : "com.bea:Name=surf1,Server=surf1,Type=WebService" },
      "WeblogicPluginEnabled" : false,
      "XMLEntityCache" : null,
      "XMLRegistry" : null
    }
}

Deployment: List all Deployments

http://localhost:7001/jolokia/search/com.bea:*,Type=ApplicationRuntime
{ "request" : { "mbean" : "com.bea:Type=ApplicationRuntime,*",
 "type" : "search"
 },
 "status" : 200,
 "timestamp" : 1334780578,
 "value" : [ "com.bea:Name=mejb,ServerRuntime=AdminServer,Type=ApplicationRuntime",
 "com.bea:Name=consoleapp,ServerRuntime=AdminServer,Type=ApplicationRuntime",
 "com.bea:Name=bea_wls_management_internal2,ServerRuntime=AdminServer,Type=ApplicationRuntime",
 "com.bea:Name=emergencyDB,ServerRuntime=AdminServer,Type=ApplicationRuntime",
 "com.bea:Name=bea_wls_deployment_internal,ServerRuntime=AdminServer,Type=ApplicationRuntime",
 "com.bea:Name=SubmitOrder,ServerRuntime=AdminServer,Type=ApplicationRuntime",
 "com.bea:Name=wls-management-services,ServerRuntime=AdminServer,Type=ApplicationRuntime",
 "com.bea:Name=bea_wls_internal,ServerRuntime=AdminServer,Type=ApplicationRuntime",
 "com.bea:Name=jolokia,ServerRuntime=AdminServer,Type=ApplicationRuntime",
 "com.bea:Name=bea_wls9_async_response,ServerRuntime=AdminServer,Type=ApplicationRuntime"
 ]
 }

Deployment: List Deployments Details for an Application with the Name SubmitOrder

http://localhost:7001/jolokia/read/com.bea:ServerRuntime=*,Name=SubmitOrder,Type=ApplicationRuntime
{ "request" : { "mbean" : "com.bea:Name=SubmitOrder,ServerRuntime=*,Type=ApplicationRuntime",
      "type" : "read"
    },
  "status" : 200,
  "timestamp" : 1334777478,
  "value" : { "com.bea:Name=SubmitOrder,ServerRuntime=AdminServer,Type=ApplicationRuntime" : { "ActiveVersionState" : 2,
          "ApplicationName" : "SubmitOrder",
          "ApplicationVersion" : null,
          "ClassRedefinitionRuntime" : null,
          "CoherenceClusterRuntime" : null,
          "ComponentRuntimes" : [ { "objectName" : "com.bea:ApplicationRuntime=SubmitOrder,Name=AdminServer_/SubmitOrder,ServerRuntime=AdminServer,Type=WebAppComponentRuntime" } ],
          "EAR" : false,
          "HealthState" : { "critical" : false,
              "mBeanName" : null,
              "mBeanType" : null,
              "reasonCode" : [  ],
              "state" : 0,
              "subsystemName" : null
            },
          "KodoPersistenceUnitRuntimes" : [  ],
          "LibraryRuntimes" : null,
          "MaxThreadsConstraintRuntimes" : [  ],
          "MinThreadsConstraintRuntimes" : [  ],
          "Name" : "SubmitOrder",
          "OptionalPackageRuntimes" : [  ],
          "Parent" : { "objectName" : "com.bea:Name=AdminServer,Type=ServerRuntime" },
          "PersistenceUnitRuntimes" : [  ],
          "QueryCacheRuntimes" : [  ],
          "RequestClassRuntimes" : [  ],
          "Type" : "ApplicationRuntime",
          "WorkManagerRuntimes" : [ { "objectName" : "com.bea:ApplicationRuntime=SubmitOrder,Name=default,ServerRuntime=AdminServer,Type=WorkManagerRuntime" } ],
          "WseeRuntimes" : [ { "objectName" : "com.bea:ApplicationRuntime=SubmitOrder,Name=SubmitOrder!EntryWSProdService,ServerRuntime=AdminServer,Type=WseeRuntime" },
              { "objectName" : "com.bea:ApplicationRuntime=SubmitOrder,Name=SubmitOrder!EntryWSService,ServerRuntime=AdminServer,Type=WseeRuntime" }
            ],
          "WseeV2Runtimes" : [  ]
        } }
}

JDBC Data Source: Retrieve Settings for emergencyDB Data Source with Target Managed Server surf1 Running at localhost:7003

http://localhost:7003/jolokia/read/com.bea:Name=emergencyDB,ServerRuntime=surf1,Type=JDBCDataSourceRuntime?ignoreErrors=true
{ "request" : { "mbean" : "com.bea:Name=emergencyDB,ServerRuntime=surf1,Type=JDBCDataSourceRuntime",
      "type" : "read"
    },
  "status" : 200,
  "timestamp" : 1334823502,
  "value" : { "ActiveConnectionsAverageCount" : 0,
      "ActiveConnectionsCurrentCount" : 0,
      "ActiveConnectionsHighCount" : 1,
      "ConnectionDelayTime" : 44,
      "ConnectionsTotalCount" : 1,
      "CurrCapacity" : 1,
      "CurrCapacityHighCount" : 1,
      "DatabaseProductName" : "Apache Derby",
      "DatabaseProductVersion" : "10.6.1.0 - (938214)",
      "DeploymentState" : 2,
      "DriverName" : "Apache Derby Network Client JDBC Driver",
      "DriverVersion" : "10.6.1.0 - (938214)",
      "Enabled" : true,
      "FailedReserveRequestCount" : 0,
      "FailuresToReconnectCount" : 0,
      "HighestNumAvailable" : 1,
      "HighestNumUnavailable" : 1,
      "JDBCDriverRuntime" : { "objectName" : "com.bea:Name=surfandconsulting_surf1_org.apache.derby.jdbc.ClientDriver,ServerRuntime=surf1,Type=JDBCDriverRuntime" },
      "LastTask" : null,
      "LeakedConnectionCount" : 0,
      "ModuleId" : "emergencyDB",
      "Name" : "emergencyDB",
      "NumAvailable" : 1,
      "NumUnavailable" : 0,
      "Parent" : { "objectName" : "com.bea:Name=surf1,Type=ServerRuntime" },
      "PrepStmtCacheAccessCount" : 0,
      "PrepStmtCacheAddCount" : 0,
      "PrepStmtCacheCurrentSize" : 0,
      "PrepStmtCacheDeleteCount" : 0,
      "PrepStmtCacheHitCount" : 0,
      "PrepStmtCacheMissCount" : 0,
      "Properties" : "ERROR: MBean getAttribute failed: weblogic.common.resourcepool.ResourcePermissionsException: User \"\" does not have permission to perform operation \"admin\" on resource \"emergencyDB\" of module \"null\" of application \"null\" of type \"ConnectionPool\" (class javax.management.MBeanException)",
      "ReserveRequestCount" : 1,
      "State" : "Running",
      "Type" : "JDBCDataSourceRuntime",
      "VersionJDBCDriver" : "org.apache.derby.jdbc.ClientDriver",
      "WaitSecondsHighCount" : 0,
      "WaitingForConnectionCurrentCount" : 0,
      "WaitingForConnectionFailureTotal" : 0,
      "WaitingForConnectionHighCount" : 0,
      "WaitingForConnectionSuccessTotal" : 0,
      "WaitingForConnectionTotal" : 0,
      "WorkManagerRuntimes" : null
    }
}

JDBC Connection Pool: Find all JMS Servers with Target set to Managed Server Running at localhost:7003


http://localhost:7003/jolokia/read/com.bea:Name=emergencyDB,ServerRuntime=surf1,Type=JDBCConnectionPoolRuntime?ignoreErrors=true

which returns the JMS server surfJMS:

{ "request" : { "mbean" : "com.bea:Name=emergencyDB,ServerRuntime=surf1,Type=JDBCConnectionPoolRuntime",
      "type" : "read"
    },
  "status" : 200,
  "timestamp" : 1334823105,
  "value" : { "ActiveConnectionsAverageCount" : 0,
      "ActiveConnectionsCurrentCount" : 0,
      "ActiveConnectionsHighCount" : 0,
      "ConnectionDelayTime" : 44,
      "ConnectionLeakProfileCount" : 0,
      "ConnectionsTotalCount" : 1,
      "CurrCapacity" : 1,
      "DeploymentState" : 2,
      "Enabled" : true,
      "FailuresToReconnectCount" : 0,
      "HighestNumAvailable" : 1,
      "HighestNumUnavailable" : 0,
      "LeakedConnectionCount" : 0,
      "MaxCapacity" : 15,
      "ModuleId" : "emergencyDB",
      "Name" : "emergencyDB",
      "NumAvailable" : 1,
      "NumUnavailable" : 0,
      "Parent" : { "objectName" : "com.bea:Name=surf1,Type=ServerRuntime" },
      "PoolState" : true,
      "Properties" : "ERROR: MBean getAttribute failed: weblogic.common.resourcepool.ResourcePermissionsException: User \"\" does not have permission to perform operation \"admin\" on resource \"emergencyDB\" of module \"null\" of application \"null\" of type \"ConnectionPool\" (class javax.management.MBeanException)",
      "State" : "Running",
      "StatementProfileCount" : 0,
      "Type" : "JDBCConnectionPoolRuntime",
      "VersionJDBCDriver" : "org.apache.derby.jdbc.ClientDriver",
      "WaitSecondsHighCount" : 0,
      "WaitingForConnectionCurrentCount" : 0,
      "WaitingForConnectionHighCount" : 0,
      "WorkManagerRuntimes" : null
    }
}

JMS: Find all JMS Servers with Target set to Managed Server Running at localhost:7003

http://localhost:7003/jolokia/search/com.bea:Type=JMSServerRuntime,*

which returns the JMS server surfJMS:

{
   "timestamp":1334776840,
   "status":200,
   "request":{
      "mbean":"com.bea:Type=JMSServerRuntime,*",
      "type":"search"
   },
   "value":[
      "com.bea:Name=surfJMS,ServerRuntime=surf1,Type=JMSServerRuntime"
   ]
}

JMS: Runtime Properties for a Particular Queue

Request the MessagesCurrentCount, MessagesHighCount and MessagesReceivedCount for a queue with the name jms/ShippingRequestQueue (note the “!” is used in the URL to escape the “/” character in the queue name) in a JMS module with the name surfJMSModule (note that JMS module and queue name are typically separated in the MBean Name attribute with a “!” which has to be escaped by another “!”).

http://localhost:7003/jolokia/read/com.bea:JMSServerRuntime=surfJMS,Name=surfJMSModule!!jms!/ShippingRequestQueue,ServerRuntime=surf1,Type=JMSDestinationRuntime/MessagesCurrentCount,MessagesHighCount,MessagesReceivedCount

which returns the following JSON structure.

{
   "request":{
      "attribute":[
         "MessagesCurrentCount",
         "MessagesHighCount",
         "MessagesReceivedCount"
      ],
      "mbean":"com.bea:JMSServerRuntime=surfJMS,Name=surfJMSModule!jms/ShippingRequestQueue,ServerRuntime=surf1,Type=JMSDestinationRuntime",
      "type":"read"
   },
   "status":200,
   "timestamp":1334775025,
   "value":{
      "MessagesCurrentCount":0,
      "MessagesHighCount":1,
      "MessagesReceivedCount":3
   }
}

The output for the queue monitoring shows that there was a total of 3 messages sent, with a maximum of 1 in the queue (because of a deployed receiver retrieving the messages immediately) and currently 0 message in the queue.

 

Spicing up WebLogic RESTful Management with Jolokia

Management and monitoring of WebLogic resources is a day-to-day challenge for many administrators. Programming a management solution by writing JMX code in Java is a low-level and time consuming process which can be best avoided using the Jython based WebLogic scripting tool (WLST).

WLST is a higher level, domain specific language (DSL) especially developed to address management issues. A few lines of WLST code typically encapsulate hundreds of lines of Java code using JMX. Although WLST is compact and easy to write it still suffers from the “J” in JMX: Every time you execute a WLST script to monitor some attribute on the application server a JVM has to be started on the client side for WLST. This overhead can become quite substantial if you are monitoring many servers and retrieving attributes at regular intervals. In particular for monitoring systems such as Nagios (or the newer Shinken) the WLST approach is not suitable.

 

WebLogic 12c RESTful Management Service

One of the distinguishing new features of WebLogic 12c is its RESTful management service which can be enabled by a simple click under DOMAIN / Configuration / General / Advanced / Enable RESTful Management Services followed by a server restart.

Once enabled, you can access the most important WebLogic 12c runtime values using a simple URL syntax from your web browser or a Unix command line tool such as curl. For example you can retrieve runtime data of the administration server with fast HTTP request instead of spawning a JVM process for WLST:

http://localhost:7001/management/tenant-monitoring/servers/AdminServer/

Jolokia

 

Basics

WebLogic 12c RESTful management is an easy and convinient start, yet there is more possible. The open source framework Jolokia was named after of one of the the hottest chilis on the planet. Jolokia is the kind of chili that most people agree better not to eat (it’s still useful, e.g. to produce military grade tear gas and marine paint).

(Image source: courtesy of R. Huss / Jolokia)

The project is best described by the its developer:

“Jolokia is an agent based approach for remote JMX access. It is an alternative to standard JSR 160 connectors. The communication between client and agent goes over HTTP (either GET or POST), where the request and response payload is represented in JSON. The Jolokia protocol supports the following operations:

- Reading and writing JMX attributes

- Execution of JMX operations

- Searching for MBean Names by pattern

- Listing of MBean Meta-data like supported attributes, operations and notifications”

Installation

The installation process is well described at the Jolokia site. You can simply get the jolokia.war file from the Jolokia download site or the Maven central repository, nothing else is needed for WebLogic.

It’s even possible to use it without any deployment at all. Starting with JDK6 you can run it as an JVM agent, a technique typically used for profilers etc. So your java call starting WebLogic  has the following format:

java -javaagent:agent.jar ...

If you like to install the whole Jolokia project (including the JMX shell described later, the Nagios plugin, a Spring Roo addon etc)  on a UNIX system with Perl and CPAN already installed it can be as easy as:

[root@ccloud ~]# perl -MCPAN -e shell cpan shell -- CPAN exploration and modules installation (v1.9800)
cpan[1]> install JMX:Jmx4Perl
[... you have to confirm the installation of several dependencies ...]
cpan[2]> exit

After building the Jolokia module it can download the jolokia.war which is then deployed to WebLogic. In case you are playing with an admin server running in development only move it to the DOMAIN_NAME/autodeploy directory otherwise deploy it via the administration console to all servers in the domain:

oracle@ccloud [~]$ jolokia download

* Loading Jolokia meta data from http://www.jolokia.org/jolokia.meta
* Good PGP signature (EF101165)
* Using Jolokia 1.0.3 for Jmx4Perl 1.04
* Downloading war agent version 1.0.3 from repository http://labs.consol.de/maven/repository
* Saved ./jolokia.war
* Good PGP signature (EF101165)

Feature Comparison: Jolokia and WebLogic 12c RESTful Management Service

Now, how does Jolokia compare to what you already have out of the box in WebLogic 12c? Here is a short overview:

WebLogic 12c
Management Service

Jolokia

Installation Not required:
enable from admin console
Simple installation:
deploy prebuilt jolokia.war
Availability Only for WebLogic 12c Multi vendor, multi version support:

  • WebLogic 9 to 12c
  • Most other application servers
  • Mule agent
  • JVM agent
  • OSGi agent
Approach Central
(available on admin server only)
Can be distributed
(target on every server in domain)
Access syntax Easy, proprietary URL format Standard MBean name
Return format HTML, JSON, XML JSON
Accessible Data Servers, Clusters, Deployed Apps, DataSources
Not supported: JMS
All accessable MBeans and attributes
Security Requires authentication with
admin or monitor role
Standard web based security
(can be restricted to certain IPs, roles, HTTPprotocols, etc.)
Documentation Oracle documentation Very good online documentation
Access for single attributes only
example: HeapMemoryUsage
No Yes
Access for inner path
example HeapMemoryUsage/max
No Yes
Bulk requests No Yes
(One HTTPrequest for different MBeans is translated into multiple JMX requests within WebLogic JVM and yet one result is returned)
Additional utilities JMX shell j4psh
Nagios plugin check_jmx4perl

Jolokia Request

The GET URL for a Jolokia read request has the following format:

<base-url>/read/<mbean name>/<attribute name>/<inner path>

To get started just paste the following URL into your browser or use the Unix command line utility curl (assuming you have the admin server running at localhost:7001). It will retrieve the configured ListenPort attributes:

http://localhost:7001/jolokia/read/com.bea:*,Type=Server/ListenPort

which will return the following result for a WebLogic domain with 3 managed servers configured:

{ "request" : { "attribute" : "ListenPort",
      "mbean" : "com.bea:Type=Server,*",
      "type" : "read"
    },
  "status" : 200,
  "timestamp" : 1334776908,
  "value" : { "com.bea:Name=AdminServer,Type=Server" : { "ListenPort" : 7001 },
      "com.bea:Name=surf1,Type=Server" : { "ListenPort" : 7003 },
      "com.bea:Name=surf2,Type=Server" : { "ListenPort" : 7005 },
      "com.bea:Name=surf3,Type=Server" : { "ListenPort" : 7007 }
    }
}

Your response will be displayed in a single line. To get the format above you can past the result into one of the many online JSON formatters (or pipe the curl output to an appropriate utility).

Also I recommend to have a look at some examples about how to use Jolokia from JavaPerl and JavaScript.

Now continue reading part II of this posting with examples showing how to use Jolokia to retrieve monitoring values for servers, deployments, JDBC and JMS.

[This posting will be part of my upcoming WebLogic 12c book]