diff --git a/com.vogella.adapters/META-INF/MANIFEST.MF b/com.vogella.adapters/META-INF/MANIFEST.MF
index d21db6d..cb6569c 100644
--- a/com.vogella.adapters/META-INF/MANIFEST.MF
+++ b/com.vogella.adapters/META-INF/MANIFEST.MF
@@ -15,5 +15,5 @@ Require-Bundle: org.eclipse.core.runtime,
org.eclipse.core.resources,
org.eclipse.e4.ui.workbench
Bundle-RequiredExecutionEnvironment: JavaSE-25
-Import-Package: jakarta.annotation;version="[2.1.0,3.0.0)"
+Import-Package: jakarta.annotation;version="[2.1.0,4.0.0)"
Automatic-Module-Name: com.vogella.adapters
diff --git a/com.vogella.contribute.parts/META-INF/MANIFEST.MF b/com.vogella.contribute.parts/META-INF/MANIFEST.MF
index e30f33e..07ffb07 100644
--- a/com.vogella.contribute.parts/META-INF/MANIFEST.MF
+++ b/com.vogella.contribute.parts/META-INF/MANIFEST.MF
@@ -18,6 +18,6 @@ Require-Bundle: org.eclipse.core.runtime,
org.eclipse.ui.workbench;bundle-version="3.134.0",
org.eclipse.e4.core.contexts
Bundle-RequiredExecutionEnvironment: JavaSE-25
-Import-Package: jakarta.annotation;version="[2.1.0,3.0.0)",
+Import-Package: jakarta.annotation;version="[2.1.0,4.0.0)",
jakarta.inject;version="[2.0.0,3.0.0)"
Automatic-Module-Name: com.vogella.contribute.parts
diff --git a/com.vogella.ide.first/META-INF/MANIFEST.MF b/com.vogella.ide.first/META-INF/MANIFEST.MF
index c602fbc..8bbd56b 100644
--- a/com.vogella.ide.first/META-INF/MANIFEST.MF
+++ b/com.vogella.ide.first/META-INF/MANIFEST.MF
@@ -12,6 +12,6 @@ Require-Bundle: org.eclipse.osgi,
org.eclipse.e4.core.di.annotations
Bundle-RequiredExecutionEnvironment: JavaSE-25
Import-Package: com.vogella.tasks.model,
- jakarta.annotation;version="[2.1.0,3.0.0)",
+ jakarta.annotation;version="[2.1.0,4.0.0)",
jakarta.inject;version="[2.0.0,3.0.0)"
Automatic-Module-Name: com.vogella.ide.first
diff --git a/com.vogella.json.validation.tests/.classpath b/com.vogella.json.validation.tests/.classpath
new file mode 100644
index 0000000..2198f33
--- /dev/null
+++ b/com.vogella.json.validation.tests/.classpath
@@ -0,0 +1,11 @@
+
+
+
+
+
+
+
+
+
+
+
diff --git a/com.vogella.json.validation.tests/.project b/com.vogella.json.validation.tests/.project
new file mode 100644
index 0000000..6be8a94
--- /dev/null
+++ b/com.vogella.json.validation.tests/.project
@@ -0,0 +1,34 @@
+
+
+ com.vogella.json.validation.tests
+
+
+
+
+
+ org.eclipse.jdt.core.javabuilder
+
+
+
+
+ org.eclipse.pde.ManifestBuilder
+
+
+
+
+ org.eclipse.pde.SchemaBuilder
+
+
+
+
+ org.eclipse.m2e.core.maven2Builder
+
+
+
+
+
+ org.eclipse.m2e.core.maven2Nature
+ org.eclipse.pde.PluginNature
+ org.eclipse.jdt.core.javanature
+
+
diff --git a/com.vogella.json.validation.tests/.settings/org.eclipse.jdt.core.prefs b/com.vogella.json.validation.tests/.settings/org.eclipse.jdt.core.prefs
new file mode 100644
index 0000000..c540a97
--- /dev/null
+++ b/com.vogella.json.validation.tests/.settings/org.eclipse.jdt.core.prefs
@@ -0,0 +1,9 @@
+eclipse.preferences.version=1
+org.eclipse.jdt.core.compiler.codegen.targetPlatform=25
+org.eclipse.jdt.core.compiler.compliance=25
+org.eclipse.jdt.core.compiler.problem.assertIdentifier=error
+org.eclipse.jdt.core.compiler.problem.enablePreviewFeatures=disabled
+org.eclipse.jdt.core.compiler.problem.enumIdentifier=error
+org.eclipse.jdt.core.compiler.problem.reportPreviewFeatures=warning
+org.eclipse.jdt.core.compiler.release=enabled
+org.eclipse.jdt.core.compiler.source=25
diff --git a/com.vogella.json.validation.tests/META-INF/MANIFEST.MF b/com.vogella.json.validation.tests/META-INF/MANIFEST.MF
new file mode 100644
index 0000000..3cb3117
--- /dev/null
+++ b/com.vogella.json.validation.tests/META-INF/MANIFEST.MF
@@ -0,0 +1,10 @@
+Manifest-Version: 1.0
+Bundle-ManifestVersion: 2
+Bundle-Name: JSON Schema Validation Example Tests
+Bundle-SymbolicName: com.vogella.json.validation.tests
+Bundle-Version: 1.0.0.qualifier
+Bundle-Vendor: VOGELLA
+Fragment-Host: com.vogella.json.validation;bundle-version="1.0.0"
+Require-Bundle: junit-jupiter-api;bundle-version="5.11.0"
+Automatic-Module-Name: com.vogella.json.validation.tests
+Bundle-RequiredExecutionEnvironment: JavaSE-25
diff --git a/com.vogella.json.validation.tests/build.properties b/com.vogella.json.validation.tests/build.properties
new file mode 100644
index 0000000..34d2e4d
--- /dev/null
+++ b/com.vogella.json.validation.tests/build.properties
@@ -0,0 +1,4 @@
+source.. = src/
+output.. = bin/
+bin.includes = META-INF/,\
+ .
diff --git a/com.vogella.json.validation.tests/pom.xml b/com.vogella.json.validation.tests/pom.xml
new file mode 100644
index 0000000..a8f2941
--- /dev/null
+++ b/com.vogella.json.validation.tests/pom.xml
@@ -0,0 +1,17 @@
+
+ 4.0.0
+
+
+ com.vogella.tycho
+ releng
+ 1.0.0-SNAPSHOT
+
+
+ com.vogella.json
+ com.vogella.json.validation.tests
+ 1.0.0-SNAPSHOT
+ eclipse-test-plugin
+
+
diff --git a/com.vogella.json.validation.tests/src/com/vogella/json/validation/tests/JsonSchemaValidationExampleTest.java b/com.vogella.json.validation.tests/src/com/vogella/json/validation/tests/JsonSchemaValidationExampleTest.java
new file mode 100644
index 0000000..9cec746
--- /dev/null
+++ b/com.vogella.json.validation.tests/src/com/vogella/json/validation/tests/JsonSchemaValidationExampleTest.java
@@ -0,0 +1,55 @@
+package com.vogella.json.validation.tests;
+
+import static org.junit.jupiter.api.Assertions.assertFalse;
+import static org.junit.jupiter.api.Assertions.assertTrue;
+
+import java.io.ByteArrayInputStream;
+import java.io.InputStream;
+import java.nio.charset.StandardCharsets;
+import java.util.Set;
+
+import org.junit.jupiter.api.Test;
+
+import com.networknt.schema.ValidationMessage;
+import com.vogella.json.validation.JsonSchemaValidationExample;
+
+class JsonSchemaValidationExampleTest {
+
+ private final JsonSchemaValidationExample example = new JsonSchemaValidationExample();
+
+ @Test
+ void validDocumentHasNoErrors() throws Exception {
+ try (InputStream schema = schema(); InputStream data = resource("data.json")) {
+ Set errors = example.validate(schema, data);
+ assertTrue(errors.isEmpty(), () -> "Expected no errors but got: " + errors);
+ }
+ }
+
+ @Test
+ void invalidDocumentReportsErrors() throws Exception {
+ // Missing required "name", negative "age", and an undeclared property.
+ String invalid = """
+ {
+ "age": -1,
+ "unexpected": true
+ }
+ """;
+ try (InputStream schema = schema();
+ InputStream data = new ByteArrayInputStream(invalid.getBytes(StandardCharsets.UTF_8))) {
+ Set errors = example.validate(schema, data);
+ assertFalse(errors.isEmpty(), "Expected validation errors for an invalid document");
+ }
+ }
+
+ private static InputStream schema() {
+ return resource("schema.json");
+ }
+
+ private static InputStream resource(String name) {
+ InputStream in = JsonSchemaValidationExample.class.getResourceAsStream(name);
+ if (in == null) {
+ throw new IllegalStateException("Missing classpath resource: " + name);
+ }
+ return in;
+ }
+}
diff --git a/com.vogella.json.validation/.classpath b/com.vogella.json.validation/.classpath
new file mode 100644
index 0000000..7a42e53
--- /dev/null
+++ b/com.vogella.json.validation/.classpath
@@ -0,0 +1,7 @@
+
+
+
+
+
+
+
diff --git a/com.vogella.json.validation/.project b/com.vogella.json.validation/.project
new file mode 100644
index 0000000..e6a71e5
--- /dev/null
+++ b/com.vogella.json.validation/.project
@@ -0,0 +1,34 @@
+
+
+ com.vogella.json.validation
+
+
+
+
+
+ org.eclipse.jdt.core.javabuilder
+
+
+
+
+ org.eclipse.pde.ManifestBuilder
+
+
+
+
+ org.eclipse.pde.SchemaBuilder
+
+
+
+
+ org.eclipse.m2e.core.maven2Builder
+
+
+
+
+
+ org.eclipse.m2e.core.maven2Nature
+ org.eclipse.pde.PluginNature
+ org.eclipse.jdt.core.javanature
+
+
diff --git a/com.vogella.json.validation/.settings/org.eclipse.jdt.core.prefs b/com.vogella.json.validation/.settings/org.eclipse.jdt.core.prefs
new file mode 100644
index 0000000..c540a97
--- /dev/null
+++ b/com.vogella.json.validation/.settings/org.eclipse.jdt.core.prefs
@@ -0,0 +1,9 @@
+eclipse.preferences.version=1
+org.eclipse.jdt.core.compiler.codegen.targetPlatform=25
+org.eclipse.jdt.core.compiler.compliance=25
+org.eclipse.jdt.core.compiler.problem.assertIdentifier=error
+org.eclipse.jdt.core.compiler.problem.enablePreviewFeatures=disabled
+org.eclipse.jdt.core.compiler.problem.enumIdentifier=error
+org.eclipse.jdt.core.compiler.problem.reportPreviewFeatures=warning
+org.eclipse.jdt.core.compiler.release=enabled
+org.eclipse.jdt.core.compiler.source=25
diff --git a/com.vogella.json.validation/META-INF/MANIFEST.MF b/com.vogella.json.validation/META-INF/MANIFEST.MF
new file mode 100644
index 0000000..558fcdb
--- /dev/null
+++ b/com.vogella.json.validation/META-INF/MANIFEST.MF
@@ -0,0 +1,11 @@
+Manifest-Version: 1.0
+Bundle-ManifestVersion: 2
+Bundle-Name: JSON Schema Validation Example
+Bundle-SymbolicName: com.vogella.json.validation
+Bundle-Version: 1.0.0.qualifier
+Bundle-Vendor: VOGELLA
+Automatic-Module-Name: com.vogella.json.validation
+Bundle-RequiredExecutionEnvironment: JavaSE-25
+Export-Package: com.vogella.json.validation
+Require-Bundle: com.networknt.json-schema-validator;bundle-version="1.5.6",
+ com.fasterxml.jackson.core.jackson-databind;bundle-version="[2.18.0,3.0.0)"
diff --git a/com.vogella.json.validation/build.properties b/com.vogella.json.validation/build.properties
new file mode 100644
index 0000000..34d2e4d
--- /dev/null
+++ b/com.vogella.json.validation/build.properties
@@ -0,0 +1,4 @@
+source.. = src/
+output.. = bin/
+bin.includes = META-INF/,\
+ .
diff --git a/com.vogella.json.validation/src/com/vogella/json/validation/JsonSchemaValidationExample.java b/com.vogella.json.validation/src/com/vogella/json/validation/JsonSchemaValidationExample.java
new file mode 100644
index 0000000..8d352ed
--- /dev/null
+++ b/com.vogella.json.validation/src/com/vogella/json/validation/JsonSchemaValidationExample.java
@@ -0,0 +1,64 @@
+package com.vogella.json.validation;
+
+import java.io.IOException;
+import java.io.InputStream;
+import java.io.UncheckedIOException;
+import java.util.Set;
+
+import com.fasterxml.jackson.databind.JsonNode;
+import com.fasterxml.jackson.databind.ObjectMapper;
+import com.networknt.schema.JsonSchema;
+import com.networknt.schema.JsonSchemaFactory;
+import com.networknt.schema.SpecVersion;
+import com.networknt.schema.ValidationMessage;
+
+/**
+ * Validates a JSON document against a JSON Schema (Draft 2020-12) using
+ * networknt/json-schema-validator.
+ */
+public class JsonSchemaValidationExample {
+
+ private static final ObjectMapper MAPPER = new ObjectMapper();
+ private static final JsonSchemaFactory FACTORY = JsonSchemaFactory
+ .getInstance(SpecVersion.VersionFlag.V202012);
+
+ /**
+ * Validates the JSON read from {@code data} against the schema read from
+ * {@code schema}.
+ *
+ * @return the validation errors, empty if the document is valid
+ */
+ public Set validate(InputStream schema, InputStream data) {
+ try {
+ JsonSchema jsonSchema = FACTORY.getSchema(schema);
+ JsonNode node = MAPPER.readTree(data);
+ return jsonSchema.validate(node);
+ } catch (IOException e) {
+ throw new UncheckedIOException("Could not read JSON schema or data", e);
+ }
+ }
+
+ public static void main(String[] args) {
+ JsonSchemaValidationExample example = new JsonSchemaValidationExample();
+ try (InputStream schema = resource("schema.json");
+ InputStream data = resource("data.json")) {
+ Set errors = example.validate(schema, data);
+ if (errors.isEmpty()) {
+ System.out.println("data.json is valid against schema.json");
+ } else {
+ System.out.println("data.json is invalid:");
+ errors.forEach(error -> System.out.println(" " + error.getMessage()));
+ }
+ } catch (IOException e) {
+ throw new UncheckedIOException(e);
+ }
+ }
+
+ private static InputStream resource(String name) {
+ InputStream in = JsonSchemaValidationExample.class.getResourceAsStream(name);
+ if (in == null) {
+ throw new IllegalStateException("Missing classpath resource: " + name);
+ }
+ return in;
+ }
+}
diff --git a/com.vogella.json.validation/src/com/vogella/json/validation/data.json b/com.vogella.json.validation/src/com/vogella/json/validation/data.json
new file mode 100644
index 0000000..9ad3614
--- /dev/null
+++ b/com.vogella.json.validation/src/com/vogella/json/validation/data.json
@@ -0,0 +1,5 @@
+{
+ "name": "Alice",
+ "age": 30,
+ "email": "alice@example.com"
+}
diff --git a/com.vogella.json.validation/src/com/vogella/json/validation/schema.json b/com.vogella.json.validation/src/com/vogella/json/validation/schema.json
new file mode 100644
index 0000000..aec2aba
--- /dev/null
+++ b/com.vogella.json.validation/src/com/vogella/json/validation/schema.json
@@ -0,0 +1,12 @@
+{
+ "$schema": "https://json-schema.org/draft/2020-12/schema",
+ "title": "Person",
+ "type": "object",
+ "properties": {
+ "name": { "type": "string" },
+ "age": { "type": "integer", "minimum": 0 },
+ "email": { "type": "string", "format": "email" }
+ },
+ "required": ["name", "age"],
+ "additionalProperties": false
+}
diff --git a/com.vogella.tasks.ui/META-INF/MANIFEST.MF b/com.vogella.tasks.ui/META-INF/MANIFEST.MF
index 8efba09..139d9e1 100644
--- a/com.vogella.tasks.ui/META-INF/MANIFEST.MF
+++ b/com.vogella.tasks.ui/META-INF/MANIFEST.MF
@@ -24,7 +24,7 @@ Require-Bundle: org.eclipse.core.runtime,
Bundle-RequiredExecutionEnvironment: JavaSE-25
Import-Package: com.vogella.tasks.events,
com.vogella.tasks.model,
- jakarta.annotation;version="[2.1.0,3.0.0)",
+ jakarta.annotation;version="[2.1.0,4.0.0)",
jakarta.inject;version="[2.0.0,3.0.0)"
Automatic-Module-Name: com.vogella.tasks.ui
Bundle-ActivationPolicy: lazy
diff --git a/pom.xml b/pom.xml
index 308bb4c..c802d21 100644
--- a/pom.xml
+++ b/pom.xml
@@ -140,8 +140,10 @@
z.ex.search
com.vogella.ide.iconreplacer
com.vogella.ide.parallelstart
+ com.vogella.json.validation
+ com.vogella.json.validation.tests