diff --git a/.github/workflows/build.yaml b/.github/workflows/build.yaml
index 3406704..54ba8bf 100644
--- a/.github/workflows/build.yaml
+++ b/.github/workflows/build.yaml
@@ -24,7 +24,8 @@ jobs:
- name: Set up JDK
uses: actions/setup-java@v1
with:
- java-version: 1.8
+ # See comment on moditect-maven-plugin in pom.xml
+ java-version: 12
- name: Compile
run: ./mvnw clean test-compile -B
- name: Test
diff --git a/.gitignore b/.gitignore
index 7adafbb..8227300 100644
--- a/.gitignore
+++ b/.gitignore
@@ -2,6 +2,13 @@
*.iml
.idea/
+### VS Code ###
+.vscode
+.project
+.settings
+.classpath
+.factorypath
+
### Maven ###
target/
/.mvn/wrapper/*.jar
diff --git a/README.md b/README.md
index c2c2418..c53047d 100644
--- a/README.md
+++ b/README.md
@@ -28,6 +28,7 @@ It's decoupled from any JSON library, but contains a separate module for Jackson
- Java 8
- Any build tool using Maven Central, or direct download
- Jackson (optional)
+- Gson (optional)
## Installation
@@ -44,6 +45,24 @@ Add the following dependency to your project:
jackson-datatype-problem
${problem.version}
+
+ org.zalando
+ problem-gson
+ ${problem.version}
+
+```
+
+### Java Modules
+
+Even though the minimum requirement is still Java 8, all modules are Java 9 compatible:
+
+```java
+module org.example {
+ requires org.zalando.problem;
+ // pick needed dependencies
+ requires org.zalando.problem.jackson;
+ requires org.zalando.problem.gson;
+}
```
## Configuration
diff --git a/jackson-datatype-problem/pom.xml b/jackson-datatype-problem/pom.xml
index c75b87b..4b5e3c7 100644
--- a/jackson-datatype-problem/pom.xml
+++ b/jackson-datatype-problem/pom.xml
@@ -11,6 +11,10 @@
jackson-datatype-problem
2.10.1
+ org.zalando.problem.jackson
+
+ org.zalando.problem.jackson;
+
diff --git a/jackson-datatype-problem/src/main/java/org/zalando/problem/AbstractThrowableProblemMixIn.java b/jackson-datatype-problem/src/main/java/org/zalando/problem/jackson/AbstractThrowableProblemMixIn.java
similarity index 80%
rename from jackson-datatype-problem/src/main/java/org/zalando/problem/AbstractThrowableProblemMixIn.java
rename to jackson-datatype-problem/src/main/java/org/zalando/problem/jackson/AbstractThrowableProblemMixIn.java
index 996ac30..bb7bc01 100644
--- a/jackson-datatype-problem/src/main/java/org/zalando/problem/AbstractThrowableProblemMixIn.java
+++ b/jackson-datatype-problem/src/main/java/org/zalando/problem/jackson/AbstractThrowableProblemMixIn.java
@@ -1,10 +1,14 @@
-package org.zalando.problem;
+package org.zalando.problem.jackson;
import com.fasterxml.jackson.annotation.JsonAnySetter;
import com.fasterxml.jackson.annotation.JsonCreator;
import com.fasterxml.jackson.annotation.JsonProperty;
-import javax.annotation.Nullable;
+import org.checkerframework.checker.nullness.qual.Nullable;
+import org.zalando.problem.AbstractThrowableProblem;
+import org.zalando.problem.StatusType;
+import org.zalando.problem.ThrowableProblem;
+
import java.net.URI;
abstract class AbstractThrowableProblemMixIn {
diff --git a/jackson-datatype-problem/src/main/java/org/zalando/problem/ExceptionalMixin.java b/jackson-datatype-problem/src/main/java/org/zalando/problem/jackson/ExceptionalMixin.java
similarity index 91%
rename from jackson-datatype-problem/src/main/java/org/zalando/problem/ExceptionalMixin.java
rename to jackson-datatype-problem/src/main/java/org/zalando/problem/jackson/ExceptionalMixin.java
index f8fc29d..e6da561 100644
--- a/jackson-datatype-problem/src/main/java/org/zalando/problem/ExceptionalMixin.java
+++ b/jackson-datatype-problem/src/main/java/org/zalando/problem/jackson/ExceptionalMixin.java
@@ -1,4 +1,4 @@
-package org.zalando.problem;
+package org.zalando.problem.jackson;
import com.fasterxml.jackson.annotation.JsonIgnore;
import com.fasterxml.jackson.annotation.JsonIgnoreProperties;
@@ -7,6 +7,8 @@
import com.fasterxml.jackson.databind.annotation.JsonSerialize;
import com.fasterxml.jackson.databind.ser.std.ToStringSerializer;
+import org.zalando.problem.ThrowableProblem;
+
import static com.fasterxml.jackson.annotation.JsonInclude.Include.NON_NULL;
@JsonIgnoreProperties(ignoreUnknown = true)
diff --git a/jackson-datatype-problem/src/main/java/org/zalando/problem/ExceptionalWithoutStacktraceMixin.java b/jackson-datatype-problem/src/main/java/org/zalando/problem/jackson/ExceptionalWithoutStacktraceMixin.java
similarity index 89%
rename from jackson-datatype-problem/src/main/java/org/zalando/problem/ExceptionalWithoutStacktraceMixin.java
rename to jackson-datatype-problem/src/main/java/org/zalando/problem/jackson/ExceptionalWithoutStacktraceMixin.java
index 45a0dc5..2f47eb3 100644
--- a/jackson-datatype-problem/src/main/java/org/zalando/problem/ExceptionalWithoutStacktraceMixin.java
+++ b/jackson-datatype-problem/src/main/java/org/zalando/problem/jackson/ExceptionalWithoutStacktraceMixin.java
@@ -1,4 +1,4 @@
-package org.zalando.problem;
+package org.zalando.problem.jackson;
import com.fasterxml.jackson.annotation.JsonIgnore;
import com.fasterxml.jackson.annotation.JsonIgnoreProperties;
diff --git a/jackson-datatype-problem/src/main/java/org/zalando/problem/ProblemMixIn.java b/jackson-datatype-problem/src/main/java/org/zalando/problem/jackson/ProblemMixIn.java
similarity index 87%
rename from jackson-datatype-problem/src/main/java/org/zalando/problem/ProblemMixIn.java
rename to jackson-datatype-problem/src/main/java/org/zalando/problem/jackson/ProblemMixIn.java
index 798c082..fccbd52 100644
--- a/jackson-datatype-problem/src/main/java/org/zalando/problem/ProblemMixIn.java
+++ b/jackson-datatype-problem/src/main/java/org/zalando/problem/jackson/ProblemMixIn.java
@@ -1,4 +1,4 @@
-package org.zalando.problem;
+package org.zalando.problem.jackson;
import com.fasterxml.jackson.annotation.JsonAnyGetter;
import com.fasterxml.jackson.annotation.JsonInclude;
@@ -6,6 +6,10 @@
import com.fasterxml.jackson.annotation.JsonTypeInfo;
import com.fasterxml.jackson.databind.annotation.JsonSerialize;
+import org.zalando.problem.DefaultProblem;
+import org.zalando.problem.Problem;
+import org.zalando.problem.StatusType;
+
import java.net.URI;
import java.util.Map;
diff --git a/jackson-datatype-problem/src/main/java/org/zalando/problem/ProblemModule.java b/jackson-datatype-problem/src/main/java/org/zalando/problem/jackson/ProblemModule.java
similarity index 87%
rename from jackson-datatype-problem/src/main/java/org/zalando/problem/ProblemModule.java
rename to jackson-datatype-problem/src/main/java/org/zalando/problem/jackson/ProblemModule.java
index a647012..31ed534 100644
--- a/jackson-datatype-problem/src/main/java/org/zalando/problem/ProblemModule.java
+++ b/jackson-datatype-problem/src/main/java/org/zalando/problem/jackson/ProblemModule.java
@@ -1,4 +1,4 @@
-package org.zalando.problem;
+package org.zalando.problem.jackson;
import com.fasterxml.jackson.core.Version;
import com.fasterxml.jackson.core.util.VersionUtil;
@@ -6,6 +6,12 @@
import com.fasterxml.jackson.databind.module.SimpleModule;
import org.apiguardian.api.API;
+import org.zalando.problem.DefaultProblem;
+import org.zalando.problem.Exceptional;
+import org.zalando.problem.Problem;
+import org.zalando.problem.Status;
+import org.zalando.problem.StatusType;
+
import java.util.Collections;
import java.util.HashMap;
import java.util.Map;
@@ -34,7 +40,7 @@ public ProblemModule() {
* @throws IllegalArgumentException if there are duplicate status codes across all status types
*/
@SafeVarargs
- public ProblemModule(final Class extends E>... types)
+ public & StatusType> ProblemModule(final Class extends E>... types)
throws IllegalArgumentException {
this(false, buildIndex(types));
@@ -76,7 +82,7 @@ public void setupModule(final SetupContext context) {
}
@SafeVarargs
- private static Map buildIndex(
+ private static & StatusType> Map buildIndex(
final Class extends E>... types) {
final Map index = new HashMap<>();
diff --git a/jackson-datatype-problem/src/main/java/org/zalando/problem/ProblemTypeConverter.java b/jackson-datatype-problem/src/main/java/org/zalando/problem/jackson/ProblemTypeConverter.java
similarity index 79%
rename from jackson-datatype-problem/src/main/java/org/zalando/problem/ProblemTypeConverter.java
rename to jackson-datatype-problem/src/main/java/org/zalando/problem/jackson/ProblemTypeConverter.java
index 38c93f1..28c65d3 100644
--- a/jackson-datatype-problem/src/main/java/org/zalando/problem/ProblemTypeConverter.java
+++ b/jackson-datatype-problem/src/main/java/org/zalando/problem/jackson/ProblemTypeConverter.java
@@ -1,7 +1,9 @@
-package org.zalando.problem;
+package org.zalando.problem.jackson;
import com.fasterxml.jackson.databind.util.StdConverter;
+import org.zalando.problem.Problem;
+
import java.net.URI;
final class ProblemTypeConverter extends StdConverter {
diff --git a/jackson-datatype-problem/src/main/java/org/zalando/problem/StatusTypeDeserializer.java b/jackson-datatype-problem/src/main/java/org/zalando/problem/jackson/StatusTypeDeserializer.java
similarity index 84%
rename from jackson-datatype-problem/src/main/java/org/zalando/problem/StatusTypeDeserializer.java
rename to jackson-datatype-problem/src/main/java/org/zalando/problem/jackson/StatusTypeDeserializer.java
index 213917c..3f89d5f 100644
--- a/jackson-datatype-problem/src/main/java/org/zalando/problem/StatusTypeDeserializer.java
+++ b/jackson-datatype-problem/src/main/java/org/zalando/problem/jackson/StatusTypeDeserializer.java
@@ -1,10 +1,12 @@
-package org.zalando.problem;
+package org.zalando.problem.jackson;
import com.fasterxml.jackson.core.JsonParser;
import com.fasterxml.jackson.databind.DeserializationContext;
import com.fasterxml.jackson.databind.JsonDeserializer;
-import javax.annotation.Nullable;
+import org.checkerframework.checker.nullness.qual.Nullable;
+import org.zalando.problem.StatusType;
+
import java.io.IOException;
import java.util.Map;
diff --git a/jackson-datatype-problem/src/main/java/org/zalando/problem/StatusTypeSerializer.java b/jackson-datatype-problem/src/main/java/org/zalando/problem/jackson/StatusTypeSerializer.java
similarity index 85%
rename from jackson-datatype-problem/src/main/java/org/zalando/problem/StatusTypeSerializer.java
rename to jackson-datatype-problem/src/main/java/org/zalando/problem/jackson/StatusTypeSerializer.java
index 0ba27e5..7ee6a80 100644
--- a/jackson-datatype-problem/src/main/java/org/zalando/problem/StatusTypeSerializer.java
+++ b/jackson-datatype-problem/src/main/java/org/zalando/problem/jackson/StatusTypeSerializer.java
@@ -1,9 +1,11 @@
-package org.zalando.problem;
+package org.zalando.problem.jackson;
import com.fasterxml.jackson.core.JsonGenerator;
import com.fasterxml.jackson.databind.JsonSerializer;
import com.fasterxml.jackson.databind.SerializerProvider;
+import org.zalando.problem.StatusType;
+
import java.io.IOException;
final class StatusTypeSerializer extends JsonSerializer {
diff --git a/problem/src/main/java/org/zalando/problem/UnknownStatus.java b/jackson-datatype-problem/src/main/java/org/zalando/problem/jackson/UnknownStatus.java
similarity index 79%
rename from problem/src/main/java/org/zalando/problem/UnknownStatus.java
rename to jackson-datatype-problem/src/main/java/org/zalando/problem/jackson/UnknownStatus.java
index 243cfd5..f6180df 100644
--- a/problem/src/main/java/org/zalando/problem/UnknownStatus.java
+++ b/jackson-datatype-problem/src/main/java/org/zalando/problem/jackson/UnknownStatus.java
@@ -1,8 +1,7 @@
-package org.zalando.problem;
+package org.zalando.problem.jackson;
-import javax.annotation.concurrent.Immutable;
+import org.zalando.problem.StatusType;
-@Immutable
final class UnknownStatus implements StatusType {
private final int statusCode;
diff --git a/jackson-datatype-problem/src/main/resources/META-INF/services/com.fasterxml.jackson.databind.Module b/jackson-datatype-problem/src/main/resources/META-INF/services/com.fasterxml.jackson.databind.Module
index e5db920..1df0daa 100644
--- a/jackson-datatype-problem/src/main/resources/META-INF/services/com.fasterxml.jackson.databind.Module
+++ b/jackson-datatype-problem/src/main/resources/META-INF/services/com.fasterxml.jackson.databind.Module
@@ -1 +1 @@
-org.zalando.problem.ProblemModule
\ No newline at end of file
+org.zalando.problem.jackson.ProblemModule
\ No newline at end of file
diff --git a/jackson-datatype-problem/src/test/java/org/zalando/problem/BusinessException.java b/jackson-datatype-problem/src/test/java/org/zalando/problem/jackson/BusinessException.java
similarity index 78%
rename from jackson-datatype-problem/src/test/java/org/zalando/problem/BusinessException.java
rename to jackson-datatype-problem/src/test/java/org/zalando/problem/jackson/BusinessException.java
index ddbcb14..2f5de2d 100644
--- a/jackson-datatype-problem/src/test/java/org/zalando/problem/BusinessException.java
+++ b/jackson-datatype-problem/src/test/java/org/zalando/problem/jackson/BusinessException.java
@@ -1,4 +1,4 @@
-package org.zalando.problem;
+package org.zalando.problem.jackson;
abstract class BusinessException extends Exception {
diff --git a/problem-gson/src/test/java/org/zalando/problem/CustomStatus.java b/jackson-datatype-problem/src/test/java/org/zalando/problem/jackson/CustomStatus.java
similarity index 86%
rename from problem-gson/src/test/java/org/zalando/problem/CustomStatus.java
rename to jackson-datatype-problem/src/test/java/org/zalando/problem/jackson/CustomStatus.java
index cb5f669..102f4da 100644
--- a/problem-gson/src/test/java/org/zalando/problem/CustomStatus.java
+++ b/jackson-datatype-problem/src/test/java/org/zalando/problem/jackson/CustomStatus.java
@@ -1,4 +1,6 @@
-package org.zalando.problem;
+package org.zalando.problem.jackson;
+
+import org.zalando.problem.StatusType;
enum CustomStatus implements StatusType {
diff --git a/jackson-datatype-problem/src/test/java/org/zalando/problem/EnforceCoverageTest.java b/jackson-datatype-problem/src/test/java/org/zalando/problem/jackson/EnforceCoverageTest.java
similarity index 81%
rename from jackson-datatype-problem/src/test/java/org/zalando/problem/EnforceCoverageTest.java
rename to jackson-datatype-problem/src/test/java/org/zalando/problem/jackson/EnforceCoverageTest.java
index cd3b579..69b8c58 100644
--- a/jackson-datatype-problem/src/test/java/org/zalando/problem/EnforceCoverageTest.java
+++ b/jackson-datatype-problem/src/test/java/org/zalando/problem/jackson/EnforceCoverageTest.java
@@ -1,16 +1,13 @@
-package org.zalando.problem;
+package org.zalando.problem.jackson;
-import com.google.gag.annotation.remark.Hack;
-import com.google.gag.annotation.remark.OhNoYouDidnt;
import org.junit.jupiter.api.Test;
+import org.zalando.problem.AbstractThrowableProblem;
import java.net.URI;
import static org.junit.jupiter.api.Assertions.assertThrows;
import static org.zalando.problem.Status.BAD_REQUEST;
-@Hack
-@OhNoYouDidnt
final class EnforceCoverageTest {
@Test
diff --git a/jackson-datatype-problem/src/test/java/org/zalando/problem/IOProblem.java b/jackson-datatype-problem/src/test/java/org/zalando/problem/jackson/IOProblem.java
similarity index 89%
rename from jackson-datatype-problem/src/test/java/org/zalando/problem/IOProblem.java
rename to jackson-datatype-problem/src/test/java/org/zalando/problem/jackson/IOProblem.java
index bafaff4..8c7052f 100644
--- a/jackson-datatype-problem/src/test/java/org/zalando/problem/IOProblem.java
+++ b/jackson-datatype-problem/src/test/java/org/zalando/problem/jackson/IOProblem.java
@@ -1,9 +1,13 @@
-package org.zalando.problem;
+package org.zalando.problem.jackson;
import com.fasterxml.jackson.annotation.JsonCreator;
import com.fasterxml.jackson.annotation.JsonProperty;
import com.fasterxml.jackson.annotation.JsonTypeInfo;
+import org.zalando.problem.Exceptional;
+import org.zalando.problem.StatusType;
+import org.zalando.problem.ThrowableProblem;
+
import java.io.IOException;
import java.net.URI;
diff --git a/jackson-datatype-problem/src/test/java/org/zalando/problem/InsufficientFundsProblem.java b/jackson-datatype-problem/src/test/java/org/zalando/problem/jackson/InsufficientFundsProblem.java
similarity index 91%
rename from jackson-datatype-problem/src/test/java/org/zalando/problem/InsufficientFundsProblem.java
rename to jackson-datatype-problem/src/test/java/org/zalando/problem/jackson/InsufficientFundsProblem.java
index 3c9f9cb..8697d3d 100644
--- a/jackson-datatype-problem/src/test/java/org/zalando/problem/InsufficientFundsProblem.java
+++ b/jackson-datatype-problem/src/test/java/org/zalando/problem/jackson/InsufficientFundsProblem.java
@@ -1,9 +1,11 @@
-package org.zalando.problem;
+package org.zalando.problem.jackson;
import com.fasterxml.jackson.annotation.JsonCreator;
import com.fasterxml.jackson.annotation.JsonProperty;
import com.fasterxml.jackson.annotation.JsonTypeName;
+import org.zalando.problem.AbstractThrowableProblem;
+
import java.net.URI;
import static org.zalando.problem.Status.BAD_REQUEST;
diff --git a/jackson-datatype-problem/src/test/java/org/zalando/problem/JacksonStackTraceProcessor.java b/jackson-datatype-problem/src/test/java/org/zalando/problem/jackson/JacksonStackTraceProcessor.java
similarity index 80%
rename from jackson-datatype-problem/src/test/java/org/zalando/problem/JacksonStackTraceProcessor.java
rename to jackson-datatype-problem/src/test/java/org/zalando/problem/jackson/JacksonStackTraceProcessor.java
index fe0546a..5392b2c 100644
--- a/jackson-datatype-problem/src/test/java/org/zalando/problem/JacksonStackTraceProcessor.java
+++ b/jackson-datatype-problem/src/test/java/org/zalando/problem/jackson/JacksonStackTraceProcessor.java
@@ -1,4 +1,4 @@
-package org.zalando.problem;
+package org.zalando.problem.jackson;
import org.zalando.problem.spi.StackTraceProcessor;
@@ -16,7 +16,11 @@ public Collection process(final Collection
final ArrayList elements = new ArrayList<>(collection);
return elements.stream()
- .filter(startsWith("sun.reflect", "java.lang.reflect", "com.fasterxml.jackson").negate())
+ .filter(startsWith(
+ "sun.reflect",
+ "java.lang.reflect",
+ "jdk.internal.reflect",
+ "com.fasterxml.jackson").negate())
.findFirst()
.map(elements::indexOf)
.map(subList(elements))
diff --git a/jackson-datatype-problem/src/test/java/org/zalando/problem/OutOfStockException.java b/jackson-datatype-problem/src/test/java/org/zalando/problem/jackson/OutOfStockException.java
similarity index 86%
rename from jackson-datatype-problem/src/test/java/org/zalando/problem/OutOfStockException.java
rename to jackson-datatype-problem/src/test/java/org/zalando/problem/jackson/OutOfStockException.java
index e669a32..c493468 100644
--- a/jackson-datatype-problem/src/test/java/org/zalando/problem/OutOfStockException.java
+++ b/jackson-datatype-problem/src/test/java/org/zalando/problem/jackson/OutOfStockException.java
@@ -1,9 +1,13 @@
-package org.zalando.problem;
+package org.zalando.problem.jackson;
import com.fasterxml.jackson.annotation.JsonCreator;
import com.fasterxml.jackson.annotation.JsonProperty;
import com.fasterxml.jackson.annotation.JsonTypeName;
+import org.zalando.problem.Exceptional;
+import org.zalando.problem.StatusType;
+import org.zalando.problem.ThrowableProblem;
+
import java.net.URI;
import static org.zalando.problem.Status.BAD_REQUEST;
diff --git a/jackson-datatype-problem/src/test/java/org/zalando/problem/ProblemMixInTest.java b/jackson-datatype-problem/src/test/java/org/zalando/problem/jackson/ProblemMixInTest.java
similarity index 96%
rename from jackson-datatype-problem/src/test/java/org/zalando/problem/ProblemMixInTest.java
rename to jackson-datatype-problem/src/test/java/org/zalando/problem/jackson/ProblemMixInTest.java
index 532080b..1bbd165 100644
--- a/jackson-datatype-problem/src/test/java/org/zalando/problem/ProblemMixInTest.java
+++ b/jackson-datatype-problem/src/test/java/org/zalando/problem/jackson/ProblemMixInTest.java
@@ -1,8 +1,14 @@
-package org.zalando.problem;
+package org.zalando.problem.jackson;
import com.fasterxml.jackson.core.JsonProcessingException;
import com.fasterxml.jackson.databind.ObjectMapper;
import org.junit.jupiter.api.Test;
+import org.zalando.problem.DefaultProblem;
+import org.zalando.problem.Exceptional;
+import org.zalando.problem.Problem;
+import org.zalando.problem.Status;
+import org.zalando.problem.StatusType;
+import org.zalando.problem.ThrowableProblem;
import java.io.IOException;
import java.io.PrintWriter;
@@ -245,7 +251,7 @@ void shouldDeserializeWithProcessedStackTrace() throws IOException {
final String stackTrace = getStackTrace(problem);
final String[] stackTraceElements = stackTrace.split("\n");
- assertThat(stackTraceElements[1], startsWith("\tat org.zalando.problem.ProblemMixInTest"));
+ assertThat(stackTraceElements[1], startsWith("\tat " + ProblemMixInTest.class.getName()));
}
private String getStackTrace(final Throwable throwable) {
diff --git a/jackson-datatype-problem/src/test/java/org/zalando/problem/ProblemModuleTest.java b/jackson-datatype-problem/src/test/java/org/zalando/problem/jackson/ProblemModuleTest.java
similarity index 85%
rename from jackson-datatype-problem/src/test/java/org/zalando/problem/ProblemModuleTest.java
rename to jackson-datatype-problem/src/test/java/org/zalando/problem/jackson/ProblemModuleTest.java
index 753027b..d6da2cc 100644
--- a/jackson-datatype-problem/src/test/java/org/zalando/problem/ProblemModuleTest.java
+++ b/jackson-datatype-problem/src/test/java/org/zalando/problem/jackson/ProblemModuleTest.java
@@ -1,6 +1,7 @@
-package org.zalando.problem;
+package org.zalando.problem.jackson;
import org.junit.jupiter.api.Test;
+import org.zalando.problem.Status;
import static org.junit.jupiter.api.Assertions.assertThrows;
diff --git a/jackson-datatype-problem/src/test/java/org/zalando/problem/jackson/UnknownStatusTest.java b/jackson-datatype-problem/src/test/java/org/zalando/problem/jackson/UnknownStatusTest.java
new file mode 100644
index 0000000..10cb501
--- /dev/null
+++ b/jackson-datatype-problem/src/test/java/org/zalando/problem/jackson/UnknownStatusTest.java
@@ -0,0 +1,17 @@
+package org.zalando.problem.jackson;
+
+import org.junit.jupiter.api.Test;
+
+import static org.junit.jupiter.api.Assertions.assertEquals;
+
+class UnknownStatusTest {
+
+ @Test
+ void shouldReturnCodeAndPhrase() {
+ final int code = 8080;
+ final UnknownStatus status = new UnknownStatus(code);
+ assertEquals(8080, status.getStatusCode());
+ assertEquals("Unknown", status.getReasonPhrase());
+ }
+
+}
\ No newline at end of file
diff --git a/jackson-datatype-problem/src/test/resources/META-INF/services/org.zalando.problem.spi.StackTraceProcessor b/jackson-datatype-problem/src/test/resources/META-INF/services/org.zalando.problem.spi.StackTraceProcessor
index 65d7271..853b16c 100644
--- a/jackson-datatype-problem/src/test/resources/META-INF/services/org.zalando.problem.spi.StackTraceProcessor
+++ b/jackson-datatype-problem/src/test/resources/META-INF/services/org.zalando.problem.spi.StackTraceProcessor
@@ -1 +1 @@
-org.zalando.problem.JacksonStackTraceProcessor
\ No newline at end of file
+org.zalando.problem.jackson.JacksonStackTraceProcessor
\ No newline at end of file
diff --git a/pom.xml b/pom.xml
index 71111c1..8dc81c7 100644
--- a/pom.xml
+++ b/pom.xml
@@ -61,15 +61,9 @@
provided
- com.google.code.findbugs
- jsr305
- 3.0.2
- provided
-
-
- com.google.gag
- gag
- 1.0.1
+ org.checkerframework
+ checker-qual
+ 3.6.0
provided
@@ -78,6 +72,16 @@
1.18.12
provided
+
+
+ org.mapstruct
+ mapstruct-processor
+ 1.4.0.CR1
+ provided
+
@@ -154,17 +158,17 @@
apiguardian-api
- com.google.code.findbugs
- jsr305
-
-
- com.google.gag
- gag
+ org.checkerframework
+ checker-qual
org.projectlombok
lombok
+
+ org.mapstruct
+ mapstruct-processor
+
@@ -258,10 +262,69 @@
maven-resources-plugin
3.2.0
+
+ org.moditect
+ moditect-maven-plugin
+ 1.0.0.RC1
+
+
+
+ add-module-infos
+ package
+
+ add-module-info
+
+
+ 9
+
+
+ ${module.name}
+
+ ${module.exports}
+
+
+ static org.apiguardian.api;
+
+
+
+
+
+ --multi-release=9
+
+
+
+
+
org.apache.maven.plugins
maven-compiler-plugin
3.8.1
+
-Xlint:unchecked,deprecation
@@ -338,6 +401,11 @@
false
+
+ org.apache.maven.plugins
+ maven-jar-plugin
+ 3.2.0
+
@@ -353,6 +421,14 @@
org.basepom.maven
duplicate-finder-maven-plugin
+
+ org.moditect
+ moditect-maven-plugin
+
+
+ org.apache.maven.plugins
+ maven-compiler-plugin
+
org.jacoco
jacoco-maven-plugin
diff --git a/problem-gson/pom.xml b/problem-gson/pom.xml
index c26e663..426d7bf 100644
--- a/problem-gson/pom.xml
+++ b/problem-gson/pom.xml
@@ -11,6 +11,10 @@
problem-gson
2.8.6
+ org.zalando.problem.gson
+
+ org.zalando.problem.gson;
+
diff --git a/problem-gson/src/main/java/org/zalando/problem/CustomProblemAdapter.java b/problem-gson/src/main/java/org/zalando/problem/gson/CustomProblemAdapter.java
similarity index 96%
rename from problem-gson/src/main/java/org/zalando/problem/CustomProblemAdapter.java
rename to problem-gson/src/main/java/org/zalando/problem/gson/CustomProblemAdapter.java
index 81eb74a..8b4b7c7 100644
--- a/problem-gson/src/main/java/org/zalando/problem/CustomProblemAdapter.java
+++ b/problem-gson/src/main/java/org/zalando/problem/gson/CustomProblemAdapter.java
@@ -1,4 +1,4 @@
-package org.zalando.problem;
+package org.zalando.problem.gson;
import com.google.gson.Gson;
import com.google.gson.JsonElement;
@@ -9,6 +9,8 @@
import com.google.gson.stream.JsonWriter;
import lombok.AllArgsConstructor;
+import org.zalando.problem.AbstractThrowableProblem;
+
import java.io.IOException;
import java.net.URI;
import java.util.Optional;
diff --git a/problem-gson/src/main/java/org/zalando/problem/DefaultProblemAdapter.java b/problem-gson/src/main/java/org/zalando/problem/gson/DefaultProblemAdapter.java
similarity index 93%
rename from problem-gson/src/main/java/org/zalando/problem/DefaultProblemAdapter.java
rename to problem-gson/src/main/java/org/zalando/problem/gson/DefaultProblemAdapter.java
index ac49b6a..59cc510 100644
--- a/problem-gson/src/main/java/org/zalando/problem/DefaultProblemAdapter.java
+++ b/problem-gson/src/main/java/org/zalando/problem/gson/DefaultProblemAdapter.java
@@ -1,4 +1,4 @@
-package org.zalando.problem;
+package org.zalando.problem.gson;
import com.google.gson.Gson;
import com.google.gson.JsonElement;
@@ -9,6 +9,11 @@
import com.google.gson.stream.JsonWriter;
import lombok.AllArgsConstructor;
+import org.zalando.problem.Problem;
+import org.zalando.problem.ProblemBuilder;
+import org.zalando.problem.StatusType;
+import org.zalando.problem.ThrowableProblem;
+
import java.io.IOException;
import java.util.Map;
@@ -65,7 +70,7 @@ public void write(final JsonWriter out, final ThrowableProblem problem) throws I
@Override
public ThrowableProblem read(final JsonReader in) throws IOException {
- final ProblemBuilder builder = new ProblemBuilder();
+ final ProblemBuilder builder = Problem.builder();
in.beginObject();
while (in.hasNext()) {
diff --git a/problem-gson/src/main/java/org/zalando/problem/ProblemAdapterFactory.java b/problem-gson/src/main/java/org/zalando/problem/gson/ProblemAdapterFactory.java
similarity index 90%
rename from problem-gson/src/main/java/org/zalando/problem/ProblemAdapterFactory.java
rename to problem-gson/src/main/java/org/zalando/problem/gson/ProblemAdapterFactory.java
index 3762bae..ea371e9 100644
--- a/problem-gson/src/main/java/org/zalando/problem/ProblemAdapterFactory.java
+++ b/problem-gson/src/main/java/org/zalando/problem/gson/ProblemAdapterFactory.java
@@ -1,4 +1,4 @@
-package org.zalando.problem;
+package org.zalando.problem.gson;
import com.google.gson.Gson;
import com.google.gson.JsonElement;
@@ -12,8 +12,14 @@
import lombok.AllArgsConstructor;
import org.apiguardian.api.API;
-import javax.annotation.CheckReturnValue;
-import javax.annotation.Nullable;
+import org.checkerframework.checker.nullness.qual.Nullable;
+import org.zalando.problem.AbstractThrowableProblem;
+import org.zalando.problem.DefaultProblem;
+import org.zalando.problem.Problem;
+import org.zalando.problem.Status;
+import org.zalando.problem.StatusType;
+import org.zalando.problem.ThrowableProblem;
+
import java.io.IOException;
import java.net.URI;
import java.util.Collections;
@@ -24,7 +30,7 @@
import static java.util.Objects.requireNonNull;
import static lombok.AccessLevel.PRIVATE;
import static org.apiguardian.api.API.Status.EXPERIMENTAL;
-import static org.zalando.problem.URITypeAdapter.TYPE;
+import static org.zalando.problem.gson.URITypeAdapter.TYPE;
/**
* Problem {@link TypeAdapterFactory}.
@@ -41,7 +47,7 @@ public ProblemAdapterFactory() {
}
@SafeVarargs
- public ProblemAdapterFactory(
+ public & StatusType> ProblemAdapterFactory(
final Class extends E>... statusTypes) {
this(false,
new StatusTypeAdapter(buildIndex(statusTypes)),
@@ -58,7 +64,7 @@ private ProblemAdapterFactory(
}
@SafeVarargs
- private static Map buildIndex(
+ private static & StatusType> Map buildIndex(
final Class extends E>... types) {
final Map index = new HashMap<>();
@@ -84,14 +90,14 @@ public ProblemAdapterFactory withStackTraces(final boolean stackTraces) {
return new ProblemAdapterFactory(stackTraces, statusAdapter, subtypes);
}
- @CheckReturnValue
+ // TODO @CheckReturnValue
public ProblemAdapterFactory registerSubtype(
final URI uri, final Class extends Problem> type) {
return registerSubType(uri, TypeToken.get(type));
}
- @CheckReturnValue
+ // TODO @CheckReturnValue
public ProblemAdapterFactory registerSubType(
final URI uri, final TypeToken extends Problem> type) {
diff --git a/problem-gson/src/main/java/org/zalando/problem/StatusTypeAdapter.java b/problem-gson/src/main/java/org/zalando/problem/gson/StatusTypeAdapter.java
similarity index 89%
rename from problem-gson/src/main/java/org/zalando/problem/StatusTypeAdapter.java
rename to problem-gson/src/main/java/org/zalando/problem/gson/StatusTypeAdapter.java
index 533509e..8c2f651 100644
--- a/problem-gson/src/main/java/org/zalando/problem/StatusTypeAdapter.java
+++ b/problem-gson/src/main/java/org/zalando/problem/gson/StatusTypeAdapter.java
@@ -1,4 +1,4 @@
-package org.zalando.problem;
+package org.zalando.problem.gson;
import com.google.gson.TypeAdapter;
import com.google.gson.stream.JsonReader;
@@ -6,7 +6,9 @@
import com.google.gson.stream.JsonWriter;
import lombok.AllArgsConstructor;
-import javax.annotation.Nullable;
+import org.checkerframework.checker.nullness.qual.Nullable;
+import org.zalando.problem.StatusType;
+
import java.io.IOException;
import java.util.Map;
import java.util.Objects;
diff --git a/problem-gson/src/main/java/org/zalando/problem/URITypeAdapter.java b/problem-gson/src/main/java/org/zalando/problem/gson/URITypeAdapter.java
similarity index 87%
rename from problem-gson/src/main/java/org/zalando/problem/URITypeAdapter.java
rename to problem-gson/src/main/java/org/zalando/problem/gson/URITypeAdapter.java
index 3d0ef62..b87a75d 100644
--- a/problem-gson/src/main/java/org/zalando/problem/URITypeAdapter.java
+++ b/problem-gson/src/main/java/org/zalando/problem/gson/URITypeAdapter.java
@@ -1,11 +1,13 @@
-package org.zalando.problem;
+package org.zalando.problem.gson;
import com.google.gson.TypeAdapter;
import com.google.gson.stream.JsonReader;
import com.google.gson.stream.JsonToken;
import com.google.gson.stream.JsonWriter;
-import javax.annotation.Nullable;
+import org.checkerframework.checker.nullness.qual.Nullable;
+import org.zalando.problem.Problem;
+
import java.io.IOException;
import java.net.URI;
diff --git a/problem-gson/src/main/java/org/zalando/problem/gson/UnknownStatus.java b/problem-gson/src/main/java/org/zalando/problem/gson/UnknownStatus.java
new file mode 100644
index 0000000..427e327
--- /dev/null
+++ b/problem-gson/src/main/java/org/zalando/problem/gson/UnknownStatus.java
@@ -0,0 +1,23 @@
+package org.zalando.problem.gson;
+
+import org.zalando.problem.StatusType;
+
+final class UnknownStatus implements StatusType {
+
+ private final int statusCode;
+
+ UnknownStatus(final int statusCode) {
+ this.statusCode = statusCode;
+ }
+
+ @Override
+ public int getStatusCode() {
+ return statusCode;
+ }
+
+ @Override
+ public String getReasonPhrase() {
+ return "Unknown";
+ }
+
+}
diff --git a/jackson-datatype-problem/src/test/java/org/zalando/problem/CustomStatus.java b/problem-gson/src/test/java/org/zalando/problem/gson/CustomStatus.java
similarity index 87%
rename from jackson-datatype-problem/src/test/java/org/zalando/problem/CustomStatus.java
rename to problem-gson/src/test/java/org/zalando/problem/gson/CustomStatus.java
index cb5f669..2c7cd99 100644
--- a/jackson-datatype-problem/src/test/java/org/zalando/problem/CustomStatus.java
+++ b/problem-gson/src/test/java/org/zalando/problem/gson/CustomStatus.java
@@ -1,4 +1,6 @@
-package org.zalando.problem;
+package org.zalando.problem.gson;
+
+import org.zalando.problem.StatusType;
enum CustomStatus implements StatusType {
diff --git a/problem-gson/src/test/java/org/zalando/problem/GsonProblemTest.java b/problem-gson/src/test/java/org/zalando/problem/gson/GsonProblemTest.java
similarity index 97%
rename from problem-gson/src/test/java/org/zalando/problem/GsonProblemTest.java
rename to problem-gson/src/test/java/org/zalando/problem/gson/GsonProblemTest.java
index 922c35f..a902f8b 100644
--- a/problem-gson/src/test/java/org/zalando/problem/GsonProblemTest.java
+++ b/problem-gson/src/test/java/org/zalando/problem/gson/GsonProblemTest.java
@@ -1,9 +1,16 @@
-package org.zalando.problem;
+package org.zalando.problem.gson;
import com.google.gson.Gson;
import com.google.gson.GsonBuilder;
import com.google.gson.stream.JsonReader;
import org.junit.jupiter.api.Test;
+import org.zalando.problem.DefaultProblem;
+import org.zalando.problem.Exceptional;
+import org.zalando.problem.Problem;
+import org.zalando.problem.ProblemBuilder;
+import org.zalando.problem.Status;
+import org.zalando.problem.StatusType;
+import org.zalando.problem.ThrowableProblem;
import java.io.File;
import java.io.FileNotFoundException;
@@ -13,6 +20,7 @@
import java.io.StringWriter;
import java.net.URI;
import java.net.URL;
+import java.util.Collections;
import java.util.List;
import java.util.Objects;
@@ -82,8 +90,8 @@ void shouldSerializeCustomProperties() {
void shouldSerializeCustomProblem() {
final int balance = 10;
final int debit = 100;
- final InsufficientFundsProblem problem = new InsufficientFundsProblem(balance, debit);
- problem.set("foo", "bar");
+ final InsufficientFundsProblem problem = new InsufficientFundsProblem(
+ balance, debit, Collections.singletonMap("foo", "bar"));
final String json = gson.toJson(problem);
assertThat("json", Objects.nonNull(json));
diff --git a/problem-gson/src/test/java/org/zalando/problem/IOProblem.java b/problem-gson/src/test/java/org/zalando/problem/gson/IOProblem.java
similarity index 87%
rename from problem-gson/src/test/java/org/zalando/problem/IOProblem.java
rename to problem-gson/src/test/java/org/zalando/problem/gson/IOProblem.java
index 0f0f179..aad11c1 100644
--- a/problem-gson/src/test/java/org/zalando/problem/IOProblem.java
+++ b/problem-gson/src/test/java/org/zalando/problem/gson/IOProblem.java
@@ -1,8 +1,12 @@
-package org.zalando.problem;
+package org.zalando.problem.gson;
import java.io.IOException;
import java.net.URI;
+import org.zalando.problem.Exceptional;
+import org.zalando.problem.StatusType;
+import org.zalando.problem.ThrowableProblem;
+
final class IOProblem extends IOException implements Exceptional {
private final URI type;
diff --git a/problem-gson/src/test/java/org/zalando/problem/InsufficientFundsProblem.java b/problem-gson/src/test/java/org/zalando/problem/gson/InsufficientFundsProblem.java
similarity index 59%
rename from problem-gson/src/test/java/org/zalando/problem/InsufficientFundsProblem.java
rename to problem-gson/src/test/java/org/zalando/problem/gson/InsufficientFundsProblem.java
index a6bb74b..3cf7d3b 100644
--- a/problem-gson/src/test/java/org/zalando/problem/InsufficientFundsProblem.java
+++ b/problem-gson/src/test/java/org/zalando/problem/gson/InsufficientFundsProblem.java
@@ -1,6 +1,10 @@
-package org.zalando.problem;
+package org.zalando.problem.gson;
import java.net.URI;
+import java.util.Collections;
+import java.util.Map;
+
+import org.zalando.problem.AbstractThrowableProblem;
import static org.zalando.problem.Status.BAD_REQUEST;
@@ -15,7 +19,14 @@ final class InsufficientFundsProblem extends AbstractThrowableProblem {
InsufficientFundsProblem(
final int balance,
final int debit) {
- super(TYPE, "Insufficient Funds", BAD_REQUEST);
+ this(balance, debit, Collections.emptyMap());
+ }
+
+ InsufficientFundsProblem(
+ final int balance,
+ final int debit,
+ final Map parameters) {
+ super(TYPE, "Insufficient Funds", BAD_REQUEST, null, null, null, parameters);
this.balance = balance;
this.debit = debit;
}
diff --git a/problem-gson/src/test/java/org/zalando/problem/MyProblem.java b/problem-gson/src/test/java/org/zalando/problem/gson/MyProblem.java
similarity index 92%
rename from problem-gson/src/test/java/org/zalando/problem/MyProblem.java
rename to problem-gson/src/test/java/org/zalando/problem/gson/MyProblem.java
index 4715a31..3f9bac9 100644
--- a/problem-gson/src/test/java/org/zalando/problem/MyProblem.java
+++ b/problem-gson/src/test/java/org/zalando/problem/gson/MyProblem.java
@@ -1,8 +1,10 @@
-package org.zalando.problem;
+package org.zalando.problem.gson;
import com.google.gson.annotations.SerializedName;
+import org.zalando.problem.Problem;
+import org.zalando.problem.StatusType;
-import javax.annotation.Nullable;
+import org.checkerframework.checker.nullness.qual.Nullable;
import java.net.URI;
class MyProblem implements Problem {
diff --git a/problem-gson/src/test/java/org/zalando/problem/OutOfStockException.java b/problem-gson/src/test/java/org/zalando/problem/gson/OutOfStockException.java
similarity index 85%
rename from problem-gson/src/test/java/org/zalando/problem/OutOfStockException.java
rename to problem-gson/src/test/java/org/zalando/problem/gson/OutOfStockException.java
index d775cd4..951499f 100644
--- a/problem-gson/src/test/java/org/zalando/problem/OutOfStockException.java
+++ b/problem-gson/src/test/java/org/zalando/problem/gson/OutOfStockException.java
@@ -1,7 +1,10 @@
-package org.zalando.problem;
+package org.zalando.problem.gson;
import java.net.URI;
+import org.zalando.problem.StatusType;
+import org.zalando.problem.ThrowableProblem;
+
import static org.zalando.problem.Status.BAD_REQUEST;
class OutOfStockException extends ThrowableProblem {
diff --git a/problem-gson/src/test/java/org/zalando/problem/ProblemAdapterFactoryTest.java b/problem-gson/src/test/java/org/zalando/problem/gson/ProblemAdapterFactoryTest.java
similarity index 95%
rename from problem-gson/src/test/java/org/zalando/problem/ProblemAdapterFactoryTest.java
rename to problem-gson/src/test/java/org/zalando/problem/gson/ProblemAdapterFactoryTest.java
index 0755604..7146e88 100644
--- a/problem-gson/src/test/java/org/zalando/problem/ProblemAdapterFactoryTest.java
+++ b/problem-gson/src/test/java/org/zalando/problem/gson/ProblemAdapterFactoryTest.java
@@ -1,7 +1,8 @@
-package org.zalando.problem;
+package org.zalando.problem.gson;
import org.junit.jupiter.api.Test;
import org.junit.jupiter.api.function.ThrowingSupplier;
+import org.zalando.problem.Status;
import static org.junit.jupiter.api.Assertions.assertDoesNotThrow;
import static org.junit.jupiter.api.Assertions.assertThrows;
diff --git a/problem-gson/src/test/java/org/zalando/problem/StatusTypeAdapterTest.java b/problem-gson/src/test/java/org/zalando/problem/gson/StatusTypeAdapterTest.java
similarity index 91%
rename from problem-gson/src/test/java/org/zalando/problem/StatusTypeAdapterTest.java
rename to problem-gson/src/test/java/org/zalando/problem/gson/StatusTypeAdapterTest.java
index 0851d8e..cb39b7f 100644
--- a/problem-gson/src/test/java/org/zalando/problem/StatusTypeAdapterTest.java
+++ b/problem-gson/src/test/java/org/zalando/problem/gson/StatusTypeAdapterTest.java
@@ -1,8 +1,9 @@
-package org.zalando.problem;
+package org.zalando.problem.gson;
import com.google.gson.Gson;
import com.google.gson.GsonBuilder;
import org.junit.jupiter.api.Test;
+import org.zalando.problem.StatusType;
import java.util.Collections;
diff --git a/problem-gson/src/test/java/org/zalando/problem/URITypeAdapterTest.java b/problem-gson/src/test/java/org/zalando/problem/gson/URITypeAdapterTest.java
similarity index 95%
rename from problem-gson/src/test/java/org/zalando/problem/URITypeAdapterTest.java
rename to problem-gson/src/test/java/org/zalando/problem/gson/URITypeAdapterTest.java
index 5ecd172..eabb92a 100644
--- a/problem-gson/src/test/java/org/zalando/problem/URITypeAdapterTest.java
+++ b/problem-gson/src/test/java/org/zalando/problem/gson/URITypeAdapterTest.java
@@ -1,10 +1,11 @@
-package org.zalando.problem;
+package org.zalando.problem.gson;
import com.google.gson.Gson;
import com.google.gson.GsonBuilder;
import com.google.gson.JsonIOException;
import com.google.gson.JsonPrimitive;
import org.junit.jupiter.api.Test;
+import org.zalando.problem.Problem;
import java.net.URI;
diff --git a/problem/src/test/java/org/zalando/problem/UnknownStatusTest.java b/problem-gson/src/test/java/org/zalando/problem/gson/UnknownStatusTest.java
similarity index 91%
rename from problem/src/test/java/org/zalando/problem/UnknownStatusTest.java
rename to problem-gson/src/test/java/org/zalando/problem/gson/UnknownStatusTest.java
index f816fdb..3327227 100644
--- a/problem/src/test/java/org/zalando/problem/UnknownStatusTest.java
+++ b/problem-gson/src/test/java/org/zalando/problem/gson/UnknownStatusTest.java
@@ -1,4 +1,4 @@
-package org.zalando.problem;
+package org.zalando.problem.gson;
import org.junit.jupiter.api.Test;
diff --git a/problem/pom.xml b/problem/pom.xml
index 8427b5c..f7c8ca7 100644
--- a/problem/pom.xml
+++ b/problem/pom.xml
@@ -10,4 +10,11 @@
problem
An implementation of the application/problem+json draft.
+
+ org.zalando.problem
+
+ org.zalando.problem;
+ org.zalando.problem.spi;
+
+
diff --git a/problem/src/main/java/org/zalando/problem/AbstractThrowableProblem.java b/problem/src/main/java/org/zalando/problem/AbstractThrowableProblem.java
index 3ad294e..38aae8b 100644
--- a/problem/src/main/java/org/zalando/problem/AbstractThrowableProblem.java
+++ b/problem/src/main/java/org/zalando/problem/AbstractThrowableProblem.java
@@ -1,11 +1,8 @@
package org.zalando.problem;
-import com.google.gag.annotation.remark.Hack;
-import com.google.gag.annotation.remark.OhNoYouDidnt;
import org.apiguardian.api.API;
-import javax.annotation.Nullable;
-import javax.annotation.concurrent.Immutable;
+import org.checkerframework.checker.nullness.qual.Nullable;
import java.net.URI;
import java.util.Collections;
import java.util.LinkedHashMap;
@@ -15,8 +12,6 @@
import static org.apiguardian.api.API.Status.INTERNAL;
import static org.apiguardian.api.API.Status.STABLE;
-@API(status = STABLE)
-@Immutable // TODO kind of a lie until we remove set(String, Object)
public abstract class AbstractThrowableProblem extends ThrowableProblem {
private final URI type;
@@ -30,29 +25,34 @@ protected AbstractThrowableProblem() {
this(null);
}
- protected AbstractThrowableProblem(@Nullable final URI type) {
+ protected AbstractThrowableProblem(
+ @Nullable final URI type) {
this(type, null);
}
- protected AbstractThrowableProblem(@Nullable final URI type,
+ protected AbstractThrowableProblem(
+ @Nullable final URI type,
@Nullable final String title) {
this(type, title, null);
}
- protected AbstractThrowableProblem(@Nullable final URI type,
+ protected AbstractThrowableProblem(
+ @Nullable final URI type,
@Nullable final String title,
@Nullable final StatusType status) {
this(type, title, status, null);
}
- protected AbstractThrowableProblem(@Nullable final URI type,
+ protected AbstractThrowableProblem(
+ @Nullable final URI type,
@Nullable final String title,
@Nullable final StatusType status,
@Nullable final String detail) {
this(type, title, status, detail, null);
}
- protected AbstractThrowableProblem(@Nullable final URI type,
+ protected AbstractThrowableProblem(
+ @Nullable final URI type,
@Nullable final String title,
@Nullable final StatusType status,
@Nullable final String detail,
@@ -60,7 +60,8 @@ protected AbstractThrowableProblem(@Nullable final URI type,
this(type, title, status, detail, instance, null);
}
- protected AbstractThrowableProblem(@Nullable final URI type,
+ protected AbstractThrowableProblem(
+ @Nullable final URI type,
@Nullable final String title,
@Nullable final StatusType status,
@Nullable final String detail,
@@ -69,7 +70,8 @@ protected AbstractThrowableProblem(@Nullable final URI type,
this(type, title, status, detail, instance, cause, null);
}
- protected AbstractThrowableProblem(@Nullable final URI type,
+ protected AbstractThrowableProblem(
+ @Nullable final URI type,
@Nullable final String title,
@Nullable final StatusType status,
@Nullable final String detail,
@@ -124,8 +126,6 @@ public Map getParameters() {
* @see Jackson Issue 562
*/
@API(status = INTERNAL)
- @Hack
- @OhNoYouDidnt
void set(final String key, final Object value) {
parameters.put(key, value);
}
diff --git a/problem/src/main/java/org/zalando/problem/DefaultProblem.java b/problem/src/main/java/org/zalando/problem/DefaultProblem.java
index c504878..6204998 100644
--- a/problem/src/main/java/org/zalando/problem/DefaultProblem.java
+++ b/problem/src/main/java/org/zalando/problem/DefaultProblem.java
@@ -1,8 +1,7 @@
package org.zalando.problem;
import org.apiguardian.api.API;
-
-import javax.annotation.Nullable;
+import org.checkerframework.checker.nullness.qual.Nullable;
import java.net.URI;
import java.util.Map;
diff --git a/problem/src/main/java/org/zalando/problem/Problem.java b/problem/src/main/java/org/zalando/problem/Problem.java
index 99e7e8d..fee821c 100644
--- a/problem/src/main/java/org/zalando/problem/Problem.java
+++ b/problem/src/main/java/org/zalando/problem/Problem.java
@@ -2,8 +2,7 @@
import org.apiguardian.api.API;
-import javax.annotation.Nullable;
-import javax.annotation.concurrent.Immutable;
+import org.checkerframework.checker.nullness.qual.Nullable;
import java.net.URI;
import java.util.Collections;
import java.util.Map;
@@ -15,9 +14,10 @@
/**
* @see RFC 7807: Problem Details for HTTP APIs
+ *
+ * {@link Problem} instances are required to be immutable.
*/
@API(status = STABLE)
-@Immutable
public interface Problem {
URI DEFAULT_TYPE = URI.create("about:blank");
diff --git a/problem/src/main/java/org/zalando/problem/ProblemBuilder.java b/problem/src/main/java/org/zalando/problem/ProblemBuilder.java
index c2721c6..576a75e 100644
--- a/problem/src/main/java/org/zalando/problem/ProblemBuilder.java
+++ b/problem/src/main/java/org/zalando/problem/ProblemBuilder.java
@@ -2,7 +2,7 @@
import org.apiguardian.api.API;
-import javax.annotation.Nullable;
+import org.checkerframework.checker.nullness.qual.Nullable;
import java.net.URI;
import java.util.Arrays;
import java.util.HashSet;
diff --git a/problem/src/main/java/org/zalando/problem/Status.java b/problem/src/main/java/org/zalando/problem/Status.java
index 3efbf02..a8b5377 100644
--- a/problem/src/main/java/org/zalando/problem/Status.java
+++ b/problem/src/main/java/org/zalando/problem/Status.java
@@ -1,9 +1,8 @@
package org.zalando.problem;
import org.apiguardian.api.API;
-
-import javax.annotation.Nonnull;
-import javax.annotation.Nullable;
+import org.checkerframework.checker.nullness.qual.NonNull;
+import org.checkerframework.checker.nullness.qual.Nullable;
import java.util.Arrays;
import java.util.Collections;
import java.util.Map;
@@ -14,20 +13,22 @@
import static org.apiguardian.api.API.Status.MAINTAINED;
/**
- * Commonly used status codes defined by HTTP, see
- * HTTP/1.1 documentation
- * for the complete list. Additional status codes can be added by applications
- * by creating an implementation of StatusType.
+ * Commonly used status codes defined by HTTP, see HTTP/1.1
+ * documentation for the complete list. Additional status codes can be added
+ * by applications by creating an implementation of StatusType.
*/
@API(status = MAINTAINED)
public enum Status implements StatusType {
/**
- * @see HTTP/1.1: Semantics and Content, section 6.2.1
+ * @see HTTP/1.1:
+ * Semantics and Content, section 6.2.1
*/
CONTINUE(100, "Continue"),
/**
- * @see HTTP/1.1: Semantics and Content, section 6.2.2
+ * @see HTTP/1.1:
+ * Semantics and Content, section 6.2.2
*/
SWITCHING_PROTOCOLS(101, "Switching Protocols"),
/**
@@ -35,36 +36,50 @@ public enum Status implements StatusType {
*/
PROCESSING(102, "Processing"),
/**
- * @see A proposal for supporting
- * resumable POST/PUT HTTP requests in HTTP/1.0
+ * @see A
+ * proposal for supporting resumable POST/PUT HTTP requests in HTTP/1.0
*/
CHECKPOINT(103, "Checkpoint"),
/**
- * 200 OK, see HTTP/1.1 documentation.
+ * 200 OK, see HTTP/1.1
+ * documentation.
*/
OK(200, "OK"),
/**
- * 201 Created, see HTTP/1.1 documentation.
+ * 201 Created, see HTTP/1.1
+ * documentation.
*/
CREATED(201, "Created"),
/**
- * 202 Accepted, see HTTP/1.1 documentation.
+ * 202 Accepted, see HTTP/1.1
+ * documentation.
*/
ACCEPTED(202, "Accepted"),
/**
- * @see HTTP/1.1: Semantics and Content, section 6.3.4
+ * @see HTTP/1.1:
+ * Semantics and Content, section 6.3.4
*/
NON_AUTHORITATIVE_INFORMATION(203, "Non-Authoritative Information"),
/**
- * 204 No Content, see HTTP/1.1 documentation.
+ * 204 No Content, see HTTP/1.1
+ * documentation.
*/
NO_CONTENT(204, "No Content"),
/**
- * 205 Reset Content, see HTTP/1.1 documentation.
+ * 205 Reset Content, see HTTP/1.1
+ * documentation.
*/
RESET_CONTENT(205, "Reset Content"),
/**
- * 206 Reset Content, see HTTP/1.1 documentation.
+ * 206 Reset Content, see HTTP/1.1
+ * documentation.
*/
PARTIAL_CONTENT(206, "Partial Content"),
/**
@@ -72,39 +87,54 @@ public enum Status implements StatusType {
*/
MULTI_STATUS(207, "Multi-Status"),
/**
- * @see WebDAV Binding Extensions
+ * @see WebDAV Binding
+ * Extensions
*/
ALREADY_REPORTED(208, "Already Reported"),
/**
- * @see Delta encoding in HTTP
+ * @see Delta
+ * encoding in HTTP
*/
IM_USED(226, "IM Used"),
/**
- * @see HTTP/1.1: Semantics and Content, section 6.4.1
+ * @see HTTP/1.1:
+ * Semantics and Content, section 6.4.1
*/
MULTIPLE_CHOICES(300, "Multiple Choices"),
/**
- * 301 Moved Permanently, see HTTP/1.1 documentation.
+ * 301 Moved Permanently, see HTTP/1.1
+ * documentation.
*/
MOVED_PERMANENTLY(301, "Moved Permanently"),
/**
- * 302 Found, see HTTP/1.1 documentation.
+ * 302 Found, see HTTP/1.1
+ * documentation.
*/
FOUND(302, "Found"),
/**
- * 303 See Other, see HTTP/1.1 documentation.
+ * 303 See Other, see HTTP/1.1
+ * documentation.
*/
SEE_OTHER(303, "See Other"),
/**
- * 304 Not Modified, see HTTP/1.1 documentation.
+ * 304 Not Modified, see HTTP/1.1
+ * documentation.
*/
NOT_MODIFIED(304, "Not Modified"),
/**
- * 305 Use Proxy, see HTTP/1.1 documentation.
+ * 305 Use Proxy, see HTTP/1.1
+ * documentation.
*/
USE_PROXY(305, "Use Proxy"),
/**
- * 307 Temporary Redirect, see HTTP/1.1 documentation.
+ * 307 Temporary Redirect, see HTTP/1.1
+ * documentation.
*/
TEMPORARY_REDIRECT(307, "Temporary Redirect"),
/**
@@ -112,79 +142,116 @@ public enum Status implements StatusType {
*/
PERMANENT_REDIRECT(308, "Permanent Redirect"),
/**
- * 400 Bad Request, see HTTP/1.1 documentation.
+ * 400 Bad Request, see HTTP/1.1
+ * documentation.
*/
BAD_REQUEST(400, "Bad Request"),
/**
- * 401 Unauthorized, see HTTP/1.1 documentation.
+ * 401 Unauthorized, see HTTP/1.1
+ * documentation.
*/
UNAUTHORIZED(401, "Unauthorized"),
/**
- * 402 Payment Required, see HTTP/1.1 documentation.
+ * 402 Payment Required, see HTTP/1.1
+ * documentation.
*/
PAYMENT_REQUIRED(402, "Payment Required"),
/**
- * 403 Forbidden, see HTTP/1.1 documentation.
+ * 403 Forbidden, see HTTP/1.1
+ * documentation.
*/
FORBIDDEN(403, "Forbidden"),
/**
- * 404 Not Found, see HTTP/1.1 documentation.
+ * 404 Not Found, see HTTP/1.1
+ * documentation.
*/
NOT_FOUND(404, "Not Found"),
/**
- * 405 Method Not Allowed, see HTTP/1.1 documentation.
+ * 405 Method Not Allowed, see HTTP/1.1
+ * documentation.
*/
METHOD_NOT_ALLOWED(405, "Method Not Allowed"),
/**
- * 406 Not Acceptable, see HTTP/1.1 documentation.
+ * 406 Not Acceptable, see HTTP/1.1
+ * documentation.
*/
NOT_ACCEPTABLE(406, "Not Acceptable"),
/**
- * 407 Proxy Authentication Required, see HTTP/1.1 documentation.
+ * 407 Proxy Authentication Required, see HTTP/1.1
+ * documentation.
*/
PROXY_AUTHENTICATION_REQUIRED(407, "Proxy Authentication Required"),
/**
- * 408 Request Timeout, see HTTP/1.1 documentation.
+ * 408 Request Timeout, see HTTP/1.1
+ * documentation.
*/
REQUEST_TIMEOUT(408, "Request Timeout"),
/**
- * 409 Conflict, see HTTP/1.1 documentation.
+ * 409 Conflict, see HTTP/1.1
+ * documentation.
*/
CONFLICT(409, "Conflict"),
/**
- * 410 Gone, see HTTP/1.1 documentation.
+ * 410 Gone, see HTTP/1.1
+ * documentation.
*/
GONE(410, "Gone"),
/**
- * 411 Length Required, see HTTP/1.1 documentation.
+ * 411 Length Required, see HTTP/1.1
+ * documentation.
*/
LENGTH_REQUIRED(411, "Length Required"),
/**
- * 412 Precondition Failed, see HTTP/1.1 documentation.
+ * 412 Precondition Failed, see HTTP/1.1
+ * documentation.
*/
PRECONDITION_FAILED(412, "Precondition Failed"),
/**
- * 413 Request Entity Too Large, see HTTP/1.1 documentation.
+ * 413 Request Entity Too Large, see HTTP/1.1
+ * documentation.
*/
REQUEST_ENTITY_TOO_LARGE(413, "Request Entity Too Large"),
/**
- * 414 Request-URI Too Long, see HTTP/1.1 documentation.
+ * 414 Request-URI Too Long, see HTTP/1.1
+ * documentation.
*/
REQUEST_URI_TOO_LONG(414, "Request-URI Too Long"),
/**
- * 415 Unsupported Media Type, see HTTP/1.1 documentation.
+ * 415 Unsupported Media Type, see HTTP/1.1
+ * documentation.
*/
UNSUPPORTED_MEDIA_TYPE(415, "Unsupported Media Type"),
/**
- * 416 Requested Range Not Satisfiable, see HTTP/1.1 documentation.
+ * 416 Requested Range Not Satisfiable, see HTTP/1.1
+ * documentation.
*/
REQUESTED_RANGE_NOT_SATISFIABLE(416, "Requested Range Not Satisfiable"),
/**
- * 417 Expectation Failed, see HTTP/1.1 documentation.
+ * 417 Expectation Failed, see HTTP/1.1
+ * documentation.
*/
EXPECTATION_FAILED(417, "Expectation Failed"),
/**
- * @see HTCPCP/1.0
+ * @see HTCPCP/1.0
*/
I_AM_A_TEAPOT(418, "I'm a teapot"),
/**
@@ -200,51 +267,69 @@ public enum Status implements StatusType {
*/
FAILED_DEPENDENCY(424, "Failed Dependency"),
/**
- * @see Upgrading to TLS Within HTTP/1.1
+ * @see Upgrading to TLS
+ * Within HTTP/1.1
*/
UPGRADE_REQUIRED(426, "Upgrade Required"),
/**
- * @see Additional HTTP Status Codes
+ * @see Additional HTTP
+ * Status Codes
*/
PRECONDITION_REQUIRED(428, "Precondition Required"),
/**
- * @see Additional HTTP Status Codes
+ * @see Additional HTTP
+ * Status Codes
*/
TOO_MANY_REQUESTS(429, "Too Many Requests"),
/**
- * @see Additional HTTP Status Codes
+ * @see Additional HTTP
+ * Status Codes
*/
REQUEST_HEADER_FIELDS_TOO_LARGE(431, "Request Header Fields Too Large"),
/**
- * @see Unavailable For Legal Reasons
+ * @see Unavailable For
+ * Legal Reasons
*/
UNAVAILABLE_FOR_LEGAL_REASONS(451, "Unavailable For Legal Reasons"),
/**
- * 500 Internal Server Error, see HTTP/1.1 documentation.
+ * 500 Internal Server Error, see HTTP/1.1
+ * documentation.
*/
INTERNAL_SERVER_ERROR(500, "Internal Server Error"),
/**
- * 501 Not Implemented, see HTTP/1.1 documentation.
+ * 501 Not Implemented, see HTTP/1.1
+ * documentation.
*/
NOT_IMPLEMENTED(501, "Not Implemented"),
/**
- * 502 Bad Gateway, see HTTP/1.1 documentation.
+ * 502 Bad Gateway, see HTTP/1.1
+ * documentation.
*/
BAD_GATEWAY(502, "Bad Gateway"),
/**
- * 503 Service Unavailable, see HTTP/1.1 documentation.
+ * 503 Service Unavailable, see HTTP/1.1
+ * documentation.
*/
SERVICE_UNAVAILABLE(503, "Service Unavailable"),
/**
- * 504 Gateway Timeout, see HTTP/1.1 documentation.
+ * 504 Gateway Timeout, see HTTP/1.1
+ * documentation.
*/
GATEWAY_TIMEOUT(504, "Gateway Timeout"),
/**
- * 505 HTTP Version Not Supported, see HTTP/1.1 documentation.
+ * 505 HTTP Version Not Supported, see HTTP/1.1
+ * documentation.
*/
HTTP_VERSION_NOT_SUPPORTED(505, "HTTP Version Not Supported"),
/**
- * @see Transparent Content Negotiation
+ * @see Transparent
+ * Content Negotiation
*/
VARIANT_ALSO_NEGOTIATES(506, "Variant Also Negotiates"),
/**
@@ -252,7 +337,8 @@ public enum Status implements StatusType {
*/
INSUFFICIENT_STORAGE(507, "Insufficient Storage"),
/**
- * @see WebDAV Binding Extensions
+ * @see WebDAV Binding
+ * Extensions
*/
LOOP_DETECTED(508, "Loop Detected"),
/**
@@ -260,18 +346,18 @@ public enum Status implements StatusType {
*/
BANDWIDTH_LIMIT_EXCEEDED(509, "Bandwidth Limit Exceeded"),
/**
- * @see HTTP Extension Framework
+ * @see HTTP Extension
+ * Framework
*/
NOT_EXTENDED(510, "Not Extended"),
/**
- * @see Additional HTTP Status Codes
+ * @see Additional HTTP
+ * Status Codes
*/
NETWORK_AUTHENTICATION_REQUIRED(511, "Network Authentication Required");
private static final Map STATUSES = Arrays.stream(values())
- .collect(collectingAndThen(
- toMap(Status::getStatusCode, identity()),
- Collections::unmodifiableMap));
+ .collect(collectingAndThen(toMap(Status::getStatusCode, identity()), Collections::unmodifiableMap));
private final int code;
private final String reason;
@@ -297,7 +383,7 @@ public int getStatusCode() {
* @return the reason phrase.
*/
@Override
- @Nonnull
+ @NonNull
public String getReasonPhrase() {
return reason;
}
diff --git a/problem/src/main/java/org/zalando/problem/ThrowableProblem.java b/problem/src/main/java/org/zalando/problem/ThrowableProblem.java
index 0883b47..8fdc4d1 100644
--- a/problem/src/main/java/org/zalando/problem/ThrowableProblem.java
+++ b/problem/src/main/java/org/zalando/problem/ThrowableProblem.java
@@ -2,8 +2,7 @@
import org.apiguardian.api.API;
-import javax.annotation.Nullable;
-import javax.annotation.concurrent.Immutable;
+import org.checkerframework.checker.nullness.qual.Nullable;
import java.util.Collection;
import java.util.Objects;
import java.util.stream.Stream;
@@ -13,8 +12,11 @@
import static org.apiguardian.api.API.Status.STABLE;
import static org.zalando.problem.spi.StackTraceProcessor.COMPOUND;
+/**
+ *
+ * {@link Problem} instances are required to be immutable.
+ */
@API(status = STABLE)
-@Immutable
public abstract class ThrowableProblem extends RuntimeException implements Problem, Exceptional {
protected ThrowableProblem() {
diff --git a/problem/src/main/java/org/zalando/problem/package-info.java b/problem/src/main/java/org/zalando/problem/package-info.java
index 7d55a70..5352e50 100644
--- a/problem/src/main/java/org/zalando/problem/package-info.java
+++ b/problem/src/main/java/org/zalando/problem/package-info.java
@@ -1,3 +1,6 @@
-@ParametersAreNonnullByDefault package org.zalando.problem;
+@DefaultQualifier(value = NonNull.class, locations = TypeUseLocation.PARAMETER)
+package org.zalando.problem;
-import javax.annotation.ParametersAreNonnullByDefault;
\ No newline at end of file
+import org.checkerframework.checker.nullness.qual.NonNull;
+import org.checkerframework.framework.qual.DefaultQualifier;
+import org.checkerframework.framework.qual.TypeUseLocation;
diff --git a/problem/src/test/java/org/example/MyProblem.java b/problem/src/test/java/org/example/MyProblem.java
index 0e56dd1..1f7275d 100644
--- a/problem/src/test/java/org/example/MyProblem.java
+++ b/problem/src/test/java/org/example/MyProblem.java
@@ -4,7 +4,7 @@
import org.zalando.problem.StatusType;
import org.zalando.problem.ThrowableProblem;
-import javax.annotation.Nullable;
+import org.checkerframework.checker.nullness.qual.Nullable;
import java.net.URI;
import java.util.Map;
diff --git a/problem/src/test/java/org/zalando/problem/EnforceCoverageTest.java b/problem/src/test/java/org/zalando/problem/EnforceCoverageTest.java
index d119dea..ffb4afb 100644
--- a/problem/src/test/java/org/zalando/problem/EnforceCoverageTest.java
+++ b/problem/src/test/java/org/zalando/problem/EnforceCoverageTest.java
@@ -1,7 +1,5 @@
package org.zalando.problem;
-import com.google.gag.annotation.remark.Hack;
-import com.google.gag.annotation.remark.OhNoYouDidnt;
import org.junit.jupiter.api.Test;
import java.net.URI;
@@ -9,8 +7,6 @@
import static org.junit.jupiter.api.Assertions.assertThrows;
import static org.zalando.problem.Status.BAD_REQUEST;
-@Hack
-@OhNoYouDidnt
class EnforceCoverageTest {
@Test