The program I'm building seems to freeze at some points on the user's system. When I test the very same steps, I see no problem. Even though Java is supposed to be a platform-independent VM, my guess is it has to do with the systems we're using (I'm on linux, the user on Mac), maybe something with file access.
I cannot access the user's system, and the user has no idea what debugging means. In order to test where the problem is, I was thinking of writing the program's progress to a file, and having him send me the file when there's a problem. Therefore my question:
Is there some kind of library which allows writing the line by line execution of a program to a file? Ideally, the values of certain variables would also be included.
edit: I'm familiar with Logger, but (like one answer says), that would require writing a lot of log statements. Is there some way to do this automatic? Maybe line by line is overkill, but something like log each method entry/exit would definitely work.
Thanks a lot!
This might be a good use case for aspect-oriented programming. Specifically, the AspectJ library for Java might suit your needs (there are others, but this is the one I'm most familiar with). You could define a logging aspect that would automatically insert method entry/exit log messages into the methods you wish to trace, without having to modify the code for those methods. The aspect can be included or excluded as you wish whenever you build the application (eg, include it just for this user until you resolve the issue).
Something like the following might be a good start:
aspect LogAllMethods {
Log log = new Log(); // pseudocode -- replace with whatever logging mechanism you like
before(): call(public * com.mycompany.*.*(..)) {
log.log("Entered method: " + thisJoinPoint);
}
after(): call(public * com.mycomapny.*.*(..)) {
log.log("Leaving method: " + thisJoinPoint);
}
}
This basically says that, before and after any public method call in the package com.mycompany, log the entry/exit and the name of the method (thisJoinPoint is a special variable in AspectJ that refers to the point in the program's execution that the aspect is being applied to). The AspectJ documentation has some nice tutorials and examples of defining aspects and how they can be used, as well as instructions on how to introduce aspects into your application.
This might be overkill for your situation and underutilization of AspectJ, but it should allow you to do some fine-grained debugging without having to add logging calls to every method in your code.
Typically the debug information you want would be included in a log file. Logging frameworks like Java's built in Logging API allow you to configure what severity of messages to produce when the program is run. In other words, you could have it normally report severe errors only, but enable debug output selectively when you need more information.
However, logging frameworks normally require you, the programmer, to explicitly tell it what to log. It doesn't simply log everything (that would be a lot of data too!).
It sounds like what you want is logging in your application. See the Wikipedia article for Java Logging Frameworks for details.
Some of the more common logging frameworks, all mentioned in the aforementioned article, are:
Log4J
Java Logging API
Apache Commons Logging
SLF4J
Related
I have built a console program in Java that uses external jars. I would like to observe my own System.out.println logs in the console, but they are being for the most part overwhelmed by messages on the console generated by some Logger (from the package org.slf4j;) which outputs massive amounts of text.
My issue is I cannot change the code that uses the Logger, because it is wrapped up in a jar and do not have its source. Is there a way to only show MY System.out.println calls? Or to otherwise quiet the messaged produced by this code I don't have source for?
Thanks!
There are a couple of approaches.
Change the log level or location. Unless it is set programatically, there is a configuration file for the SLF4j system. Modify the level so it displays only warn or only error. Alternatively, change the logger so that it goes to a file instead of stdout.
If you on a *nix system, and depending upon how you invoke the program, it is possible to do something akin to java PROGRAM | grep -v "org.slf4j" (or whatever the package is). This approach will remove any lines that match from the display.
It sounds like you're using a library that uses SLF4J for its logging, which is a fairly standard library. As helpful as it can be that there are all those libraries out there that do useful things, one of the challenges of using them is that one needs to integrate their logging into the one used by your application. SLF4J provides a standard logging interface that many libraries use, and allows them to bind to a standard logging implementation like Logback or log4j.
I would expect that most SLF4J-using libraries would depend on the slf4j-api only, and not have a specific logging implementation binding in their dependencies. By default, SLF4J uses the "no-op" logger, meaning that no logging is output (other than an initial warning that that's what it's doing). You could add the slf4j-nop library if that's what you want for your testing, to remove all logging.
But since you're actually seeing output, it seems that the library you're using is also for some reason including a binding to an actual logging framework. At that point, your options are:
Figure out how that binding and actual logging framework is getting into your classpath and remove it. (If you're using Maven to manage your dependencies, for example, you might add an <exclude> element for them.), or
Figure out what logging framework is being used (If you're using Maven, I find the dependency:tree output useful), essentially adopt using it for your application as well, and configure it to log the way you want, hiding the messages that you find irrelevant.
If we had more details on how you were getting this library's dependencies in your application (I've given information for Maven as it's what I'm most familiar with and it's rather standard), or what logging framework you thereby unwittingly added to your application, somebody may be able to direct you further.
I've hit one of those bugs that only seem to show up in production. Whenever I try to reproduce the error on my development machine, even with the same input data, I draw a blank.
So, I want to be able to trace the entire execution flow of this Java servlet which is running through Tomcat 7, from its invocation to the final exception that gets thrown. Ideally, it'd give me a lengthy list of method calls, parameters and return values. Something like the *nix strace, except for Java classes.
I did find Execution trace/flow in java 6 and higher where in the comments BTrace is linked to. I've had a look at it, but don't really see how it might help me. Also, it looks to be centered around running through a separate Java program. I'm OK with adding a bit of code, but really don't want to have to go into every method to add a trace call.
The absolute best would be if whatever approach used to do this can be coaxed into logging through slf4j (since I already use that for logging), but any logging is better than none.
How to obtain such a trace of a servlet?
I am not aware of an automatic tool for this but it is fairly easy to do by hand.
Just pick a few relevant places (for example inside the servlet) when it is actually called and do something like:
logger.info("Called X with Params "+y, new Exception());
That will give you the method, the parameters and the stack trace.
Scatter a few more log lines like that in relevant places and you should be able to track down the problem.
Maybe the Mapped Diagnostic Context can help you in this situation. Since you're using slf4j, it should be no problem to switch to logback as logging framework.
With it, you can provide additional informations, such as URI, session etc. + you can extend your logging pattern to include method and class to drill down your stack.
I want to log information to a file and want to know is there any advantage in using the Java Logger class versus my own personal method of logging?
I know using a logger I just add my own FileHandler to the logger. My personal method is just using a FileOutputStream.
Honestly your logger may be as good, it's pretty easy to put in log levels, filtering, etc.
The problem is when you start to put together code from 10 different groups each with their own logging. Some use System.out, some use some custom logger, some use log4j, ...
How do you parse or redirect the output? How do you filter all that output to just show your messages (For instance, filtering options in log4j won't prevent messages being sent straight to System.out).
It's a pretty big bulk change depending on which system you are moving from/to. Better just to use one very common one from the beginning and hope that it's the one everybody else on the project chooses.
The real question is: why would you bother writing your own logger when there are already existing libraries for doing that? Does your logger do something that the others don't? I kind of doubt it.
Standardization is another big issue - see Bill K's answer.
For most scenarios, a standard logging framework is the way to go. They are pretty flexible. But using your own implementation can also be a valid option, specially if we are not speaking of traditional logging (global debugging, problems, warning messages) but about specific informational meesages or accounting.
Among other factors, bear in mind that the standarization of logging allows third party libraries to cooperate. For example, if you have a standard web application using (say) Hibernate, and you have configured a standard Java logging lib, then you can not only log from your own code but also tell Hibernate to log debugging info to your log files (not necessarily the same files). That is very useful - almost a must.
If you code your own logging library with a plain FileOutputStream, you must decide -among other things- if you are going to keep the file opened, or reopen-append-close in each write - and you must take of synchronization and related issues. Nothing terribly complicated, though.
The logger gives to ability to define different levels of importance of the logged messages and the ability to use different sink for the output - the console, a file, etc.
Also it's easy to enable or disable only some type of message when using a logger - for example you don't want to see every debug message in production.
A logging framework allows you specify logging levels (e.g. log only critical messages, log only debug messages etc.). It also allows you to log to multiple destinations (e.g. to a file, to syslog etc.) and you can do this even after your application is fully built by just changing a config file and not changing any code. It can also format your logs easily depending on various parameters.
There are numerous other advantages since proper logging is a rather involved problem and these packages have been written to solve them. I think the important question, why would you not use them?
Well I would always prefer tested thing and approved by community over something which still need a lot of test. Logger allows you many things which will consume you some time to implement and to test the robustness of your solution. A big plus will be the know-how of the next person who will do something with your code, in case it will be your logger, normally it would take more time to learn how its working out, since there is much more examples and documentation for java.util.logger.
Like all others mention, there are more advantages to using a more common logging system over writing your own. To be honest, the Java util logging api is not nearly as extensive and configurable as other libraries you might find out there on the internet.
Bare in mind that rolling your own always has the disadvantage of being less tested and therefore more prone to break or skip some potentially crucial messages.
Personally I prefer using SLF4J since it allows me to plug in adapters for more commonly used logging frameworks and then let's me pick my own actual logging implementation, this solves most of the problems with different library writers preferring different logging frameworks. And if you consider yourself up for the task you could writer an implementation for SLF4J yourself ;)
Have you heard of any library which would allow me to set up tracing for specific methods at runtime?
Instead of adding (and removing) lots of System.out.println in my code (and having to re-compile and re-deploy) I would like to have a magic thing which would print out a line for each call of selected method without any change in the code. This would work without re-compiling, so some kind of JVM agent (or some non-standard JVM would be needed?). Sounds like a job for aspect programming?
A typical scenario would be to start an application, configure the traced methods dynamically (in a separate file or similar) and then everytime a selected method is called a line with its name (and arguments) is printed out to System.out (or some log file).
Naturally one could think of tens of additional features, but this basic set would be a great tool. BTW, I use Eclipse interactive debugger too, not only the System.out tracing technique, but both have some advantages and sometimes Eclipse is not enough.
Yes what you are referring to is known as Aspect oriented programming. A typical library providing this for Java is AspectJ. You define what are called pointcuts, essentially regular expressions for classes and method names, including wildcards, and the code to execute at each pointcut, known as an advice. This is useful for logging and also security checks and similar cross cutting concerns.
You can turn pointcut advices on and off through configuration. You can have an advice execute before a method call, after it returns or even after it throws an exception. Arguments are also available.
An aspectj java agent is needed for this to work.
In my experience, that kind of very detailed tracing (much more detailed than one would normally use for logging) as a debugging technique is indicative of insufficient unit testing and integration testing.
You can do this using a tool called InTrace.
NOTE: InTrace is a free and open source tool which I have written.
Log4J useful for disabling logging depending on "log-level" (DEBUG, INFO, WARN, FATAL).
You specify in configuration file what the least level you want to appear in logs, e.g., don't log anything below INFO level, and voila!
Looks like there's yet another solution - called Byteman. In their own words:
Byteman is a tool which simplifies tracing and testing of Java
programs. Byteman allows you to insert extra Java code into your
application, either as it is loaded during JVM startup or even after
it has already started running. The injected code is allowed to access
any of your data and call any application methods, including where
they are private. You can inject code almost anywhere you want and
there is no need to prepare the original source code in advance nor do
you have to recompile, repackage or redeploy your application. In fact
you can remove injected code and reinstall different code while the
application continues to execute.
Jackplay is the tool you are looking for.
It allows you to enable logging on method entry and exit points without any coding or redeployment.
It also allows redefining a method body. It gives you web based UI as control panel to enable or undo tracing on your class.methods.
I was wondering how should I proceed to debug while working with frameworks. Like specifically how can i tell which method is being called when a particular event happens.
thanks
raja
There are multiple ways to do this
1) Adding eclipse debug points (as described above)
2) Enable log statements. Most frameworks use logging (log4j, slf4j etc). So write a log4j.xml and create a category for "com.xxx" where all your framework classes have a package structure of com.xxx.yyy or com.xxx.aaa. Set the logging to be debug level and run the program (which uses the framework) analysing the log files should tell you
3) In eclipse if you cant run the program (so option 1 is not really possible) you can do a "Search usage" for an API to get who is using this. This option is however limited by the fact some frameworks use reflection, interfaces etc.