Pergunta

this is my first posted question. I have a fairly complicated OQL query which lists static fields of classes loaded in our packages. One problem I'm seeing with running the query against 'jhat' of Java 1.6.0_24 is that the 'unique' function doesn't work as expected. I expect

select unique(['a', 'b', 'c', 'a'])

to return ['a', 'b', 'c'] but instead it returns ['a'], wtf?

If anyone's interested the actual full query is (replace 'com.mydomain' with what you like):

select cl.name + ' -- ' + unique(map(filter(referees(cl), "classof(it).name != 'java.lang.Class' && classof(it).name != 'java.lang.String' && classof(it).name != 'sun.misc.Launcher$AppClassLoader' && classof(it).name != 'java.security.ProtectionDomain' && classof(it).name != '[Ljava.security.cert.Certificate;' && classof(it).name != 'sun.plugin2.applet.JNLP2ClassLoader'"), "classof(it).name")).join(', ')
from instanceof java.lang.Class cl
where /com.mydomain./(cl.name) && ! /com.mydomain.xs.protobuf./(cl.name)
&& length(filter(referees(cl), "classof(it).name != 'java.lang.Class' && classof(it).name != 'java.lang.String' && classof(it).name != 'sun.misc.Launcher$AppClassLoader' && classof(it).name != 'java.security.ProtectionDomain'")) > 0;
Foi útil?

Solução

By default, unique uniquifies on the object's objectid, which is suitable for actual traced objects, but for strings it returns null. Thus, only the last string is kept (since all the strings have non-unique objectid values).

You have two options:

  1. Uniquify on the traced objects, rather than their names:

    map(unique(filter(map(referees(cl), classof), "it.name != ...")), "it.name")
    
  2. Specify the "function" to uniquify with, so that it works for strings:

    unique(['a', 'b', 'c', 'a'], 'it')
    

    This will cause the strings themselves to be uniquified.

Licenciado em: CC-BY-SA com atribuição
Não afiliado a StackOverflow
scroll top