using Eclipse MAT 1.9.1 OQL
I want to list all the classes in the heap dump in a certain package.
I am trying the query:
SELECT c.getName() as name, c.getName().indexOf("com.mycompany") as idx FROM java.lang.Class c WHERE idx > 0
getting:
java.lang.NullPointerException: idx at org.eclipse.mat.parser.internal.oql.compiler.Operation$GreaterThan.evalNull(Operation.java:232) at org.eclipse.mat.parser.internal.oql.compiler.Operation$RelationalOperation.compute(Operation.java:92) at org.eclipse.mat.parser.internal.oql.OQLQueryImpl.accept(OQLQueryImpl.java:1161) at org.eclipse.mat.parser.internal.oql.OQLQueryImpl.accept(OQLQueryImpl.java:1151) at org.eclipse.mat.parser.internal.oql.OQLQueryImpl.filterClasses(OQLQueryImpl.java:1133) at org.eclipse.mat.parser.internal.oql.OQLQueryImpl.doFromItem(OQLQueryImpl.java:921) at org.eclipse.mat.parser.internal.oql.OQLQueryImpl.internalExecute(OQLQueryImpl.java:690) at org.eclipse.mat.parser.internal.oql.OQLQueryImpl.execute(OQLQueryImpl.java:667) at org.eclipse.mat.inspections.OQLQuery.execute(OQLQuery.java:52) at org.eclipse.mat.inspections.OQLQuery.execute(OQLQuery.java:1) at org.eclipse.mat.query.registry.ArgumentSet.execute(ArgumentSet.java:132) at org.eclipse.mat.ui.snapshot.panes.OQLPane$OQLJob.doRun(OQLPane.java:468) at org.eclipse.mat.ui.editor.AbstractPaneJob.run(AbstractPaneJob.java:34) at org.eclipse.core.internal.jobs.Worker.run(Worker.java:60)
Please advise.
There are several things wrong with that query. idx
in
SELECT c.getName() as name, c.getName().indexOf("com.mycompany") as idx FROM java.lang.Class c WHERE idx > 0
is a column name, so is not visible to the WHERE
clause.
OQL evaluates the FROM
clause first selecting a list of objects, then the c
variable is visible to the WHERE
clause where each of the objects is examined to see if it will be passed to the SELECT
clauses.
So try:
SELECT c.getName() as name, c.getName().indexOf("com.mycompany") as idx FROM java.lang.Class c WHERE c.getName().indexOf("com.mycompany") > 0
but that fails for the reason:
Problem reported:
Method getName() not found in object java.lang.Class [id=0x6c027f2c8] of type org.eclipse.mat.parser.model.InstanceImpl
because some java.lang.Class objects in the heap dump are in fact not ordinary classes which could have instances, but plain object instances of type java.lang.Class. That sounds odd, but those objects are byte
,short
,int
,long
,float
,double
,char
,boolean
,void
. They are just used to describe classes and methods for reflection - but instances of those can't exist.
Inside of MAT objects in the heap dump are represented as
org.eclipse.mat.snapshot.model.IObject
and some are also of a subtype org.eclipse.mat.snapshot.model.IClass
. We need to exclude those 9 special objects above. I've changed your query to look for com.sun as my dumps won't have com.mycompany objects.
SELECT c.getName() AS name, c.getName().indexOf("com.sun") AS idx
FROM java.lang.Class c
WHERE ((c implements org.eclipse.mat.snapshot.model.IClass) and (c.getName().indexOf("com.sun") > 0))
This still doesn't work, because if the class name starts with 'com.sun' the index will be 0 and will fail the test. Change the test operator:
SELECT c.getName() AS name, c.getName().indexOf("com.sun") AS idx
FROM java.lang.Class c
WHERE ((c implements org.eclipse.mat.snapshot.model.IClass) and (c.getName().indexOf("com.sun") >= 0))
This now works and finds some classes.
We can simplify the query a little by using attribute notation, where @val is a bean introspection which is the equivalent of getVal().
SELECT c.@name AS name, c.@name.indexOf("com.sun") AS idx
FROM java.lang.Class c
WHERE ((c implements org.eclipse.mat.snapshot.model.IClass) and (c.getName().indexOf("com.sun") >= 0))