34
Proper Null handling with modern java techniques Nikola Petrov<[email protected]> Ontotext AD November 7, 2014 Nikola Petrov<[email protected]> Proper Null handling with modern java techniques

Proper Null handling with modern java techniques

Embed Size (px)

Citation preview

Page 1: Proper Null handling with modern java techniques

Proper Null handling with modern java techniques

Nikola Petrov<[email protected]>

Ontotext AD

November 7, 2014

Nikola Petrov<[email protected]> Proper Null handling with modern java techniques

Page 2: Proper Null handling with modern java techniques

NullPointerException - it happens to the best of us

java.lang.NullPointerException: nullat com.ontotext.trree.n.for(Unknown Source) ~[graphdb-se-6.0.7914.jar:na]at com.ontotext.trree.n.addStatement(Unknown Source) ~[graphdb-se-6.0.7914.jar:na]at com.ontotext.trree.SailConnectionImpl.commitInternal(Unknown Source) [graphdb-se-6.0.7914.jar:na]at org.openrdf.sail.helpers.SailConnectionBase.commit(SailConnectionBase.java:421) [sesame-sail-api-2.7.8.jar:na]at org.openrdf.repository.sail.SailRepositoryConnection.commit(SailRepositoryConnection.java:106) [sesame-repository-sail-2.7.8.jar:na]at org.openrdf.http.server.repository.statements.StatementsController.getAddDataResult(StatementsController.java:435) [sesame-http-server-spring-2.7.8.jar:na]at org.openrdf.http.server.repository.statements.StatementsController.handleRequestInternal(StatementsController.java:130) [sesame-http-server-spring-2.7.8.jar:na]at org.springframework.web.servlet.mvc.AbstractController.handleRequest(AbstractController.java:153) [spring-webmvc-3.2.9.RELEASE.jar:3.2.9.RELEASE]at com.ontotext.forest.sesame.SesameController.statements(SesameController.java:153) [forest-sesame-2.1.12-RC3.jar:na]at sun.reflect.GeneratedMethodAccessor108.invoke(Unknown Source) ~[na:na]at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43) ~[na:1.7.0_65]at java.lang.reflect.Method.invoke(Method.java:606) ~[na:1.7.0_65]at org.springframework.web.method.support.InvocableHandlerMethod.invoke(InvocableHandlerMethod.java:215) [spring-web-3.2.9.RELEASE.jar:3.2.9.RELEASE]at org.springframework.web.method.support.InvocableHandlerMethod.invokeForRequest(InvocableHandlerMethod.java:132) [spring-web-3.2.9.RELEASE.jar:3.2.9.RELEASE]at org.springframework.web.servlet.mvc.method.annotation.ServletInvocableHandlerMethod.invokeAndHandle(ServletInvocableHandlerMethod.java:104) [spring-webmvc-3.2.9.RELEASE.jar:3.2.9.RELEASE]at org.springframework.web.servlet.mvc.method.annotation.RequestMappingHandlerAdapter.invokeHandleMethod(RequestMappingHandlerAdapter.java:745) [spring-webmvc-3.2.9.RELEASE.jar:3.2.9.RELEASE]at org.springframework.web.servlet.mvc.method.annotation.RequestMappingHandlerAdapter.handleInternal(RequestMappingHandlerAdapter.java:685) [spring-webmvc-3.2.9.RELEASE.jar:3.2.9.RELEASE]at org.springframework.web.servlet.mvc.method.AbstractHandlerMethodAdapter.handle(AbstractHandlerMethodAdapter.java:80) [spring-webmvc-3.2.9.RELEASE.jar:3.2.9.RELEASE]

....

Nikola Petrov<[email protected]> Proper Null handling with modern java techniques

Page 3: Proper Null handling with modern java techniques

Java8 Optional

If you are using java8 you can return Optional.empty() instead ofnull

It forces you to handle the null on the type level

You can easily test if the Optional is the empty singleton objectwith the isPresent() method

There are also convenient methods to handle the case whenthere is a wrapped non null object

More info athttp://docs.oracle.com/javase/8/docs/api/java/util/Optional.html

Nikola Petrov<[email protected]> Proper Null handling with modern java techniques

Page 4: Proper Null handling with modern java techniques

Java8 Optional

If you are using java8 you can return Optional.empty() instead ofnull

It forces you to handle the null on the type level

You can easily test if the Optional is the empty singleton objectwith the isPresent() method

There are also convenient methods to handle the case whenthere is a wrapped non null object

More info athttp://docs.oracle.com/javase/8/docs/api/java/util/Optional.html

Nikola Petrov<[email protected]> Proper Null handling with modern java techniques

Page 5: Proper Null handling with modern java techniques

Java8 Optional

If you are using java8 you can return Optional.empty() instead ofnull

It forces you to handle the null on the type level

You can easily test if the Optional is the empty singleton objectwith the isPresent() method

There are also convenient methods to handle the case whenthere is a wrapped non null object

More info athttp://docs.oracle.com/javase/8/docs/api/java/util/Optional.html

Nikola Petrov<[email protected]> Proper Null handling with modern java techniques

Page 6: Proper Null handling with modern java techniques

Java8 Optional

If you are using java8 you can return Optional.empty() instead ofnull

It forces you to handle the null on the type level

You can easily test if the Optional is the empty singleton objectwith the isPresent() method

There are also convenient methods to handle the case whenthere is a wrapped non null object

More info athttp://docs.oracle.com/javase/8/docs/api/java/util/Optional.html

Nikola Petrov<[email protected]> Proper Null handling with modern java techniques

Page 7: Proper Null handling with modern java techniques

Java8 Optional

If you are using java8 you can return Optional.empty() instead ofnull

It forces you to handle the null on the type level

You can easily test if the Optional is the empty singleton objectwith the isPresent() method

There are also convenient methods to handle the case whenthere is a wrapped non null object

More info athttp://docs.oracle.com/javase/8/docs/api/java/util/Optional.html

Nikola Petrov<[email protected]> Proper Null handling with modern java techniques

Page 8: Proper Null handling with modern java techniques

Examples

Optional<String> result ....String value = result.orElse("");

Optional<String> result = ....result.ifPresent(value ->

System.out.println(value););

Optional<String> result = ....Optional<String[]> otherResult = result.map(value -> value.split(":"));

Nikola Petrov<[email protected]> Proper Null handling with modern java techniques

Page 9: Proper Null handling with modern java techniques

Examples

Optional<String> result ....String value = result.orElse("");

Optional<String> result = ....result.ifPresent(value ->

System.out.println(value););

Optional<String> result = ....Optional<String[]> otherResult = result.map(value -> value.split(":"));

Nikola Petrov<[email protected]> Proper Null handling with modern java techniques

Page 10: Proper Null handling with modern java techniques

Examples

Optional<String> result ....String value = result.orElse("");

Optional<String> result = ....result.ifPresent(value ->

System.out.println(value););

Optional<String> result = ....Optional<String[]> otherResult = result.map(value -> value.split(":"));

Nikola Petrov<[email protected]> Proper Null handling with modern java techniques

Page 11: Proper Null handling with modern java techniques

But what if I cannot use java8

Java8 is still not used by most of us

What about existing APIs

Annotations coming to the rescue

Nikola Petrov<[email protected]> Proper Null handling with modern java techniques

Page 12: Proper Null handling with modern java techniques

But what if I cannot use java8

Java8 is still not used by most of us

What about existing APIs

Annotations coming to the rescue

Nikola Petrov<[email protected]> Proper Null handling with modern java techniques

Page 13: Proper Null handling with modern java techniques

But what if I cannot use java8

Java8 is still not used by most of us

What about existing APIs

Annotations coming to the rescue

Nikola Petrov<[email protected]> Proper Null handling with modern java techniques

Page 14: Proper Null handling with modern java techniques

But what if I cannot use java8

<dependency><groupId>com.google.code.findbugs</groupId><artifactId>jsr305</artifactId><version>2.0.2</version><!-- Not needed at runtime thanks to the way java works --><scope>provided</scope>

</dependency>

Nikola Petrov<[email protected]> Proper Null handling with modern java techniques

Page 15: Proper Null handling with modern java techniques

JSR 305 Annotations For Software defects

The annotations were part of findbugs but were standardised

Might be included with java9 or java8 at some point

Eclipse - Null Analysis

Intellij - will show a demo

Findbugs, Sonar, (maybe Netbeans) have support for them

Nikola Petrov<[email protected]> Proper Null handling with modern java techniques

Page 16: Proper Null handling with modern java techniques

JSR 305 Annotations For Software defects

The annotations were part of findbugs but were standardised

Might be included with java9 or java8 at some point

Eclipse - Null Analysis

Intellij - will show a demo

Findbugs, Sonar, (maybe Netbeans) have support for them

Nikola Petrov<[email protected]> Proper Null handling with modern java techniques

Page 17: Proper Null handling with modern java techniques

JSR 305 Annotations For Software defects

The annotations were part of findbugs but were standardised

Might be included with java9 or java8 at some point

Eclipse - Null Analysis

Intellij - will show a demo

Findbugs, Sonar, (maybe Netbeans) have support for them

Nikola Petrov<[email protected]> Proper Null handling with modern java techniques

Page 18: Proper Null handling with modern java techniques

JSR 305 Annotations For Software defects

The annotations were part of findbugs but were standardised

Might be included with java9 or java8 at some point

Eclipse - Null Analysis

Intellij - will show a demo

Findbugs, Sonar, (maybe Netbeans) have support for them

Nikola Petrov<[email protected]> Proper Null handling with modern java techniques

Page 19: Proper Null handling with modern java techniques

JSR 305 Annotations For Software defects

The annotations were part of findbugs but were standardised

Might be included with java9 or java8 at some point

Eclipse - Null Analysis

Intellij - will show a demo

Findbugs, Sonar, (maybe Netbeans) have support for them

Nikola Petrov<[email protected]> Proper Null handling with modern java techniques

Page 20: Proper Null handling with modern java techniques

List of annotations

javax.annotation.WillNotClosejavax.annotation.WillCloseWhenClosedjavax.annotation.WillClosejavax.annotation.Syntaxjavax.annotation.Signedjavax.annotation.RegExjavax.annotation.PropertyKeyjavax.annotation.OverridingMethodsMustInvokeSuperjavax.annotation.Nullablejavax.annotation.Nonnulljavax.annotation.Nonnegativejavax.annotation.MatchesPatternjavax.annotation.CheckReturnValuejavax.annotation.CheckForSignedjavax.annotation.CheckForNull

Nikola Petrov<[email protected]> Proper Null handling with modern java techniques

Page 21: Proper Null handling with modern java techniques

Example usage

public SemanticLocation(@Nullable NativeJmxConnection jmxConnection,String location,@Nullable String username,@Nullable String password) throws URISyntaxException, RepositoryException {

}

@Nullablepublic NativeJmxConnection getJmxConnection() {

return jmxConnection;}

@Nonnullpublic SemanticRepository getRepository(String repositoryID) {

return repositories.getUnchecked(repositoryID);}

Nikola Petrov<[email protected]> Proper Null handling with modern java techniques

Page 22: Proper Null handling with modern java techniques

Example usage

public SemanticLocation(@Nullable NativeJmxConnection jmxConnection,String location,@Nullable String username,@Nullable String password) throws URISyntaxException, RepositoryException {

}

@Nullablepublic NativeJmxConnection getJmxConnection() {

return jmxConnection;}

@Nonnullpublic SemanticRepository getRepository(String repositoryID) {

return repositories.getUnchecked(repositoryID);}

Nikola Petrov<[email protected]> Proper Null handling with modern java techniques

Page 23: Proper Null handling with modern java techniques

Annotating the whole codebase

You should embrace the non nullness

But wait I will now have to annotate every method and states it’sreturn type, and parameters nullness

Annotate whole packages, example follows

Nikola Petrov<[email protected]> Proper Null handling with modern java techniques

Page 24: Proper Null handling with modern java techniques

Annotating the whole codebase

You should embrace the non nullness

But wait I will now have to annotate every method and states it’sreturn type, and parameters nullness

Annotate whole packages, example follows

Nikola Petrov<[email protected]> Proper Null handling with modern java techniques

Page 25: Proper Null handling with modern java techniques

Annotating the whole codebase

You should embrace the non nullness

But wait I will now have to annotate every method and states it’sreturn type, and parameters nullness

Annotate whole packages, example follows

Nikola Petrov<[email protected]> Proper Null handling with modern java techniques

Page 26: Proper Null handling with modern java techniques

package-info.java example

Create a package-info.java and annotate it to state the nullnessfor the whole package

/*** Javadoc for the whole package

*/@ParametersAreNonnullByDefaultpackage com.ontotext.<package-name>;

Just create a template for it in your IDE and create it every time anew package is created

Nikola Petrov<[email protected]> Proper Null handling with modern java techniques

Page 27: Proper Null handling with modern java techniques

package-info.java example

Create a package-info.java and annotate it to state the nullnessfor the whole package

/*** Javadoc for the whole package

*/@ParametersAreNonnullByDefaultpackage com.ontotext.<package-name>;

Just create a template for it in your IDE and create it every time anew package is created

Nikola Petrov<[email protected]> Proper Null handling with modern java techniques

Page 28: Proper Null handling with modern java techniques

package-info.java example

Create a package-info.java and annotate it to state the nullnessfor the whole package

/*** Javadoc for the whole package

*/@ParametersAreNonnullByDefaultpackage com.ontotext.<package-name>;

Just create a template for it in your IDE and create it every time anew package is created

Nikola Petrov<[email protected]> Proper Null handling with modern java techniques

Page 29: Proper Null handling with modern java techniques

Annotating whole package

It is a good practise to have that file because it documents theresponsibility of the whole package

The @ParametersAreNonnullByDefault is part of JSR305 andtools recognize it. Sadly there is no@ReturnValuesAreNonnullByDefault

The JSR305 states that you can define a NonNullByDefaultannotation with @TypeQualifierDefault(somewhat complicated...)

Sadly TypeQualifierDefault annotations are not supportedmainstream, although Intellij added support in the latest version

Nikola Petrov<[email protected]> Proper Null handling with modern java techniques

Page 30: Proper Null handling with modern java techniques

Annotating whole package

It is a good practise to have that file because it documents theresponsibility of the whole package

The @ParametersAreNonnullByDefault is part of JSR305 andtools recognize it. Sadly there is no@ReturnValuesAreNonnullByDefault

The JSR305 states that you can define a NonNullByDefaultannotation with @TypeQualifierDefault(somewhat complicated...)

Sadly TypeQualifierDefault annotations are not supportedmainstream, although Intellij added support in the latest version

Nikola Petrov<[email protected]> Proper Null handling with modern java techniques

Page 31: Proper Null handling with modern java techniques

Annotating whole package

It is a good practise to have that file because it documents theresponsibility of the whole package

The @ParametersAreNonnullByDefault is part of JSR305 andtools recognize it. Sadly there is no@ReturnValuesAreNonnullByDefault

The JSR305 states that you can define a NonNullByDefaultannotation with @TypeQualifierDefault(somewhat complicated...)

Sadly TypeQualifierDefault annotations are not supportedmainstream, although Intellij added support in the latest version

Nikola Petrov<[email protected]> Proper Null handling with modern java techniques

Page 32: Proper Null handling with modern java techniques

Annotating whole package

It is a good practise to have that file because it documents theresponsibility of the whole package

The @ParametersAreNonnullByDefault is part of JSR305 andtools recognize it. Sadly there is no@ReturnValuesAreNonnullByDefault

The JSR305 states that you can define a NonNullByDefaultannotation with @TypeQualifierDefault(somewhat complicated...)

Sadly TypeQualifierDefault annotations are not supportedmainstream, although Intellij added support in the latest version

Nikola Petrov<[email protected]> Proper Null handling with modern java techniques

Page 33: Proper Null handling with modern java techniques

NonNullByDefault

package com.ontotext.annotations;

import javax.annotation.Nonnull;import javax.annotation.meta.TypeQualifierDefault;import java.lang.annotation.Documented;import java.lang.annotation.ElementType;import java.lang.annotation.Retention;import java.lang.annotation.RetentionPolicy;

/*** This annotation can be applied to a package, class or method to

* indicate that the class fields, method return types and parameters in

* that element are not null by default unless there is: The method

* overrides a method in a superclass (in which case the annotation of

* the corresponding parameter in the superclass applies) there is a

* default parameter annotation applied to a more tightly nested element.

*/@Documented@Nonnull@TypeQualifierDefault(

{ElementType.ANNOTATION_TYPE,ElementType.CONSTRUCTOR,ElementType.FIELD,ElementType.LOCAL_VARIABLE,ElementType.METHOD,ElementType.PACKAGE,ElementType.PARAMETER,ElementType.TYPE

})@Retention(RetentionPolicy.RUNTIME)public @interface NonNullByDefault {}

Nikola Petrov<[email protected]> Proper Null handling with modern java techniques

Page 34: Proper Null handling with modern java techniques

Questions?

Questions?

Nikola Petrov<[email protected]> Proper Null handling with modern java techniques