Pregunta

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;
¿Fue útil?

Solución

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 bajo: CC-BY-SA con atribución
No afiliado a StackOverflow
scroll top