Постоји неколико широко распрострањених библиотека за исписивање дијагностичких порука (енгл. logging). На пример, java.util.logging.
У својим програмима користим ово, али ми недостаје условна компилација. Оно што у Ц/Ц++ могу да урадим са #ifdef . . . не могу у јави. Тако сам приморан да дијагностику коју користим искључиво за време развоја, и не желим да буде присутна у крајњем производу морам да пишем овако:
void foo(int bar) {
if (DEBUG)
logger.trace("U foo(" + bar + ")");
}
Међутим, са јавом 1.5, дошла је и кључна реч assert. Ово је добродошло јер омогућава убацивање провера у сам код, а да то не ремети перформансе крајњег производа. Као посебан бонус, који није доступан у Ц/Ц++, асерти се могу укључити по потреби једноставним давањем аргумента -ea јавиној виртуелној машини.
То ме је подстакло да направим једноставан систем за условну дијагностику сличан #ifdef приступу у Ц/Ц++. Користим постојеће пакете (на пример java.util.logging) али унутар асерта. Наравно, ово није могуће урадити директно јер, на жалост, интерфејси дефинисани у овим пакетима не враћају никакву вредност. Мени је било потребно да сваки метод враћа вредност true да бих исти могао да користим унутар assert исказа:
void foo(int bar) {
assert logger.trace("U foo(" + bar + ")");
}
Ово ми даје управо оно што сам желео: условну дијагностику која је у нормалном режиму рада потпуно избачена оптимизацијом. То је чак и боље од Ц/Ц++ условне компилације јер се са јавом коначна компилација врши на рачунару корисника: уколико је јава виртуелна машина стартована са опцијом -ea онда ће дијагностика бити исписивана, у супротном не.
Моја имплементација се састоји у дефинисању интерфејса:
http://www.eclipse.org/legal/epl-v10.html
package org.java3declipse.logger;
<p><b></b>
<p>
<p>
<p>
<code></code>
<p>
<pre>
</pre>
@author
public interface ILogger {
boolean info(String msg);
boolean warning(String msg);
boolean error(String msg);
boolean error(String msg, Throwable t);
boolean debug(String msg);
boolean debug(String msg, Throwable t);
}
И имплементацији истог:
http://www.eclipse.org/legal/epl-v10.html
package org.java3declipse.logger;
import java.io.ByteArrayOutputStream;
import java.io.PrintStream;
import java.util.logging.ConsoleHandler;
import java.util.logging.Formatter;
import java.util.logging.Handler;
import java.util.logging.Level;
import java.util.logging.LogRecord;
@see
@author
public class Logger implements ILogger {
private ILogger logger_;
<code></code>
@param
<code></code>
public Logger(java.util.logging.Logger logger) {
logger_ = this.new JavaUtilLogger(logger);
}
<code></code>
@param
<code></code>
public Logger(ILogger logger) {
logger_ = logger;
}
public boolean info(String msg) {
return logger_.info(msg);
}
public boolean warning(String msg) {
return logger_.warning(msg);
}
public boolean error(String msg) {
return logger_.error(msg);
}
public boolean error(String msg, Throwable t) {
return logger_.error(msg, t);
}
public boolean debug(String msg) {
return logger_.debug(msg);
}
public boolean debug(String msg, Throwable t) {
return logger_.debug(msg, t);
}
private class JavaUtilLogger implements ILogger {
final java.util.logging.Logger javaUtilLogger;
public JavaUtilLogger(java.util.logging.Logger logger) {
javaUtilLogger = logger;
}
public boolean info(String msg) {
javaUtilLogger.info(msg);
return true;
}
public boolean warning(String msg) {
javaUtilLogger.warning(msg);
return true;
}
public boolean error(String msg) {
javaUtilLogger.severe(msg);
return true;
}
public boolean error(String msg, Throwable t) {
javaUtilLogger.log(Level.SEVERE, msg, t);
return true;
}
public boolean info(String string, Throwable e) {
javaUtilLogger.log(Level.INFO, string, e);
return true;
}
public boolean debug(String msg) {
javaUtilLogger.log(Level.FINE, msg);
return true;
}
public boolean debug(String msg, Throwable t) {
javaUtilLogger.log(Level.FINE, msg, t);
return true;
}
}
private static class SimpleFormatter extends Formatter {
@Override
public String format(LogRecord record) {
StringBuffer sb = new StringBuffer(80);
final String ln = record.getLoggerName();
final String msg = record.getMessage();
int level = record.getLevel().intValue();
if (level == Level.INFO.intValue())
sb.append("[INFO] ");
else if (level == Level.WARNING.intValue())
sb.append("[WARNING] ");
else if (level == Level.SEVERE.intValue())
sb.append("[SEVERE] ");
if (null != ln) {
sb.append(record.getLoggerName());
if (ln.length() + msg.length() > 75)
sb.append("\n");
else
sb.append("\t");
}
sb.append(record.getMessage());
sb.append("\n");
final Throwable thr = record.getThrown();
if (null != thr) {
ByteArrayOutputStream btbuff
= new ByteArrayOutputStream(80);
sb.append("Exception: ");
thr.printStackTrace(new PrintStream(btbuff));
sb.append(btbuff.toString());
sb.append("\n");
}
return sb.toString();
}
}
@param
<code></code>
@return
public static ILogger getLogger(String ID) {
java.util.logging.Logger logger
= java.util.logging.Logger.getLogger(ID);
Handler h = new ConsoleHandler();
h.setFormatter(new SimpleFormatter());
logger.setUseParentHandlers(false);
logger.addHandler(h);
return new Logger(logger);
}
}