12

C# is the language I am most comfortable with but do Java when at work. I guess you can say I am very comfortable with using the Visual Studio IDE. One of the things I enjoyed about its debugger is that I can put watch variables ("Expressions" in Eclipse) for any expression. So I could take a peek at values of specific fields public or non-public, call methods, etc. with no problem as I am debugging.

It doesn't seem like I can do the same in Eclipse. I have to resort to calling the associated getter method for the field (assuming it has one). If it doesn't have one, I either have to temporarily add one so I can view it and remember to remove it when I'm done or I'm just SOL.

How can I put a watch expression for an object on one of its private fields? Or am I just doing it wrong and I have to craft special expressions to view them?
(Or is there a better way for me to get the information that I want?)

e.g.,

I have an HttpServletRequest and want to keep an eye on the requestURI. If I just watch the request variable, it lists a lot of its fields and it's just too much information. I'm only interested in one thing in the object so to minimize this, I want to add a watch expression for that one thing.

The field name is apparently requestURI so I added the expression: request.requestURI. Eclipse throws an error saying it's not a field (it is, it's just not public). Instead of going directly to the field, I had to go to the getter: request.getRequestURI() and that works fine. But I can't always count on the getter being available.

the variables view
The Variables view

the expressions view
The Expressions view

Jeff Mercado
  • 129,526
  • 32
  • 251
  • 272

4 Answers4

8

The Eclipse evaluates expression considering the private/protected fields of Declared Type, not of Actual Type.

Example:

Number n1 = new Integer(1000);
Integer n2 = new Integer(1000);

Expressions:

n1.value  can't be evaluate
n2.value  returns 1000, perfectly

An alternative is use DetailFormatter (right-click in variable > New Detail Formatter).

The Eclipse will use this expression instead of toString() method when the textual representation of a object of type is displayed (in Variables View, for example).

Your DetailFormatter (for ApplicationHttpRequest) can be:

requestURI 

or

"URI: " + requestURI + "\n" +
"Path: " + servletPath
Dmitry Ginzburg
  • 7,391
  • 2
  • 37
  • 48
  • That's an interesting point thanks for the insight. Though it's too bad it isn't smart enough to figure this out itself. They certainly should have been able to. – Jeff Mercado Apr 06 '12 at 02:32
  • I think this answer best explained the situation. Sure the cast helps, but this explains the why better. – Jeff Mercado Apr 08 '12 at 01:04
  • This answer is correct, but you don't need a DetailFormatter to make it work. Just cast your object to its Actual Type if the field you want isn't in its Declared Type and then grab the field. But I haven't been able to get it to work if you have multiple layers where you need to do this... – Tim Aug 29 '14 at 15:25
  • i have an org.apache.catalina.connector.RequestFacade and want to watch the field coyoteRequest - but it gives me only "coyoteRequest cannot be resolved or is not a field" – wutzebaer Mar 31 '16 at 10:42
5

Doesn’t matter if the field is private or protected, eclipse expressions will evaluate correctly. But the scope of variable matters.

Correct me if i am wrong.

requestURI is a protected field in org.apache.catalina.core.ApplicationHttpRequest which implements HttpServletRequest. In your case variable request is of type HttpServletRequest and you are trying to access HttpServletRequest.requestURI and this field Doesn’t exist and eclipse fails. I think it's normal. May be if you do proper casting, expression will evaluate correctly.

titogeo
  • 2,156
  • 2
  • 24
  • 41
  • The type of the request object is actually `org.apache.catalina.connector.RequestFacade`. But even then, casting it still doesn't work. (that would be an _ugly_ way to resolve this "problem") – Jeff Mercado Apr 02 '12 at 16:37
  • Actually, I think Tito is right about the types. Column 2 in your variables view is the "Value" column, right? As far as I know, that column will show concrete type, and it shows ApplicationHttpRequest, not RequestFacade. – sharakan Apr 02 '12 at 21:40
  • Ah sorry, ignore my first comment. My current situation right now has the request object a `RequestFacade` (within a struts action). I didn't realize it wasn't the same in my screenshot (within a servlet). I'll have to reevaluate this when I get the chance. – Jeff Mercado Apr 02 '12 at 22:44
  • Hey what do you know, the casting looks like it's working. http://i.stack.imgur.com/y95Rv.png – Jeff Mercado Apr 02 '12 at 22:53
1

Writing an expression in the Expressions view evaluates just as if you had written a line of code, and just executed it prior to the currently highlighted line. There is one difference that I know about (probably others to, but this is the important one) which is that you can bypass the class accessor visibility restrictions, and see private, protected and default members that the current stack frame perhaps couldn't.

That said the expression does require you to have the correct kind of reference. If you inserted this line in to code, the java compiler would complain that requestURI is not a field of HttpServletRequest. And therefore, you need to cast to the class (or subclass of) that actually declares the field: ApplicationHttpRequest.

Now, why they didn't bother exposing the same magic in Expressions as they do in Variables where as you point out they list ALL members of the concrete class even if the declared type wouldn't show them, I couldn't say.

sharakan
  • 6,821
  • 1
  • 34
  • 61
-1

In Eclipse while debugging, you can right-click on a variable and click on the Watch menu item. In the Debug perspective it will add an Expressions tab that will have a list of variables you are watching. I'm not sure how to do it in the other IDE's.

Tony
  • 1,401
  • 9
  • 11
  • Yeah I know that but that's not the issue... I want to watch a private field of a variable... Eclipse apparently can't do it. – Jeff Mercado Feb 15 '12 at 23:23