16

I have couple of ThreadLocals populated in my web app. And, while remote debugging the webapp, I want to see the value of these ThreadLocal variables in Eclipse (just like the way Eclipse shows other variables in the variables tab in Debug perspective).

Any idea how can I view the value of ThreadLocal variables during debugging in Eclipse?

Thanks!

Nick Bastin
  • 30,415
  • 7
  • 59
  • 78
peakit
  • 28,597
  • 27
  • 63
  • 80

3 Answers3

7

When you hit any breakpoint, just use view Expressions to display the value of Thread.currentThread() and you will be able to inspect every ThreadLocal value.

enter image description here

Aldian
  • 2,592
  • 2
  • 27
  • 39
4

In your code you have to place the values into a local variable, which you can see. You should be able to breakpoint where the ThreadLocal is used.

The problem is that the debugger's connection is on a different thread to the one you are interested in. Eclipse could have a solution for this, but I don't know what it is.

Peter Lawrey
  • 525,659
  • 79
  • 751
  • 1,130
  • @peakit I didn't understand. Even I am in need of debugging the thread local variables. I also tried to see the utilization of those threads using VisualVM. I don't know how to check them in the profiler tab. Can you please explain? – Nagarajan Shanmuganathan Jun 17 '16 at 07:02
  • @NagarajanShanmuganathan you can only see the contents of a ThreadLocal when you get() the value and put it in a local variable. – Peter Lawrey Jun 17 '16 at 09:51
1

If you want more details i.e. want to see the threadlocal variables for all the threads following code might help:

    public static String printThreadLocal() {
        StringBuilder sb = new StringBuilder();
        try {
            Thread[] tarray = new Thread[Thread.activeCount()];
            Thread.enumerate(tarray);
            for (int i = 0; i < tarray.length; i++) {
                Field threadLocalField = Thread.class.getDeclaredField("threadLocals");
                threadLocalField.setAccessible(true);
                Object o1 = threadLocalField.get(tarray[i]); //Thread.currentThread());
                Field tableField = o1.getClass().getDeclaredField("table");
                tableField.setAccessible(true);
                Object[] o2 = (Object[]) tableField.get(o1);
                for (Object temp : o2) {
                    if (temp != null) {
                        Field valueField = temp.getClass().getDeclaredField("value");
                        valueField.setAccessible(true);
                        Object o3 = valueField.get(temp);
                        sb.append(o3.toString() + "\n");
                    }
                }
            }

        } catch (NoSuchFieldException | SecurityException | IllegalArgumentException | IllegalAccessException e) {
            e.printStackTrace();
        }

        return sb.toString();
    }

You can add MyClass.printThreadLocal() to Expressions.

Ameer Tamboli
  • 1,218
  • 12
  • 20