Select Page

Luis Colorado, Zia Consulting

Luis Colorado
Alfresco Software Engineer at Zia Consulting

What is an Alfresco JMX dump?

JMX dumps are a treasure trove of information about an Alfresco system. They contain most of the actual settings and internal properties plus other valuable information that will help you diagnose and troubleshoot problems in your system.

Unfortunately, Alfresco Community does not provide access to the JMX properties so it is not able to produce a JMX dump. However, much of the information provided by the dump can be found using the Order of the Bee Support Tools add-on.

Why do I want a JMX dump?

Reviewing a JMX dump is like having x-ray specs for your Alfresco system. Although Alfresco 5.2 and later provide much of that information in the admin console, the JMX dump provides additional details and has other uses and advantages:

  • For auditing and keeping a record of the configuration of your system.
  • For automation it can be generated from the command line or a script so a scheduled program can monitor for certain conditions.
  • There is no need to install anything.

How to obtain a JMX dump

JMX dumps can be obtained using the web browser user interface or using a command line. Each version of Alfresco has slightly different methods to generate the dump, so you may want to take a look at the specific instructions for your version.

From the command line or a program, you have two options to get a JMX dump:

      • With curl you can use a simple command line to get the JMX dump:

        curl -o jmxdump.zip -u {admin_user}:{admin_password} https://{host}:{port}/alfresco/s/api/admin/jmxdump

        If you are using Linux, you probably have it already available. For Windows, you would need to download this useful tool.

         

      • Executing a REST call with your favorite tool or language:

      GET /alfresco/service/api/admin/jmxdump

Just remember that Alfresco returns the JMX dump as a compressed zip file. If you are developing a script, you will have to add a step to your program to decompress it.

Understanding the JMX dump report

You may be shocked the first time that you open a JMX dump. What you see looks pretty chaotic and cryptic, perhaps with some familiar words here and there. Below is an example of the first lines which may be a bit different from yours:

JmxDumpUtil started: April 13, 2019 7:14:32 PM GMT

Attribute Name Attribute Value

————– ————————————————-

** Object Name Alfresco:Name=Authority

** Object Type org.alfresco.enterprise.repo.management.Authority

NumberOfGroups 10

NumberOfUsers  4


After the first line with the title and timestamp, you will notice the first
object listed in the report. This is one of the myriad JMX managed beans exposed in Alfresco (for convenience, I will call them simply “objects”). The report shows the following kinds of attributes for each object:

  • The Object Name and Object Type. The combination of name and type strings are unique in the report, and refer to a particular object (bean) in memory.
  • The properties. In the example above, we see two properties: NumberOfGroups and NumberOfUsers with the numeric values of 10 and 4, respectively. The properties can also be strings, booleans, etc.

We will explain in detail this simple object later. Other objects may have dozens of properties, and some properties may contain long lists, strings with large XML, or JSON data structures. The JMX dump may look intimidating at some points but remember that, in the end, it’s just a large list of Alfresco objects.

In this article we discuss a relatively small number of objects with useful properties explaining what information is useful and how to find it in the output.

Before we get to the goodies, an important note:

Configuring Alfresco: alfresco-global.properties versus admin console

Although the JMX dump lists the settings in alfresco-global.properties (see object GlobalProperties later in this article), the values for some properties may have been overridden by the admin console or by using a JMX client. You may want to review our article about best practices using the admin console to learn more about properties saved to the database using JMX.

If you notice that changing a value in alfresco-global.properties doesn’t seem to work, that may mean that the property was set using the admin console. However, you can still find its actual value in the admin console or the JMX dump.

Finding the object with the actual value of a property in the JMX dump may be tricky, but often the name of the property in alfresco-global.properties and the object have similar or identical names. For example, the property solr.host has the same name in alfresco-global.properties and the object with the settings for Solr, which is named Alfresco:Type=Configuration,Category=Search,id1=managed,id2=solr.

As a corollary, I must say that you would normally not change settings using the admin console and especially not in production. There are some exceptions which are discussed in more detail in our article about best practices using the admin console.

Time to dig in!

Now, let’s take a look at some of the most useful objects in the JMX dump report.

The settings in alfresco-global.properties

The object GlobalProperties contains the properties as defined in the file tomcat/shared/classes/alfresco-global.properties, and other properties files under that directory:

** Object Name: Alfresco:Name=GlobalProperties

** Object Type: org.alfresco.enterprise.repo.management.PropertiesDynamicMBean

This object lists many more properties than your file alfresco-global.properties because it includes all the default properties. As mentioned before, the settings listed in this list may be overridden by the settings defined using the admin console or a JMX client such as JConsole.

Status of the Alfresco license

** Object Name: Alfresco:Name=License
** Object Type: org.alfresco.enterprise.repo.management.LicenseDescriptor

The property currentUsers contains the number of users who have not been deauthorized. Keep in mind that a user may have been deleted but will continue to count against your license limit unless you deactivate it. Why is this? Alfresco designed this to avoid user pooling where users are added and deleted to cheat the license limit. Undeleting a user is easy, but reactivating a user requires a special code from Alfresco support.

The property ValidUntil shows the expiration date of the license.

Java Memory and Options

** Object Name: java.lang:type=Runtime
** Object Type: sun.management.RuntimeImpl

The InputArguments show the effective Java options. The most important argument is -Xmx, which has the maximum memory heap size.

Actions

** Object Name: Alfresco:Name=RunningActions
** Object Type: org.alfresco.enterprise.repo.management.ActionsImpl

The object RunningActions contains the enabled actions in your repository. You will not only find your custom actions but also Alfresco’s own actions. As a bonus, you also get interesting statistics such as the average time to complete, the number of invocations, and the number of executions with errors.

Slow requests

** Object Name: Catalina:type=RequestProcessor,worker="http-apr-8080",name=HttpRequest1
** Object Type: org.apache.tomcat.util.modeler.BaseModelMBean

This is an interesting type of object. You may see hundreds of this RequestProcessor objects. Each Tomcat request processor accepts incoming messages on a separate thread. If you search for the string “RequestProcessor” you will see the many Tomcat processors (threads) waiting for requests. You will notice that the worker shows the type of connection (for example, ajp or http) and the port (for example, 8009, 8080, 8443).

Each thread has a wealth of information and statistics. We can’t cover all of them right now, but you will find two interesting properties that will show data about the slow requests for each thread:

  • MaxRequestUri. This is the slowest URI for this thread.
  • maxTime. The maximum time to respond to the MaxRequestURI in milliseconds.

Logging settings

The following object contains the list of all the logging settings:

** Object Name: Alfresco:Name=Log4jHierarchy
** Object Type: org.apache.log4j.jmx.HierarchyDynamicMBean

For each line, you will find a corresponding object with the logging level. For example, for the following line:

logger=org.alfresco.repo.content.transform.TransformerDebug            log4j:logger=org.alfresco.repo.content.transform.TransformerDebug

The corresponding object is the following:

** Object Name: log4j:logger=org.alfresco.repo.content.transform.TransformerDebug
** Object Type: org.apache.log4j.jmx.LoggerDynamicMBean

The priority may be DEBUG, WARN, etc., although in most cases it will be , that is, undefined. This is one of the few cases where you want to use admin console in production. As mentioned in the documentation, you can also use jconsole or some other JMX client to change logging. You can find more details in our article about best practices using admin console.

Database configuration and connections

There are two objects with useful information about the database. The ConnectionPool shows the connection limit (maxActive), the number of active connections (NumActive), and the connection string (Url) as defined in alfresco-global.properties:

** Object Name: Alfresco:Name=ConnectionPool
** Object Type: org.apache.commons.dbcp.BasicDataSource

The DatabaseInformation object (shown below) has low-level information about the driver and the full connection string (URL) including the default settings:

** Object Name: Alfresco:Name=DatabaseInformation
** Object Type: org.alfresco.enterprise.repo.management.Database

What modules are installed

** Object Name: Alfresco:Name=ModuleService
** Object Type: org.alfresco.enterprise.repo.management.ModuleService

The property AllModules contains the list with all the installed modules. It is useful to check the installation date (module.installDate), if the module was installed but absent (module.installState=UNKNOWN), the target version (module.repo.version.min and max), and the module.version.

What version of ImageMagick is installed

** Object Name: Alfresco:Name=ContentTransformer,Type=ImageMagick
** Object Type: org.alfresco.repo.content.transform.ContentTransformerWorker

The VersionString shows the version of ImageMagick.

LibreOffice and JODConverter

Usually it is better to perform the transformation of Office documents using the JODConverter, which not only starts and stops LibreOffice as required, but works around some of its quirks. The alternative would be to call LibreOffice directly to perform the transformation but it is not as stable and dependable as using the JODConverter. It is a good idea to check the LibreOffice/OpenOffice object to make sure that it is not enabled for direct calls (ooo.enabled=false):

** Object Name: Alfresco:Type=Configuration,Category=OOoDirect,id1=default
** Object Type: OOoDirect$default

It is a good idea to confirm the property ooo.exe points to the right soffice.bin program.

Once you have found the location of LibreOffice, you can use the following command:

     {path_to_ooo.exe}/soffice.bin --version

Finally, it is important to confirm that the JODConverter is enabled in the following object:

** Object Name: Alfresco:Type=Configuration,Category=OOoJodconverter,id1=default

** Object Type: OOoJodconverter$default

The property jodconverter.enabled should be true.

Location of the SSL key stores

It is very easy to lose track of the actual location of the key store, especially when you upgrade Alfresco. The following objects have the location of the different stores used by authentication and encryption:

** Object Name: Alfresco:Name=Encryption,KeyStore=Key Store
** Object Name: Alfresco:Name=Encryption,KeyStore=SSL Key Store ** Object Name: Alfresco:Name=Encryption,KeyStore=SSL Trust Store

Current and enabled users

** Object Name: Alfresco:Name=Authority

** Object Type: org.alfresco.enterprise.repo.management.Authority


This object has the NumberOfGroups and NumberOfUsers. The latter has a count of all the users, including those authorized or not (see the discussion about authorized users in the documentation). This NumberOfUsers does not count against your license limit.

In contrast, within the object License, which we discussed earlier, the CurrentUsers has the number of authorized users, that is, the number of users that count against your license. Note that deleting a user is not enough to reduce this count, you have to deauthorize it. As you would expect, CurrentUsers should not exceed MaxUsers.

Scheduled jobs

Alfresco has numerous jobs that run based on a periodic schedule. The name of the objects for those scheduled jobs start with “Name=Schedule…” in the JMX dump. For example, the following job starts a backup of the Solr index of the main content store:

** Object Name: Alfresco:Name=Schedule,Group=DEFAULT,Type=MonitoredCronTrigger,Trigger=search.alfrescoCoreBackupTrigger
** Object Type: org.alfresco.enterprise.scheduler.MonitoredRAMJobStore$MonitoredCronTrigger

You can use the CronExpression, MayFireAgain, and NextFireTime in the schedule object to make sure  that it is an active job. PreviousFireTime and NextFireTime have the last and next starting time of the job. StartTime has the time when the job scheduled was started which is usually about the time when Alfresco started. The most important property is cronExpression which contains a Quartz cron expression to schedule the execution of the jobs. You can find the meaning of each expression, or build your own, using one of the online tools available on the web.

You can trigger scheduled jobs (like LDAP sync.) using a JMX client such as JConsole. This particular use case is now possible via the admin console, but under the hood it’s just triggering the associated JMX operation.

Conclusion

JMX dumps contain most of the actual settings and internal properties of an enterprise Alfresco system plus other valuable information to document, diagnose, and troubleshoot problems. Do yourself a favor and get a fresh JMX dump today for your records—before you upgrade Alfresco or change your configuration.

Pin It on Pinterest

Sharing is caring

Share this post with your friends!