I'm about to commit an ugly temporary hack in order to work around a blocking issue while we wait for an external resource to be fixed. Aside from marking it with a big scary comment and a bunch of FIXMEs, I'd love to have the compiler throw an obvious warning message as a reminder so we don't forget to take this out. For example, something like:
[javac] com.foo.Hacky.java:192: warning: FIXME temporary hack to work around library bug, remove me when library is fixed!
Is there a way I can cause an intentional compiler warning with a message of my choosing? Failing that, what's the easiest thing to add to the code to throw an existing warning, with perhaps a message in a string on the offending line so it gets printed in the warning message?
EDIT: Deprecated tags don't seem to be doing anything for me:
/**
* @deprecated "Temporary hack to work around remote server quirks"
*/
@Deprecated
private void doSomeHackyStuff() { ... }
No compiler or runtime errors in eclipse or from sun javac 1.6 (running from ant script), and it's definitely executing the function.
I wrote a library that does this with annotations: Lightweight Javac @Warning Annotation
Usage is very simple:
And compiler will throw warning message with your text
One good hack deserves another... I usually generate compiler warnings for the described purpose by introducing an unused variable in the hacky method, thus:
This unused variable will generate a warning which (depending upon your compiler) will look something like this:
This solution is not as nice as a custom annotation, but it has the advantage that it requires no advance preparation (assuming the compiler is already configured to issue warnings for unused variables). I would suggest that this approach is only suitable for short-lived hacks. For long-lived hacks, I would argue that effort to create a custom annotation would be justified.
how about marking the method or class as @Deprecated? docs here. Note that there is both a @Deprecated and a @deprecated - the capital D version is the annotation and the lowercase d is the javadoc version. The javadoc version allows you to specify an arbitrary string explaining what is going on. But compilers are not required to emit a warning when seeing it (though many do). The annotation should always cause a warning, though i don't think you can add an explanation to it.
UPDATE here is the code I just tested with: Sample.java contains:
SampleCaller.java contains:
when i run "javac Sample.java SampleCaller.java" i get the following output:
I am using sun's javac 1.6. If you want an honest to goodness warning rather than just a note, use the -Xlint option. Maybe that will percolate up through Ant properly.
I think that a custom annotation, which will be processed by the compiler, is the solution. I frequently write custom annotations to do things at runtime, but I never tried to use them at compilation time. So, I can only give you pointers on the tools you may need :
I don't know if this solution is really practicable. I'll try to implement it myself when I find some time.
Edit
I successfully implemented my solution. And as a bonus, I used java's service provider facility to simplify its use. Actually, my solution is a jar that contains 2 classes : the custom annotation and the annotation processor. To use it, just add this jar in the classpath of your project, and annotate whatever you want ! This is working fine right inside my IDE (NetBeans).
Code of the annotation :
Code of the processor :
To enable the resulting jar as a service provider, add the file
META-INF/services/javax.annotation.processing.Processor
in the jar. This file is an acsii file that must contain the following text :Some quick and not so dirty approach, may be to use a
@SuppressWarnings
annotation with a deliberately wrongString
argument:This will generate a warning because it is not recognized by the compiler as a specific warning to suppress:
One technique that I've seen used is to tie this into unit testing (you do unit test, right?). Basically you create a unit test that fails once the external resource fix is achieved. Then you comment that unit test to tell others how to undo your gnarly hack once the issue is resolved.
What's really slick about this approach is that the trigger for undoing your hack is a fix of the core issue itself.