Javadoc generation

1,944 views
Skip to first unread message

StefCl

unread,
Jan 12, 2010, 4:15:55 AM1/12/10
to Project Lombok
Hello,

I'm very interested in to @Data and @Setter / @Getter annotation. Our
internal policy requires that we document every getter/setter method
in order to generate a clean java documentation, is there any
workaround in this regard?

Kind regards

Reinier Zwitserloot

unread,
Jan 12, 2010, 9:59:02 AM1/12/10
to Project Lombok
Yes, fix your notion of 'clean java documentation'. A public API
method that has no javadoc is not broken. I'd argue the opposite,
THIS:

public class User {
/**
* Returns the name of the user.
*
* @return The name of the user.
*/
public String getName() {
return this.name;
}
}

is very very broken, even though I see it fairly often and is a style
espoused in many enterprise settings. It's broken because it repeats
itself ad nauseam, and violating the 'Dont-Repeat-Yourself' principle
is always bad (see footnote 1), and in this case, worse, 2 of the 4
repeats are in comments, and comments are _impossible_ to unit/
integration/regression test. Therefore, any need to change name later
will most likely result in an outdated (and probably confusing and
wrong) until someone bothers to notice it.

The pragmatic endresult for the API user is this:
- documentation that is needlessly long and repetitive (User.getName
() returns the "name" of the "User"? I really need the docs to tell me
this!)
- documentation is going to run out of date. For example, if
User.getName() is later changed to getFullName and a method,
getNickName is added, then the original documentation is less useful
than the method name and can get confusing.

The pragmatic endresult for the ones coding the API is this:
- source files explode into truly stupendously large files (500+
lines for a simple @Data class that, with lombok and no javadoc, would
have been 5)
- many violations of DRY, some of which can't even be tested.
- all in all this spells out: Massive maintainance headache.


The solution to this problem is to stop seeing missing javadoc as
indicative of a broken state. Comments are BAD and this extends to a
certain extent to javadoc: If the code itself, by using clear
structure and properly chosen names of things (parameters, methods),
conveys its meaning naturally, then that is always far superior to
writing comments, which run out of date and cannot be tested.


We're unfortunately not always in a position to change the accepted
style rules, even if they aren't very good, so we may be able to cater
to this scenario. Also, there's the situation where a basic getter/
setter DOES in fact need documentation to highlight certain specific
stuff that can't be conveyed in the field name, so let's brainstorm a
solution to this.

We could copy any javadoc on the field over to the getter and setter,
and 'link' the getter and setter to each other using an @see
annotation. But, the javadoc for a getter and for a setter aren't the
same. 3 solutions spring to mind:

1. Copy over the javadoc, and add a specific line that is just
"returns the (fieldName) from the (className)" and "sets the
(fieldName) for the (className)" along with @returns and @param. This
way if you want the standard javadoc you just have to javadoc the
field with /** */ and we'll add the rest.

2. Accept the javadoc that's there as the getter javadoc, and generate
nothing for the setter, unless there's a top level div or p tag in the
javadoc with 'class="setterDocs"'. In that case we rip out the
contents, use that as setter javadoc, and leave the rest as getter
javadoc. We'll take any @return that's there as being for the getter,
and any @param as for the setter.

I'm leaning towards #2 as doing #1 just feels like propagating a
ridiculous java practice. With #2, you can generate the drudgery
javadoc like so:

/**
* Returns the name of the User.
* <div class="setterDocs">
* Sets the name of the User.
* </div>
*
* @param name The new name of the User.
* @return The name of the User.
*/
@Getter @Setter private String name;

As a last bit of boilerplate reduction, we may allow a templatey way
to fill this in:

/**
* {@lombok default}
*/
@Getter @Setter private String name;


What do you think? Which one seems more likely to work for you? What
syntax would be good for this? The stuff I've reproduced below is just
a strawman syntax so we have something to point at while we discuss
options.


footnote 1: Why is DRY bad?

DRY is bad for two reasons:

1. it's a maintainance nightmare; if ever you want to change something
that's been repeated elsewhere, you break stuff unless you change it
in all other places as well. The IDE can figure out the link between
'foo.method()' and the declaration of 'method' in Foo.java, but it is
far less good at seeing such links in other places.

2. The information density of repeated stuff is by definition bad: It
has the complexity density of the thing you copied, but, as it is
repeated info, the information density is low. The good scenario is
for stuff to carry a lot of information (high information density) but
not be very hard to understand (low complexity density). DRY
violations are the reverse.

StefCl

unread,
Jan 13, 2010, 5:48:15 AM1/13/10
to Project Lombok
I agree that some getter/setters comments may look useless, but as you
said it's not always the case and some people (including me) feel
uncomfortable about mixing documented and undocumented methods in a
code documentation. Especially if that javadoc is made available to a
third party company.

Let's consider this example :

private String fileEncoding = null;

/**
* Get the file encoding. Most common values are UTF-8, Latin2.
* @return fileEncoding, The file encoding, null = auto-detect.
*/
public String getFileEncoding();

/**
* Set the file encoding, if not set by the user, we will try to detect
it using byte order mark.
* @param fileEncoding The file encoding, null = auto detect.
*/
public String setFileEncoding(String fileEncoding);

Ok, please do not focus on how java compliant it is, I know there
might be classes or constants in the JDK related to encodings.

A solution that seems reasonable to me would be to share the same
documentation block between the getter and the setter, I mean the
remarks concerning null acceptation, auto-detect, possible values, are
all part of the same *property* documentation. I'm not sure it's that
common to have completely different comments between a getter and a
setter that affect the same member variable, so why not describing it
as a property.

Once that property is properly documented, there's not much left to
say in @param and @return, a default text like "the current value
of", "new value for" would be more than enough.

Something like :

/**
* The file encoding, most common values are (.....) if set to null
(default), the code will try to detect it automatically using byte
order mark.
*/
@Getter @Setter
private String fileEncoding = null;

which is, in my opinion, not too complicated, not redundant and does
its job perfectly as describing the property.
What do you think?

v6ak

unread,
Jan 13, 2010, 7:48:48 AM1/13/10
to Project Lombok
On 13 led, 11:48, StefCl <stefatw...@gmail.com> wrote:
> Something like :
>
> /**
> * The file encoding, most common values are (.....) if set to null
> (default), the code will try to detect it automatically using byte
> order mark.
> */
> @Getter @Setter
> private String fileEncoding = null;
>
> which is, in my opinion, not too complicated, not redundant and does
> its job perfectly as describing the property.

I agree that some extra note can be useful. I was imaginating this one
variant when I was writing following issue:
http://code.google.com/p/projectlombok/issues/detail?id=97&colspec=ID%20Type%20Status%20Priority%20Target%20Component%20Owner%20Summary

v6ak

Reinier Zwitserloot

unread,
Jan 13, 2010, 5:28:36 PM1/13/10
to Project Lombok
We talked about it and will (eventually) add this feature; see issue
97:

http://code.google.com/p/projectlombok/issues/detail?id=97

On Jan 13, 1:48 pm, v6ak <v...@volny.cz> wrote:
> On 13 led, 11:48, StefCl <stefatw...@gmail.com> wrote:
>
> > Something like :
>
> > /**
> > * The file encoding, most common values are (.....) if set to null
> > (default), the code will try to detect it automatically using byte
> > order mark.
> > */
> > @Getter @Setter
> > private String fileEncoding = null;
>
> > which is, in my opinion, not too complicated, not redundant and does
> > its job perfectly as describing the property.
>
> I agree that some extra note can be useful. I was imaginating this one

> variant when I was writing following issue:http://code.google.com/p/projectlombok/issues/detail?id=97&colspec=ID...
>
> v6ak

StefCl

unread,
Jan 14, 2010, 2:24:16 AM1/14/10
to Project Lombok
Thanks,
The proposed syntax sounds great!
Reply all
Reply to author
Forward
0 new messages