I know all of the philosophical arguments against preprocessors and macros in Java. I don\'t agree that just because some may abuse a language feature, it should be excluded
Logging should be a cross-cutting concern, anyway. It's possible to do what you want with aspects.
Update
@ralph
Well, this is a question from 2+ years ago, but since I'm having the same need for __LINE__
and __FILE__
and you had mentioned SCALA; here are some ideas I'm having, using Scala macros (as of v2.10.0-RC1)
def $currentPosition:String = macro _currentPosition;
def _currentPosition(c:Context):c.Expr[String]={ import c.universe._;
val pos = c.enclosingPosition;
c.Expr(Literal(Constant(
s"${pos.source.path}: line ${pos.line}, column ${pos.column}" )))
}
Macros being evaluated at compile-time, $currentPosition
is replaced with a literal string that describes its position in the source code. For example, put in a println
at line 13, it displays:
/sandbox/tmp_juno_workspace2/LogMacro_Test/src/test/Trial.scala: line 13, column 15
I have not played with these mechanisms extensively, but by tweaking the thing, one can develop the logging features (s)he requires (I should add that writing macros can be difficult - it is for me!).
IMHO the "correct" way to achieve this would be to write a compiler plugin to perform the substitution, but is it really worth that amount of effort?
You can use the compiler API to do this, but be careful. The "rules" for annotation processors/compiler plugins state that they are not supposed to modify the class being generated. Sun/Oracle may enforce this at anytime.
For now, have a peek at http://projectlombok.org. It uses the compiler API to generate getters, setters and so forth. They have source code that you could use as a model, or you could contribute handlers to them.
you could probably do something like the following:
public class Foo {
@FileName private static String fileName;
@LineNumber private static int lineNumber;
...
public void foo() {
log(fileName, lineNumber, "some message");
}
}
Then have the annotation processor change the fileName and lineNumber references to the actual file/line.
Just be aware that this could break with later JDK versions. I don't know if Sun/Oracle will actually enforce the "don't modify the class being generated" rule, but they could.