Update MRI projects release notes
[docs.git] / docs / contributor-guides / coding-guidelines / coding-guidelines-java.rst
1 .. _coding-guidelines-java:
2
3 ##########################
4 Coding Guidelines for Java
5 ##########################
6
7 *Note: This document is a work in progress.*
8
9 In General we follow the Google Java Code Style Guide with a few exceptions.
10 See: https://google.github.io/styleguide/javaguide.html
11
12 -  4 spaces indentation
13 -  120 characters line length
14 -  72 or 80 characters for Javadoc
15 -  import ordering
16    (https://wiki-archive.opendaylight.org/view/GettingStarted:_Eclipse_Setup#Import_ordering)
17 -  YangTools Design Guidelines
18    (https://wiki-archive.opendaylight.org/view/YANG_Tools:Design_and_Coding_Guidelines)
19 -  follow JLS modifier ordering
20    (http://checkstyle.sourceforge.net/config_modifier.html)
21 -  do not use underscores (_) in identifiers, as they trigger warnings with JDK8
22 -  Uppercase " *static final Logger LOG = ...* " (See 5.2.4 examples)
23
24 Checkstyle
25 ==========
26
27 All OpenDaylight projects automatically run Checkstyle, as the
28 ``maven-checkstyle-plugin`` is declared in the odlparent.
29
30 Checkstyle Warnings are considered as errors by default since Magnesium.
31 They will prevent your project from building if code violations are found.
32 Checkstyle enforcement can be disabled by defining the following property in the
33 related pom.xml:
34
35  .. code-block:: none
36
37    <properties>
38     <odlparent.checkstyle.enforce>false</odlparent.checkstyle.enforce>
39    </properties>
40
41 Utility classes with only static methods
42 ----------------------------------------
43
44 In general we recommend that you typically do not overuse utility classes with
45 only static methods, but instead write helper @Singleton classes without static
46 methods which you can easily @Inject via Dependency Injection into other classes
47 requiring them.
48 This makes it easier to use non-static helpers in other utilities which can then
49 in turn be @Inject into your helper (which you cannot do with static).
50 It also makes it easier to mock the helpers for use in unit tests.
51
52 If you must write utility classes with only static methods, or have existing
53 code that is not trivial to change, then please mark the respective class final,
54 and give it a private constructor.
55 Please do not throw any exception from the private constructor
56 (it is not required).
57
58 Suggested process (steps) to move a non-compliant project to enforcement
59 ------------------------------------------------------------------------
60
61 We recommend moving existing at least large projects (which typically have
62 hundreds or thousands of Checkstyle violations) to full compliance and
63 enforcement through a series of Gerrit changes on single artefacts (bundles),
64 as opposed to a single change fixing everything and change the POM to enable
65 enforcement all in one go (god forbid for an entire repository and not just a
66 single artifact), because:
67
68 #. single review would be virtually impossible to even remotely sensibly
69    code review by committers
70 #. batching style changes by type is easy to review (and approve lines
71    in bulk "by trust"), for example:
72
73    #. *(...project name...) Organize Imports for Checkstyle compliance*
74    #. *(...project name...) Checkstyle compliance: line length*
75    #. *(...project name...) Checkstyle compliance: various types of
76       small changes*
77    #. ''(...project name...) Checkstyle compliant Exception handling'
78    #. ''(...project name...) Checkstyle final clean up & enforcement'
79
80 #. it's particularly important to split and separately submit
81    "trivial pure cosmetic" (e.g. code formatting) from "interesting impactful"
82    (e.g. changes to exception handling) changes required by Checkstyle
83 #. in general, doing small steps and intermediate merges are more rewarding for
84    contributing developers than long running massive Gerrit changes
85 #. more small changes makes the contributors Stats Great Again
86    (ODL top contributors submit massive amounts of micro changes)
87
88 During such a process, it should be considered "normal" and perfectly
89 acceptable, that new intermediately merged changes introduce some (small)
90 regressions and "re-dirty" some previously cleaned up files;
91 it's OK that they'll be re-fixed as part of new changes by the developers
92 contributing the clean up in new changes (or rebases)
93 - until enforcement is enabled at the end of a series of clean up changes.
94
95 ``@SuppressWarnings``
96 ---------------------
97
98 If really needed, projects can override individual Checkstyle rules on a
99 case-by-case basis by using a ``@SuppressWarnings`` annotation:
100
101  .. code-block:: none
102
103    @SuppressWarnings("checkstyle:methodparampad")
104    public AbstractDataTreeListener (INetvirtSfcOF13Provider provider, Class<T> clazz) {
105    }
106
107 The rule ID (e.g. ``checkstyle:methodparampad`` above) is the name of the
108 respective Checkstyle module; these IDs can be found e.g. in the
109 ``git/odlparent/checkstyle/src/main/resources/odl_checks.xml``
110 configuration, or directly on the Checkstyle website from the
111 http://checkstyle.sourceforge.net/checks.html list.
112 For example, for the
113 http://checkstyle.sourceforge.net/config_coding.html#EqualsHashCode rule
114 you would put ``@SuppressWarnings("checkstyle:EqualsHashCode")``.
115
116 This ``@SuppressWarnings("checkstyle:...")`` should in practice be very very rarely
117 needed.
118 Please put a comment explaining why you need to suppress a Checkstyle warning
119 into the code for other to understand, for example:
120
121  .. code-block:: none
122
123    @Override
124    @SuppressWarnings("checkstyle:EqualsHashCode"
125    // In this particular case an equals without hashCode is OK because
126    // [explain!] (I'm a certified grown up and know what I'm doing.)
127    public boolean equals(Object obj) {
128
129 Please contact odlparent-dev@lists.opendaylight.org if you feel a Checkstyle
130 rule is too strict in general and should be reviewed.
131
132 The `Evolving Checkstyle old wiki page <https://wiki-archive.opendaylight.org/view/EvolvingCheckstyle>`__
133 documents how to test changes to Checkstyle rules.
134
135 Notes for particular Checks
136 ---------------------------
137
138 {@inheritDoc} JavaDoc
139 ^^^^^^^^^^^^^^^^^^^^^
140
141 This JavaDoc is useless visual noise that hinders code readability.
142 It is not required to put this, and has no impact. JavaDoc does this by default:
143
144 .. code:: java
145
146    /**
147     * {@inheritDoc}
148     */
149    @Override // (or on a constructor)
150
151 The only case where {@inheritDoc} is useful is when you actually have
152 additional Java documentation.
153 Default JavaDoc interprets as replace the parent documentation.
154 If you truly want the full text of the parent to be copy/pasted by JavaDoc in
155 addition to your additional one, then use:
156
157 .. code:: java
158
159    /**
160     * {@inheritDoc}
161     * For this specific implementation...
162     */
163    @Override // (or on a constructor)
164
165 See also
166 https://github.com/sevntu-checkstyle/sevntu.checkstyle/issues/467 &
167 http://tornorbye.blogspot.ch/2005/02/inheriting-javadoc-comments.html
168
169 IllegalThrows
170 ^^^^^^^^^^^^^
171
172 Instead of declaring "throws Exception", in almost all cases you should instead
173 throw a custom existing or new ODL Exception.
174 Instead of an unchecked exception (unchecked = extends RuntimeException;
175 if you must for some technical reason, but should be rare, and avoided),
176 it's recommended to use a custom module specific checked exception
177 (checked = extends Exception);
178 which can wrap a caught RuntimeException, if needed.
179
180 In order to avoid proliferation of many kinds of checked Exception subtypes for
181 various particular nitty gritty things which could possibly go wrong, note that
182 it in ODL is perfectly OK & recommended to have just ONE checked exception for a
183 small given functional ODL module (subsystem), and throw that from all of its
184 API methods.
185 This makes sense because a typical caller wouldn't want do anything different -
186 what you are "bubbling up" is just that one of the operations which one module
187 asked another ODL module to do couldn't be performed.
188 This avoids having multiple throws for each exception in API methods, and having
189 problems with extendibility due to having to add more exceptions to the "throws"
190 declaration of API methods.
191
192 The exception for "throws Exception" may be a main() method where it's customary
193 to let anything propagate to the CLI, or ``@Test testSomething() throws Exception``
194 where it is acceptable (Checkstyle does NOT flag this particular use of
195 "throws Exception" in @Test methods).
196
197 IllegalCatch
198 ^^^^^^^^^^^^
199
200 The `IllegalCatch <http://checkstyle.sourceforge.net/config_coding.html#IllegalCatch>`__
201 violation should almost never be suppressed in regular "functional" code.
202 Normal code should only catch specific sub classes of the checked Exception,
203 and never any generic and/or unchecked exceptions.
204
205 In the old pre-Java 7 days, some people used "catch (Exception e)" to
206 "save typing" as a shorthand for having to catch a number of possibly thrown
207 types of checked exceptions declared with "throws" by a method within the try
208 block.
209 Nowadays, `since Java 7, using a multi-catch block <http://docs.oracle.com/javase/7/docs/technotes/guides/language/catch-multiple.html>`__
210 is the right way to do this.
211 In addition to being "nicer" to read because it's clearer, much more importantly
212 than, a multi-catch does not also accidentally catch RuntimeException, as catch
213 (Exception e) would.
214 Catching RuntimeException such as NullPointerException & Co. is typically not
215 what the developer who used "catch (Exception e)" as shorthand intended.
216
217 If a catch (Exception e) is used after a try { } block which does not call any
218 methods declaring that they may throw checked exceptions with their throws
219 clause (perhaps not anymore, after code was changed), then that catch may really
220 have been intended to catch any possible RuntimeException instead?
221 In that case, if there exceptionally really is a particular reason to want to
222 "do something and recover from anything that could possibly go wrong, incl.
223 NullPointerException, IndexOutOfBoundsException, IllegalArgumentException,
224 IllegalStateException & Co.", then it is clearer to just catch
225 (RuntimeException e) instead of catch (Exception e).
226 Before doing this, double check that this truly is the intention of that code,
227 by having a closer look at code called within the try,
228 and see if that called code couldn't simply be made more robust.
229 Be particularly careful with methods declaring checked exceptions in their
230 “throws” clause:
231 if any matching exception is thrown inside the “try” block, changing
232 “catch (Exception e)” to “catch (RuntimeException e)” could change the method
233 behavior since the exception will exit the method instead of being processed by
234 the “catch” block.
235
236 Proliferation of catch (Exception or RuntimeException e)
237 { LOG.error("It failed", e); } in regular "functional" code is a symptom of a
238 missing abstraction in framework code; e.g. an Abstract interface implementation
239 helper with correct default error handling, so that functional code does
240 not have to repeat this over and over again.
241 For example:
242
243 #. For DataBroker related transaction management, check out the (at the time of
244    writing still in review) new utilities from
245    `c/63372 <https://git.opendaylight.org/gerrit/#/c/63372/>`__ & Co.
246 #. For RPC related catch, see
247    `c/63413 <https://git.opendaylight.org/gerrit/#/c/63413/>`__
248 #. Instead of ``catch(Exception)`` after a ``try { close(anAutoCloseable) }``
249    just use ``AutoCloseables.closeOrWarn(anAutoCloseable)`` introduced in
250    https://git.opendaylight.org/gerrit/#/c/44145/
251
252 Sometimes developers also simply don't see that an existing framework API
253 intends implementations to simply propagate their errors up to them.
254 For example, for Exception handling in:
255
256 #. OsgiCommandSupport's ``doExecute()``, the right thing to do is... nothing.
257    The parent ``doExecute()`` method declaration throws Exception,
258    and that is intentional by the Good People of Karaf.
259    Therefore, ``catch(Exception)`` in a OsgiCommandSupport's ``doExecute`` is not required
260    : in this case it's perfectly OK to just let any error "propagate" upwards
261    automatically.
262    If ``doExecute()`` calls other private methods of an OsgiCommandSupport
263    implementation, then it is perfectly OK to make those methods declare
264    ``"throws SomeException"`` too, and not "handle" them yourself.
265
266 #. Callable's ``call()`` passed to a ``DataStoreJobCoordinator enqueueJob()``,
267    the right thing to do is... nothing.
268    Do not catch ``(Exception)`` but let it propagate.
269    If it's useful to "augment" the exception message with more custom details
270    which are available inside Callable's ``call()``, then the right thing to do is
271    to ``catch (Exception e)
272    { throw new YourProjectApiException("Failed to ... for {}", aDetail, e); }``
273    and, exceptionally, use ``@SuppressWarnings("checkstyle:IllegalCatch")``.
274
275 #. ``org.opendaylight.infrautils.inject.AbstractLifecycle``'s start() and stop()
276    methods, again the right thing to do is... nothing.
277    Do not catch any Exception but let it propagate.
278
279 Here are some cases where ``catch(Exception)`` is almost always wrong, and a
280 respective ``@SuppressWarnings`` almost never acceptable:
281
282 #. In Tests code you typically just ``@Test testSomething() throws
283    (Some)Exception`` instead of catch,
284    or uses ``@Test(expected = ReadFailedException.class)``.
285    One rare case we have seen where it's justified is a
286    ``@Test(expected = ReadFailedException.class)``
287    with ``catch (Exception e) throw e.getCause()``.
288
289 #. In one time "setup" (initialization) kind of code.
290    For example, catch for a ``DataBroker registerDataChangeListener`` makes little
291    sense - it's typically much better to let a failure to register a data change
292    listener "bubble up" then continue, even if logged, and have users wonder why
293    the listener isn't working much later.
294
295 Only in lower-level "Framework" kind of code, catch (Exception e) is sometimes
296 justified / required,
297 and thus ``@SuppressWarnings("checkstyle:IllegalCatch")`` acceptable.
298
299 Catching ``Throwable`` in particular is considered an absolute No No
300 (see e.g. discussion in https://git.opendaylight.org/gerrit/#/c/60855/)
301 in almost all cases.
302 You may got confused any meant to catch Exception (see above)
303 or RuntimeException?
304
305 Carefully consider whether you mean to catch and set some flag and/or
306 log, and then rethrow, or intended to "swallow" the exception.
307
308 ``System.out``
309 ^^^^^^^^^^^^^^
310
311 The ``RegexpSingleLineJava`` "Line contains console output" and "Line contains
312 ``printStackTrace``" should NEVER be suppressed.
313
314 In ``src/main`` code, ``System.out.println`` has no place, ever (it should probably be
315 a ``LOG.info``; and ``System.err`` probably a ``LOG.error``).
316
317 In Java code producing Karaf console output, we should only use ``System.out``, and
318 add the corresponding ``@SuppressWarnings``. ``System.out`` handles pipes and remote
319 sessions correctly.
320
321 In ``src/test`` code, there should be no need to write things out - the point of a
322 test is to assert something.
323 During development of a test it is sometimes handy to print things to the console
324 to see what is going on instead of using the debugger, but this should be removed
325 in final code, for clarity, and non-verbose test execution.
326 If you must, do you a Logger even in a test - just like in ``src/main`` code.
327 This also makes it easier to later move code such as helper methods from test to
328 production code.
329
330 Javadoc Paragraph: < p > tag should be preceded with an empty line
331 ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
332
333 Checkstyle (rightfully) flags this kind of JavaDoc up as not ideal for
334 readability:
335
336 .. code:: java
337
338      /**
339       * Utilities for...
340       * <p>This...
341
342 and you can address this either like this:
343
344 .. code:: java
345
346      /**
347       * Utilities for...
348       *
349       * <p>This...
350
351 or like this:
352
353 .. code:: java
354
355      /**
356       * Utilities for...
357       * <p/>
358       * This...
359
360 Different ODL developers `agree to disagree <https://git.opendaylight.org/gerrit/#/c/46842/>`__
361 on which of the above is more readable.
362
363 Additional Resources
364 --------------------
365
366 -  ``Checkstyle`` http://checkstyle.sourceforge.net/
367 -  ``Maven``:
368    https://github.com/checkstyle/checkstyle/blob/master/src/main/resources/google_checks.xml
369 -  ``Eclipse``:
370    https://github.com/google/styleguide/blob/gh-pages/eclipse-java-google-style.xml
371 -  ``IntelliJ``:
372    https://github.com/google/styleguide/blob/gh-pages/intellij-java-google-style.xml
373 -  `How to set Checkstyle up in IntelliJ old wiki page <https://wiki-archive.opendaylight.org/view/How_to_set_Checkstyle_up_in_IntelliJ>`__
374
375 PMD Copy/Paste Detection (CPD)
376 ==============================
377
378 odlparent includes `PMD <https://pmd.github.io>`__ with its `CPD <https://pmd.github.io/pmd-6.0.0/pmd_userdocs_cpd.html>`__
379 (Copy/Paste detection), which will warn but yet not fail the build for any
380 duplicate code (not just within but also across classes within the same module)
381 .
382 You should refactor any such copy/pasted code, and can then enforce CPD to fail
383 the build for future non regression by adding this to your POM:
384
385 .. code-block:: text
386
387    <pmd.cpd.fail>true</pmd.cpd.fail>
388
389 Note that CPD's analysis is text-based and not semantic, so it will flag code
390 which "looks" identical to it even if it uses different Java types (which do not
391 share a common super type; so that it's non-trivial to refactor).
392 So in the unlikely case that there is a real good justified reason for what
393 looks like copy paste to PMD, you can selectively suppress true PMD CPD false
394 positives for a few lines, a method or god forbid an entire class, using:
395
396 .. code-block:: text
397
398    @SuppressWarnings("CPD-START")
399    ...
400    @SuppressWarnings("CPD-END")
401
402 Classes methods / fields ordering
403 =================================
404
405 Ordering based on modifiers. This is based on visibility and mutability:
406
407 | public static final fields
408 | static final fields
409 | private static final fields
410 | private final fields
411 | private non-final fields
412 | private volatile fields
413 | private constructors
414 | public constructors
415 | static factory methods
416 | public methods
417 | static methods
418 | private methods
419 | The first group should be very strict, with the exception of
420   FieldUpdaters, which should be private static final, but defined just
421   above the volatile field they access. The reason for that is they are
422   tied via a string literal name.
423
424 The second group is less clear-cut and depends on how instances are created --
425 there are times when juggling the order makes it easier to understand what is
426 going on (e.g. co-locating a private static method with static factory method
427 which uses it).
428
429 The third group is pretty much free-for-all.
430 The goal is to group things so that people do not have scroll around to
431 understand the code flow.
432 Public methods are obviously entry-points,
433 hence are mostly glanced over by users.
434
435 Overall this has worked really well so far because;
436
437 -  the first group gives a 10000-foot overview of what is going on in the class,
438    its footprint and references to other classes
439 -  the second group gives instantiation entry-points, useful for examining who
440    creates the objects and how
441 -  the third group is implementation details -- for when you really need to dive
442    into the details.
443
444 Note this list does not include non-private fields.
445 The reason is that public fields should be forbidden, as should be any mutable
446 non-private fields.
447 The reason for that is they are a nightmare to navigate when attempting to
448 reason about object life-cycle.
449
450 Same reasoning applies to inner class, keep them close to the methods which use
451 them so that the class is easy to read.
452 If the inner class needs to be understood before the methods that operate on it,
453 place it before them, otherwise (especially if it's an implementation detail)
454 after them.
455 That's when an inner class is appropriate of course.
456
457 error-prone
458 ===========
459
460 The infrautils projects has adopted the `error-prone code quality tool <http://errorprone.info>`__
461 (by Google), with suitable customized configuration.
462
463 You can use it by using ``org.opendaylight.infrautils:parent`` instead of
464 ``org.opendaylight.odlparent:bundle-parent``.
465
466 Note that ``@SuppressWarnings("InconsistentOverloads")`` needs to be placed on the
467 class, not method; see
468 https://github.com/google/error-prone/pull/870 and
469 https://github.com/google/error-prone/issues/869.
470
471 SpotBugs
472 ========
473
474 SpotBugs is the successor project to FindBugs (which is dead).
475
476 SpotBugs is enforced by default across all artifacts since Magnesium.
477 For artifacts that do not pass SpotBugs, either fix them or disable enforcement
478 by defining the following property in the pom.xml:
479
480  .. code-block:: none
481
482   <properties>
483    <odlparent.spotbugs.enforce>false</odlparent.spotbugs.enforce>
484   </properties>
485
486 All notes re. FindBugs listed below do still apply to SpotBugs as well
487 (it's compatible).
488
489 FindBugs
490 ========
491
492 Note that starting with odlparent 3.0.0 when we say "FindBugs" we now actually
493 mean "SpotBugs", see above.
494
495 ``@FBSuppressWarnings``
496 -----------------------
497
498 If really needed, projects can to override individual FindBugs rules on
499 a case-by-case basis by using a ``@SuppressFBWarnings`` annotation:
500
501 .. code:: java
502
503    @SuppressFBWarnings("RCN_REDUNDANT_NULLCHECK_OF_NONNULL_VALUE")
504    public V get(K key) {
505
506 Unchecked/unconfirmed cast from ``com.google.common.truth.Subject`` to ``com.google.common.truth.BooleanSubject`` etc.
507 ----------------------------------------------------------------------------------------------------------------------
508
509 FindBugs seems to be too dumb to deal with perfectly valid Google Truth test
510 code (which does not use any explicit cast...) so it's OK to:
511
512 .. code:: java
513
514    @SuppressFBWarnings("BC_UNCONFIRMED_CAST")
515
516 an entire JUnit \*Test class because of that.
517
518 null analysis errors, incl. FindBugs' NP_NONNULL_FIELD_NOT_INITIALIZED_IN_CONSTRUCTOR
519 -------------------------------------------------------------------------------------
520
521 see the general null analysis next chapter.
522
523 ``nonNullAndOptional``
524 ^^^^^^^^^^^^^^^^^^^^^^
525
526 Some of the content from this chapter may be moved to
527 http://www.lastnpe.org later...
528
529 Everything ``@NonNullByDefault``
530 --------------------------------
531
532 Do not use null anywhere, assume all method arguments and return values are
533 ``NonNullByDefault``.
534
535 null annotations from ``org.eclipse.jdt.annotation`` instead of ``javax.annotation``
536 ------------------------------------------------------------------------------------
537
538 We prefer using the null annotations from the package ``org.eclipse.jdt.annotation``
539 , instead of the ones from ``javax.annotation``
540 (or those from ``org.jetbrains:annotations``, or ... ``Android``/``Lombok's``/some of the
541 other ones out there).
542
543 This is because the org.eclipse one are modern generics enabled @Target
544 TYPE_USE annotations, whereas the other ones are not.
545
546 Obviously we do NOT "depend on Eclipse" in any way, or "need Eclipse at
547 run-time" just because of 4 annotations from an org.eclipse package,
548 which are available in a very small JAR at build-time; e.g.
549 ``org.eclipse.jdt.annotation.NonNull`` is absolutely no different from
550 ``javax.annotation.Nullable``, in that regard.
551
552 BTW: The ``javax.annotation NonNull`` & Co. are not more or less "official"
553 than others; Prof. FindBugs Bill Pugh pushed those to Maven central, but
554 his "dormant" JSR 305 was never officially finalized and approved;
555 he's since moved on, and no longer maintains FindBugs.
556
557 The Eclipse annotations are also supported by SpotBugs/FindBugs (`says
558 this issue <https://github.com/spotbugs/spotbugs/issues/471>`__) as well
559 as NullAway.
560
561 null analysis by FindBugs VS. Eclipse JDT
562 -----------------------------------------
563
564 FindBugs' null analysis is inferior to Eclipse JDT's, because:
565
566 -  richer null analysis
567 -  generics enabled (see above)
568 -  works with existing external libraries, through external annotations,
569    see http://www.lastnpe.org
570 -  much better in-IDE support, at least for Eclipse users
571
572 *WIP: We are aiming at, eventualy, running headless Eclipse JDT-based null
573 analysis during the build, not just for users of the Eclipse IDE UI;
574 watch*\ `issue ODLPARENT-116 <https://jira.opendaylight.org/browse/ODLPARENT-116>`__
575 \ *, and*\ http://www.lastnpe.org\ *.*
576
577 BTW: FindBugs is dead anyway, long live SpotBugs! \_TODO Gerrit & more
578 documentation to clarify this...\_
579
580 PS: An alternative interesting null checker tool is the `Checker
581 Framework <https://checkerframework.org>`__.
582
583 Runtime null checks
584 -------------------
585
586 In addition to static null analysis during development, you can check null
587 safety at run-time.
588 Please use either `JDK's Object's requireNonNull <http://docs.oracle.com/javase/7/docs/api/java/util/Objects.html#requireNonNull(java.lang.Object,java.lang.String)>`__
589 \ () or `Guava's
590 Preconditions <https://github.com/google/guava/wiki/PreconditionsExplained>`__
591 ``checkNotNull()`` utility, instead of if (something == null).
592 Please also use the variant of ``requireNonNull()`` or ``checkNotNull()`` with the
593 String message to indicate what argument is checked.
594 For example:
595
596 .. code:: java
597
598    public doSomething(Something something) {
599        this.something = Objects.requireNonNull(something, "something");
600    }
601
602 We recommend use of JDK's Object's ``requireNonNull()`` instead of Guava's
603 Preconditions ``checkNotNull()`` just because the String message of the former can
604 prevent the problem you can have with the latter if you confuse the order of the
605 arguments.
606
607 We accept and think its OK that ``checkNotNull()`` throws a NullPointerException and
608 not an IllegalArgumentException (even though code otherwise should never
609 manually throw new NullPointerException),
610 because in this particular case a NullPointerException would have happened
611 anyway later, so it's just an earlier NullPointerException, with added
612 information of what is null.
613
614 We NEVER catch (NullPointerException e) anywhere, because they are programming
615 errors which should "bubble up", to be fixed, not suppressed.
616
617 ``nullable`` errors for fields related to dependency injection
618 --------------------------------------------------------------
619
620 null analysis frameworks, such as Eclipse's or FindBugs or other, will not like
621 this kind of code in a ``@NonNullByDefault`` package:
622
623 .. code:: java
624
625    class Example {
626         @Inject
627         Service s;
628    }
629
630 the recommended solution is to always use constructor instead of field
631 injection instead, like this:
632
633 .. code:: java
634
635    class Example {
636        final Service s;
637        @Inject
638        Example(Service s) {
639            this.s = s;
640        }
641    }
642
643 When this exceptionally is not possible, like in a JUnit component test,
644 then it's acceptable to suppress warnings:
645
646 .. code:: java
647
648    @SuppressFBWarnings("NP_NONNULL_FIELD_NOT_INITIALIZED_IN_CONSTRUCTOR")
649    class SomeTest {
650        public @Rule GuiceRule guice = new GuiceRule(TestModule.class);
651        private @Inject Service service;
652    }
653
654 Optional
655 --------
656
657 You do not have to use Optional, because real null analysis can give us the same
658 benefit.
659
660 If cleaning up code for null safety, then do not mix introducing Optional with
661 other null related clean up changes; it's clearer for reviews if you FIRST fix
662 missing null checks and add null related annotations, and then THEN (optionally)
663 switch some return types to Optional.
664
665 You can use Optional for return types, but not method arguments.
666
667 Never use ``Optional<Collection<...>>`` (obviously incl. ``Optional<List<...>>``
668 or ``Optional<Set<...>>`` AND ``Optional<Map<...>>`` etc.),
669 just return a respective empty Collection instead.
670
671 Note that instead of if ``(anOptional.isPresent()) { return anOptional.get(); }
672 else { return null; }``
673 you can and for readability should just use return ``anOptional.orNull()``.
674 However ideally any such code should not return null but an Optional of
675 something itself.
676
677 Note that instead of ``if (aNullable == null) ? Optional.absent() :
678 Optional.of(aNullable)a``
679 ;you can and for readability should just use ``Optional.fromNullable(aNullable)``.
680
681 To transform an Optional into something else if it present, use the transform()
682 method instead of an if () check;.
683 for example:
684
685 .. code:: java
686
687    List vrfEntries = MDSALUtil.read(broker, LogicalDatastoreType.CONFIGURATION, vpnVrfTables).transform(VrfTables::getVrfEntry).or(new ArrayList<>());
688
689 **Take care** with ``Optional.transform()`` though: if the transformation can return
690 null, ``Optional.transform()`` will fail with a NullPointerException
691 (this is the case of most YANG-generated methods).
692 You can use Java 8 ``Optional.map()`` instead; when it encounters null, it returns
693 ``Optional.empty()``.
694 The above example would become
695
696 .. code:: java
697
698    List<VrfEntry> vrfEntries = MDSALUtil.read(broker, LogicalDatastoreType.CONFIGURATION, vpnVrfTables).toJavaUtil().map(VrfTables::getVrfEntry).orElse(new ArrayList<>());
699
700 Prefer the newer Java 8 ``java.util.Optional`` (JUO) over the older Google Guava
701 ``com.google.common.base.Optional`` (GGO), because it offers a better functional
702 style API for use with Java 8 lambdas, which leads to much more naturally
703 readable code.
704 Until we fully migrate all ODL APIs (which is planned), in glue code calling
705 existing APIs returning GGO (such as the DataBroker API) but itself then wanting
706 to return a function of that as JUO, please just use the ``toJavaUtil()`` method
707 available in Guava Optional.
708
709 Further Reading & Watching
710 ^^^^^^^^^^^^^^^^^^^^^^^^^^
711
712 -  https://github.com/google/guava/wiki/UsingAndAvoidingNullExplained
713 -  https://stackoverflow.com/questions/26327957/should-java-8-getters-return-optional-type
714
715 Streaming and lambdas
716 =====================
717
718 Lambdas are very useful when encapsulating varying behavior.
719 For example, you can use them instead of boolean behavior selection parameters:
720
721 .. code:: java
722
723    public void someMethodA(SomeObject A) {
724        commonMethod(A, false);
725    }
726
727    public void someMethodB(SomeObject B) {
728        commonMethod(B, true);
729    }
730
731    private void commonMethod(SomeObject C, boolean behaviour) {
732        // common code
733
734        if (behaviour) {
735            doA();
736        } else {
737            doB();
738        }
739
740        // common code
741    }
742
743 can be replaced with
744
745 .. code:: java
746
747    public void someMethodA(SomeObject A) {
748        commonMethod(A, this::doA);
749    }
750
751    public void someMethodB(SomeObjectB) {
752        commonMethod(B, this::doB);
753    }
754
755    private void commonMethod(SomeObject C, Function behaviour) {
756        // common code
757
758        behaviour.apply();
759
760        // common code
761    }
762
763 They are also useful for replacing small anonymous inner classes which follow
764 the functional pattern (implementing an interface with a single non-default
765 method).
766 Your IDE will typically suggest such transformations.
767
768 Lambdas should be avoided when the resulting code is more complex and/or longer
769 than the non-functional form.
770 This can happen particularly with streaming.
771
772 Streaming also has its place, especially when combined with Optional (see above)
773 or when processing collections.
774 It should however be avoided when many objects are created in the resulting
775 lambda expressions, especially if DTOs end up being necessary to convey
776 information from one lambda to the next where a single variable could do the
777 trick in a more traditional form. (TODO: provide examples.)
778