Eclipse MAT OQL list of classes in a certain package

1.2k views Asked by At

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.

1

There are 1 answers

0
user13762112 On BEST ANSWER

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, [email protected]("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))