Why is it there in the first place?
You've checked unstable code into the mainline? Why?
Unstable code shouldn't be checked into trunk / main / master or whatever the main trunk name is. This is considered to be high risk development and should instead have been sequestered off in its own branch that you worked on rather than checked into main.
I would strongly encourage you (and your team lead) to read Advanced SCM Branching Strategies. In particular, pay attention to the development role and what it says about what is considered to be high risk development:
In general, consider using separate branches for each high-risk project. High risk projects are characterized by large size, large numbers of people, unfamiliar subject matter, highly technical subject matter, very tight time lines, uncertain delivery dates, incomplete or volatile requirements, and geographically distributed project teams. Similarly, consider designating a single branch for low risk development in each release. Several sources including [WING98] recommend using the mainline for this purpose. Consider the factors discussed above for the mainline before committing to this course of action. Low risk development may have different policy from the mainline even if you have multiple members of a product family coordinating through the mainline.
Letting people check unstable (or unused) code into mainline means that you will confuse future development efforts about trying to maintain this code. Every branch and clone of the rep from now until the end of time will contain this until someone says "its dead codE" and deletes it.
There are some that say "well, if its in a branch it gets forgotten" and while that may be true, having forgotten dead (and unstable) code in mainline is many times worse as it confuses all future development until it is removed - and then it is even more forgotten. A nicely named branch of "/fooProject/branches/WeisBigIdea" (or equivalent) is visible and easier to work with in the future - especially if it kind of works.
@Deprecated
The first thing is the @Deprecated
annotation. This goes beyond the javadoc and spits out compiler warnings. javac
provides a -deprecation
flag that is described as:
Show a description of each use or override of a deprecated member or class. Without -deprecation
, javac
shows a summary of the source files that use or override deprecated members or classes. -deprecation is shorthand for -Xlint:deprecation
.
As noted, this goes above and beyond the standard compiler warnings.
In many IDEs, deprecated methods and values are shown with a strikethrough:
foo.bar();
And would produce output like:
$ javac -Xlint:all Foo.java Bar.java
Bar.java:2: warning: [deprecation] Foo in unnamed package has been deprecated
interface Bar extends Foo { }
^
Depending on your build structure, you may have warnings break the build. This would only break the build if one of your classes was used (not if it is just simply compiled in).
@CustomAnnotation
There are many approaches to this. For example, the Lightweight javac @Warning annotation which provides an annotation processor that fires off a warning at compile time when something with that annotation is used (a netbeans tutorial on custom annotation processors so you can get an idea of what is going on behind the scenes).
Oracle even describes an example of using custom annotations for an @Unfinished
annotation in Making the Most of Java's Metadata, Part 2: Custom Annotations.
With the AnnotationProcessor, you can run arbitrary code at compile time. Its really up to you to decide what you want it to do. Warn, break the build when something is used. There are numerous tutorials out there on the web for how to write this sort of code. Whether you want to generate an error when its compiled (this will be annoying and lead to it getting deleted) or if its used (quite a bit more complex to write).
Note that all of this implies changing the builds to actually use the annotation processor.