Is there a way to link JDK annotations to requirements? - java

Hi guys: Is there an open source way to associate java #annotations to functional requirements, or for example, TRAC tickets, etc? I want to do something like this:
I'm thinking along the lines of an eclipse plugin which somehow links up with another FOSS project tracking tool, wiki, or maybe even a CSV file.
A somewhat silly but exemplary illustration of what I desire is below:
#Requirement WalkDogTwiceADay
public void walkTheDog()
{
}
#Requirement WalkDogTwiceADay
public void dogWalkerThread()
{
walkTheDog(); //in the morning.
Thread.sleep(36000000);
walkTheDog(); //at night
}

Annotations are metadata, they simply add information to your code for other tools to use or to be inspected at runtime via reflection.
One thing you can do is write an annotation processor that will generate the necessary artefacts. Those could be configuration files, scripts, code...
Another thing you can do is write some tool that knows how to interpret your annotations and uses reflection to find them and take the appropriate actions. For this you'd need to make sure that the annotation type is set to have runtime retention, as opposed to only source or class.
Perhaps some of the stuff found in the answers to this question might prove of use. If that's the case, go ahead and use it. But writing custom annotation processors or code for handling them is not all that terribly hard. The difficult part is getting to know the Java model API that's used by annotation processors, which is like reflection but at compile time (before you have fully-formed classes).

in a previous life, we did something similar with #requirement ##### annotations, and then had a custom javadoc task that turned the requirement annotations into hyperlinks in the javadocs.
I was going to write an addin for eclipse that turned them into links in the code as well, but never got that far.

Related

Java custom annotation/decorator #Testing

I want to do something like this:
#Testing
private void methodThatGivesWarningIfUserTriesToUseThis() {
}
where #Testing is a custom annotation/decorator in Java. I'd like the behaviour of this #Testing annotation to act ALMOST EXACTLY like the #Deprecated annotation - if i or someone else accidentally tries to use this in other parts of the code, the IDE will give a warning (and the method name also has a strike-through across the font). So for ex
how do i do this?
**note: i do not want to use #Deprecated because the method is not deprecated, i just want only to use it for testing purposes
**this marker should also be checked at compile time, not runTime.
The problem is that annotations are, as their name states, only for annotating :)
Creating such annotation is pretty easy, you need to do something like this:
public #interface Testing
In order for it to be used by your IDE at compile time you have to write a plug-in.
Here is a good start I found in another SO question for starting with the plugin development.
It sounds like you're describing something like #VisibleForTesting, which is part of the Guava libraries (formerly known as "Google Collections"). If you do create one of your own, you'll probably want it to be #Documented and #Retention(SOURCE).
I'm not aware of any hook or feature that would cause non-#Deprecated members to trigger warnings or IDE flags as if they were #Deprecated. Because the Mirror API and Reflection API don't track individual expressions and statements (as documented in this SO answer), you probably won't have much luck detecting it yourself without a full Java parser.
You might consider writing a custom Lint rule to solve this problem. When your #Testing annotation is detected, the IDE would show a Lint warning (e.g., a yellow underline in the case of Eclipse+ADT).
A detailed guide to scanning Java source files for specific issues with Lint can be found in the Android Tools docs here.

Java annotation for commented out code

So like probably many people out there I usually comment out code temporarily, mostly for debugging purposes. I currently put something like **DEBUG** or whatever that is easily searched for, but I thought having the compiler output a warning (or even an error) whenever it finds code that is temporarily commented out could be useful. I thought of using an annotation, but annotations can't be used to mark comments.
Does anyone know of a better approach than putting an easily searchable string in the commented-out section of code?
there are plenty of code inspection tools out there that can alert you to the presence of code patterns that you define. most of them have built-in support for detecting common stuff like "//todo" comments left in code etc.
most IDEs support auto-detection of //todo as well (intellij idea, for example).
a common command-line tool for this is checkstyle. you could run it as part of your build and have it point these things out to you
At least Eclipse allows you to use (and define your own) markers put in comments, that can be easily listed afterwards. There's at least TODO and XXX, but I believe you could make your own as well.
If you're using Maven, consider to use the taglist-maven-plugin.

Modify Java sourcecode programmatically with Java or Groovy

To automate certain manual tasks in an legacy project, I need to modify existing java files from within java or groovy code.
I donĀ“t want to use RegEx, because it would be neither quick nor clean in my opinion.
I found javassist and srcgen4javassist. The first one lets me modify my sources as I wish, but only writes bytecode, loosing all comments and annotations. And with the second one I didnt manage to read an existing Class not created with srcgen4javassist itself.
Is there an elegant solution, or do i need to bite the bullet and use Regex?
you could really parse the code using something like eclipse's ASTParser at which point you coudl locate your replacement targets xpath-style, but its a lot of work.
you could also consider marking replacement areas with annotation and writing an annotation processor to generate/alter sources at runtime, but (at least in my opinion) the API is cumbersome.
you can combine regexp with some marker in the source code, something like
//START REPLACEMENT-TARGET
...code to be edited/replaced
//END REPLACEMENT TARGET
which would make your regexp targeting a lot safer.

Retro-actively add Java annotations to methods?

Is there a way to modify .class files in order to add Java annotations to certain methods? Basically I want to traverse methods of each class file in a jar file and annotate certain ones. Note that this is not at run-time while using the jar file. Rather, after I'm done I want to have modified class files with the annotations.
I do have access to the source code, so if there's an automatic source code modifier, that would work as well...
I'm assuming I'll need a tool such as Javassist or ASM. If so, which one should I use and how would I go about it?
Actually, this is a classic use case for AspectJ:
declare #method : public * BankAccount+.*(..) : #Secured(role="supervisor")
While I will grant you that direct byte code manipulation is more powerful, AspectJ is much more user-friendly, and it immediately gives you compiler warnings when you are doing something wrong.
Also, if you use Load Time Weaving, you can leave the original library jar unchanged, because the weaving happens at class-load time.
Reference:
Declare Annotation
AspectJ in Action (book)
Googling for an hour or so turned this article up which seems to completely answer my question: use ASM. To write class files using the changed bytecode, use ClassWriter.
Well, time to get to work then, I guess. :)

The drawbacks of annotation processing in Java?

I am considering starting a project which is used to generate code in Java using annotations (I won't get into specifics, as it's not really relevant). I am wondering about the validity and usefulness of the project, and something that has struck me is the dependence on the Annontation Processor Tool (apt).
What I'd like to know, as I can't speak from experience, is what are the drawbacks of using annotation processing in Java?
These could be anything, including the likes of:
it is hard to do TDD when writing the processor
it is difficult to include the processing on a build system
processing takes a long time, and it is very difficult to get it to run fast
using the annotations in an IDE requires a plugin for each, to get it to behave the same when reporting errors
These are just examples, not my opinion. I am in the process of researching if any of these are true (including asking this question ;-) )
I am sure there must be drawbacks (for instance, Qi4J specifically list not using pre-processors as an advantage) but I don't have the experience with it to tell what they are.
The ony reasonable alternative to using annotation processing is probably to create plugins for the relevant IDEs to generate the code (it would be something vaguely similar to override/implement methods feature that would generate all the signatures without method bodies). However, that step would have to be repeated each time relevant parts of the code changes, annotation processing would not, as far as I can tell.
In regards to the example given with the invasive amount of annotations, I don't envision the use needing to be anything like that, maybe a handful for any given class. That wouldn't stop it being abused of course.
I created a set of JavaBean annotations to generate property getters/setters, delegation, and interface extraction (edit: removed link; no longer supported)
Testing
Testing them can be quite trying...
I usually approach it by creating a project in eclipse with the test code and building it, then make a copy and turn off annotation processing.
I can then use Eclipse to compare the "active" test project to the "expected" copy of the project.
I don't have too many test cases yet (it's very tedious to generate so many combinations of attributes), but this is helping.
Build System
Using annotations in a build system is actually very easy. Gradle makes this incredibly simple, and using it in eclipse is just a matter of making a plugin specifying the annotation processor extension and turning on annotation processing in projects that want to use it.
I've used annotation processing in a continuous build environment, building the annotations & processor, then using it in the rest of the build. It's really pretty painless.
Processing Time
I haven't found this to be an issue - be careful of what you do in the processors. I generate a lot of code in mine and it runs fine. It's a little slower in ant.
Note that Java6 processors can run a little faster because they are part of the normal compilation process. However, I've had trouble getting them to work properly in a code generation capacity (I think much of the problem is eclipse's support and running multiple-phase compiles). For now, I stick with Java 5.
Error Processing
This is one of the best-thought-through things in the annotation API. The API has a "messenger" object that handles all errors. Each IDE provides an implementation that converts this into appropriate error messages at the right location in the code.
The only eclipse-specific thing I did was to cast the processing environment object so I could check if it was bring run as a build or for editor reconciliation. If editing, I exit. Eventually I'll change this to just do error checking at edit time so it can report errors as you type. Be careful, though -- you need to keep it really fast for use during reconciliation or editing gets sluggish.
Code Generation Gotcha
[added a little more per comments]
The annotation processor specifications state that you are not allowed to modify the class that contains the annotation. I suspect this is to simplify the processing (further rounds do not need to include the annotated classes, preventing infinite update loops as well)
You can generate other classes, however, and they recommend that approach.
I generate a superclass for all of the get/set methods and anything else I need to generate. I also have the processor verify that the annotated class extends the generated class. For example:
#Bean(...)
public class Foo extends FooGen
I generate a class in the same package with the name of the annotated class plus "Gen" and verify that the annotated class is declared to extend it.
I have seen someone use the compiler tree api to modify the annotated class -- this is against spec and I suspect they'll plug that hole at some point so it won't work.
I would recommend generating a superclass.
Overall
I'm really happy using annotation processors. Very well designed, especially looking at IDE/command-line build independence.
For now, I would recommend sticking with the Java5 annotation processors if you're doing code generation - you need to run a separate tool called apt to process them, then do the compilation.
Note that the API for Java 5 and Java 6 annotation processors is different! The Java 6 processing API is better IMHO, but I just haven't had luck with java 6 processors doing what I need yet.
When Java 7 comes out I'll give the new processing approach another shot.
Feel free to email me if you have questions. (scott#javadude.com)
Hope this helps!
I think if annotation processor then definitely use the Java 6 version of the API. That is the one which will be supported in the future. The Java 5 API was still in the in the non official com.sun.xyz namespace.
I think we will see a lot more uses of the annotation processor API in the near future. For example Hibernate is developing a processor for the new JPA 2 query related static meta model functionality. They are also developing a processor for validating Bean Validation annotations. So annotation processing is here to stay.
Tool integration is ok. The latest versions of the mainstream IDEs contain options to configure the annotation processors and integrate them into the build process. The main stream build tools also support annotation processing where maven can still cause some grief.
Testing I find a big problem though. All tests are indirect and somehow verify the end result of the annotation processing. I cannot write any simple unit tests which just assert simple methods working on TypeMirrors or other reflection based classes. The problem is that one cannot instantiate these type of classes outside the processors compilation cycle. I don't think that Sun had really testability in mind when designing the API.
One specific which would be helpful in answering the question would be as opposed to what? Not doing the project, or doing it not using annotations? And if not using annotations, what are the alternatives?
Personally, I find excessive annotations unreadable, and many times too inflexible. Take a look at this for one method on a web service to implement a vendor required WSDL:
#WebMethod(action=QBWSBean.NS+"receiveResponseXML")
#WebResult(name="receiveResponseXML"+result,targetNamespace = QBWSBean.NS)
#TransactionAttribute(TransactionAttributeType.NOT_SUPPORTED)
public int receiveResponseXML(
#WebParam(name = "ticket",targetNamespace = QBWSBean.NS) String ticket,
#WebParam(name = "response",targetNamespace = QBWSBean.NS) String response,
#WebParam(name = "hresult",targetNamespace = QBWSBean.NS) String hresult,
#WebParam(name = "message",targetNamespace = QBWSBean.NS) String message) {
I find that code highly unreadable. An XML configuration alternative isn't necessarily better, though.

Categories

Resources