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 for all.
I would like to include __FILE__
and __LINE__
macros in my Java and Scala code for efficient logging. Any use of Exception is unacceptable because of runtime performance impacts. Those people who argue that logging can be turned off in "production code" should heed the advise of Brian Kernighan:
Removing the error messages "now that the program is working" is like wearing a parachute on the ground, but taking it off once you're in the air.
Is there any possibility that these macros might make it into the language? If not, is there any way to run a preprocessor like m4 using Maven?
Thanks.
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?
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)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 aprintln
at line 13, it displays: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!).
Logging should be a cross-cutting concern, anyway. It's possible to do what you want with aspects.
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:
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.