IntelliJ + External Library + @PropertyKey How To
I am a daily user of
IntelliJ IDEA to edit
my Java code and
Apache Wicket to write my web
application. I decided recently to use IntelliJ's annotations to
make my code a little more robust by using @Nullable
,
@NotNull
, @NonNls
and
@PropertyKey
.
In this blog post I explain how to
manually add annotation to an external library.
IntelliJ annotations
Let's explain quickly how you can use these annotations and the problem I faced with the latter.
-
@Nullable
: tells the editor that the field, parameter, return type may benull
. This way, IDEA will highlight you if you forget to check nullity. -
@NotNull
: tells the editor that the field, parameter, return type will never benull
. This way, IDEA will highlight you if you do unnecessary null checking. It even can throwRuntimeException
if a method is invoked with anull
parameter although it shouldn't. The exception tells exactly what parameter of what method, it can help a lot debbugging aNullPointerException
coming out from nowhere ! -
@NonNls
: tells the editor that the string you entered is not involved in internationalization of any kind so it will not bother you with duplicate string literals. -
@PropertyKey(resourceBundle)
: tells the editor that the following string have to be present in a specific resource bundle. This way, IDEA is able to notice you missing translations in your application.
How to use it...
The first thing to do to use it is simply to annotate your source code like this:
This method is completely useless, but it can ease explaining how
annotations work. By looking at the prototype we can now see that
the method never returns null
value, doesn't accept a
first parameter with a null
value, takes its second
parameter from the "fr.gatay.cedric.bloggure.language
"
resource bundle and accepts a potentially null
third
parameter.
Last but not least, if we look at the implementation, we see that we
tell IDEA not to verify the "Return Value" string against i18n
rules.
How to use it, in libraries...
If in your project, you want to use this feature in included
libraries you might be glad the guys at Jetbrains included a feature
called "External annotations". It allows you to specify a location
where to save these annotations.
Here is a quick example on how to add @NotNull
on
org.apache.wicket.extensions.Initializer
:
First, invoke intention action, and select the annotation you want
to put
Then, configure external annotation root, I tend to use a folder
named annotation at the root of my workspace.
That's all, if you look at the folder you specified, you will have
the following structure:
In the folder corresponding to the package of the class you wanted
to annotate you will find an annotations.xml
file like
the following:
The problem is that it is not easily possible to add
@PropertyKey
or @NotNls
annotation in
external libraries.
How to manually add an annotation
In my case, I wanted to add @PropertyKey
on Apache
Wicket feedback messages methods. My Wicket Application have a
converter for string that handles internationalization, so I want to
add
@PropertyKey(resourceBundle="fr.gatay.cedric.bloggure.language")
to the String parameter of
org.apache.wicket.Component
info and error methods.
By digging into the generated annotations.xml
file for
@NotNull
annotation, I found out how to manually add my
annotation. In my case, I end up with an
annotations.xml
file like this in the folder
${annotationsRoot}/org/apache/wicket/
:
If you look closely at this sample, you will quickly understand how
things work. First, the item
element specify the method
on which you want to put the annotation, please notice the number at
the end specifying the parameter on which the annotation will be
applied (starting at 0).
Inside the item
element, you find the
annotation
element specifying the fully qualified class
name of the annotation to apply. In the case of an annotation with
parameters (like @PropertyKey
), you can set these
parameters using the val
element, name
xml
attribute refers to the attribute's name and val
xml
attribute to the attribute's value.
You might need to restart IntelliJ for the new values to be read.