Telling javac to ignore System.out.println() - java

i'm using System.out.println() (sout) for debugging and general state overview purposes while programming (which is especially helpful for network stuff). Since i want my code to be efficient at the end, is there a way to tell the java compiler to ignore souts?
I already tried some googling, but the solutions where very unsatisfying, like putting all souts inside an if with a global variable. (Tripling the lines and making code very unreadable if a lot of souts are needed)
Anyone know if such a compiler option exists (if not, why not?), or if there is some other more elegant solution then the one stated above. Thank you for your answers :)

Use logging. You can indicate a log level that normally won't be displayed, and with logging properties can be made to appear. This can be done controlled etc.
Logger.getLogger(getClass().getName()).log(Level.FINE, "...");
In fact there are many examples and aspects to logging. So if you want your code to be minimalistic but mature, use logging.
An alternative way would be to use unit tests, and to not output in the production code. This requires more strictness and allows to find regression errors.
And a third alternative would be to more liberally use (unchecked) exceptions, IllegalArgumentException, IllegalStateException. To have an informative fail-fast.

First I would like to say that the real answer to this question is to use a logging framework as others have shown.
But if you are committed to using System.out, you can still achieve the desired effect. In the below class, I change System.out (by using the System.setOut method) to another PrintStream that does not actually print anything.
import java.io.*;
class Sys
{
public static void main ( String [ ] args ){
System.setOut(new PrintStream(new OutputStream(){
#Override
public void write(int b){
}
}));
System.out.println("Hello World!");
}
}
My answer can be improved upon. For example, it will still convert objects to string for printing, but you can solve that by setting out to an overrided PrintStream class that does absolutely nothing.
But the more you improve upon it, the more you are just implementing a logging utility which someone else has already done. This is why I suggest logging is the real answer.

Related

Is there a simple way to log everything in Java?

In teaching myself about Java errors and warnings, I have been exploring the documentation for java.util.logging.Logger. It seems as if everything within the Logger class is geared toward logging specific items--which makes sense from a practical persepctive.
However, I would like to be able to log everything that can be logged. It fits my learning style to look at everything that can be logged for a working program, then break things to see how the logfile changes. From there, it's easier for me to understand how to control what does and doesn't get logged.
I saw this post and this post with which I'm going to be starting, but I'm wondering if there are other resources that'd help me implement a "log everything" solution to increase my understanding of the class?
The logging classes will add messages to one or more appenders. You have to give it messages - it seems you're asking how you can log everything so I don't have to give a message to log. This isn't what loggers do. I think what you want is a debugger, and then step through your code.
Nothing logs on its own.
Given that you have two options:
Use a debugger instead. It matches more with your requirements. Step through the code and inspect variables on the fly. To use debugger, you can use any standard IDE like IntelliJ Idea or Eclipse.
Use AOP : Define an aspect which keeps logging all method parameters and return types. You could use Spring AOP for that
If you are a beginner, I would recommend option 1.
I am with the two other guys, but if you wanna see errors, you could use Exceptions with try-catch blocks like this:
try
{
//enter your code here
Test f = new Test();
}
catch(Exception e){
e.printStackTrace();
}

Reflections bad or good practice for commands

Well, I saw there were some questions and answers about this, but they didn't really satisfy me.
Let's say for example, I have programmed a console. It's a nice JFrame with an output and an input txtField/Area. But this console should not only be used for output, but also to run commands.
Because I would need this console very often and I don't want to change the code of the console I programmed it this way:
The console has one method to register commands.
console.registerCommand(String command, String methodToInvoke, Object invokeObject);
With this method I'm able to use this console everywhere without the need of changing or inharitance.
Whenever the String command is written the console knows it's a registered keyword and executes the method via reflection.
Would this be a good or bad practice? On code styling and in performance! And what could I do better?
I also found it quite neat to use reflections this way to add ActionListeners to MenuItems in a TrayIcon.
Edit
To the Answer below:
Ok with commands i would accept this is a way to do. But in the Tray example I wrote a TrayHelper Class which creates the TrayIcon. There I want to add MenuItems and their ActionListeners but without creating every Object myself and add them to the Tray. So I wrote Methods like this:
public void addMenuItem(String label, String methodToInvoke, String invokeObject);
This method not only executes the method when the MenuItem is clicked, but also creates the MenuItem first, adds an ActionListener to it which invokes the Method, and adds it to the TrayIcon.
So in order to use this TrayHelper I can now just write:
th.addMenuItem("Exit","exitMethod",this);//executes the exitMethod of
//this class after Menuitem Exit
//was clicked
I don't really see how i could do this without reflection other than to write all the Objects myself again and adding them to the Tray. Or I'm blind :)
Edit 2
Ok, I was blind. I just didn't realize how to do this without reflection, but it is so simple.
Especially with the Command pattern.
Because of the anonymous classes I could do it that way, and I really like the way to write code this way (I always did it with ActionListeners)
th.addMenuItem("Test",new Command(){
public void execute(){
//do stuff
}
});
Thank you :)
There is a better way to do this. This helps to hide the action done inside a command object. As you have to change the command, you don't have to mess with your other code.
Further, you can have a lot of different commands and they can be related by inheritance or aggregation or be injected into each other as needed AND NOBODY ELSE HAS TO KNOW.
First you have an interface:
public interface Command {
void execute();
}
Then you have your code take one of these:
console.registerCommand(Command command);
Then you write various classes that implement the interface and do something:
public class OneCommand implements Command {
public void execute() {
theObject.theMethod(theCommand); // calls what you would have with reflection
}
}
This is the standard GOF Command Pattern and you can read more about it here: LINK TO WIKIPEDIA
Note that this pattern, along with the other GOF patterns, were published in a book in 1994. The authors collected these best practices over many software projects. That book is in its 40th printing (according to Wikipedia).
All this suggests that lots of people have found lots of reasons to use these over many pieces of softwear, over many years and in many programming languages and systems.
It doesn't mean you need to always use them but use of a tried and tested pattern will help avoid unseen pitfalls.

Annoying format for functions

I have started working with a large code base, and a lot of the code has been set up with a strange format for functions. more or less every function has the following format
foo(){
trace_messages()
// this is what I don't get
try{
// all code goes here
} finally {
trace_messages()
}
}
I can't see any sense behind the insistence on wrapping more or less the entire work of function in a try. Is this some sort of 'best practice' that I never got told about?
EDIT:
perhaps I should have stated, but the two calls to trace_messages() are actually different sections of code, but more or less the same... if you follow my meaning
The intention of that code was to make sure that trace_messages() was guaranteed to executed in the beginning and before the end of foo().
finally is guaranteed to execute both in case everything runs fine, and if the code inside try fails miserably with some nasty uncaught runtime exception.
I agree that the format chosen to achieve this intention is not of the best, normally that is done with some sort of AOP, in Spring you would wrap foo() into Around advice.
Find the definition of trace_messages(), and you will see what the last guy was trying to do. If you are using an IDE like Eclipse, right-click on trace_messages() and there should be an option to jump directly to the definition.

Is it possible to prevent a class from using a method in java?

Suppose I have a class called Foo. This class will be modified by many people, and WILL print information to the console. To this effect, we have the following method:
private void print(String message){ ... }
which prints out to the screen in the format we want.
However, while reviewing code from other devs I see that they constantly call System.out.println(...)
instead, which results in barely-readable printouts.
My question is the following: is it possible to prevent any and every use of System.out.println() in Foo.java? If so, how?
I've tried looking this up, but all I found had to do with inheritance, which is not related to my question.
Thanks a lot!
N.S.
EDIT: I know that whatever I have to do to prevent the use of a method could be removed by a dev, but we have as a policy never to remove code marked //IMPORTANT so it could still be used as a deterrent.
EDIT2: I know I can simply tell the devs not to do it or use code reviews to filter the "errors" out but 1) I'm already doing it and it costs a lot of time and 2) the question is whether this is possible or not, NOT how to deal with my devs.
public methods are just that - public. There is no way to restrict access to them.
This kind of problem is usually "solved" by setting up some code-checker like PMD or checkstyle and integrating them into the continuous integration build. So violations of these stuff will be emailed to someone with a big hammer :-)
Although communicating that developers should not use System.out directly would be preferred, you could set System.out to another PrintStream, then use the alternative PrintStream in the private method. That way, when people use System.out.println they won't output anything but you'll still be able to use the alternative PrintStream... something like they do here: http://halyph.blogspot.com/2011/07/how-to-disable-systemout.html
Pre-commit hooks for your revision control system (SVN, Git, Mercurial) can grep for uses of System.{err,out} and prevent commit if they occur.
http://stuporglue.org/svn-pre-commit-hook-which-can-syntax-check-all-files/ is an example that takes an action for different changed files based on file extension for SVN. You should be able to modify that example to take an example based on some subset of Java files and reject if something like the following is true
egrep -q '\bSystem\.(err|out)\b'
You can redirect System.out calls to a streams that ignores the output or that redirects it to your logging system.
System.setOut(printStream);
You can also kill those using System.out.println in a production environment.
You can replace the OutputStream of System with your own implementation that would either throw an exception, or redirect the call to your own print implementation (which you would need to make public).
No, it's not possible to 100% prevent a class from ever using a specific method in Java.
Having that said...
My suggestion would be to add code analysis to your build process and failing the build on any occurrence of System.out.println. A good place to start if you're interested in going this route would be to check out PMD.
Also... have some constructive discussions with your developers and talk about why they're doing what they're doing. Good luck.

How to remove debug statements from production code in Java

Is it possible for the compiler to remove statements used for debugging purposes (such as logging) from production code? The debug statements would need to be marked somehow, maybe using annotations.
It's easy to set a property (debug = true) and check it at each debug statement, but this can reduce performance. It would be nice if the compiler would simply make the debug statements vanish.
Two recommendations.
First:
for real logging, use a modern logging package like log4j or java's own built in logging. Don't worry about performance so much, the logging level check is on the order of nanoseconds. (it's an integer comparison).
And if you have more than a single log statement, guard the whole block:
(log4j, for example:)
if (logger.isDebugEnabled()) {
// perform expensive operations
// build string to log
logger.debug("....");
}
This gives you the added ability control logging at runtime. Having to restart and run a debug build can be very inconvenient.
Second:
You may find assertions are more what you need. An assertion is a statement which evaluates to a boolean result, with an optional message:
assert (sky.state != FALLING) : "The sky is falling!";
Whenever the assertion results in a false, the assertion fails and an AssertionError is thrown containing your message (this is an unchecked exception, intended to exit the application).
The neat thing is, these are treated special by the JVM and can toggled at runtime down to the class level, using a VM parameter (no recompile needed). If not enabled, there is zero overhead.
public abstract class Config
{
public static final boolean ENABLELOGGING = true;
}
import static Config.*;
public class MyClass
{
public myMethod()
{
System.out.println("Hello, non-logging world");
if (ENABLELOGGING)
{
log("Hello, logging world.");
}
}
}
The compiler will remove the code block with "Hello, logging world." in it if ENABLE_LOGGING is set to true because it's a static final value. If you use an obfuscator such as proguard, then the Config class will vanish too.
An obfuscator would also allow things like this instead:
public class MyClass
{
public myMethod()
{
System.out.println("Hello, non-logging world");
Log.log("Hello, logging world.");
}
}
import static Config.*;
public abstract class Log
{
public static void log(String s)
{
if (ENABLELOGGING)
{
log(s);
}
}
}
The method Log#log would reduce to nothing in the compiler, and be removed by the obfuscator, along with any calls to that method and eventually even the Log class would itself be removed.
Another possibility is to put the if statement within your logging function, you get less code this way, but at the expense of some extra function calls.
I'm also not a big fan of completely removing the debug code. Once you're in production, you'll probably need access to debug messages if something goes wrong. If you remove all of your code level debugging, than this isn't a possibility.
This "trick" seems to make your debug statements vanished
public static final boolean DEBUG = false;
if (DEBUG) { //disapeared on compilation }
The post said that javac is smart enough to check the static final boolean and exclude the debug statements. (I did not personally try it)
For logging, I personally donot like to see code like:
if (logger.isDebugEnabled()) {
logger.debug("....");
}
realImportantWork();
The logging things distracts me from the realImportantWork(). The right way for me is:
logger.debug("....");
realImportantWork()
plus the config which excludes all debug messages on Production.
I mean that the logger.isDebugEnabled() control should be the job of the logging framework, not my job. Most logging framework support concepts like "logger", "LogLevel".. which can do the trick.
Use Java Preprocessor? (google foo low but this is a link to the old Joel forums discussing it)
Java contains some sort of preprocessor of its own. It's called APT. It processes and generates code. At the moment I'm not sure how this should work (I haven't tried it). But it seems to be used for these kind of things.
I would also highly recommend using a logging framework.
The logger.IsDebugEnabled() is not mandatory, it is just that it can be faster to check whether the system is in the debug level before logging.
Using a logging framework means you can configure logging levels on the fly without restarting the application.
You could have logging like:
logger.error("Something bad happened")
logger.debug("Something bad happend with loads more detail")
To directly answer your question: I don't know.
But here is another solution to your problem:
In my mind, there are two statements that collide with each other here: "debug statements" and "production code".
What is the purpose of debug statements? Help to get rid of bugs while (unit) testing. If a piece of software is properly tested and works according to the requirements, debug statements are nothing else but OBSOLETE.
I strongly disagree with leaving any debug statements in production code. I bet nobody bothers testing side-effects of debug code in production code. The code probably does what it's supposed to do, but does it do more than that? Do all your #defines work correctly and really take ALL of the debug code out? Who analyzes 100000 lines of pre-processed code to see if all the debug stuff is gone?
Unless we have a different definition of production code, you should consider taking out the debug statements after the code is tested and be done with it.

Categories

Resources