See where variable value is set when debugging in Eclipse - java

I would like to know if when debugging in Eclipse, is there a feature/way to focus on a variable and "back-track" where the variable got its value..? I hope I'm being clear enough, but I can see if this appears as a weird question.
The thing is, I have two similar classes, both using a #Resource instance of the same class. One of the classes runs fine but the other one gets a NullPointerException for the instance variable in question. And I can't see how this is. So if you know a way to "back-track" in the Eclipse debugger to see "how old" and where a value in a variable is set I would greatly appreciate it!
And if there's no such feature for some obvious reason and this question in stupid I apologize in advance...

You'd have to set a field breakpoint on the field in question before the value is set and catch it when it happens. "Standard" debuggers don't have the back-in-time feature. Omniscient debuggers do, though. These record every single action taken by a VM so that you can ask these kinds of questions at any point during execution. They're not widely used and have understandably high performance penalties. There are at least a couple of open source ones out there: TOD and ODB.

Unfortunately this is not possible in the standard Eclipse debugger. There is a commercial product called "Chronon Time-Travelling Debugger", which I have not tried but sounds as if it might do what you want, and is available for a 30-day free trial.

Related

How to find Methods that call openConnection() and NOT closeConnection()?

I am currently dealing with a OutOfMemoryException in my Tomcat application, probably due to a problem with my connection pooling. Since my codebase is rather large it is quite hard to see if there is any point where a connection is only opened but not closed.
Is there any easy way in Eclipse to show me all methods that call the openConnection()-Method, but not the closeConnection()-Method?
This is a tricky problem. Are you able to replicate this on a test system?
In the following I describe how I would approach solving your problem given the information you have provided.
First verify that this is actually the problem, by using a profiler on a system showing the problem while running. The traditional start is to use the stand alone version of the Netbeans profiler - VisualVMM (https://visualvm.github.io/) - where it is easy to see the memory usage over time, and to enable object allocation insights. I am unsure if the current version of VisualVM can tell you where a given object was allocated, but if it can then that might be the fastest way to identify your problematic code. If not then a trial version of a profiler that can, might be worth looking into.
If the profiler confirms that "calling X.openConnection() and then not calling X.closeConnection()" somewhere is the problem, but you still need to find out exactly where and tools like Findbugs - http://findbugs.sourceforge.net/ - and PMD - https://pmd.github.io/ - does not help you (a bit of effort here goes a long way), then I would suggest changing your code so that you collect the information you need.
If you are actually talking about database connections, then this is not an uncommon problem, so tools exist to help you. There is a rather old question at How to check the Database Connection leakage in Java EE application? but which has suggestions on how to approach this. It also has suggestions on how to catch this with tests.
At this point I would look into code - please consider the following non-compilable pseudocode. Write a revised subclass of X which maintains a global
var openConnections = new ArrayList<Map<X, Exception>>():
where each call to openConnection() also adds a single element with the object and a corresponding exception to a list somewhat like this:
public ... openConnection(...) {
openConnections.add(Map.of(this, new Exception()));
return super.openConnection();
}
and then each call to closeConnection() removes it again.
public ... closeConnection(...) {
// Loop over openConnections, if the current map has this as the first key, then
// delete that entry.
return super.closeConnection();
}
You should then at any time be able to see your open connections in the debugger, and where they were invoked from.
If you have the time I would strongly suggest that you rewrite your code to conform to the AutoCloseable interface instead as it allows you to use try-with-resources to let the compiler help you, and hints to static code analysis tools that this is what you want to do every time. See implements Closeable or implements AutoCloseable for a good starter question with answers.

Is there a way to tell if there is code not being used in java?

Whenever I program, I seem to accumulate a lot of "trash" code, code that is not in use anymore. Just to keep my code neat, and to avoid making any expensive and unnecessary computations, Is there an easy way to tell if there is code that is not being used?
One of the basic principles which will help you in this regard is to reduce visibility of everything as much as possible. If a class can be private don't make it default, protected or public. Same applies for methods and variables. It is much easier when you can say for sure if something is not being used outside a class. In cases like this even IDEs like Eclipse and IntelliJ Idea will suggest you about unused code.
Using this practice while developing and refactoring code is the best way to clean unused code confidently without the possibility of breaking the application. This will help in scenarios even when reflection is being used.
It's difficult to do in Java since it's a reflective language. (You can't simply hunt for calls to a certain class or function, for example, since reflection can be used to call a function using strings that can only be resolved at runtime.)
So in full generality, you cannot be certain.
If you have adequate unit tests for your code base then the possibility of redundant code should not be a cause for concern.
I think "unused code" means the code that is always not executed at runtime. I hope I interpreted you correctly.
The way to do a simple check on this is very easy. Just use IntelliJ IDEA to write your code. It will tell you that parts of your code that will never be executed and also the parts where the code can be simplified. For example,
if (x == 5) {
}
And then it will tell you that this if statement is redundant. Or if you have this:
return;
someMethod();
The IDE will tell you that someMethod() can never be reached. And it also provides a lot of other cool features.
But sometimes this isn't enough. What if you have
if (x == 5) {
someMethod();
}
But actually in your code, x can only be in the range of 1 to 4? The IDE won't tell you about this. You can use a tool that shows your code coverage by running lots of tests. Then you can see which part of your code is not executed.
If you don't want to use such a tool, you can put breakpoints in your methods. Then run some tests by hand. When the debugger steps through your code, you can see exactly where the code goes and exactly which piece(s) of code is not executed.
Another method to do this is to use the Find/Replace function of the IDE. Check if some of your public/private methods are not being called anywhere. For example, to check whether someMethod() is called, search for someMethod in the whole project and see if there are occurrences other than the declaration.
But the most effective way would be,
Stop writing this kind of code in the first place!
i think the best way to check that is to install a plugin of coverage like eclemma and create unit and integration tests to get 100% of coverage of the code that accomplish the use code/task you have.
The code that don't need to be tested or don't pass over it after the tests are completed and run, is code that you are not using
Try to avoid accumulating trash in the first place. Remove stuff you don't need anymore. (You could make a backup or better use a source code management system.)
You should also write unit tests for your functions. So you know if it still works after you remove something.
Aside from that, most IDEs will show you unused local variables and private methods.
I do imagine situation when you have app developed by years and some part of your functions doesn't used anymore even they still working. Example: Let's assume you make some changes on internal systems when specific event occured but it is not occurs anymore.
I would say you could use AspectJ to obtain such data / log and then analyze after some time.

Is there anything in java where commenting code out, that isn't ever used, changes how the code could function? Like C/C++ memory leaks? [closed]

Closed. This question needs debugging details. It is not currently accepting answers.
Edit the question to include desired behavior, a specific problem or error, and the shortest code necessary to reproduce the problem. This will help others answer the question.
Closed 7 years ago.
Improve this question
So... at work we are looking at a chunk of code, that as far as we can see (logs on the server, config files, etc) cannot and does not run unless specifically told in the config file to run. We are currently trying to work out the last of the bugs, this really main one now. One of the things that fix this bug (only relevant part of my question) is commenting out said code that never gets run.
Edit, more info:
But when this code isn't commented out, the constructor doesn't even get created, so no logs can be seen until it is fixed. Also, the code runs the first time without this difficulty, it is just when it is restarted.
Edit 2:
This code doesn't have any relation with the problem that is being created, it can't actually be called from what is being done.
The question I have is is there anything in java where commenting code out, that isn't ever used, changes how the code could function? Examples would be memory leak in C/C++.
If commenting it out corrects the bug, then this code is actually used.
Try debugging it by adding a breaking point on said unused code and see for yourself.
If commenting fixes the problem, that code is definitely being used. As suggested, try putting a breakpoint or printing on said code.
The question I have is is there anything in java where commenting code out, that isn't ever used, changes how the code could function?
When you comment, the compiler ignores everything commented so, you code does change; you are 'deleting' a portion of code.
By its very nature, commenting code out changes out a program runs. If the code was there previously and it was doing some operation that was deemed critical, and it's subsequently commented out, you have indeed changed how the code could function.
If it were the case that the code was never used, then commenting it out would have the same effect as deleting it; that is, it wouldn't change the behavior at all. You would require a regression test to ensure this, though.
Your scenario is the opposite of that, the code is very much in use.
Now, the likelihood of that introducing new and aberrant behavior is strongly dependent on what test suite you have to ensure that regressions don't occur. If there is no test suite, you have to take extra precautions to ensure that the undesirable behavior is corrected.
In practice, however, you should avoid commenting code out in favor of using your VCS tool (Subversion, Git, Mercurial, etc) to resurrect it should it be needed again.
Other than the potential need for that code later on, I can see no reason it would effect your final product. When cleaning up legacy code, I often comment out blocks that I think are unused, then do a clean compile to test if it actually needed anywhere. So I think your safe amusing that commented out code doesn't actually do anything.
Open the code in an editor that allows you to see what the usages of the code are. For example, if you use Netbeans, right-click a method declaration and select "Find Usages" to see all the places in your code that call that method.
If the code is in fact executing and commenting it out fixes one known bug, I would be very leery of going ahead with that route without knowing how or why the code is executing or how or why the bug is occurring.
I'll repeat what I said in a comment above: check the stack trace in the code in question.
And a few things to look for since there are some pitfalls you might not be thinking about...
Even if there are no usages of the methods in your file, you could be triggering code to run from elsewhere without realizing it. You could have properties which are defined where they are declared which will execute code, or you could have static code.
public class MyClass
{
{ System.out.println("This text will output even if you never create a MyClass instance. The class just needs to be loaded."); }
private static JFrame jframe = new JFrame(); // similar thing here as above; JFrame() constructor is executed, possibly without you even realizing when or how
private ContentPane pane = jframe.getContentPane(); // called when object instantiated, even if you don't do anything else to it, even though this is not in its constructor
{ jframe.setVisible(true); }
}
The above code will output a message to standard output, will create and show a window, and when you create an instance of this class it will execute JFrame's getContentPane() even though this class has no constructor to tell it to do so, because of the way the property is defined.
So you see, there are multiple places where executed code could be hidden. Again, you need to understand your problem more before you should feel safe just deleting (that's essentially what commenting-out is) code.

"Cosmetic" clean-up of old, unknown code. Which steps, which order? How invasive?

When I receive code I have not seen before to refactor it into some sane state, I normally fix "cosmetic" things (like converting StringTokenizers to String#split(), replacing pre-1.2 collections by newer collections, making fields final, converting C-style arrays to Java-style arrays, ...) while reading the source code I have to get familiar with.
Are there many people using this strategy (maybe it is some kind of "best practice" I don't know?) or is this considered too dangerous, and not touching old code if it is not absolutely necessary is generally prefered? Or is it more common to combine the "cosmetic cleanup" step with the more invasive "general refactoring" step?
What are the common "low-hanging fruits" when doing "cosmetic clean-up" (vs. refactoring with more invasive changes)?
In my opinion, "cosmetic cleanup" is "general refactoring." You're just changing the code to make it more understandable without changing its behavior.
I always refactor by attacking the minor changes first. The more readable you can make the code quickly, the easier it will be to do the structural changes later - especially since it helps you look for repeated code, etc.
I typically start by looking at code that is used frequently and will need to be changed often, first. (This has the biggest impact in the least time...) Variable naming is probably the easiest and safest "low hanging fruit" to attack first, followed by framework updates (collection changes, updated methods, etc). Once those are done, breaking up large methods is usually my next step, followed by other typical refactorings.
There is no right or wrong answer here, as this depends largely on circumstances.
If the code is live, working, undocumented, and contains no testing infrastructure, then I wouldn't touch it. If someone comes back in the future and wants new features, I will try to work them into the existing code while changing as little as possible.
If the code is buggy, problematic, missing features, and was written by a programmer that no longer works with the company, then I would probably redesign and rewrite the whole thing. I could always still reference that programmer's code for a specific solution to a specific problem, but it would help me reorganize everything in my mind and in source. In this situation, the whole thing is probably poorly designed and it could use a complete re-think.
For everything in between, I would take the approach you outlined. I would start by cleaning up everything cosmetically so that I can see what's going on. Then I'd start working on whatever code stood out as needing the most work. I would add documentation as I understand how it works so that I will help remember what's going on.
Ultimately, remember that if you're going to be maintaining the code now, it should be up to your standards. Where it's not, you should take the time to bring it up to your standards - whatever that takes. This will save you a lot of time, effort, and frustration down the road.
The lowest-hanging cosmetic fruit is (in Eclipse, anyway) shift-control-F. Automatic formatting is your friend.
First thing I do is trying to hide most of the things to the outside world. If the code is crappy most of the time the guy that implemented it did not know much about data hiding and alike.
So my advice, first thing to do:
Turn as many members and methods as
private as you can without breaking the
compilation.
As a second step I try to identify the interfaces. I replace the concrete classes through the interfaces in all methods of related classes. This way you decouple the classes a bit.
Further refactoring can then be done more safely and locally.
You can buy a copy of Refactoring: Improving the Design of Existing Code from Martin Fowler, you'll find a lot of things you can do during your refactoring operation.
Plus you can use tools provided by your IDE and others code analyzers such as Findbugs or PMD to detect problems in your code.
Resources :
www.refactoring.com
wikipedia - List of tools for static code analysis in java
On the same topic :
How do you refactor a large messy codebase?
Code analyzers: PMD & FindBugs
By starting with "cosmetic cleanup" you get a good overview of how messy the code is and this combined with better readability is a good beginning.
I always (yeah, right... sometimes there's something called a deadline that mess with me) start with this approach and it has served me very well so far.
You're on the right track. By doing the small fixes you'll be more familiar with the code and the bigger fixes will be easier to do with all the detritus out of the way.
Run a tool like JDepend, CheckStyle or PMD on the source. They can automatically do loads of changes that are cosemetic but based on general refactoring rules.
I do not change old code except to reformat it using the IDE. There is too much risk of introducing a bug - or removing a bug that other code now depends upon! Or introducing a dependency that didn't exist such as using the heap instead of the stack.
Beyond the IDE reformat, I don't change code that the boss hasn't asked me to change. If something is egregious, I ask the boss if I can make changes and state a case of why this is good for the company.
If the boss asks me to fix a bug in the code, I make as few changes as possible. Say the bug is in a simple for loop. I'd refactor the loop into a new method. Then I'd write a test case for that method to demonstrate I have located the bug. Then I'd fix the new method. Then I'd make sure the test cases pass.
Yeah, I'm a contractor. Contracting gives you a different point of view. I recommend it.
There is one thing you should be aware of. The code you are starting with has been TESTED and approved, and your changes automatically means that that retesting must happen as you may have inadvertently broken some behaviour elsewhere.
Besides, everybody makes errors. Every non-trivial change you make (changing StringTokenizer to split is not an automatic feature in e.g. Eclipse, so you write it yourself) is an opportunity for errors to creep in. Do you get the exact behaviour right of a conditional, or did you by mere mistake forget a !?
Hence, your changes implies retesting. That work may be quite substantial and severely overwhelm the small changes you have done.
I don't normally bother going through old code looking for problems. However, if I'm reading it, as you appear to be doing, and it makes my brain glitch, I fix it.
Common low-hanging fruits for me tend to be more about renaming classes, methods, fields etc., and writing examples of behaviour (a.k.a. unit tests) when I can't be sure of what a class is doing by inspection - generally making the code more readable as I read it. None of these are what I'd call "invasive" but they're more than just cosmetic.
From experience it depends on two things: time and risk.
If you have plenty of time then you can do a lot more, if not then the scope of whatever changes you make is reduced accordingly. As much as I hate doing it I have had to create some horrible shameful hacks because I simply didn't have enough time to do it right...
If the code you are working on has lots of dependencies or is critical to the application then make as few changes as possible - you never know what your fix might break... :)
It sounds like you have a solid idea of what things should look like so I am not going to say what specific changes to make in what order 'cause that will vary from person to person. Just make small localized changes first, test, expand the scope of your changes, test. Expand. Test. Expand. Test. Until you either run out of time or there is no more room for improvement!
BTW When testing you are likely to see where things break most often - create test cases for them (JUnit or whatever).
EXCEPTION:
Two things that I always find myself doing are reformatting (CTRL+SHFT+F in Eclipse) and commenting code that is not obvious. After that I just hammer the most obvious nail first...

Generics in legacy code

We've got a fairly large amount of code that just made the jump to Java 5. We've been using generics in those components targeted at being released in the Java 5 version, but the remaining code is, of course, full of raw types. I've set the compiler to generate an error for raw types and started manually clearing them, but at the present rate it'll take a very long time to go through with it (there are about 2500 errors). And that's with Eclipse's helpful Infer Generic Type quick fix, which always gets rid of the errors, but often generates code that needs further work.
Is there any better way to dealing with this? Are there any automated tools better than Eclipse? Any way to apply the refactoring to all occurences instead of doing them one-by-one? Or do you just ignore the warnings?
I would suggest ignoring the warnings. Otherwise, you'll be putting a lot of time into updating the legacy code without making any improvements to its functionality.
Update: Great comment from Luke that I thought should get more visibility:
"Generics are a way to catch run time bugs at compile time. Unless this legacy code has bugs in it that you think are related to casting I would leave it alone (if it ain't broke, don't fix it)"
As far as I know, you're going about it as efficiently as possible. It's
obviously not perfect, but you'll finish eventually.
I recommend that you do it in stages, however; there are likely parts of the
code that would benefit more from this than others, focus on those. Trying to
do it all in one sweep runs the risk of introducing new bugs to your code. We
have one such place where we have a collection that holds context-dependent
data, and generics actually can't work for it.
Basically, do what you're doing, but do it in stages as part of other work,
instead of trying to fix it all in one throw.
Faced with a similar challenge, we opted to upgrade to Java 5 style generics only in the code that was edited for another reason. So if you have a bug to fix in DoItFast.java, update DoItFast.java to use Java 5 style generics. The areas of the code that are being edited and changed regularly will get updated quickly. After a few weeks or months of this behavior, you can reevaluate the condition of your code base.
If that doesn't get the job done fast enough for you, sometimes I'll use the slow time after lunch to just mindlessly cleanup a few classes and speed the process along.
I don't think it is necessary to update all the old code. Maybe if you could somehow identify which parts of the old code are used frequently, and only update those to use generic types? Or maybe you could only worry when the raw type is returned from a public function? A lot of these cases are probably just private/local variables, which are already written without generic types and presumably work just fine, so it's probably not worth the effort to rewrite them.
I understand with IDEA you can select all your classes, popup the context menu and select Refactor | Generify. Job done. It's certainly a more enjoyable experience to work with generified code (IMO).

Categories