Liferay CE 7.x / Liferay DXP 7.x Java Agents

Using a monitoring agent requires a little extra setup...

A SysAdmin came up to me and said he was having issues starting Liferay DXP 7.0, a bunch of CNFEs were coming up at startup.

I found that they were set up to use Wily for monitoring their JVMs, and it was those classes that were generating CNFEs.

In general, when you add the -Djavaagent=XXX parameter onto your app server's startup command, you're enabling an agent which will have full access inside of the JVM, but only as long as the class loader hierarchy is available. The classes in the agent are injected into the highest point of the class loader hierarchy so they are normally visible across the entire app server.

Except, of course, for Liferay's OSGi container.

Liferay takes great care when creating the OSGi container to limit the "pollution" of the OSGi container's class loader to prevent classes from the app server leaking in as global classes in the OSGi container.

For monitoring agents, though, the agent packages will not be available within OSGi even though the agent is still going to try to inject itself into object instantiation.

This leads to all of the ClassNotFoundExceptions for missing packages/classes during startup.

Enabling Agent Monitoring in OSGi

We can actually enable the agent inside of the OSGi container, but it takes an additional configuration step.

In our portal-ext.properties file, we need to add the packages from the agent to the module.framework.properties.org.osgi.framework.bootdelegation property.

Note here that I said "add".  You can't just say module.framework.properties.org.osgi.framework.bootdelegation=com.agent.* and think it is going to work out because that strips out all of the other packages Liferay normally passes through the boot delegation.

To find your list, you need your portal.properties file or access to the portlet properties panel in the System Administration control panel (or from Github or from your copy of your DXP source or ...).  Using the existing value as the guide, you'll end up with a value like:

module.framework.properties.org.osgi.framework.bootdelegation=\
  __redirected,\
  com.liferay.aspectj,\
  com.liferay.aspectj.*,\
  com.liferay.portal.servlet.delegate,\
  com.liferay.portal.servlet.delegate*,\
  com.sun.ccpp,\
  com.sun.ccpp.*,\
  com.sun.crypto.*,\
  com.sun.image.*,\
  com.sun.jmx.*,\
  com.sun.jna,\
  com.sun.jndi.*,\
  com.sun.mail.*,\
  com.sun.management.*,\
  com.sun.media.*,\
  com.sun.msv.*,\
  com.sun.org.*,\
  com.sun.syndication,\
  com.sun.tools.*,\
  com.sun.xml.*,\
  com.yourkit.*,\
  sun.*,\
  com.agent.*

See how I tacked on the "com.agent.*" at the end of the list?

You'll of course change the "com.agent" stuff to match whatever package your particular agent is using, but hopefully you get the idea.

Update

Hey, so this covers what you need to do, but I didn't really help out with what packages you need to use to replace the com.agent stuff with.

So help me fill this table.  We'll use the product on one side, the package(s) you need on the other side. Just use the values for your APM tool.

I'll start the table here, add a comment with yours and we'll flush this out...

Product Package(s)
AppDynamics com.singularity.*
Manage Engine APM Insight  com.manageengine.apminsight.*
Glowroot org.glowroot.agent, org.glowroot.agent.*
Elastic APM co.elastic.apm.agent.*

 

Blogs

Thank for this article, it came handy at the right time.

You could add elasticSearch APM: co.elastic.apm.agent.*