Is it possible to set breakpoint so that it stop only if the given method is called from subclass?
I.e. both a method defined and breakpoint set are in superclass. Method is not overridden in subclass but is called for it. I need to catch only those cases, when it happen from given subclass.
This is suitable to track incorrect usage in highly branched libraries. For example class VeryCoolAncestor is called 1000 times, while only 1 of the calls are of my buggy class B.
I would like to know if it is possible in Eclipse. If it is not possible in Eclipse, then I would like to know any other debuggers where it is possible.
I need automation, so I don't need to know workarounds like inserting test calls in the code or test overriding methods.
You can use conditional breakpoints in Eclipse.
Right click on the breakpoint, then select "Breakpoint Properties", then enable the "Conditional" checkbox and add an instanceof statement that satisfies your requirements:
Or, you can write a block just for debugging purposes, having one statement:
if(someCondition) {
System.out.println("Breakpoint here");
}
Related
There is a possibility to add a watchpoint in the Eclipse, like mentioned e.g. here How to detect when a variable changes value
After invoking the watchpoint, the class which contains watched field is displayed and I am able to see that a setter was called. What I would like to know, is where exactly, in which place in the code, the setter(or constructor) was called.
This existing answer suggests that there is no such feature.
But beyond that, there is a simply workaround: use eclipse to find all usages of the method/ctor that sets the thing you are interested in, and then put break points on each of those.
Alternatively, you could put a test in your code under test, to throw exceptions in certain cases, delivering you a nice stack trace containing the call chain.
When debugging in IntelliJ Idea if I put a break point on a method signature it warns me about slow performance. However, what I do instead is just put it on the first executable line of code in the function and it works fine for my purposes.
My understanding is that if I see the function I will for sure see right before the first line of executable code inside the function but IntelliJ disagrees. What differences would I expect to see in with these two different debug methods?
Using method breakpoints creates a need to check every time a method is called to determine whether it needs to be breaked for every method call on the application. They also disable JVM optimizations such as method inlining.
Regardless to say this issue is not IDEA related, might even be applicable for other programming languages.
Don't have IntelliJ IDEA in front of me, but based on documentation, I think with method breakpoints you aren't actually going inside method implementation, but rather step-by-step on method calls. Which is probably the reason for performance impact, since IDEA must walk through caller stack, compared to just walking through lines of code in a single method in case of line breakpoint.
I have the following problem, we might even call it a classic one:
public void myMethod(Map<Object, Object> parameter){
someOtherObject.method(parameter);
.
.
.
someOtherThirdPartyObject.method(parameter);
}
And suddenly, in the end some method touched the input parameter Map, and I don't know where and how. Now, I know it would be desirable to make the parameter immutable, but it is not and that is the root of the problem. For instance, the methods inside myMethod are intended to perform some validations, but they do some more as well, which is wrong by design.
So, the question is how to create a breakpoint in this method where the execution pauses if an attribute of this parameter Map changes? It might be a good idea to put a conditional breakpoint after each method call, but if you have 20-odd methods, it's rather painful.
How can I debug when this input parameter is changing?
What you want appears to be called a "watchpoint". I actually didn't know this functionality existed and I used to work on the Eclipse Project!
http://help.eclipse.org/indigo/index.jsp?topic=%2Forg.eclipse.cdt.doc.user%2Ftasks%2Fcdt_t_add_watch.htm
It looks like you'll have to figure out what fields are being editted and then set a "Write" watchpoint using the help document above.
Additionally, Eclipse highlights variables which are modified, so if you step over your method calls one by one you will be able to see which one is modifying the value (and which field is being modified) because it will be highlighted (bright yellow, by default) in the "variables" tab in the "debug" perspective. Once you know which method if modifying the data you can run debug again, but this time debug the method that changes the value and just keep repeating until you find the problem.
This is a classic problem solving scenario where you start with a very large search space and systematically and methodologically narrow it down until the search space is small enough for you to locate the problem.
If you're trying to locate a spot where your map is being modified incorrectly, you might want to first start at the higher levels of the myMethod. Put breakpoints around the methods called inside the myMethod method. At each breakpoint, look at the contents of the Map. Eclipse has a variable watch panel where you can see the contents of every variable at a specific moment in time.
When you hit the breakpoint where you notice something is wrong. Stop. You now know to dig into someOtherObject.method(parameter); assuming the data was changed at it's breakpoint.
Now, someotherObject.method will likely have other methods inside it. Put your breakpoints inside this method around all of it's function calls and repeat the process. Continue repeating until there are no more methods left. Eventually, you will narrow down the problem and have the answer.
Unfortunately, there is no magic "fix my code" button for these types of problems. It just takes good, old fashioned Sherlock Holmes style investigative skills and reasoning to eliminate areas of the code that you know aren't the problem until you're left with a smaller section that allows you to get at the root cause.
If no code modification is allowed, you can
use the watchpoints method described by acattle to watch changes at this specific map instance or
have breakpoints in the Map methods modifying its state (if you want to do that for multiple instances). It does not matter that the Map code is binary only, you can still open it using Ctrl-Shift-T (Open Type), select the methods like put(...) or remove(...) in the outline view and add breakpoints using the context menu in the outline view.
My need is pretty simple: I want to change a method call objClass1.method1() by a call objClass2.method2() in my whole Eclipse project. Unfortunately, I can't find a plugin able to do this. Can you help?
Edit:
To be more accurate, objClass1 is part of a third party library, so I need to change the method calls. I can't start at the method definition. When I right-click on a method1 call, I have no "rename" option in my "Refactor" menu.
I don't want to change or rename my methods. I want to exchange one call by another in my whole project.
An example of what needs to be done:
Before refactoring:
Injector injector=Guice.createInjector(new IContactModule());
After refactoring:
Injector injector=IContactInjectorSingleton.getInjector();
And this needs to be done a several points in my project.
What you ask for is no refactoring. A refactoring is defined as "a change that alters the code while not changing the behavior of the code". In this sense renaming a class or renaming a method is a refactoring (you change the code but the program does the same as before). But what you suggest does NOT preserve the behavior of the code so there will never be a "refactoring" for this.
Of course one might be able to write a plugin that is able to perform the text changes you want in a more or less safe way. But this will only work in very specific circumstances (what if your new method needs an argument the old one dons't need? What if there are more than one method with the same name but different parameters? ...). So I don't believe such a plugin exists, nor it makes much sense to develop such a plugin.
Just right click on the class/method name and choose Refactor > Rename.
EDIT:
To be more accurate, objClass1 is part of a third party library, so I need to change the method calls. I can't start at the method definition. When I right-click on a method1 call, I have no "rename" option in my "Refactor" menu.
Hence I would suggest you to simply make a replacement:
Search menu > File, type the old name, choose the context of the search ("Enclosing project"), click on Replace and type the new name.
EDIT2:
From the example you added to the question I think that a manual replacement, using the tool I just suggested, it's the best way. It's a complex issue, as #Arne pointed out, so it's better to make it in a controlled way. Moreover I doubt it is such a frequent operation to require a plugin to be built.
You could use the eclipse refactoring by selecting the methods name. Right click for context menu or Alt-Shift-R, in the Rename-Dialog a preview dialog is available which shows all suggested changes in one place.
First, move the body of objClass1.method1() into objClass2.method2(), and have method1 simply call method2. It may not be quite as "simple" as that, if for instance method1 uses fields of Class1 for instance, in which case you should probably include this as a parameter to the new method and perhaps use getters for the fields. If you can make the method static before doing this, it will be easier to avoid those kinds of problems. Anyway, make that transformation, so method1 is just calling method2. Now use the Inline Method refactoring to make method1 go away. You're done.
I'm using Eclipse to debug a Java class. I want the debugger to break any time a public method of class X is invoked. However, this class has a lot public methods, so I'd prefer not to have to do this manually. Does Eclipse provide a simple way to do this?
Thanks,
Don
Not completely automatically, but:
Select all methods in the Outline view
Right click and choose "Toggle method breakpoint"
This will add breakpoints to all selected methods.