SLING-11718 : Migrate to Jakarta JSON API
diff --git a/pom.xml b/pom.xml
index f606fb8..c24331e 100644
--- a/pom.xml
+++ b/pom.xml
@@ -22,7 +22,7 @@
     </parent>
 
     <artifactId>org.apache.sling.feature</artifactId>
-    <version>1.3.1-SNAPSHOT</version>
+    <version>2.0.0-SNAPSHOT</version>
 
     <name>Apache Sling Feature Model</name>
     <description>
@@ -98,9 +98,9 @@
             <scope>provided</scope>
         </dependency>
         <dependency>
-            <groupId>org.apache.geronimo.specs</groupId>
-            <artifactId>geronimo-json_1.1_spec</artifactId>
-            <version>1.2</version>
+            <groupId>jakarta.json</groupId>
+            <artifactId>jakarta.json-api</artifactId>
+            <version>2.0.2</version>
             <scope>provided</scope>
         </dependency>
         <dependency>
@@ -124,7 +124,7 @@
         <dependency>
             <groupId>org.apache.felix</groupId>
             <artifactId>org.apache.felix.cm.json</artifactId>
-            <version>1.0.6</version>
+            <version>2.0.0</version>
             <scope>provided</scope>
         </dependency>
         <dependency>
@@ -142,25 +142,25 @@
         <dependency>
             <groupId>org.mockito</groupId>
             <artifactId>mockito-core</artifactId>
-            <version>3.3.0</version>
+            <version>3.12.4</version>
             <scope>test</scope>
         </dependency>
         <dependency>
             <groupId>org.osgi</groupId>
             <artifactId>org.osgi.util.function</artifactId>
-            <version>1.0.0</version>
+            <version>1.2.0</version>
             <scope>test</scope>
         </dependency>
         <dependency>
             <groupId>org.apache.felix</groupId>
             <artifactId>org.apache.felix.feature</artifactId>
-            <version>1.0.0</version>
+            <version>1.0.2</version>
             <scope>test</scope>
         </dependency>
         <dependency>
-            <groupId>org.apache.johnzon</groupId>
-            <artifactId>johnzon-core</artifactId>
-            <version>1.2.14</version>
+            <groupId>org.eclipse.parsson</groupId>
+            <artifactId>parsson</artifactId>
+            <version>1.0.2</version>
             <scope>test</scope>
         </dependency>
     </dependencies>
diff --git a/src/main/java/org/apache/sling/feature/Artifact.java b/src/main/java/org/apache/sling/feature/Artifact.java
index 76e15f8..ea6b035 100644
--- a/src/main/java/org/apache/sling/feature/Artifact.java
+++ b/src/main/java/org/apache/sling/feature/Artifact.java
@@ -26,9 +26,9 @@
 import java.util.stream.Collectors;
 import java.util.stream.Stream;
 
-import javax.json.JsonString;
-import javax.json.JsonValue;
-import javax.json.JsonValue.ValueType;
+import jakarta.json.JsonString;
+import jakarta.json.JsonValue;
+import jakarta.json.JsonValue.ValueType;
 
 /**
  * An artifact consists of
@@ -96,7 +96,7 @@
                 }
                 final JsonValue value = metadataEntry.getValue();
                 if ( value.getValueType() == ValueType.STRING || value.getValueType() == ValueType.NUMBER || value.getValueType() == ValueType.FALSE || value.getValueType() == ValueType.TRUE ) {
-                    this.getMetadata().put(key, org.apache.felix.cm.json.Configurations.convertToObject(value).toString());
+                    this.getMetadata().put(key, org.apache.felix.cm.json.io.Configurations.convertToObject(value).toString());
                 } else {
                     throw new IllegalArgumentException("Key ".concat(key).concat(" is not one of the allowed types string, number or boolean : ").concat(value.getValueType().name()));
                 }
diff --git a/src/main/java/org/apache/sling/feature/Configuration.java b/src/main/java/org/apache/sling/feature/Configuration.java
index 6b004f7..f296307 100644
--- a/src/main/java/org/apache/sling/feature/Configuration.java
+++ b/src/main/java/org/apache/sling/feature/Configuration.java
@@ -24,7 +24,7 @@
 import java.util.List;
 import java.util.stream.Collectors;
 
-import org.apache.felix.cm.json.Configurations;
+import org.apache.felix.cm.json.io.Configurations;
 import org.osgi.util.converter.Converters;
 
 
diff --git a/src/main/java/org/apache/sling/feature/ExecutionEnvironmentExtension.java b/src/main/java/org/apache/sling/feature/ExecutionEnvironmentExtension.java
index e2f7595..0afb61b 100644
--- a/src/main/java/org/apache/sling/feature/ExecutionEnvironmentExtension.java
+++ b/src/main/java/org/apache/sling/feature/ExecutionEnvironmentExtension.java
@@ -16,10 +16,10 @@
  */
 package org.apache.sling.feature;
 
-import javax.json.JsonString;
-import javax.json.JsonStructure;
-import javax.json.JsonValue;
-import javax.json.JsonValue.ValueType;
+import jakarta.json.JsonString;
+import jakarta.json.JsonStructure;
+import jakarta.json.JsonValue;
+import jakarta.json.JsonValue.ValueType;
 
 import org.osgi.framework.Version;
 
diff --git a/src/main/java/org/apache/sling/feature/Extension.java b/src/main/java/org/apache/sling/feature/Extension.java
index 1842d61..865fc09 100644
--- a/src/main/java/org/apache/sling/feature/Extension.java
+++ b/src/main/java/org/apache/sling/feature/Extension.java
@@ -20,9 +20,9 @@
 import java.io.StringReader;
 import java.io.StringWriter;
 
-import javax.json.Json;
-import javax.json.JsonStructure;
-import javax.json.JsonWriter;
+import jakarta.json.Json;
+import jakarta.json.JsonStructure;
+import jakarta.json.JsonWriter;
 
 import org.apache.sling.feature.builder.BuilderContext;
 
@@ -99,22 +99,6 @@
     /**
      * Create a new extension
      *
-     * @param t        The type of the extension
-     * @param name     The name of the extension
-     * @param required Whether the extension is required or optional
-     * @throws IllegalArgumentException If name or t are {@code null}
-     * @deprecated Use {@link #Extension(ExtensionType, String, ExtensionState)}
-     */
-    @Deprecated
-    public Extension(final ExtensionType t,
-            final String name,
-            final boolean required) {
-        this(t, name, required ? ExtensionState.REQUIRED : ExtensionState.OPTIONAL);
-    }
-
-    /**
-     * Create a new extension
-     *
      * @param type  The type of the extension
      * @param name  The name of the extension
      * @param state The state of the extension
@@ -163,28 +147,6 @@
     }
 
     /**
-     * Return whether the extension is required or optional
-     *
-     * @return Return {@code true} if the extension is required.
-     * @deprecated Use {@link #getState()}
-     */
-    @Deprecated
-    public boolean isRequired() {
-        return this.state == ExtensionState.REQUIRED;
-    }
-
-    /**
-     * Return whether the extension is required or optional
-     *
-     * @return Return {@code true} if the extension is optional.
-     * @deprecated Use {@link #getState()}
-     */
-    @Deprecated
-    public boolean isOptional() {
-        return !this.isRequired();
-    }
-
-    /**
      * Get the text of the extension
      * @return The text
      * @throws IllegalStateException if the type is not {@code ExtensionType#TEXT}
diff --git a/src/main/java/org/apache/sling/feature/builder/BuilderContext.java b/src/main/java/org/apache/sling/feature/builder/BuilderContext.java
index f3924a8..54d2ef8 100644
--- a/src/main/java/org/apache/sling/feature/builder/BuilderContext.java
+++ b/src/main/java/org/apache/sling/feature/builder/BuilderContext.java
@@ -22,7 +22,6 @@
 import java.util.LinkedHashMap;
 import java.util.List;
 import java.util.Map;
-import java.util.stream.Collectors;
 
 import org.apache.sling.feature.ArtifactId;
 
@@ -169,21 +168,6 @@
     }
 
     /**
-     * Add overrides for artifact clashes.
-     *
-     * @param overrides The overrides
-     * @return The builder context
-     * @throws IllegalArgumentException If the provided overrides are not following
-     *                                  the artifact id syntax
-     * @deprecated Use {@link #addArtifactsOverride(ArtifactId)} instead.
-     */
-    @Deprecated
-    public BuilderContext addArtifactsOverrides(final List<String> overrides) {
-        this.artifactsOverrides.addAll(overrides.stream().map(f -> ArtifactId.parse(f)).collect(Collectors.toList()));
-        return this;
-    }
-
-    /**
      * Add an override for artifact clashes.
      *
      * @param override The override
diff --git a/src/main/java/org/apache/sling/feature/builder/BuilderUtil.java b/src/main/java/org/apache/sling/feature/builder/BuilderUtil.java
index b96e7a8..4d4cdd1 100644
--- a/src/main/java/org/apache/sling/feature/builder/BuilderUtil.java
+++ b/src/main/java/org/apache/sling/feature/builder/BuilderUtil.java
@@ -32,15 +32,15 @@
 import java.util.stream.Collectors;
 import java.util.stream.Stream;
 
-import javax.json.Json;
-import javax.json.JsonArray;
-import javax.json.JsonArrayBuilder;
-import javax.json.JsonObject;
-import javax.json.JsonObjectBuilder;
-import javax.json.JsonStructure;
-import javax.json.JsonValue;
-import javax.json.JsonValue.ValueType;
-import javax.json.JsonWriter;
+import jakarta.json.Json;
+import jakarta.json.JsonArray;
+import jakarta.json.JsonArrayBuilder;
+import jakarta.json.JsonObject;
+import jakarta.json.JsonObjectBuilder;
+import jakarta.json.JsonStructure;
+import jakarta.json.JsonValue;
+import jakarta.json.JsonValue.ValueType;
+import jakarta.json.JsonWriter;
 
 import org.apache.sling.feature.Artifact;
 import org.apache.sling.feature.ArtifactId;
diff --git a/src/main/java/org/apache/sling/feature/builder/package-info.java b/src/main/java/org/apache/sling/feature/builder/package-info.java
index 686594b..dc61f63 100644
--- a/src/main/java/org/apache/sling/feature/builder/package-info.java
+++ b/src/main/java/org/apache/sling/feature/builder/package-info.java
@@ -17,7 +17,7 @@
  * under the License.
  */
 
-@org.osgi.annotation.versioning.Version("1.3.0")
+@org.osgi.annotation.versioning.Version("2.0.0")
 package org.apache.sling.feature.builder;
 
 
diff --git a/src/main/java/org/apache/sling/feature/io/CloseShieldWriter.java b/src/main/java/org/apache/sling/feature/io/CloseShieldWriter.java
deleted file mode 100644
index f5add8b..0000000
--- a/src/main/java/org/apache/sling/feature/io/CloseShieldWriter.java
+++ /dev/null
@@ -1,43 +0,0 @@
-/*
- * Licensed to the Apache Software Foundation (ASF) under one or more
- * contributor license agreements. See the NOTICE file distributed with this
- * work for additional information regarding copyright ownership. The ASF
- * licenses this file to You under the Apache License, Version 2.0 (the
- * "License"); you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
- * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
- * License for the specific language governing permissions and limitations under
- * the License.
- */
-package org.apache.sling.feature.io;
-
-import java.io.FilterWriter;
-import java.io.IOException;
-import java.io.Writer;
-
-/**
- * Proxy writer that prevents the underlying writer from being closed.
- * <p>
- * This class is typically used in cases where a writer needs to be passed to a component that wants to explicitly close
- * the writer even if other components would still use the writer for output.
- * </p>
- * @deprecated
- */
-@Deprecated
-public class CloseShieldWriter extends FilterWriter {
-
-    public CloseShieldWriter(Writer out) {
-        super(out);
-    }
-
-    @Override
-    public void close() throws IOException {
-        // NOOP
-    }
-
-}
diff --git a/src/main/java/org/apache/sling/feature/io/ConfiguratorUtil.java b/src/main/java/org/apache/sling/feature/io/ConfiguratorUtil.java
deleted file mode 100644
index 2428db3..0000000
--- a/src/main/java/org/apache/sling/feature/io/ConfiguratorUtil.java
+++ /dev/null
@@ -1,80 +0,0 @@
-/*
- * Licensed to the Apache Software Foundation (ASF) under one or more
- * contributor license agreements.  See the NOTICE file distributed with
- * this work for additional information regarding copyright ownership.
- * The ASF licenses this file to You under the Apache License, Version 2.0
- * (the "License"); you may not use this file except in compliance with
- * the License.  You may obtain a copy of the License at
- *
- *      http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-package org.apache.sling.feature.io;
-
-import java.io.IOException;
-import java.io.Writer;
-import java.util.Collections;
-import java.util.Dictionary;
-
-import javax.json.Json;
-import javax.json.stream.JsonGenerator;
-import javax.json.stream.JsonGeneratorFactory;
-
-import org.apache.felix.cm.json.Configurations;
-import org.apache.sling.feature.Configuration;
-
-/**
- * Helper class to write JSON structures as defined in
- * <a href="https://osgi.org/specification/osgi.cmpn/7.0.0/service.configurator.html#d0e131765">OSGi Configurator Specification 1.0</a>.
- * @deprecated Use {@link org.apache.felix.cm.json.Configurations} instead.
- */
-@Deprecated
-public class ConfiguratorUtil {
-
-    private ConfiguratorUtil() {
-    }
-
-    protected static final JsonGenerator newGenerator(final Writer writer) {
-        JsonGeneratorFactory generatorFactory = Json.createGeneratorFactory(Collections.singletonMap(JsonGenerator.PRETTY_PRINTING, true));
-
-        // prevent closing of the underlying writer
-        Writer closeShieldWriter = new CloseShieldWriter(writer);
-        return generatorFactory.createGenerator(closeShieldWriter);
-    }
-
-    /** Write the OSGi configuration to a JSON structure.
-     * The writer is not closed.
-     *
-     * @param writer Writer
-     * @param props The configuration properties to write */
-    public static void writeConfiguration(final Writer writer, final Dictionary<String, Object> props) {
-        final Object artifactId = props.remove(Configuration.PROP_ARTIFACT_ID);
-        try {
-            Configurations.buildWriter().build(writer).writeConfiguration(props);
-        } catch (IOException e) {
-            throw new RuntimeException("Unable to write configuration.", e);
-        } finally {
-            if ( artifactId != null ) {
-                props.put(Configuration.PROP_ARTIFACT_ID, artifactId);
-            }
-        }
-    }
-
-    public static void writeConfiguration(final JsonGenerator generator, final Dictionary<String, Object> props) {
-        final Object artifactId = props.remove(Configuration.PROP_ARTIFACT_ID);
-        try {
-            Configurations.buildWriter().build(generator).writeConfiguration(props);
-        } catch (IOException e) {
-            throw new RuntimeException("Unable to write configuration.", e);
-        } finally {
-            if ( artifactId != null ) {
-                props.put(Configuration.PROP_ARTIFACT_ID, artifactId);
-            }
-        }
-    }
-}
diff --git a/src/main/java/org/apache/sling/feature/io/json/ConfigurationJSONReader.java b/src/main/java/org/apache/sling/feature/io/json/ConfigurationJSONReader.java
index ace7a36..d718b15 100644
--- a/src/main/java/org/apache/sling/feature/io/json/ConfigurationJSONReader.java
+++ b/src/main/java/org/apache/sling/feature/io/json/ConfigurationJSONReader.java
@@ -21,9 +21,9 @@
 import java.util.Hashtable;
 import java.util.Map;
 
-import org.apache.felix.cm.json.ConfigurationReader;
-import org.apache.felix.cm.json.ConfigurationReader.ConfiguratorPropertyHandler;
-import org.apache.felix.cm.json.ConfigurationResource;
+import org.apache.felix.cm.json.io.ConfigurationReader;
+import org.apache.felix.cm.json.io.ConfigurationReader.ConfiguratorPropertyHandler;
+import org.apache.felix.cm.json.io.ConfigurationResource;
 import org.apache.sling.feature.Configuration;
 import org.apache.sling.feature.Configurations;
 
@@ -54,7 +54,7 @@
     Configurations readConfigurations(final String location, final Reader reader) throws IOException {
         final Configurations result = new Configurations();
 
-        final ConfigurationReader cfgReader = org.apache.felix.cm.json.Configurations
+        final ConfigurationReader cfgReader = org.apache.felix.cm.json.io.Configurations
             .buildReader()
             .withIdentifier(location)
             .verifyAsBundleResource(true)
diff --git a/src/main/java/org/apache/sling/feature/io/json/ConfigurationJSONWriter.java b/src/main/java/org/apache/sling/feature/io/json/ConfigurationJSONWriter.java
index e189e3b..9bdd8cc 100644
--- a/src/main/java/org/apache/sling/feature/io/json/ConfigurationJSONWriter.java
+++ b/src/main/java/org/apache/sling/feature/io/json/ConfigurationJSONWriter.java
@@ -21,8 +21,8 @@
 import java.util.Collections;
 import java.util.Hashtable;
 
-import org.apache.felix.cm.json.ConfigurationResource;
-import org.apache.felix.cm.json.ConfigurationWriter;
+import org.apache.felix.cm.json.io.ConfigurationResource;
+import org.apache.felix.cm.json.io.ConfigurationWriter;
 import org.apache.sling.feature.Configuration;
 import org.apache.sling.feature.Configurations;
 
@@ -43,7 +43,7 @@
     private void writeConfigurations(final Writer writer, final Configurations configs)
             throws IOException {
 
-        final ConfigurationWriter cfgWriter = org.apache.felix.cm.json.Configurations
+        final ConfigurationWriter cfgWriter = org.apache.felix.cm.json.io.Configurations
             .buildWriter()
             .build(writer);
 
@@ -53,7 +53,7 @@
             if ( cfg.getProperties() instanceof Hashtable && cfg.getProperties().get(Configuration.PROP_ARTIFACT_ID) == null ) {
                 properties = (Hashtable<String, Object>)cfg.getProperties();
             } else {
-                properties = org.apache.felix.cm.json.Configurations.newConfiguration();
+                properties = org.apache.felix.cm.json.io.Configurations.newConfiguration();
                 for(final String name : Collections.list(cfg.getProperties().keys()) ) {
                     if ( !Configuration.PROP_ARTIFACT_ID.equals(name) ) {
                         properties.put(name, cfg.getProperties().get(name));
diff --git a/src/main/java/org/apache/sling/feature/io/json/FeatureJSONReader.java b/src/main/java/org/apache/sling/feature/io/json/FeatureJSONReader.java
index bfb8083..9627564 100644
--- a/src/main/java/org/apache/sling/feature/io/json/FeatureJSONReader.java
+++ b/src/main/java/org/apache/sling/feature/io/json/FeatureJSONReader.java
@@ -27,18 +27,18 @@
 import java.util.Set;
 import java.util.function.BiConsumer;
 
-import javax.json.Json;
-import javax.json.JsonArray;
-import javax.json.JsonException;
-import javax.json.JsonObject;
-import javax.json.JsonString;
-import javax.json.JsonStructure;
-import javax.json.JsonValue;
-import javax.json.JsonValue.ValueType;
+import jakarta.json.Json;
+import jakarta.json.JsonArray;
+import jakarta.json.JsonException;
+import jakarta.json.JsonObject;
+import jakarta.json.JsonString;
+import jakarta.json.JsonStructure;
+import jakarta.json.JsonValue;
+import jakarta.json.JsonValue.ValueType;
 
-import org.apache.felix.cm.json.ConfigurationReader;
-import org.apache.felix.cm.json.ConfigurationReader.ConfiguratorPropertyHandler;
-import org.apache.felix.cm.json.ConfigurationResource;
+import org.apache.felix.cm.json.io.ConfigurationReader;
+import org.apache.felix.cm.json.io.ConfigurationReader.ConfiguratorPropertyHandler;
+import org.apache.felix.cm.json.io.ConfigurationResource;
 import org.apache.felix.utils.resource.CapabilityImpl;
 import org.apache.felix.utils.resource.RequirementImpl;
 import org.apache.sling.feature.Artifact;
@@ -225,7 +225,7 @@
     private void addConfigurations(final JsonObject json,
             final Artifact artifact,
             final Configurations container) throws IOException {
-        final ConfigurationReader reader = org.apache.felix.cm.json.Configurations.buildReader()
+        final ConfigurationReader reader = org.apache.felix.cm.json.io.Configurations.buildReader()
                 .verifyAsBundleResource(true)
                 .withIdentifier(this.location)
                 .withConfiguratorPropertyHandler(new ConfiguratorPropertyHandler(){
@@ -410,7 +410,7 @@
             return null;
         }
         if ( value.getValueType() == ValueType.STRING || value.getValueType() == ValueType.NUMBER || value.getValueType() == ValueType.FALSE || value.getValueType() == ValueType.TRUE ) {
-            return org.apache.felix.cm.json.Configurations.convertToObject(value).toString();
+            return org.apache.felix.cm.json.io.Configurations.convertToObject(value).toString();
         }
         throw new IOException(this.exceptionPrefix.concat("Key ").concat(key).concat(" is not one of the allowed types string, number or boolean : ").concat(value.getValueType().name()));
     }
@@ -436,7 +436,7 @@
      */
     private boolean checkTypeBoolean(final String key, final JsonValue value) throws IOException {
         if ( value.getValueType() == ValueType.TRUE || value.getValueType() == ValueType.FALSE ) {
-            return (Boolean)org.apache.felix.cm.json.Configurations.convertToObject(value);
+            return (Boolean)org.apache.felix.cm.json.io.Configurations.convertToObject(value);
         }
         throw new IOException(this.exceptionPrefix.concat("Key ").concat(key).concat(" is not of type boolean : ").concat(value.getValueType().name()));
     }
@@ -546,7 +546,7 @@
                         for(final JsonValue val : checkTypeArray("Prototype removal extensions", removalObj.get(JSONConstants.PROTOTYPE_EXTENSION_REMOVALS))) {
                             checkTypeObjectOrString("Prototype removal extension", val);
                             if ( val.getValueType() == ValueType.STRING ) {
-                                final String propVal = org.apache.felix.cm.json.Configurations.convertToObject(val).toString();
+                                final String propVal = org.apache.felix.cm.json.io.Configurations.convertToObject(val).toString();
                                 if ( propVal.startsWith("#")) {
                                     continue;
                                 }
@@ -673,7 +673,7 @@
      */
     private Feature readFeature(final Reader reader)
     throws IOException {
-        final JsonObject json = Json.createReader(org.apache.felix.cm.json.Configurations.jsonCommentAwareReader(reader)).readObject();
+        final JsonObject json = Json.createReader(org.apache.felix.cm.json.io.Configurations.jsonCommentAwareReader(reader)).readObject();
 
         checkModelVersion(json);
 
@@ -752,7 +752,7 @@
                         throw new IOException("Framework property " + propEntry.getKey() + " does not exists (metadata)");
                     }
                     for(final Map.Entry<String, JsonValue> ve : checkTypeObject(JSONConstants.FRAMEWORK_PROPERTIES_METADATA.concat(".").concat(propEntry.getKey()), propEntry.getValue()).entrySet()) {
-                        metadata.put(ve.getKey(), org.apache.felix.cm.json.Configurations.convertToObject(ve.getValue()));
+                        metadata.put(ve.getKey(), org.apache.felix.cm.json.io.Configurations.convertToObject(ve.getValue()));
                     }
                 }
             } else if ( JSONConstants.VARIABLES_METADATA.equals(key) ) {
@@ -762,7 +762,7 @@
                         throw new IOException("Variable " + varEntry.getKey() + " does not exists (metadata)");
                     }
                     for(final Map.Entry<String, JsonValue> ve : checkTypeObject(JSONConstants.VARIABLES_METADATA.concat(".").concat(varEntry.getKey()), varEntry.getValue()).entrySet()) {
-                        metadata.put(ve.getKey(), org.apache.felix.cm.json.Configurations.convertToObject(ve.getValue()));
+                        metadata.put(ve.getKey(), org.apache.felix.cm.json.io.Configurations.convertToObject(ve.getValue()));
                     }
                 }
 
diff --git a/src/main/java/org/apache/sling/feature/io/json/FeatureJSONWriter.java b/src/main/java/org/apache/sling/feature/io/json/FeatureJSONWriter.java
index cab70c4..97de500 100644
--- a/src/main/java/org/apache/sling/feature/io/json/FeatureJSONWriter.java
+++ b/src/main/java/org/apache/sling/feature/io/json/FeatureJSONWriter.java
@@ -26,12 +26,12 @@
 import java.util.List;
 import java.util.Map;
 
-import javax.json.Json;
-import javax.json.stream.JsonGenerator;
-import javax.json.stream.JsonGeneratorFactory;
+import jakarta.json.Json;
+import jakarta.json.stream.JsonGenerator;
+import jakarta.json.stream.JsonGeneratorFactory;
 
-import org.apache.felix.cm.json.ConfigurationResource;
-import org.apache.felix.cm.json.ConfigurationWriter;
+import org.apache.felix.cm.json.io.ConfigurationResource;
+import org.apache.felix.cm.json.io.ConfigurationWriter;
 import org.apache.sling.feature.Artifact;
 import org.apache.sling.feature.ArtifactId;
 import org.apache.sling.feature.Bundles;
@@ -129,7 +129,7 @@
 
         generator.writeKey(JSONConstants.FEATURE_CONFIGURATIONS);
 
-        final ConfigurationWriter cfgWriter = org.apache.felix.cm.json.Configurations
+        final ConfigurationWriter cfgWriter = org.apache.felix.cm.json.io.Configurations
                 .buildWriter()
                 .build(generator);
 
@@ -139,7 +139,7 @@
             if ( cfg.getProperties() instanceof Hashtable && cfg.getProperties().get(Configuration.PROP_ARTIFACT_ID) == null ) {
                 properties = (Hashtable<String, Object>)cfg.getProperties();
             } else {
-                properties = org.apache.felix.cm.json.Configurations.newConfiguration();
+                properties = org.apache.felix.cm.json.io.Configurations.newConfiguration();
                 for(final String name : Collections.list(cfg.getProperties().keys()) ) {
                     if ( !Configuration.PROP_ARTIFACT_ID.equals(name) ) {
                         properties.put(name, cfg.getProperties().get(name));
@@ -465,7 +465,7 @@
         }
         if ( !output.isEmpty() ) {
             final Extension ext = new Extension(ExtensionType.JSON, Extension.EXTENSION_NAME_INTERNAL_DATA, ExtensionState.OPTIONAL);
-            ext.setJSONStructure(org.apache.felix.cm.json.Configurations.convertToJsonValue(output).asJsonObject());
+            ext.setJSONStructure(org.apache.felix.cm.json.io.Configurations.convertToJsonValue(output).asJsonObject());
             this.writeExtension(generator, ext, null);
         }
     }
diff --git a/src/main/java/org/apache/sling/feature/io/json/ManifestUtils.java b/src/main/java/org/apache/sling/feature/io/json/ManifestUtils.java
index dae75c8..ea79b8d 100644
--- a/src/main/java/org/apache/sling/feature/io/json/ManifestUtils.java
+++ b/src/main/java/org/apache/sling/feature/io/json/ManifestUtils.java
@@ -26,9 +26,9 @@
 import java.util.function.Function;
 import java.util.stream.Collectors;
 
-import javax.json.JsonValue;
+import jakarta.json.JsonValue;
 
-import org.apache.felix.cm.json.Configurations;
+import org.apache.felix.cm.json.io.Configurations;
 import org.apache.felix.utils.resource.CapabilityImpl;
 import org.osgi.framework.BundleException;
 import org.osgi.framework.Version;
diff --git a/src/main/java/org/apache/sling/feature/io/json/package-info.java b/src/main/java/org/apache/sling/feature/io/json/package-info.java
index 3d9728d..a7e975e 100644
--- a/src/main/java/org/apache/sling/feature/io/json/package-info.java
+++ b/src/main/java/org/apache/sling/feature/io/json/package-info.java
@@ -17,7 +17,7 @@
  * under the License.
  */
 
-@org.osgi.annotation.versioning.Version("1.2.0")
+@org.osgi.annotation.versioning.Version("2.0.0")
 package org.apache.sling.feature.io.json;
 
 
diff --git a/src/main/java/org/apache/sling/feature/io/package-info.java b/src/main/java/org/apache/sling/feature/io/package-info.java
index b1049d4..6b3f539 100644
--- a/src/main/java/org/apache/sling/feature/io/package-info.java
+++ b/src/main/java/org/apache/sling/feature/io/package-info.java
@@ -17,7 +17,7 @@
  * under the License.
  */
 
-@org.osgi.annotation.versioning.Version("1.2.0")
+@org.osgi.annotation.versioning.Version("2.0.0")
 package org.apache.sling.feature.io;
 
 
diff --git a/src/main/java/org/apache/sling/feature/osgi/Converters.java b/src/main/java/org/apache/sling/feature/osgi/Converters.java
index 4169914..e6c3d0f 100755
--- a/src/main/java/org/apache/sling/feature/osgi/Converters.java
+++ b/src/main/java/org/apache/sling/feature/osgi/Converters.java
@@ -27,7 +27,7 @@
 import java.util.Map;
 import java.util.ServiceLoader;
 
-import org.apache.felix.cm.json.Configurations;
+import org.apache.felix.cm.json.io.Configurations;
 import org.apache.sling.feature.Artifact;
 import org.apache.sling.feature.ArtifactId;
 import org.apache.sling.feature.Configuration;
diff --git a/src/main/java/org/apache/sling/feature/osgi/package-info.java b/src/main/java/org/apache/sling/feature/osgi/package-info.java
index d756741..eb9806f 100644
--- a/src/main/java/org/apache/sling/feature/osgi/package-info.java
+++ b/src/main/java/org/apache/sling/feature/osgi/package-info.java
@@ -17,7 +17,7 @@
  * under the License.
  */
 
-@org.osgi.annotation.versioning.Version("1.0.0")
+@org.osgi.annotation.versioning.Version("1.0.1")
 package org.apache.sling.feature.osgi;
 
 
diff --git a/src/main/java/org/apache/sling/feature/package-info.java b/src/main/java/org/apache/sling/feature/package-info.java
index 62be58d..7940e20 100644
--- a/src/main/java/org/apache/sling/feature/package-info.java
+++ b/src/main/java/org/apache/sling/feature/package-info.java
@@ -17,7 +17,7 @@
  * under the License.
  */
 
-@org.osgi.annotation.versioning.Version("1.9.0")
+@org.osgi.annotation.versioning.Version("2.0.0")
 package org.apache.sling.feature;
 
 
diff --git a/src/test/java/org/apache/sling/feature/builder/BuilderUtilTest.java b/src/test/java/org/apache/sling/feature/builder/BuilderUtilTest.java
index 7b3a874..50e8a5b 100644
--- a/src/test/java/org/apache/sling/feature/builder/BuilderUtilTest.java
+++ b/src/test/java/org/apache/sling/feature/builder/BuilderUtilTest.java
@@ -34,15 +34,15 @@
 import java.util.Map.Entry;
 import java.util.stream.Collectors;
 
-import javax.json.Json;
-import javax.json.JsonArray;
-import javax.json.JsonArrayBuilder;
-import javax.json.JsonObject;
-import javax.json.JsonObjectBuilder;
-import javax.json.JsonReader;
-import javax.json.JsonString;
-import javax.json.JsonValue;
-import javax.json.stream.JsonGenerator;
+import jakarta.json.Json;
+import jakarta.json.JsonArray;
+import jakarta.json.JsonArrayBuilder;
+import jakarta.json.JsonObject;
+import jakarta.json.JsonObjectBuilder;
+import jakarta.json.JsonReader;
+import jakarta.json.JsonString;
+import jakarta.json.JsonValue;
+import jakarta.json.stream.JsonGenerator;
 
 import org.apache.sling.feature.Artifact;
 import org.apache.sling.feature.ArtifactId;
diff --git a/src/test/java/org/apache/sling/feature/io/ConfiguratorUtilTest.java b/src/test/java/org/apache/sling/feature/io/ConfiguratorUtilTest.java
deleted file mode 100644
index 6f52e4c..0000000
--- a/src/test/java/org/apache/sling/feature/io/ConfiguratorUtilTest.java
+++ /dev/null
@@ -1,126 +0,0 @@
-/*
- * Licensed to the Apache Software Foundation (ASF) under one or more
- * contributor license agreements.  See the NOTICE file distributed with
- * this work for additional information regarding copyright ownership.
- * The ASF licenses this file to You under the Apache License, Version 2.0
- * (the "License"); you may not use this file except in compliance with
- * the License.  You may obtain a copy of the License at
- *
- *      http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-package org.apache.sling.feature.io;
-
-import java.io.IOException;
-import java.io.StringReader;
-import java.io.StringWriter;
-import java.util.Arrays;
-import java.util.Dictionary;
-import java.util.Hashtable;
-import java.util.Map;
-import java.util.Objects;
-
-import org.apache.felix.cm.json.Configurations;
-import org.hamcrest.Description;
-import org.hamcrest.TypeSafeDiagnosingMatcher;
-import org.hamcrest.core.Every;
-import org.junit.Assert;
-import org.junit.Test;
-import org.osgi.util.converter.Converter;
-import org.osgi.util.converter.Converters;
-import org.osgi.util.converter.TypeReference;
-
-public class ConfiguratorUtilTest {
-
-    @Test
-    public void testConfigurationWriteReadRoundtrip() throws IOException {
-        Dictionary<String, Object> props = new Hashtable<>();
-        props.put("Integer-simple", 1);
-        props.put("Integer-array", new Integer[]{1,2});
-        props.put("Integer-list", Arrays.asList(1, 2));
-        props.put("int-array", new int[]{1,2});
-        props.put("Long-simple", 1);
-        props.put("Long-array", new Long[]{1L,2L});
-        props.put("Long-list", Arrays.asList(1l, 2l));
-        props.put("long.array", new long[]{1,2});
-        props.put("Boolean-simple", Boolean.TRUE);
-        props.put("Boolean-array", new Boolean[] {Boolean.TRUE, Boolean.FALSE});
-        props.put("Boolean-list", Arrays.asList(Boolean.TRUE, Boolean.FALSE));
-        props.put("bool-array", new boolean[] {true, false});
-        props.put("Float-simple", 1.0d);
-        props.put("Float-array", new Float[]{1.0f, 2.0f});
-        props.put("Float-list", Arrays.asList(1.0f, 2.0f));
-        props.put("float.array", new float[]{1.0f,2.0f});
-        props.put("Double-simple", 1.0d);
-        props.put("Double-array", new Double[]{1.0d,2.0d});
-        props.put("Double-list", Arrays.asList(1.0d, 2.0d));
-        props.put("double.array", new double[]{1.0d,2.0d});
-        props.put("Byte-simple", (byte)1);
-        props.put("Byte-array", new Byte[]{1,2});
-        props.put("Byte-list", Arrays.asList((byte)1, (byte)2));
-        props.put("byte.array", new byte[]{1,2});
-        props.put("Short-simple", (short) 1);
-        props.put("Short-array", new Short[]{1,2});
-        props.put("Short-list", Arrays.asList((short)1, (short)2));
-        props.put("Short-array", new short[]{1,2});
-        props.put("Character-simple", 1);
-        props.put("Character-array", new Character[]{'a','b'});
-        props.put("Character-list", Arrays.asList('a', 'b'));
-        props.put("char-array", new char[]{'a','b'});
-        props.put("String-simple", "test");
-        props.put("String-array", new String[]{"test1", "test2"});
-        props.put("String-list", Arrays.asList("test1", "test2"));
-        StringWriter writer = new StringWriter();
-        ConfiguratorUtil.writeConfiguration(writer, props);
-        writer.close();
-        assertConfigurationJson(writer.toString(), props);
-    }
-
-    protected void assertConfigurationJson(String json, Dictionary<String, Object> expectedProps) throws IOException {
-        final Hashtable<String, Object> readProps = Configurations.buildReader().verifyAsBundleResource(true).build(new StringReader(json)).readConfiguration();
-        // convert to maps for easier comparison
-        Converter converter = Converters.standardConverter();
-        Map<String, Object> expectedPropsMap = converter.convert(expectedProps).to(new TypeReference<Map<String,Object>>(){});
-        Map<String, Object> actualPropsMap = converter.convert(readProps).to(new TypeReference<Map<String,Object>>(){});
-        Assert.assertThat(actualPropsMap.entrySet(), Every.everyItem(new MapEntryMatcher<>(expectedPropsMap)));
-    }
-
-    public static class MapEntryMatcher<K, V> extends TypeSafeDiagnosingMatcher<Map.Entry<K, V>> {
-
-        private final Map<K,V> expectedMap;
-
-        public MapEntryMatcher(Map<K, V> expectedMap) {
-            this.expectedMap = expectedMap;
-        }
-
-        @Override
-        public void describeTo(Description description) {
-            description.appendText("contained in the expected map");
-        }
-
-        @Override
-        protected boolean matchesSafely(Map.Entry<K, V> item, Description description) {
-            if (expectedMap.get(item.getKey()) == null){
-                description.appendText("key '" + item.getKey() + "' is not present");
-                return false;
-            } else {
-                boolean isEqual;
-                if (item.getValue().getClass().isArray()) {
-                    isEqual = Objects.deepEquals(expectedMap.get(item.getKey()), item.getValue());
-
-                } else {
-                    isEqual = expectedMap.get(item.getKey()).equals(item.getValue());
-                }
-                if (!isEqual) {
-                    description.appendText("has the wrong value for key '" + item.getKey() + "': Expected=" + expectedMap.get(item.getKey()) + " (" + expectedMap.get(item.getKey()).getClass() + ")" + ", Actual=" + item.getValue() + " (" + item.getValue().getClass() + ")");
-                }
-                return isEqual;
-            }
-        }
-    }
-}
diff --git a/src/test/java/org/apache/sling/feature/io/json/FeatureJSONWriterTest.java b/src/test/java/org/apache/sling/feature/io/json/FeatureJSONWriterTest.java
index 43b35a6..43398b5 100644
--- a/src/test/java/org/apache/sling/feature/io/json/FeatureJSONWriterTest.java
+++ b/src/test/java/org/apache/sling/feature/io/json/FeatureJSONWriterTest.java
@@ -26,11 +26,11 @@
 import java.io.StringWriter;
 import java.util.Arrays;
 
-import javax.json.Json;
-import javax.json.JsonArray;
-import javax.json.JsonObject;
-import javax.json.JsonValue;
-import javax.json.JsonValue.ValueType;
+import jakarta.json.Json;
+import jakarta.json.JsonArray;
+import jakarta.json.JsonObject;
+import jakarta.json.JsonValue;
+import jakarta.json.JsonValue.ValueType;
 
 import org.apache.sling.feature.Feature;
 import org.junit.Assert;
diff --git a/src/test/java/org/apache/sling/feature/osgi/ConvertersTest.java b/src/test/java/org/apache/sling/feature/osgi/ConvertersTest.java
index 5d538a3..156a8b3 100644
--- a/src/test/java/org/apache/sling/feature/osgi/ConvertersTest.java
+++ b/src/test/java/org/apache/sling/feature/osgi/ConvertersTest.java
@@ -28,7 +28,7 @@
 import java.util.Arrays;
 import java.util.Hashtable;
 
-import org.apache.felix.cm.json.Configurations;
+import org.apache.felix.cm.json.io.Configurations;
 import org.apache.sling.feature.Artifact;
 import org.apache.sling.feature.ArtifactId;
 import org.apache.sling.feature.Configuration;