Eclipse MAT OQL中特定包中的类列表

huangapple go评论93阅读模式
英文:

Eclipse MAT OQL list of classes in a certain package

问题

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

请建议。

英文:

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

得分: 3

以下是您要翻译的内容:

有几个问题存在于这个查询中。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

但是由于以下原因,它会失败:

报告的问题:
在对象 java.lang.Class [id=0x6c027f2c8] 中未找到 getName() 方法,类型为 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))


<details>
<summary>英文:</summary>

There are several things wrong with that query. `idx` in 
`SELECT c.getName() as name, c.getName().indexOf(&quot;com.mycompany&quot;) as idx FROM java.lang.Class c WHERE idx &gt; 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(&quot;com.mycompany&quot;) as idx FROM java.lang.Class c WHERE c.getName().indexOf(&quot;com.mycompany&quot;) &gt; 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&#39;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&#39;ve changed your query to look for com.sun as my dumps won&#39;t have com.mycompany objects.

    SELECT c.getName() AS name, c.getName().indexOf(&quot;com.sun&quot;) AS idx 
    FROM java.lang.Class c 
    WHERE ((c implements org.eclipse.mat.snapshot.model.IClass) and (c.getName().indexOf(&quot;com.sun&quot;) &gt; 0))
    
This still doesn&#39;t work, because if the class name starts with &#39;com.sun&#39; the index will be 0 and will fail the test. Change the test operator:

    SELECT c.getName() AS name, c.getName().indexOf(&quot;com.sun&quot;) AS idx 
    FROM java.lang.Class c 
    WHERE ((c implements org.eclipse.mat.snapshot.model.IClass) and (c.getName().indexOf(&quot;com.sun&quot;) &gt;= 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(&quot;com.sun&quot;) AS idx 
    FROM java.lang.Class c 
    WHERE ((c implements org.eclipse.mat.snapshot.model.IClass) and (c.getName().indexOf(&quot;com.sun&quot;) &gt;= 0)) 



</details>



huangapple
  • 本文由 发表于 2020年7月29日 03:28:59
  • 转载请务必保留本文链接:https://go.coder-hub.com/63141472.html
匿名

发表评论

匿名网友

:?: :razz: :sad: :evil: :!: :smile: :oops: :grin: :eek: :shock: :???: :cool: :lol: :mad: :twisted: :roll: :wink: :idea: :arrow: :neutral: :cry: :mrgreen:

确定