-
Notifications
You must be signed in to change notification settings - Fork 0
Legacy code: tips for migration
Some ideas and tools to consider:
-
start by adding
@NonNullApi
only, annotate the scope and then continue with@NonNullFields
(or vice versa)
Api can be split to return and param if we think it will make migration easier -
start from splitting the codebase by scope into smaller chunks: module, package, class, [method]
What makes a good split? Independence of 'chunks' one from each others - few dependencies between them (low coupling). It gives flexibility to choose different approach to annotate each 'chunk' it's own way. -
try analyzing flow
from entry points? -
try starting from adding
@Nullable
only and adding defaults later -
try searching for patterns
return null;
,= null;
,null,
,Optional.ofNullable
, etc. -
try IntelliJ Infer nullity
based on static analyzes -
try Daikon
based on null values detection during program execution
Start from weaker requirements to have some time to adapt without breaking the build
-
IDEs parser highlighting -> error-prone compiler
-
NullAway and Checker Framework warn -> error
-
CI pipeline - Github weak -> strong requirement to accept PR
- Where most NPE exceptions flee first
- Where we change code most often
- Where we can separate changes easiest
- Starting from top or bottom of dependency graph
Some IDEs, IntelliJ for instance, allow to define custom code formatter rules for user defined scopes in the code. During migration, different scopes can be used to easily distinguish between code which has been already annotated (but possibly has everything non-nullable) and code which hasn't.
-
Red: not annotated
-
Yellow: under migration – goal: bring attention to potential issues
IDE highlighting
@Nullable + @NonNullApi and @NonNullFields -
Green: annotated – compile time detection of most of NPE
NullAway (via errorprone)
CI pipeline + IDEs compiler -
Greener: all type uses annotated – compile time verification of NPE absence
Checker Framework -
Greenest: system boundaries guarded – runtime verification of input data
-
Gray: outside scope of our code
until? - many libraries start describe API contracts by annotating it with nullable annotations
CheckerFramework provides method to annotate 3rd party jars by annotating API in external files