blob: 7ebdd4880679bbb66eb4a8b1169a681fad369fe9 [file] [log] [blame]
J. Duke319a3b92007-12-01 00:00:00 +00001<!--
2Copyright 2005-2006 Sun Microsystems, Inc. All Rights Reserved.
3DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
4
5This code is free software; you can redistribute it and/or modify it
6under the terms of the GNU General Public License version 2 only, as
7published by the Free Software Foundation. Sun designates this
8particular file as subject to the "Classpath" exception as provided
9by Sun in the LICENSE file that accompanied this code.
10
11This code is distributed in the hope that it will be useful, but WITHOUT
12ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
13FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
14version 2 for more details (a copy is included in the LICENSE file that
15accompanied this code).
16
17You should have received a copy of the GNU General Public License version
182 along with this work; if not, write to the Free Software Foundation,
19Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
20
21Please contact Sun Microsystems, Inc., 4150 Network Circle, Santa Clara,
22CA 95054 USA or visit www.sun.com if you need additional information or
23have any questions.
24-->
25
26<html>
27<head>
28<style>
29.key { color: red; font-weight: bold }
30</style>
31<title>
32Object Query Language (OQL)
33</title>
34</head>
35<body>
36<h1>Object Query Language (OQL)</h1>
37
38<p>
39OQL is SQL-like query language to query Java heap. OQL allows to filter/select information
40wanted from Java heap. While pre-defined queries such as "show all instances of class X"
41are already supported by HAT, OQL adds more flexibility. OQL is based on JavaScript expression
42language.
43</p>
44
45<p>
46OQL query is of the form
47
48<pre>
49<code>
50 <span class="key">select</span> &lt;JavaScript expression to select&gt;
51 [ <span class="key">from</span> [<span class="key">instanceof</span>] &lt;class name&gt; &lt;identifier&gt;
52 [ <span class="key">where</span> &lt;JavaScript boolean expression to filter&gt; ] ]
53</code>
54</pre>
55where class name is fully qualified Java class name (example: java.net.URL) or array class name.
56[C is char array name, [Ljava.io.File; is name of java.io.File[] and so on.
57Note that fully qualified class name does not always uniquely identify a
58Java class at runtime. There may be more than one Java class with the same
59name but loaded by different loaders. So, class name is permitted to be
60id string of the class object.
61
62If <span class="key">instanceof</span> keyword is used, subtype objects are selected. If this
63keyword is not specified, only the instances of exact class specified are selected. Both
64<span class="key">from</span> and <span class="key">where</span> clauses are optional.
65</p>
66
67
68<p>
69In <span class="key">select</span> and (optional) <span class="key">where</span> clauses, the expression
70used in JavaScript expression. Java heap objects are wrapped as convenient script objects so that
71fields may be accessed in natural syntax. For example, Java fields can be accessed with obj.field_name
72syntax and array elements can be accessed with array[index] syntax. Each Java object selected is
73bound to a JavaScript variable of the identifier name specified in <span class="key">from</span> clause.
74</p>
75
76<h2>OQL Examples</h2>
77
78<ul>
79<li>select all Strings of length 100 or more
80<pre>
81<code>
82 select s from java.lang.String s where s.count >= 100
83</code>
84</pre>
85<li>select all int arrays of length 256 or more
86<pre>
87<code>
88 select a from [I a where a.length >= 256
89</code>
90</pre>
91<li>show content of Strings that match a regular expression
92<pre>
93<code>
94 select s.value.toString() from java.lang.String s
95 where /java/(s.value.toString())
96</code>
97</pre>
98<li>show path value of all File objects
99<pre>
100<code</b>
101 select file.path.value.toString() from java.io.File file
102</code>
103</pre>
104<li>show names of all ClassLoader classes
105<pre>
106<code>
107 select <a href="#classof">classof</a>(cl).name
108 from instanceof java.lang.ClassLoader cl
109</code>
110</pre>
111<li>show instances of the Class identified by given id string
112<pre>
113<code>
114 select o from instanceof 0xd404b198 o
115</code>
116</pre>
117Note that 0xd404b198 is id of a Class (in a session). This is found by
118looking at the id shown in that class's page.
119</ul>
120
121<h2>OQL built-in objects, functions</h2>
122
123<h3>heap object</h3>
124
125The <b>heap</b> built-in object supports the following methods:
126
127<ul>
128<li><b>heap.forEachClass</b> -- calls a callback function for each Java Class
129<pre>
130<code>
131 heap.forEachClass(callback);
132</code>
133</pre>
134<li><b>heap.forEachObject</b> -- calls a callback function for each Java object
135<pre>
136<code>
137 heap.forEachObject(callback, clazz, includeSubtypes);
138</code>
139</pre>
140<code>clazz</code> is the class whose instances are selected. If not specified, defaults to java.lang.Object. <code>includeSubtypes</code> is a boolean flag
141that specifies whether to include subtype instances or not. Default value of
142this flag is true.
143<a name="findClass"></a>
144<li><b>heap.findClass</b> -- finds Java Class of given name
145<pre>
146<code>
147 heap.findClass(className);
148</code>
149</pre>
150where <code>className</code> is name of the class to find. The resulting Class
151object has following properties:
152<ul>
153<li>name - name of the class.
154<li>superclass - Class object for super class (or null if java.lang.Object).
155<li>statics - name, value pairs for static fields of the Class.
156<li>fields - array of field objects. field object has name, signature
157properties.
158<li>loader - ClassLoader object that loaded this class.
159<li>signers - signers that signed this class.
160<li>protectionDomain - protection domain to which this class belongs.
161</ul>
162Class objects have the following methods:
163<ul>
164<li>isSubclassOf - tests whether given class is direct or indirect
165subclass of this class or not.
166<li>isSuperclassOf - tests whether given Class is direct or indirect
167superclass of this class or not.
168<li>subclasses - returns array of direct and indirect subclasses.
169<li>superclasses - returns array of direct and indirect superclasses.
170</ul>
171<a name="findObject"></a>
172<li><b>heap.findObject</b> -- finds object from given object id
173<pre>
174<code>
175 heap.findObject(stringIdOfObject);
176</code>
177</pre>
178<a name="classes"></a>
179<li><b>heap.classes</b> -- returns an enumeration of all Java classes
180<a name="objects"></a>
181<li><b>heap.objects</b> -- returns an enumeration of Java objects
182<pre>
183<code>
184 heap.objects(clazz, [includeSubtypes], [filter])
185</code>
186</pre>
187<code>clazz</code> is the class whose instances are selected. If not specified, defaults to java.lang.Object. <code>includeSubtypes</code> is a boolean flag
188that specifies whether to include subtype instances or not. Default value of
189this flag is true. This method accepts an optional filter expression to filter
190the result set of objects.
191<a name="finalizables"></a>
192<li><b>heap.finalizables</b> -- returns an enumeration of Java objects that are
193pending to be finalized.
194<li><b>heap.livepaths</b> -- return an array of paths by which a given object
195is alive. This method accepts optional second parameter that is a boolean
196flag. This flag tells whether to include paths with weak reference(s) or not.
197By default, paths with weak reference(s) are not included.
198<pre>
199<code>
200 select heap.livepaths(s) from java.lang.String s
201</code>
202</pre>
203Each element of this array itself is another array. The later array is
204contains an objects that are in the 'reference chain' of the path.
205<li><b>heap.roots</b> -- returns an Enumeration of Roots of the heap.
206<a name="rootobj"></a>
207Each Root object has the following properties:
208<ul>
209<li>id - String id of the object that is referred by this root
210<li>type - descriptive type of Root (JNI Global, JNI Local, Java Static etc)
211<li>description - String description of the Root
212<li>referrer - Thread Object or Class object that is responsible for this root or null
213</ul>
214</ul>
215
216Examples:
217<ul>
218<li>access static field 'props' of class java.lang.System
219<pre>
220<code>
221 select heap.findClass("java.lang.System").statics.props
222 select heap.findClass("java.lang.System").props
223</code>
224</pre>
225<li>get number of fields of java.lang.String class
226<pre>
227<code>
228 select heap.findClass("java.lang.String").fields.length
229</code>
230</pre>
231<li> find the object whose object id is given
232<pre>
233<code>
234 select heap.findObject("0xf3800b58")
235</code>
236</pre>
237<li>select all classes that have name pattern java.net.*
238<pre>
239<code>
240 select <a href="#filter">filter</a>(heap.classes(), "/java.net./(it.name)")
241</code>
242</pre>
243</ul>
244
245<h3>functions on individual objects</h3>
246
247<ul>
248<li><a href="#allocTrace">allocTrace(jobject)</a>
249<li><a href="#classof">classof(jobject)</a>
250<li><a href="#forEachReferrer">forEachReferrer(callback, jobject)</a>
251<li><a href="#identical">identical(o1, o2)</a>
252<li><a href="#objectid">objectid(jobject)</a>
253<li><a href="#reachables">reachables(jobject, excludedFields)</a>
254<li><a href="#referrers">referrers(jobject)</a>
255<li><a href="#referees">referees(jobject)</a>
256<li><a href="#refers">refers(jobject)</a>
257<li><a href="#root">root(jobject)</a>
258<li><a href="#sizeof">sizeof(jobject)</a>
259<li><a href="#toHtml">toHtml(obj)</a>
260</ul>
261
262<a name="allocTrace"></a>
263<h4>allocTrace function</h4>
264
265This returns allocation site trace of a given Java object if available.
266allocTrace returns array of frame objects. Each frame object has the following
267properties:
268<ul>
269<li>className - name of the Java class whose method is running in the frame.
270<li>methodName - name of the Java method running in the frame.
271<li>methodSignature - signature of the Java method running in the frame.
272<li>sourceFileName - name of source file of the Java class running in the frame.
273<li>lineNumber - source line number within the method.
274</ul>
275
276<a name="classof"></a>
277<h4>classof function</h4>
278
279Returns Class object of a given Java Object. The result object supports the
280following properties:
281<ul>
282<li>name - name of the class.
283<li>superclass - Class object for super class (or null if java.lang.Object).
284<li>statics - name, value pairs for static fields of the Class.
285<li>fields - array of field objects. Field objects have name, signature
286properties.
287<li>loader - ClassLoader object that loaded this class.
288<li>signers - signers that signed this class.
289<li>protectionDomain - protection domain to which this class belongs.
290</ul>
291Class objects have the following methods:
292<ul>
293<li>isSubclassOf - tests whether given class is direct or indirect
294subclass of this class or not.
295<li>isSuperclassOf - tests whether given Class is direct or indirect
296superclass of this class or not.
297<li>subclasses - returns array of direct and indirect subclasses.
298<li>superclasses - returns array of direct and indirect superclasses.
299</ul>
300
301Examples:
302<ul>
303<li>show class name of each Reference type object
304<pre>
305<code>
306 select classof(o).name from instanceof java.lang.ref.Reference o
307</code>
308<li>show all subclasses of java.io.InputStream
309<pre>
310<code>
311 select heap.findClass("java.io.InputStream").subclasses()
312</code>
313<li>show all superclasses of java.io.BufferedInputStream
314<pre>
315<code>
316 select heap.findClass("java.io.BufferedInputStream").superclasses()
317</code>
318</pre>
319</ul>
320
321<a name="forEachReferrer"></a>
322<h4>forEachReferrer function</h4>
323
324calls a callback function for each referrer of a given Java object.
325
326<a name="identical"></a>
327<h4>identical function</h4>
328<p>
329Returns whether two given Java objects are identical or not.
330</p>
331Example:
332<pre>
333<code>
334 select identical(heap.findClass("Foo").statics.bar, heap.findClass("AnotherClass").statics.bar)
335</code>
336</pre>
337
338<a name="objectid"></a>
339<h4>objectid function</h4>
340
341<p>
342Returns String id of a given Java object. This id can be passed to
343<a href="#findObject">heap.findObject</a> and may also be used to compare
344objects for identity.
345</p>
346Example:
347<pre>
348<code>
349 select objectid(o) from java.lang.Object o
350</code>
351</pre>
352
353<a name="reachables"></a>
354<h4>reachables function</h4>
355<p>
356Returns an array of Java objects that are transitively referred from the
357given Java object. Optionally accepts a second parameter that is comma
358separated field names to be excluded from reachability computation.
359Fields are written in class_name.field_name pattern.
360</p>
361Examples:
362<ul>
363<li>print all reachable objects from each Properties instance.
364<pre>
365<code>
366 select reachables(p) from java.util.Properties p
367</code>
368</pre>
369<li>print all reachables from each java.net.URL but omit the objects reachable
370via the fields specified.
371<pre>
372<code>
373 select reachables(u, 'java.net.URL.handler') from java.net.URL u
374</code>
375</pre>
376</ul>
377
378<a name="referrers"></a>
379<h4>referrers function</h4>
380<p>
381Returns an enumeration of Java objects that hold reference to a given Java
382object.
383</p>
384Examples:
385<ul>
386<li> print number of referrers for each java.lang.Object instance
387<pre>
388<code>
389 select count(referrers(o)) from java.lang.Object o
390</code>
391</pre>
392<li>print referrers for each java.io.File object
393<pre>
394<code>
395 select referrers(f) from java.io.File f
396</code>
397</pre>
398<li>print URL objects only if referred by 2 or more
399<pre>
400<code>
401 select u from java.net.URL u where count(referrers(u)) > 2
402</code>
403</pre>
404</ul>
405
406<a name="referees"></a>
407<h4>referees function</h4>
408<p>
409Returns an array of Java objects to which the given Java
410object directly refers to.
411</p>
412Example: to print all static reference fields of java.io.File class
413<pre>
414<code>
415 select referees(<a href="#findClass">heap.findClass</a>("java.io.File"))
416</code>
417</pre>
418
419<a name="refers"></a>
420<h4>refers function</h4>
421<p>
422Returns whether first Java object refers to second Java object or not.
423</p>
424
425<a name="root"></a>
426<h4>root function</h4>
427<p>
428If given object is a member of root set of objects, this function returns
429a descriptive <a href="#rootobj">Root object</a> describing why it is so.
430If given object is not a root, then this function returns null.
431</p>
432
433<a name="sizeof"></a>
434<h4>sizeof function</h4>
435
436Returns size of the given Java object in bytes
437Example:
438<pre>
439<code>
440 select sizeof(o) from [I o
441</code>
442</pre>
443
444<a name="toHtml"></a>
445<h4>toHtml function</h4>
446
447Returns HTML string for the given Java object. Note that this is called
448automatically for objects selected by select expression. But, it may be useful
449to print more complex output.
450
451Example: print hyperlink in bold font weight
452<pre>
453<code>
454 select "&lt;b&gt;" + toHtml(o) + "&lt;/b&gt;" from java.lang.Object o
455</code>
456</pre>
457
458<h3>Selecting multiple values</h3>
459<p>
460Multiple values can be selected using JavaScript object literals or arrays.
461</p>
462
463Example: show name and thread for each thread object
464<pre>
465<code>
466 select { name: t.name? t.name.toString() : "null", thread: t }
467 from instanceof java.lang.Thread t
468</code>
469</pre>
470
471<h3>array/iterator/enumeration manipulation functions</h3>
472
473<p>
474These functions accept an array/iterator/enumeration and an
475expression string [or a callback function] as input. These functions iterate
476the array/iterator/enumeration and apply the expression (or function) on
477each element. Note that JavaScript objects are associative arrays. So,
478these functions may also be used with arbitrary JavaScript objects.
479</p>
480
481<ul>
482<li><a href="#concat">concat(array1/enumeration1, array2/enumeration2)</a>
483<li><a href="#contains">contains(array/enumeration, expression)</a>
484<li><a href="#count">count(array/enumeration, expression)</a>
485<li><a href="#filter">filter(array/enumeration, expression)</a>
486<li><a href="#length">length(array/enumeration)</a>
487<li><a href="#map">map(array/enumeration, expression)</a>
488<li><a href="#max">max(array/enumeration, [expression])</a>
489<li><a href="#min">min(array/enumeration, [expression])</a>
490<li><a href="#sort">sort(array/enumeration, [expression])</a>
491<li><a href="#sum">sum(array/enumeration, [expression])</a>
492<li><a href="#toArray">toArray(array/enumeration)</a>
493<li><a href="#unique">unique(array/enumeration, [expression])</a>
494</ul>
495
496<a name="concat"></a>
497<h4>concat function</h4>
498<p>
499Concatenates two arrays or enumerations (i.e., returns composite
500enumeration).
501</p>
502
503<a name="contains"></a>
504<h4>contains function</h4>
505<p>
506Returns whether the given array/enumeration contains an element
507the given boolean expression specified in code. The code evaluated
508can refer to the following built-in variables.
509</p>
510<ul>
511<li>it -> currently visited element
512<li>index -> index of the current element
513<li>array -> array/enumeration that is being iterated
514</ul>
515Example: select all Properties objects that are referred by
516some static field some class.
517<pre>
518<code>
519 select p from java.util.Properties p
520 where contains(<a href="#referrers">referrers</a>(p), "<a href="#classof">classof</a>(it).name == 'java.lang.Class'")
521</code>
522</pre>
523
524<a name="count"></a>
525<h4>count function</h4>
526<p>
527count function returns the count of elements of the input array/enumeration
528that satisfy the given boolean expression. The boolean expression code can
529refer to the following built-in variables.
530</p>
531<ul>
532<li>it -> currently visited element
533<li>index -> index of the current element
534<li>array -> array/enumeration that is being iterated
535</ul>
536Example: print number of classes that have specific name pattern
537<pre>
538<code>
539 select count(<a href="#classes">heap.classes()</a>, "/java.io./(it.name)")
540</code>
541</pre>
542
543<a name="filter"></a>
544<h4>filter function</h4>
545<p>
546filter function returns an array/enumeration that contains elements
547of the input array/enumeration that satisfy the given boolean
548expression. The boolean expression code can refer to the following built-in
549variables.
550</p>
551<ul>
552<li>it -> currently visited element
553<li>index -> index of the current element
554<li>array -> array/enumeration that is being iterated
555<li>result -> result array/enumeration
556</ul>
557Examples:
558<ul>
559<li>show all classes that have java.io.* name pattern
560<pre>
561<code>
562 select filter(<a href="#classes">heap.classes</a>(), "/java.io./(it.name)")
563</code>
564</pre>
565<li> show all referrers of URL object where the referrer is not from
566java.net package
567<pre>
568<code>
569 select filter(<a href="#referrers">referrers</a>(u), "! /java.net./(<a href="#classof">classof</a>(it).name)")
570 from java.net.URL u
571</code>
572</pre>
573</ul>
574
575<a name="length"></a>
576<h4>length function</h4>
577<p>
578length function returns number of elements of an array/enumeration.
579</p>
580
581<a name="map"></a>
582<h4>map function</h4>
583<p>
584Transforms the given array/enumeration by evaluating given code
585on each element. The code evaluated can refer to the following built-in
586variables.
587</p>
588<ul>
589<li>it -> currently visited element
590<li>index -> index of the current element
591<li>array -> array/enumeration that is being iterated
592<li>result -> result array/enumeration
593</ul>
594<p>
595map function returns an array/enumeration of values created by repeatedly
596calling code on each element of input array/enumeration.
597</p>
598Example: show all static fields of java.io.File with name and value
599<pre>
600<code>
601 select map(<a href="#findClass">heap.findClass</a>("java.io.File").statics, "index + '=' + <a href="#toHtml">toHtml</a>(it)")
602</code>
603</pre>
604
605<a name="max"></a>
606<h4>max function</h4>
607<p>
608returns the maximum element of the given array/enumeration.
609Optionally accepts code expression to compare elements of the array.
610By default numerical comparison is used. The comparison expression can
611use the following built-in variables:
612</p>
613<ul>
614<li>lhs -> left side element for comparison
615<li>rhs -> right side element for comparison
616</ul>
617Examples:
618<ul>
619<li>find the maximum length of any String instance
620<pre>
621<code>
622 select max(map(heap.objects('java.lang.String', false), 'it.count'))
623</code>
624</pre>
625<li>find string instance that has the maximum length
626<pre>
627<code>
628 select max(heap.objects('java.lang.String'), 'lhs.count > rhs.count')
629</code>
630</pre>
631</ul>
632
633<a name="min"></a>
634<h4>min function</h4>
635<p>
636returns the minimum element of the given array/enumeration. Optionally
637accepts code expression to compare elements of the array. By default numerical
638comparison is used. The comparison expression can use the following built-in
639variables:
640</p>
641<ul>
642<li>lhs -> left side element for comparison
643<li>rhs -> right side element for comparison
644</ul>
645Examples:
646<ul>
647<li>find the minimum size of any Vector instance
648<pre>
649<code>
650 select min(map(heap.objects('java.util.Vector', false), 'it.elementData.length'))
651</code>
652</pre>
653<li>find Vector instance that has the maximum length
654<pre>
655<code>
656 select min(heap.objects('java.util.Vector'), 'lhs.elementData.length < rhs.elementData.length')
657</code>
658</ul>
659
660<a name="sort"></a>
661<h4>sort function</h4>
662<p>
663sorts given array/enumeration. Optionally accepts code expression to
664compare elements of the array. By default numerical comparison is used.
665The comparison expression can use the following built-in variables:
666</p>
667<ul>
668<li>lhs -> left side element for comparison
669<li>rhs -> right side element for comparison
670</ul>
671Examples:
672<ul>
673<li> print all char[] objects in the order of size.
674<pre>
675<code>
676 select sort(<a href="#objects">heap.objects</a>('[C'), '<a href="#sizeof">sizeof</a>(lhs) - sizeof(rhs)')
677</code>
678</pre>
679<li> print all char[] objects in the order of size but print
680size as well.
681<pre>
682<code>
683 select <a href="#map">map</a>(sort(<a href="#objects">heap.objects</a>('[C'), '<a href="#sizeof">sizeof</a>(lhs) - sizeof(rhs)'), '{ size: sizeof(it), obj: it }')
684</code>
685</pre>
686</ul>
687
688<a name="sum"></a>
689<h4>sum function</h4>
690<p>
691This function returns the sum of all the elements of the given input array or
692enumeration. Optionally, accepts an expression as second param. This is used
693to map the input elements before summing those.
694</p>
695Example: return sum of sizes of the reachable objects from each Properties object
696<pre>
697<code>
698 select sum(<a href="#map">map</a>(<a href="#reachables">reachables</a>(p), '<a href="#sizeof">sizeof</a>(it)'))
699 from java.util.Properties p
700
701 // or omit the map as in ...
702 select sum(<a href="#reachables">reachables</a>(p), '<a href="#sizeof">sizeof</a>(it)')
703 from java.util.Properties p
704</code>
705</code>
706</pre>
707
708<a name="toArray"></a>
709<h4>toArray function</h4>
710<p>
711This function returns an array that contains elements of the input
712array/enumeration.
713</p>
714
715<a name="unique"></a>
716<h4>unique function</h4>
717<p>
718This function returns an array/enumeration containing unique elements of the
719given input array/enumeration
720</p>
721Example: select unique char[] instances referenced from Strings. Note that
722more than one String instance can share the same char[] for the content.
723<pre>
724<code>
725 // number of unique char[] instances referenced from any String
726 select count(unique(map(heap.objects('java.lang.String'), 'it.value')))
727
728 // total number of Strings
729 select count(heap.objects('java.lang.String'))
730</code>
731</pre>
732
733<h3>More complex examples</h3>
734
735<h4>Print histogram of each class loader and number of classes loaded by it</h4>
736
737<pre>
738<code>
739 select <a href="#map">map</a>(<a href="#sort">sort</a>(map(heap.objects('java.lang.ClassLoader'),
740 '{ loader: it, count: it.classes.elementCount }'), 'lhs.count < rhs.count'),
741 'toHtml(it) + "&lt;br&gt;"')
742</code>
743</pre>
744<p>
745The above query uses the fact that, <b>java.lang.ClassLoader</b> has a private
746field called <b>classes</b> of type <b>java.util.Vector</b> and Vector has a
747private field named <b>elementCount</b> that is number of elements in the
748vector. We select multiple values (loader, count) using JavaScript object
749literal and map function. We sort the result by count (i.e., number of classes
750loaded) using sort function with comparison expression.
751</p>
752
753<h4>Show parent-child chain for each class loader instance</h4>
754
755<pre>
756<code>
757 select <a href="#map">map</a>(heap.objects('java.lang.ClassLoader'),
758 function (it) {
759 var res = '';
760 while (it != null) {
761 res += toHtml(it) + "-&gt;";
762 it = it.parent;
763 }
764 res += "null";
765 return res + "&lt;br&gt;";
766 })
767</code>
768</pre>
769<p>
770Note that we use <b>parent</b> field of <b>java.lang.ClassLoader</b> class
771and walk until parent is null using the callback function to map call.
772</p>
773
774<h4>Printing value of all System properties</h4>
775
776<pre>
777<code>
778 select <a href="#map">map</a>(<a href="#filter">filter(<a href="#findClass">heap.findClass</a>('java.lang.System').props.table, 'it != null'),
779 function (it) {
780 var res = "";
781 while (it != null) {
782 res += it.key.value.toString() + '=' +
783 it.value.value.toString() + '&lt;br&gt;';
784 it = it.next;
785 }
786 return res;
787 });
788</code>
789</pre>
790<p>
791The above query uses the following facts:
792<ul>
793<li>java.lang.System has static field by name 'props' of type java.util.Properties.
794<li>java.util.Properties has field by 'table' of type java.util.Hashtable$Entry
795(this field is inherited from java.util.Hashtable). This is the hashtable
796buckets array.
797<li>java.util.Hashtable$Entry has 'key', 'value' and 'next' fields. Each
798entry points the next entry (or null) in the same hashtable bucket.
799<li>java.lang.String class has 'value' field of type char[].
800</ul>
801<p>
802<b>Note that this query (and many other queries) may not be stable - because
803private fields of Java platform classes may be modified/removed without any
804notification! (implementation detail)</b>. But, using such queries on user
805classes may be safe - given that user has the control over the classes.
806</p>
807
808</body>
809</html>