Eclipse MAT OQL 某个包中的类列表

Posted

技术标签:

【中文标题】Eclipse MAT OQL 某个包中的类列表【英文标题】:Eclipse MAT OQL list of classes in a certain package 【发布时间】:2020-07-28 19:28:59 【问题描述】:

使用 Eclipse MAT 1.9.1 OQL

我想列出某个包中堆转储中的所有类。

我正在尝试查询:

SELECT c.getName() as name, c.getName().indexOf("com.mycompany") as idx FROM java.lang.Class c WHERE idx > 0 

得到:

java.lang.NullPointerException: idx at org.eclipse.mat.parser.internal.oql.compiler.Operation$GreaterThan.evalNull(Operation.java:232) 在 org.eclipse.mat.parser.internal.oql.compiler.Operation$RelationalOperation.compute(Operation.java:92) 在 org.eclipse.mat.parser.internal.oql.OQLQueryImpl.accept(OQLQueryImpl.java:1161) 在 org.eclipse.mat.parser.internal.oql.OQLQueryImpl.accept(OQLQueryImpl.java:1151) 在 org.eclipse.mat.parser.internal.oql.OQLQueryImpl.filterClasses(OQLQueryImpl.java:1133) 在 org.eclipse.mat.parser.internal.oql.OQLQueryImpl.doFromItem(OQLQueryImpl.java:921) 在 org.eclipse.mat.parser.internal.oql.OQLQueryImpl.internalExecute(OQLQueryImpl.java:690) 在 org.eclipse.mat.parser.internal.oql.OQLQueryImpl.execute(OQLQueryImpl.java:667) 在 org.eclipse.mat.inspections.OQLQuery.execute(OQLQuery.java:52) 在 org.eclipse.mat.inspections.OQLQuery.execute(OQLQuery.java:1) 在 org.eclipse.mat.query.registry.ArgumentSet.execute(ArgumentSet.java:132) 在 org.eclipse.mat.ui.snapshot.panes.OQLPane$OQLJob.doRun(OQLPane.java:468) 在 org.eclipse.mat.ui.editor.AbstractPaneJob.run(AbstractPaneJob.java:34) 在 org.eclipse.core.internal.jobs.Worker.run(Worker.java:60)

请指教。

【问题讨论】:

【参考方案1】:

该查询有几处错误。 idxSELECT c.getName() as name, c.getName().indexOf("com.mycompany") as idx FROM java.lang.Class c WHERE idx > 0 是列名,因此对 WHERE 子句不可见。 OQL 评估FROM 子句首先选择对象列表,然后c 变量对WHERE 子句可见,其中检查每个对象以查看它是否将传递给SELECT 子句。 所以试试:

SELECT c.getName() as name, c.getName().indexOf("com.mycompany") as idx FROM java.lang.Class c WHERE c.getName().indexOf("com.mycompany") > 0

但失败的原因是:

Problem reported: 
Method getName() not found in object java.lang.Class [id=0x6c027f2c8] of type org.eclipse.mat.parser.model.InstanceImpl

因为堆转储中的一些 java.lang.Class 对象实际上不是可以具有实例的普通类,而是 java.lang.Class 类型的普通对象实例。这听起来很奇怪,但这些对象是byte,short,int,long,float,double,char,boolean,void。它们仅用于描述反射的类和方法 - 但它们的实例不能存在。

堆转储中的 MAT 对象内部表示为 org.eclipse.mat.snapshot.model.IObject 和一些也是org.eclipse.mat.snapshot.model.IClass 的子类型。我们需要排除上述 9 个特殊对象。我已将您的查询更改为查找 com.sun,因为我的转储中没有 com.mycompany 对象。

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))

这仍然不起作用,因为如果类名以 'com.sun' 开头,则索引将为 0 并且将无法通过测试。更改测试运算符:

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))

这现在可以工作并找到一些类。

我们可以通过使用属性表示法稍微简化查询,其中@val 是一个bean 自省,相当于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)) 

【讨论】:

以上是关于Eclipse MAT OQL 某个包中的类列表的主要内容,如果未能解决你的问题,请参考以下文章

线程堆栈通过 MAT OQL 归档

怎么引用jar包中的类

Java eclipse中创建项目以后缺省包和命名的包有啥区别?

怎么在java项目中调自定义的jar包中的类?

在MyEclipse中如何用查看引用的jar包中的class文件的java源代码

Java 包(package)