signature test migration from jakartaee-tck repo.

Signed-off-by: gurunandan.rao@oracle.com <gurunandan.rao@oracle.com>
diff --git a/impl-tck/pom.xml b/impl-tck/pom.xml
index 8591ede..9bf1177 100644
--- a/impl-tck/pom.xml
+++ b/impl-tck/pom.xml
@@ -24,7 +24,7 @@
 
     <groupId>org.eclipse.jsonp</groupId>
     <artifactId>jakarta.json-tck</artifactId>
-    <version>1.0.0-SNAPSHOT</version>
+    <version>2.1.0-SNAPSHOT</version>
     <packaging>pom</packaging>
 
     <modules>
@@ -33,9 +33,9 @@
     </modules>
 
     <properties>
-        <jsonp-api.version>2.0.1-SNAPSHOT</jsonp-api.version>
+        <jsonp-api.version>2.1.0-SNAPSHOT</jsonp-api.version>
         <jsonp-impl.version>1.0.1-SNAPSHOT</jsonp-impl.version>
-        <jsonp-tck.version>2.0.0-SNAPSHOT</jsonp-tck.version>
+        <jsonp-tck.version>2.1.0-SNAPSHOT</jsonp-tck.version>
     </properties>
 
     <dependencies>
diff --git a/impl-tck/tck-tests-plugability/pom.xml b/impl-tck/tck-tests-plugability/pom.xml
index 698078f..cc48ed7 100644
--- a/impl-tck/tck-tests-plugability/pom.xml
+++ b/impl-tck/tck-tests-plugability/pom.xml
@@ -25,7 +25,7 @@
     <parent>
         <groupId>org.eclipse.jsonp</groupId>
         <artifactId>jakarta.json-tck</artifactId>
-        <version>1.0.0-SNAPSHOT</version>
+        <version>2.1.0-SNAPSHOT</version>
     </parent>
 
     <artifactId>jakarta.json-tck-tests-plugability</artifactId>
diff --git a/impl-tck/tck-tests/pom.xml b/impl-tck/tck-tests/pom.xml
index cc77e86..b485005 100644
--- a/impl-tck/tck-tests/pom.xml
+++ b/impl-tck/tck-tests/pom.xml
@@ -25,11 +25,15 @@
     <parent>
         <groupId>org.eclipse.jsonp</groupId>
         <artifactId>jakarta.json-tck</artifactId>
-        <version>1.0.0-SNAPSHOT</version>
+        <version>2.1.0-SNAPSHOT</version>
     </parent>
 
     <artifactId>jakarta.json-tck-tests</artifactId>
 
+    <properties>
+        <jakarta.json.version>2.1.0-SNAPSHOT</jakarta.json.version>
+    </properties>
+
     <dependencies>
         <dependency>
             <groupId>jakarta.json</groupId>
@@ -43,11 +47,87 @@
             <version>${jsonp-tck.version}</version>
             <scope>test</scope>
         </dependency>
+        <dependency>
+            <groupId>org.netbeans.tools</groupId>
+            <artifactId>sigtest-maven-plugin</artifactId>
+            <version>1.4</version>
+        </dependency>
     </dependencies>
 
     <build>
         <plugins>
             <plugin>
+                <groupId>org.apache.maven.plugins</groupId>
+                <artifactId>maven-dependency-plugin</artifactId>
+                <version>3.2.0</version>
+                <executions>
+                    <execution>
+                        <id>copy-jsonp-tck-signature-files</id>
+                        <phase>generate-test-sources</phase>
+                        <goals>
+                            <goal>unpack</goal>
+                        </goals>
+                        <configuration>
+                        <artifactItems>
+                            <artifactItem>
+                                <groupId>jakarta.json</groupId>
+                                <artifactId>jakarta.json-tck-tests</artifactId>
+                                <version>${jsonp-tck.version}</version>
+                                <type>jar</type>
+                                <overWrite>true</overWrite>
+                            </artifactItem>
+                      </artifactItems>
+                      <!-- We need the signature file, mapping file and package list file -->
+                      <includes>**/*sig-test*,**/*jakarta.json.sig_*,**/*sig-test-pkg-list.txt</includes>
+                      <outputDirectory>${project.build.directory}/signaturedirectory</outputDirectory>
+                      </configuration>
+                    </execution>
+                </executions>
+            </plugin> 
+            <plugin>
+                <groupId>org.apache.maven.plugins</groupId>
+                <artifactId>maven-dependency-plugin</artifactId>
+                <version>3.2.0</version>
+                <executions>
+                  <execution>
+                    <id>copy</id>
+                    <phase>generate-test-sources</phase>
+                    <goals>
+                        <goal>copy</goal>
+                    </goals>
+                    <configuration>
+                      <artifactItems>
+                           <artifactItem>
+                              <groupId>jakarta.json</groupId>
+                              <artifactId>jakarta.json-api</artifactId>
+                              <version>${jakarta.json.version}</version>
+                              <type>jar</type>
+                              <overWrite>true</overWrite>
+                              <outputDirectory>${project.build.directory}/signaturedirectory</outputDirectory>
+                              <destFileName>jakarta.json-api.jar</destFileName>
+                          </artifactItem>
+                      </artifactItems>
+                    </configuration>
+                  </execution>
+                </executions>
+            </plugin> 
+            <plugin>
+                <artifactId>maven-surefire-plugin</artifactId>
+                <version>3.0.0-M4</version>
+                <configuration>
+                  <trimStackTrace>false</trimStackTrace>
+                  <failIfNoTests>true</failIfNoTests>
+                    <dependenciesToScan>jakarta.json:jakarta.json-tck-tests</dependenciesToScan>
+                    <systemPropertyVariables>
+                        <jimage.dir>${project.build.directory}/jdk11-bundle</jimage.dir>
+                        <signature.mapfile>${project.build.directory}/signaturedirectory/jakarta/jsonp/tck/signaturetest/sig-test.map</signature.mapfile>
+                        <signature.repositoryDir>${project.build.directory}/signaturedirectory/jakarta/jsonp/tck/signaturetest</signature.repositoryDir>
+                        <signature.packagelist>${project.build.directory}/signaturedirectory/jakarta/jsonp/tck/signaturetest/sig-test-pkg-list.txt</signature.packagelist>
+                        <signature.sigTestClasspath>${project.build.directory}/signaturedirectory/jakarta.json-api.jar:${project.build.directory}/jdk11-bundle/java.base:${project.build.directory}/jdk11-bundle/java.rmi:${project.build.directory}/jdk11-bundle/java.sql:${project.build.directory}/jdk11-bundle/java.naming</signature.sigTestClasspath>
+                    </systemPropertyVariables>
+                  </configuration>
+            </plugin>
+            <plugin>
                 <artifactId>maven-surefire-plugin</artifactId>
                 <version>3.0.0-M4</version>
                 <configuration>
diff --git a/tck/pom.xml b/tck/pom.xml
index 87753b8..ad5e6f7 100644
--- a/tck/pom.xml
+++ b/tck/pom.xml
@@ -27,7 +27,7 @@
 
     <groupId>jakarta.json</groupId>
     <artifactId>jakarta.json-tck</artifactId>
-    <version>2.0.0-SNAPSHOT</version>
+    <version>2.1.0-SNAPSHOT</version>
     <packaging>pom</packaging>
 
     <modules>
@@ -54,8 +54,8 @@
 
     <properties>
         <project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
-        <maven.compiler.target>1.8</maven.compiler.target>
-        <maven.compiler.source>1.8</maven.compiler.source>
+        <maven.compiler.target>11</maven.compiler.target>
+        <maven.compiler.source>11</maven.compiler.source>
         <junit.jupiter.version>5.7.2</junit.jupiter.version>
         <arquillian.junit5.version>1.7.0.Alpha5</arquillian.junit5.version>
     </properties>
@@ -64,7 +64,7 @@
         <dependency>
             <groupId>jakarta.json</groupId>
             <artifactId>jakarta.json-api</artifactId>
-            <version>2.0.1-SNAPSHOT</version>
+            <version>2.1.0-SNAPSHOT</version>
             <scope>provided</scope>
         </dependency>
         <dependency>
diff --git a/tck/tck-common/pom.xml b/tck/tck-common/pom.xml
index 50d6c67..084b7fa 100644
--- a/tck/tck-common/pom.xml
+++ b/tck/tck-common/pom.xml
@@ -1,7 +1,7 @@
 <?xml version="1.0" encoding="UTF-8"?>
 <!--
 
-    Copyright (c) 2020 Oracle and/or its affiliates. All rights reserved.
+    Copyright (c) 2021 Oracle and/or its affiliates. All rights reserved.
 
     This program and the accompanying materials are made available under the
     terms of the Eclipse Public License v. 2.0, which is available at
@@ -22,7 +22,7 @@
     <parent>
         <groupId>jakarta.json</groupId>
         <artifactId>jakarta.json-tck</artifactId>
-        <version>2.0.0-SNAPSHOT</version>
+        <version>2.1.0-SNAPSHOT</version>
     </parent>
 
     <artifactId>jakarta.json-tck-common</artifactId>
diff --git a/tck/tck-tests-plugability/pom.xml b/tck/tck-tests-plugability/pom.xml
index 9ffbf88..e57e80b 100644
--- a/tck/tck-tests-plugability/pom.xml
+++ b/tck/tck-tests-plugability/pom.xml
@@ -1,7 +1,7 @@
 <?xml version="1.0" encoding="UTF-8"?>
 <!--
 
-    Copyright (c) 2020 Oracle and/or its affiliates. All rights reserved.
+    Copyright (c) 2021 Oracle and/or its affiliates. All rights reserved.
 
     This program and the accompanying materials are made available under the
     terms of the Eclipse Public License v. 2.0, which is available at
@@ -22,7 +22,7 @@
     <parent>
         <groupId>jakarta.json</groupId>
         <artifactId>jakarta.json-tck</artifactId>
-        <version>2.0.0-SNAPSHOT</version>
+        <version>2.1.0-SNAPSHOT</version>
     </parent>
 
     <artifactId>jakarta.json-tck-tests-plugability</artifactId>
@@ -32,7 +32,7 @@
         <dependency>
             <groupId>jakarta.json</groupId>
             <artifactId>jakarta.json-tck-common</artifactId>
-            <version>2.0.0-SNAPSHOT</version>
+            <version>2.1.0-SNAPSHOT</version>
             <scope>provided</scope>
         </dependency>
     </dependencies>
diff --git a/tck/tck-tests/pom.xml b/tck/tck-tests/pom.xml
index af1c6d0..494b6c6 100644
--- a/tck/tck-tests/pom.xml
+++ b/tck/tck-tests/pom.xml
@@ -22,7 +22,7 @@
     <parent>
         <groupId>jakarta.json</groupId>
         <artifactId>jakarta.json-tck</artifactId>
-        <version>2.0.0-SNAPSHOT</version>
+        <version>2.1.0-SNAPSHOT</version>
     </parent>
 
     <artifactId>jakarta.json-tck-tests</artifactId>
@@ -32,7 +32,7 @@
         <dependency>
             <groupId>jakarta.json</groupId>
             <artifactId>jakarta.json-tck-common</artifactId>
-            <version>2.0.0-SNAPSHOT</version>
+            <version>2.1.0-SNAPSHOT</version>
             <scope>provided</scope>
         </dependency>
     </dependencies>
diff --git a/tck/tck-tests/src/main/java/jakarta/jsonp/tck/api/provider/JsonProviderTest.java b/tck/tck-tests/src/main/java/jakarta/jsonp/tck/api/provider/JsonProviderTest.java
index 09cc300..573458b 100644
--- a/tck/tck-tests/src/main/java/jakarta/jsonp/tck/api/provider/JsonProviderTest.java
+++ b/tck/tck-tests/src/main/java/jakarta/jsonp/tck/api/provider/JsonProviderTest.java
@@ -43,13 +43,16 @@
  *
  */
 public class JsonProviderTest {
+
+    private static final String JSONP_PROVIDER_FACTORY = "jakarta.json.provider";
+
     
     /**
      * Verifies it is possible to obtain the JsonProvider implementation from a System property.
      */
     @Test
     public void systemProperty() {
-        System.setProperty(JsonProvider.JSONP_PROVIDER_FACTORY, DummyJsonProvider.class.getName());
+        System.setProperty(JSONP_PROVIDER_FACTORY, DummyJsonProvider.class.getName());
         JsonProvider provider = JsonProvider.provider();
         assertEquals(DummyJsonProvider.class, provider.getClass());
     }
diff --git a/tck/tck-tests/src/main/java/jakarta/jsonp/tck/signaturetest/ApiCheckDriver.java b/tck/tck-tests/src/main/java/jakarta/jsonp/tck/signaturetest/ApiCheckDriver.java
new file mode 100644
index 0000000..612e5f3
--- /dev/null
+++ b/tck/tck-tests/src/main/java/jakarta/jsonp/tck/signaturetest/ApiCheckDriver.java
@@ -0,0 +1,162 @@
+/*
+ * Copyright (c) 2021 Oracle and/or its affiliates. All rights reserved.
+ *
+ * This program and the accompanying materials are made available under the
+ * terms of the Eclipse Public License v. 2.0, which is available at
+ * http://www.eclipse.org/legal/epl-2.0.
+ *
+ * This Source Code may also be made available under the following Secondary
+ * Licenses when the conditions for such availability set forth in the
+ * Eclipse Public License v. 2.0 are satisfied: GNU General Public License,
+ * version 2 with the GNU Classpath Exception, which is available at
+ * https://www.gnu.org/software/classpath/license.html.
+ *
+ * SPDX-License-Identifier: EPL-2.0 OR GPL-2.0 WITH Classpath-exception-2.0
+ */
+
+/*
+ * $Id$
+ */
+package jakarta.jsonp.tck.signaturetest;
+
+import java.io.ByteArrayOutputStream;
+import java.io.File;
+import java.io.PrintWriter;
+import java.io.Serializable;
+import java.lang.reflect.Constructor;
+import java.lang.reflect.Method;
+import java.util.LinkedList;
+import java.util.List;
+
+
+public final class ApiCheckDriver extends SignatureTestDriver
+    implements Serializable {
+
+  /* flags for the Diff utility argument list */
+  private static final String BASE_FLAG = "-base";
+
+  private static final String TEST_FLAG = "-test";
+
+  private static final String PACKAGE_NO_SUBS_FLAG = "-PackageWithoutSubpackages";
+
+  private static final String PACKAGE_FLAG = "-package";
+
+  private static final String EXPACKAGE_FLAG = "-expackage";
+
+  private static final String REFLECT_FLAG = "-reflect";
+
+  private static final String CONST_FLAG = "-constvalues";
+
+  // ---------------------------------------- Methods from SignatureTestDriver
+
+  @Override
+  protected String normalizeFileName(File f) {
+    return f.getPath();
+  }
+
+  @Override
+  protected String[] createTestArguments(String packageListFile, String mapFile,
+      String signatureRepositoryDir, String packageOrClassUnderTest,
+      String classpath, boolean bStaticMode) throws Exception {
+
+    Class pkgListClass = Class.forName("javasoft.sqe.apiCheck.PackageList");
+    Constructor pkgCtor = pkgListClass
+        .getDeclaredConstructor(new Class[] { String.class });
+    Object pkgInstance = pkgCtor.newInstance(new Object[] { packageListFile });
+
+    Method pkgMethod = pkgListClass.getDeclaredMethod("getSubPackagesFormatted",
+        new Class[] { String.class });
+
+    String excludePkgs = (String) pkgMethod.invoke(pkgInstance,
+        new Object[] { packageOrClassUnderTest });
+
+    List sigArgsList = new LinkedList();
+
+    sigArgsList.add(BASE_FLAG);
+    sigArgsList.add(
+        getSigFileInfo(packageOrClassUnderTest, mapFile, signatureRepositoryDir)
+            .getFile());
+
+    if (classpath != null && classpath.length() > 0) {
+      sigArgsList.add(TEST_FLAG);
+      sigArgsList.add(classpath);
+    }
+
+    sigArgsList.add(REFLECT_FLAG);
+    sigArgsList.add(CONST_FLAG);
+    sigArgsList.add(PACKAGE_FLAG);
+    sigArgsList.add(packageOrClassUnderTest);
+
+    if (excludePkgs != null && excludePkgs.length() > 0) {
+      sigArgsList.add(EXPACKAGE_FLAG);
+      sigArgsList.add(excludePkgs);
+    }
+
+    return (String[]) (sigArgsList.toArray(new String[sigArgsList.size()]));
+
+  } // END createTestArguments
+
+  @Override
+  protected boolean runSignatureTest(String packageOrClassName,
+      String[] testArguments) throws Exception {
+
+    Class diffClass = Class.forName("javasoft.sqe.apiCheck.Diff");
+    Method mainMethod = diffClass.getDeclaredMethod("main",
+        new Class[] { String[].class });
+    mainMethod.invoke(null, new Object[] { testArguments });
+
+    Method diffMethod = diffClass.getDeclaredMethod("diffsFound",
+        new Class[] {});
+    return (!((Boolean) diffMethod.invoke(null, new Object[] {}))
+        .booleanValue());
+
+  } // END runSignatureTest
+
+  @Override
+  protected boolean runPackageSearch(String packageOrClassName,
+      String[] testArguments) throws Exception {
+    Class sigTestClass = Class
+        .forName("com.sun.tdk.signaturetest.SignatureTest");
+    Object sigTestInstance = sigTestClass.newInstance();
+
+    ByteArrayOutputStream output = new ByteArrayOutputStream();
+
+    // we want to replace the PACKAGE_FLAG with PACKAGE_NO_SUBS_FLAG
+    for (int ii = 0; ii < testArguments.length; ii++) {
+      if (testArguments[ii].equals(PACKAGE_FLAG)) {
+        testArguments[ii] = PACKAGE_NO_SUBS_FLAG;
+      }
+    }
+
+    // dump args for debugging aid
+    System.out.println(
+        "\nCalling:  com.sun.tdk.signaturetest.SignatureTest() with following args:");
+    for (int ii = 0; ii < testArguments.length; ii++) {
+      System.out.println("	  testArguments[" + ii + "] = " + testArguments[ii]);
+    }
+
+    @SuppressWarnings("unchecked")
+    Method runMethod = sigTestClass.getDeclaredMethod("run",
+        new Class[] { String[].class, PrintWriter.class, PrintWriter.class });
+    runMethod.invoke(sigTestInstance,
+        new Object[] { testArguments, new PrintWriter(output, true), null });
+
+    String rawMessages = output.toString();
+
+    // currently, there is no way to determine if there are error msgs in
+    // the rawmessages, so we will always dump this and call it a status.
+    System.out.println(
+        "********** Status Report '" + packageOrClassName + "' **********\n");
+    System.out.println(rawMessages);
+    return sigTestInstance.toString().substring(7).startsWith("Passed.");
+  }
+
+  @Override
+  protected boolean verifyJTAJarForNoXA(String classpath, String repositoryDir) 
+      throws Exception  {
+    // Need to find out whether implementing this method is really required now.
+    // By default, signature test framework will use sigtest
+    return true;
+  }
+
+} // END ApiCheckDriver
diff --git a/tck/tck-tests/src/main/java/jakarta/jsonp/tck/signaturetest/ApiCheckRecorder.java b/tck/tck-tests/src/main/java/jakarta/jsonp/tck/signaturetest/ApiCheckRecorder.java
new file mode 100644
index 0000000..0ebcc91
--- /dev/null
+++ b/tck/tck-tests/src/main/java/jakarta/jsonp/tck/signaturetest/ApiCheckRecorder.java
@@ -0,0 +1,79 @@
+/*
+ * Copyright (c) 2021 Oracle and/or its affiliates. All rights reserved.
+ *
+ * This program and the accompanying materials are made available under the
+ * terms of the Eclipse Public License v. 2.0, which is available at
+ * http://www.eclipse.org/legal/epl-2.0.
+ *
+ * This Source Code may also be made available under the following Secondary
+ * Licenses when the conditions for such availability set forth in the
+ * Eclipse Public License v. 2.0 are satisfied: GNU General Public License,
+ * version 2 with the GNU Classpath Exception, which is available at
+ * https://www.gnu.org/software/classpath/license.html.
+ *
+ * SPDX-License-Identifier: EPL-2.0 OR GPL-2.0 WITH Classpath-exception-2.0
+ */
+
+/*
+ * @(#)SigTestRecorder.java	1.1 03/03/05
+ */
+
+package jakarta.jsonp.tck.signaturetest;
+
+import java.lang.reflect.Method;
+import java.util.ArrayList;
+import java.util.List;
+
+/**
+ * <p>
+ * This implementation of {@link Recorder} will record signatures using the
+ * <code>ApiCheck</code> framework.
+ * </p>
+ */
+public class ApiCheckRecorder extends Recorder {
+
+  // ------------------------------------------------------------ Constructors
+
+  public ApiCheckRecorder(String[] args) {
+
+    super(args);
+    System.setProperty("pkg.list.file.path", packageListFile);
+    System.setProperty("map.file.path", signatureMapFile);
+    System.setProperty("signature.repository.dir", signatureRepositoryDir);
+
+  } // END ApiCheckRecorder
+
+  // ------------------------------------------------------- Protected Methods
+
+  protected String[] createCommandLine(String version, String classpath,
+      String outputFileName, String packageName) {
+
+    List command = new ArrayList();
+
+    command.add("-constvalues");
+    command.add("-xpriv");
+
+    command.add("-in");
+    command.add(classpath);
+
+    return ((String[]) command.toArray(new String[command.size()]));
+
+  } // END getCommandLine
+
+  protected void writePackageListFile(String basePackageName,
+      String signatureFile, String packageListFile) throws Exception {
+
+    // no-op as this is done internally by our version of ApiCheck
+
+  } // END writePackageListFile
+
+  protected void doRecord(String[] commandLine) throws Exception {
+
+    Class batchSetup = Class.forName("javasoft.sqe.apiCheck.BatchSetup");
+    Method mainMethod = batchSetup.getDeclaredMethod("main",
+        new Class[] { String[].class });
+    mainMethod.invoke(null, new Object[] { commandLine });
+
+  } // END doRecord
+
+} // END SigTestRecorder
diff --git a/tck/tck-tests/src/main/java/jakarta/jsonp/tck/signaturetest/PackageList.java b/tck/tck-tests/src/main/java/jakarta/jsonp/tck/signaturetest/PackageList.java
new file mode 100644
index 0000000..ab3240a
--- /dev/null
+++ b/tck/tck-tests/src/main/java/jakarta/jsonp/tck/signaturetest/PackageList.java
@@ -0,0 +1,430 @@
+/*
+ * Copyright (c) 2021 Oracle and/or its affiliates. All rights reserved.
+ *
+ * This program and the accompanying materials are made available under the
+ * terms of the Eclipse Public License v. 2.0, which is available at
+ * http://www.eclipse.org/legal/epl-2.0.
+ *
+ * This Source Code may also be made available under the following Secondary
+ * Licenses when the conditions for such availability set forth in the
+ * Eclipse Public License v. 2.0 are satisfied: GNU General Public License,
+ * version 2 with the GNU Classpath Exception, which is available at
+ * https://www.gnu.org/software/classpath/license.html.
+ *
+ * SPDX-License-Identifier: EPL-2.0 OR GPL-2.0 WITH Classpath-exception-2.0
+ */
+
+/*
+ * $Id$
+ */
+
+package jakarta.jsonp.tck.signaturetest;
+
+import java.io.BufferedReader;
+import java.io.BufferedWriter;
+import java.io.File;
+import java.io.FileNotFoundException;
+import java.io.FileReader;
+import java.io.FileWriter;
+import java.util.ArrayList;
+import java.util.Arrays;
+import java.util.Iterator;
+import java.util.List;
+import java.util.Set;
+import java.util.TreeSet;
+
+/**
+ * This class represents a package list file. A package list file is used in
+ * conjunction with a set of signature files to execute API signature tests.
+ * Users specify which set of package APIs are verified. Each package's
+ * signature is verified independently. As such all valid sub-packages must be
+ * excluded while a package's signature is being verified. This allows API check
+ * to determine incompatible additional packages included in a distribution.
+ * <p/>
+ * This class builds a package list file when signatures are recorded and
+ * provides an API to provide valid sub-package lists when signatures are played
+ * back (verified).
+ * <p/>
+ * In record mode, this class reads the existing package list file, if one
+ * exists, and removes the package (as well as sub-packages) that are currently
+ * being recorded. All package names read from the existing package list file
+ * are held in a tree set which sorts the package names and keeps duplicate
+ * package names from ocurring. The user can then instruct this class to write
+ * out the package list file. At this point this class reads the currently
+ * recorded signature file and extracts each package names and adds it to the
+ * tree set. After this step the previous package list file is saved as a backup
+ * and the new package list file is written to disk.
+ * <p/>
+ * In playback mode, this class reads the contents of the package list file and
+ * stores each package name in a tree set. Users can then invoke the
+ * getSubPackages method to retrieve the valid sub-packages for any given
+ * package. This is done by simply examining the package names in the tree set
+ * and returning any package name that starts with the parent package name and a
+ * trailing period character.
+ */
+class PackageList {
+
+  // Any line in the packageFile starting with this character is a comment
+  private static final char COMMENT_CHAR = '#';
+
+  private static final String BACKUP_EXT = ".bak";
+
+  // File containing the list of packages and sub-packages
+  private File packageFile;
+
+  // Signature file where the package signatures were recorded
+  private File sigFile;
+
+  // Name of the package being recorded
+  private String additionalPackageName;
+
+  // Name of packages and sub-packages in the
+  private Set packageNames = new TreeSet();
+
+  /**
+   * Creates an instance of the PackageList class. The PackageList instance
+   * reads the specified package file and populates it's internal state with the
+   * package names found in this file. Users should use this c'tor when playing
+   * back signature files. Users can init the PackageList instance then use the
+   * "String[] getSubPackages(String packageName)" method to get the list of
+   * valid sub-packages for every package who's signature is being verified.
+   *
+   * @param packageFileName
+   *          The name of the file that contains the package list. This file
+   *          contains the names of all the packages that exist across all the
+   *          signature files that makeup this deliverable. This file is used to
+   *          generate a list of valid sub-packages that must be exclued when
+   *          testing theor parent package's signature.
+   *
+   * @throws Exception
+   *           when the packageFileName does not exist.
+   */
+  public PackageList(String packageFileName) throws Exception {
+    packageFile = new File(packageFileName);
+    if (packageFile.exists() && packageFile.isFile()) {
+      extractExistingPackageNames();
+    } else {
+      throw new FileNotFoundException(packageFileName);
+    }
+  }
+
+  /**
+   * Creates an instance of the PackageList class. The PackageList instance
+   * reads the contents of the packageFileName and stores it in it's internal
+   * state. Next, any packages whos name starts with the specified packageName
+   * are removed from the internal package list. This is done because this is
+   * the package being recorded and we need to remove any previously recorded
+   * package names in case any sub-packages have been removed since the last
+   * time the signatures were recorded. Users should use this c'tor when they
+   * are recording signature files never during playback.
+   *
+   * @param packageName
+   *          The name of the package whos signatures are being recorded (along
+   *          with sub-packages).
+   * @param sigFileName
+   *          The name of the file that contains the recored signatures.
+   * @param packageFileName
+   *          The name of the file that contains the package list. This file
+   *          contains the names of all the packages that exist across all the
+   *          signature files that makeup this deliverable. This file is used to
+   *          generate a list of valid sub-packages that must be exclued when
+   *          testing their parent package's signature.
+   *
+   * @throws Exception
+   *           when an error occurs reading the packageFileName or the
+   *           sigFileName does not exist.
+   */
+  public PackageList(String packageName, String sigFileName,
+      String packageFileName) throws Exception {
+    this.additionalPackageName = packageName;
+    sigFile = new File(sigFileName);
+    if (!sigFile.exists() || !sigFile.isFile()) {
+      throw new FileNotFoundException(sigFileName);
+    }
+    packageFile = new File(packageFileName);
+    if (packageFile.exists() && packageFile.isFile()) {
+      extractExistingPackageNames();
+      removeExistingPackage();
+    }
+  }
+
+  /**
+   * Read the package names stored in the package list file. Each package name
+   * found in the package list file is added to the internal tree set.
+   *
+   * @throws Exception
+   *           if there is an error opening or reading the package list file.
+   */
+  private void extractExistingPackageNames() throws Exception {
+    BufferedReader in = new BufferedReader(new FileReader(packageFile));
+    String line;
+    String trimLine;
+    try {
+      while ((line = in.readLine()) != null) {
+        trimLine = line.trim();
+        if (isComment(trimLine) || "".equals(trimLine)) {
+          continue;
+        }
+        packageNames.add(trimLine);
+      }
+    } finally {
+      try {
+        in.close();
+      } catch (Exception e) {
+      }
+    }
+  }
+
+  /**
+   * Returns true if the specified string starts with a comment character as
+   * denoted by the COMMENT_CHAR constant.
+   *
+   * @param line
+   *          Determins of this line is a comment line
+   *
+   * @return boolean True if the specified line is a comment line else false.
+   */
+  private boolean isComment(String line) {
+    if (line == null) {
+      return false;
+    }
+    String theLine = line.trim();
+    if (theLine.length() > 0) {
+      return (theLine.charAt(0) == COMMENT_CHAR);
+    }
+
+    return false;
+  }
+
+  /**
+   * Removes package names from the package list file. The packages that are
+   * removed are the ones currently being recorded. The packages being recorded
+   * is denoted by this.additionalPackageName. This includes any sub-packages of
+   * the additionalPackageName. This step is necessary in the cases where a
+   * sub-package has been removed from a parent package in between signature
+   * recordings.
+   */
+  private void removeExistingPackage() {
+    String delPackage = this.additionalPackageName;
+    String packageName;
+    List delPkgs = new ArrayList();
+    // iterate over package set and find package names to remove
+    for (Iterator i = packageNames.iterator(); i.hasNext();) {
+      packageName = (String) i.next();
+      if (packageName.startsWith(delPackage)) {
+        delPkgs.add(packageName);
+      }
+    }
+    // actually remove the package names from the set
+    for (int i = 0; i < delPkgs.size(); i++) {
+      packageName = (String) (delPkgs.get(i));
+      packageNames.remove(packageName);
+      System.out.println(
+          "PackageList.removeExistingPackage() \"" + packageName + "\"");
+    }
+  }
+
+  /**
+   * Write the package list out to the package list file. This is done by
+   * reading all the package names in the specified signature file and adding
+   * them to the internal tree set. Then the old package list file is removed
+   * and the new package list file is written out.
+   *
+   * @throws Exception
+   *           if there is a problem removing the existing package file or
+   *           writting the new package list file.
+   */
+  public void writePkgListFile() throws Exception {
+    readPkgsFromSigFile();
+    removePkgFile();
+    writePkgFile();
+  }
+
+  /**
+   * Extract the package name from the specified string. The specified string
+   * should have the form: "package jakarta.ejb;"
+   *
+   * @param packageLine
+   *          The string containing the package name.
+   *
+   * @return String The extracted package name.
+   *
+   * @throws Exception
+   *           if the specified string does not conform to the expected format.
+   */
+  private String parsePackageName(String packageLine) throws Exception {
+
+    // sig test framework doesn't have the concept of package entries
+    // as the ApiCheck signature format does.
+    // Instead, we need to parse an entry similar to this:
+    // CLSS public jakarta.some.package.SomeClass
+
+    return packageLine.substring(packageLine.lastIndexOf(' ') + 1,
+        packageLine.lastIndexOf('.'));
+  }
+
+  /**
+   * Reads the package names from the signature file. Each package name that is
+   * read is added to this classes internal tree set.
+   *
+   * @throws Exception
+   *           if there is an error opening or reading the signature file.
+   */
+  private void readPkgsFromSigFile() throws Exception {
+    BufferedReader in = new BufferedReader(new FileReader(sigFile));
+    String line;
+    String trimLine;
+    try {
+      while ((line = in.readLine()) != null) {
+        trimLine = line.trim();
+        if (trimLine.startsWith("CLSS")) {
+          packageNames.add(parsePackageName(trimLine));
+        }
+      }
+    } finally {
+      try {
+        in.close();
+      } catch (Exception e) {
+      }
+    }
+  }
+
+  /**
+   * Removes the existing package list file. The package list file is actually
+   * moved to a backup file if it exists. The old backup is lost.
+   *
+   * @throws Exception
+   *           if there is an error moving the current package list file to a
+   *           backup file.
+   */
+  private void removePkgFile() throws Exception {
+    File backupPkgFile = new File(packageFile.getPath() + BACKUP_EXT);
+    if (backupPkgFile.exists() && backupPkgFile.isFile()) {
+      backupPkgFile.delete();
+    }
+    if (packageFile.isFile() && packageFile.exists()) {
+      File copyPackageFile = new File(packageFile.getPath());
+      copyPackageFile.renameTo(backupPkgFile);
+    }
+  }
+
+  /**
+   * Write a simple header to the package list file to explain what the file is.
+   *
+   * @param out
+   *          The BufferedWriter to dump the header to.
+   *
+   * @throws Exception
+   *           if there is any errors writing the header to the specified
+   *           BufferedWriter.
+   */
+  private void writeHeader(BufferedWriter out) throws Exception {
+    out.write(COMMENT_CHAR);
+    out.write(COMMENT_CHAR);
+    out.newLine();
+    out.write(COMMENT_CHAR + " This file contains a list of all the packages");
+    out.newLine();
+    out.write(COMMENT_CHAR + " contained in the signature files for this");
+    out.newLine();
+    out.write(
+        COMMENT_CHAR + " deliverable.  This file is used to exclude valid");
+    out.newLine();
+    out.write(COMMENT_CHAR + " sub-packages from being verified when their");
+    out.newLine();
+    out.write(COMMENT_CHAR + " parent package's signature is checked.");
+    out.newLine();
+    out.write(COMMENT_CHAR);
+    out.write(COMMENT_CHAR);
+    out.newLine();
+    out.newLine();
+  }
+
+  /**
+   * Write the list of package names out to a package list file.
+   *
+   * @throws Exception
+   *           if there is an error creating and writting the package list file.
+   */
+  private void writePkgFile() throws Exception {
+    BufferedWriter out = null;
+    try {
+      out = new BufferedWriter(new FileWriter(packageFile));
+      writeHeader(out);
+      for (Iterator i = packageNames.iterator(); i.hasNext();) {
+        String packageName = (String) i.next();
+        out.write(packageName);
+        out.newLine();
+        System.out
+            .println("PackageList.writePkgFile() \"" + packageName + "\"");
+      }
+    } finally {
+      if (out != null) {
+        out.close();
+      }
+    }
+  }
+
+  /**
+   * Returns the list of sub-packages that exist in the specified package name.
+   *
+   * @param pkgName
+   *          The name of the package we want the sub-package list for.
+   *
+   * @return String[] The sub-packages that live under the specified parent
+   *         package.
+   */
+  public String[] getSubPackages(String pkgName) {
+    List result = new ArrayList();
+    String subPackageName = pkgName + ".";
+    for (Iterator i = packageNames.iterator(); i.hasNext();) {
+      String packageName = (String) i.next();
+      if (packageName.startsWith(subPackageName)) {
+        result.add(packageName);
+      }
+    }
+    return (String[]) (result.toArray(new String[result.size()]));
+  }
+
+  /**
+   * Returns the list of sub-packages that exist in the specified package name.
+   * The returned string matches the API check format of specifying multiple
+   * packages with a single string. Each package name is separated with the "+"
+   * character.
+   *
+   * @param pkgName
+   *          The name of the package we want the sub-package list for.
+   *
+   * @return String The sub-packages that live under the specified parent
+   *         package.
+   */
+  public String getSubPackagesFormatted(String pkgName) {
+    StringBuffer formattedResult = new StringBuffer();
+    String[] result = getSubPackages(pkgName);
+    for (int i = 0; i < result.length; i++) {
+      formattedResult.append(result[i]);
+      if (i < (result.length - 1)) {
+        formattedResult.append("+");
+      }
+    }
+    return formattedResult.toString();
+  }
+
+  /*
+   * Test Driver
+   */
+  public static void main(String[] args) throws Exception {
+    System.out.println("\n\n*** Creating package list file ***\n\n");
+    PackageList list = new PackageList("jakarta.ejb",
+        "/home/ryano/cts-tools-master/tools/api-check/test/jakarta.ejb.sig_2.1",
+        "/home/ryano/cts-tools-master/tools/api-check/test/pkg-list.txt");
+    list.writePkgListFile();
+
+    System.out
+        .println("\n\n*** Reading sub-packages from package list file ***\n\n");
+    PackageList readList = new PackageList(
+        "/home/ryano/cts-tools-master/tools/api-check/test/pkg-list.txt");
+    System.out.println(Arrays.asList(readList.getSubPackages("jakarta.ejb")));
+    System.out.println(readList.getSubPackagesFormatted("jakarta.ejb"));
+  }
+
+} // end class PackageList
diff --git a/tck/tck-tests/src/main/java/jakarta/jsonp/tck/signaturetest/README b/tck/tck-tests/src/main/java/jakarta/jsonp/tck/signaturetest/README
new file mode 100644
index 0000000..1cc412c
--- /dev/null
+++ b/tck/tck-tests/src/main/java/jakarta/jsonp/tck/signaturetest/README
@@ -0,0 +1,96 @@
+The latest signature files are updated in the jsonp-api repoitory 
+(tck/tck-tests/src/main/java/jakarta/jsonp/tck/signaturetest) 
+generated using sigtest-maven-plugin.jar(version 1.4).
+
+The signature tests are run using the sigtest-maven-plugin.jar and the framework avaliable in this folder.
+
+
+
+For TCK developers  :-
+
+  1. Generate Signature Files : The signature file will be generated by the TCK team using jsonp/tck/pom.xml 
+  where the below commented code can be used. The classpath should contain the api jar for which we are generating the signature file.
+
+      <!--plugin>
+          <groupId>org.netbeans.tools</groupId>
+          <artifactId>sigtest-maven-plugin</artifactId>
+                      <version>1.4</version>
+                      <executions>
+                          <execution>
+                              <goals>
+                                  <goal>generate</goal>
+                              </goals>
+                          </execution>
+                      </executions>
+                      <configuration>
+                          <FileName>${project.build.directory}/jakarta.json.sig_${version}</FileName>
+                    <packages>jakarta.json, jakarta.json.spi, jakarta.json.stream</packages>
+                      </configuration>
+      </plugin-->
+
+      The signature file name expected is jakarta.json.sig_${version} , where version is the api version for which the signature is generated.
+
+  2. Place the required files in the TCK folder :
+
+    All the below files has to be placed in the folder tck/tck-tests/src/main/java/jakarta/jsonp/tck/signaturetest, so they are included as part of the TCK jar during the build.
+
+    -The signature file generated from above of the name jakarta.json.sig_${version}
+    -The mapping file will be named sig-test.map, it contains the api to version mapping. This file will be used to pick the right signature file when running the signature test.
+    -The package list file will be named sig-test-pkg-list.txt, contains the list of packages tested.
+
+
+
+For TCK users (to run the signature test as a Junit test) :-
+
+  1. The signature test related files will need to be extracted from the jar to a known location to be used for running the test.
+For eg: in maven we can use the below code to extract the signature file, mapping file and package list file to ${project.build.directory}/signaturedirectory.
+
+  <plugin>
+    <groupId>org.apache.maven.plugins</groupId>
+    <artifactId>maven-dependency-plugin</artifactId>
+    <version>3.2.0</version>
+    <executions>
+        <execution>
+            <id>copy-jsonp-tck-signature-files</id>
+            <phase>generate-test-sources</phase>
+            <goals>
+                <goal>unpack</goal>
+            </goals>
+            <configuration>
+            <artifactItems>
+                <artifactItem>
+                    <groupId>jakarta.json</groupId>
+                    <artifactId>jakarta.json-tck-tests</artifactId>
+                    <version>${jsonp-tck.version}</version>
+                    <type>jar</type>
+                    <overWrite>true</overWrite>
+                </artifactItem>
+          </artifactItems>
+          <!-- We need the signature file, mapping file and package list file -->
+          <includes>**/*sig-test*,**/*jakarta.json.sig_*,**/*sig-test-pkg-list.txt</includes>
+          <outputDirectory>${project.build.directory}/signaturedirectory</outputDirectory>
+          </configuration>
+        </execution>
+    </executions>
+  </plugin> 
+  2. Set the below system properties correctly :
+
+    jimage.dir //The jdk9+(jdk11 for this release) will be extracted to this location as to use the Java modules in the path.
+    optional.tech.packages.to.ignore // The optional package that should be ignored while running the signature test
+    signature.mapfile //The full path of the signature mapping file
+    signature.repositoryDir // The directory where the signature file is placed.
+    signature.packagelist //The full path of the list of packages that will be tested.
+    signature.sigTestClasspath // the sigTestClasspath that will contain the implementation jar that needs to be tested along with dependent jars.
+
+    For eg:
+
+    <jimage.dir>${project.build.directory}/jdk11-bundle</jimage.dir>
+    <optional.tech.packages.to.ignore>jakarta.xml.bind</optional.tech.packages.to.ignore>
+    <signature.mapfile>${project.build.directory}/signaturedirectory/jakarta/jsonp/tck/signaturetest/sig-test.map</signature.mapfile>
+    <signature.repositoryDir>${project.build.directory}/signaturedirectory/jakarta/jsonp/tck/signaturetest</signature.repositoryDir>
+    <signature.packagelist>${project.build.directory}/signaturedirectory/jakarta/jsonp/tck/signaturetest/sig-test-pkg-list.txt</signature.packagelist>
+    <signature.sigTestClasspath>${project.build.directory}/signaturedirectory/jakarta.json-api.jar:${project.build.directory}/jdk11-bundle/java.base:${project.build.directory}/jdk11-bundle/java.rmi:${project.build.directory}/jdk11-bundle/java.sql:${project.build.directory}/jdk11-bundle/java.naming</signature.sigTestClasspath>
+
+  3. The signature test alone can be run using below command within jersey-tck/ directory.
+
+  mvn clean verify -Dit.test=jakarta.jsonp.tck.signaturetest.**
diff --git a/tck/tck-tests/src/main/java/jakarta/jsonp/tck/signaturetest/Recorder.java b/tck/tck-tests/src/main/java/jakarta/jsonp/tck/signaturetest/Recorder.java
new file mode 100644
index 0000000..cce2559
--- /dev/null
+++ b/tck/tck-tests/src/main/java/jakarta/jsonp/tck/signaturetest/Recorder.java
@@ -0,0 +1,282 @@
+/*
+ * Copyright (c) 2021 Oracle and/or its affiliates. All rights reserved.
+ *
+ * This program and the accompanying materials are made available under the
+ * terms of the Eclipse Public License v. 2.0, which is available at
+ * http://www.eclipse.org/legal/epl-2.0.
+ *
+ * This Source Code may also be made available under the following Secondary
+ * Licenses when the conditions for such availability set forth in the
+ * Eclipse Public License v. 2.0 are satisfied: GNU General Public License,
+ * version 2 with the GNU Classpath Exception, which is available at
+ * https://www.gnu.org/software/classpath/license.html.
+ *
+ * SPDX-License-Identifier: EPL-2.0 OR GPL-2.0 WITH Classpath-exception-2.0
+ */
+
+/*
+ * $Id$
+ */
+
+package jakarta.jsonp.tck.signaturetest;
+
+import java.io.BufferedInputStream;
+import java.io.File;
+import java.io.FileInputStream;
+import java.io.FileNotFoundException;
+import java.io.IOException;
+import java.util.Arrays;
+import java.util.Iterator;
+import java.util.Properties;
+
+public abstract class Recorder {
+
+  protected Properties signatureMap;
+
+  protected String packageListFile;
+
+  protected String classpath;
+
+  protected String signatureRepositoryDir;
+
+  protected String signatureMapFile;
+
+  // ------------------------------------------------------------ Constructors
+
+  public Recorder(String[] args) {
+
+    System.out.println("\nCalling:  Recorder with following args:");
+    for (int ii = 0; ii < args.length; ii++) {
+      System.out.println("	  args[" + ii + "] = " + args[ii]);
+    }
+
+    Arguments arguments = new Arguments(args);
+    packageListFile = arguments.getPackageList();
+    classpath = arguments.getClasspath();
+    signatureRepositoryDir = arguments.getRepository();
+    signatureMapFile = arguments.getSignatureMap();
+    loadSignatureMap(signatureMapFile);
+  }
+
+  // ---------------------------------------------------------- Public Methods
+
+  /**
+   * <p>
+   * Record the signatures for each package listed in the
+   * <code>TS_HOME/bin/sig-test.map</code> file.
+   * </p>
+   */
+  public void batchRecord() {
+
+    for (Iterator i = signatureMap.keySet().iterator(); i.hasNext();) {
+      String basePackageName = (String) i.next();
+      String version = (String) signatureMap.get(basePackageName);
+      String outputFileName = getOutputFileName(basePackageName, version);
+      String[] commandLine = createCommandLine(version, classpath,
+          outputFileName, basePackageName);
+
+      try {
+
+        // dump command line args passed to Setup()...
+        System.out.println("\n\nDUMPING SIGTEST COMMAND LINE: \n");
+        for (int ii = 0; ii < commandLine.length; ii++) {
+          System.out.println("commandLine[" + ii + "] = " + commandLine[ii]);
+        }
+        System.out.println("\nDONE DUMPING SIGTEST COMMAND LINE. \n\n");
+
+        doRecord(commandLine);
+      } catch (Exception e) {
+        throw new RuntimeException(e);
+      }
+
+      try {
+        writePackageListFile(basePackageName, outputFileName, packageListFile);
+      } catch (Exception e) {
+        System.out.println("Unexpected exception: " + e);
+        e.printStackTrace();
+        System.exit(1);
+      }
+    }
+
+  } // END batchRecord
+
+  // ------------------------------------------------------- Protected Methods
+
+  /**
+   * Write, to a separate file, all of the packages that were recorded. How this
+   * is accomplised will be dependent on the framework.
+   * 
+   * @param basePackageName
+   *          the base package
+   * @param signatureFile
+   *          the file in which the signatures were recorded to
+   * @param packageListFile
+   *          the name of the package list file (which may or may not exist)
+   * @throws Exception
+   *           if an error occurs writing the file
+   */
+  protected abstract void writePackageListFile(String basePackageName,
+      String signatureFile, String packageListFile) throws Exception;
+
+  /**
+   * Create a array of arguments appropriate for use with different signature
+   * recording frameworks.
+   * 
+   * @param version
+   *          The version of the API
+   * @param classpath
+   *          the classpath containing classes that will be recorded
+   * @param outputFileName
+   *          the file in which to write the recorded signatures to
+   * @param packageName
+   *          the base package name of the signatures that will be recorded
+   */
+  protected abstract String[] createCommandLine(String version,
+      String classpath, String outputFileName, String packageName);
+
+  /**
+   * Perform whatever action in necessary to do the actual recording of the
+   * signatures.
+   * 
+   * @param commandLine
+   *          the options to invoke the recording facility
+   * @throws Exception
+   *           if an error occurs during the record process
+   */
+  protected abstract void doRecord(String[] commandLine) throws Exception;
+
+  // --------------------------------------------------------- Private Methods
+
+  private void loadSignatureMap(String signatureTestMapFile) {
+
+    signatureMap = new Properties();
+    try {
+      signatureMap.load(
+          new BufferedInputStream(new FileInputStream(signatureTestMapFile)));
+    } catch (FileNotFoundException fnfe) {
+      throw new RuntimeException(
+          "Unable to find or read file '" + signatureTestMapFile + '\'');
+    } catch (IOException ioe) {
+      throw new RuntimeException(
+          "Error processing file '" + signatureTestMapFile + '\'', ioe);
+    }
+
+  } // END loadSignatureMap
+
+  private String getOutputFileName(String name, String version) {
+
+    StringBuffer fileName = new StringBuffer();
+    fileName.append(signatureRepositoryDir).append(File.separatorChar);
+    fileName.append(name).append(".sig_").append(version);
+    return fileName.toString();
+
+  } // END getOutputFileName
+
+  // --------------------------------------------------- Static Nested Classes
+
+  private static class Arguments {
+
+    private static final String CLASSPATH_ARG = "-classpath";
+
+    private static final String PKG_LIST_ARG = "-packagelist";
+
+    private static final String SIG_MAP_ARG = "-sigmap";
+
+    private static final String REPOSITORY_ARG = "-repository";
+
+    private String classpath;
+
+    private String packageList;
+
+    private String signatureMap;
+
+    private String repository;
+
+    // -------------------------------------------------------- Constructors
+
+    Arguments(String[] args) {
+
+      // all 4 arguments must be defined, thus there should be 8 elements
+      if (args.length != 8) {
+        System.out
+            .println("Error - incorrect number of args should be 8 but was:  "
+                + args.length);
+        System.out.println("Args passed in were:  ");
+        for (int ii = 0; ii < args.length; ii++) {
+          System.out.println("args[" + ii + "] = " + args[ii]);
+        }
+
+        throw new IllegalArgumentException();
+      }
+
+      String[] clonedArgs = (String[]) args.clone();
+      Arrays.sort(clonedArgs);
+      // ensure the proper arguments are specified
+      if (Arrays.binarySearch(clonedArgs, CLASSPATH_ARG) < 0
+          || Arrays.binarySearch(clonedArgs, PKG_LIST_ARG) < 0
+          || Arrays.binarySearch(clonedArgs, SIG_MAP_ARG) < 0
+          || Arrays.binarySearch(clonedArgs, REPOSITORY_ARG) < 0) {
+        usage();
+        System.exit(1);
+      }
+
+      for (int i = 0; i < args.length; i += 2) {
+        if (CLASSPATH_ARG.equals(args[i])) {
+          classpath = args[i + 1];
+        } else if (PKG_LIST_ARG.equals(args[i])) {
+          packageList = args[i + 1];
+        } else if (SIG_MAP_ARG.equals(args[i])) {
+          signatureMap = args[i + 1];
+        } else if (REPOSITORY_ARG.equals(args[i])) {
+          repository = args[i + 1];
+        } else {
+          // shouldn't get here
+          usage();
+          System.exit(1);
+        }
+      }
+
+    } // END Arguments
+
+    // ---------------------------------------------------------- Properties
+
+    public String getClasspath() {
+
+      return classpath;
+
+    } // END getClasspath
+
+    public String getPackageList() {
+
+      return packageList;
+
+    } // END getPackageList
+
+    public String getSignatureMap() {
+
+      return signatureMap;
+
+    } // END getSignatureMap
+
+    public String getRepository() {
+
+      return repository;
+
+    } // END getRepository
+
+    private static void usage() {
+
+      String usage = "Usage:"
+          + "\t-classpath (classpath to JARs and/or classes under test)\n"
+          + "\t-packageList (Reference to the sig-test-pkg-list.txt file)\n"
+          + "\t-sigmap (Reference to the sig-test.map file)\n"
+          + "\t-repository (Directory in which to write the recorded"
+          + "\tsignatures to)\n\n";
+
+      System.err.println(usage);
+
+    } // END usage
+
+  } // END Arguments
+
+}
diff --git a/tck/tck-tests/src/main/java/jakarta/jsonp/tck/signaturetest/RecorderFactory.java b/tck/tck-tests/src/main/java/jakarta/jsonp/tck/signaturetest/RecorderFactory.java
new file mode 100644
index 0000000..68470b2
--- /dev/null
+++ b/tck/tck-tests/src/main/java/jakarta/jsonp/tck/signaturetest/RecorderFactory.java
@@ -0,0 +1,87 @@
+/*
+ * Copyright (c) 2021 Oracle and/or its affiliates. All rights reserved.
+ *
+ * This program and the accompanying materials are made available under the
+ * terms of the Eclipse Public License v. 2.0, which is available at
+ * http://www.eclipse.org/legal/epl-2.0.
+ *
+ * This Source Code may also be made available under the following Secondary
+ * Licenses when the conditions for such availability set forth in the
+ * Eclipse Public License v. 2.0 are satisfied: GNU General Public License,
+ * version 2 with the GNU Classpath Exception, which is available at
+ * https://www.gnu.org/software/classpath/license.html.
+ *
+ * SPDX-License-Identifier: EPL-2.0 OR GPL-2.0 WITH Classpath-exception-2.0
+ */
+
+/*
+ * $Id$
+ */
+
+package jakarta.jsonp.tck.signaturetest;
+
+/**
+ * <p>
+ * This class is a bit overloaded in that it serves as both a factory and entry
+ * point from Ant to handle signature recording.
+ * </p>
+ *
+ * <p>
+ * The desired <code>type</code> is provided using a system property with a key
+ * of <code>recorder.type</code>. Valid values for the
+ * <code>recorder.type</code> property are:
+ * <ul>
+ * <li>apicheck</li>
+ * <li>sigtest</li>
+ * </ul>
+ * </p>
+ * 
+ * <p>
+ * If the <code>recorder.type</code> property is not set, this factory will
+ * return a <code>SignatureTestRecorder</code> using the SigTest framework.
+ * </p>
+ */
+public class RecorderFactory {
+
+  public static final String API_CHECK_RECORDER = "apicheck";
+
+  public static final String SIG_TEST_RECORDER = "sigtest";
+
+  // ---------------------------------------------------------- Public Methods
+
+  /**
+   * Returns a {@link Recorder} instance to handle recording signatures based on
+   * the value specified via the <code>type</code> argument.
+   * 
+   * @param type
+   *          the type of {@link Recorder} to use
+   * @param args
+   *          the args to pass to the {@link Recorder}
+   * @return a {@link Recorder} instanced based on the <code>type</code>
+   *         provided
+   */
+  public static Recorder getRecorder(String type, String[] args) {
+
+    if (type == null) {
+      throw new IllegalArgumentException("'type' cannot be null");
+    }
+
+    if (type.equals(API_CHECK_RECORDER)) {
+      return new ApiCheckRecorder(args);
+    } else if (type.equals(SIG_TEST_RECORDER)) {
+      return new SigTestRecorder(args);
+    } else {
+      throw new IllegalArgumentException("Unknown type: " + type);
+    }
+
+  } // END getRecorder
+
+  public static void main(String[] args) {
+
+    String type = System.getProperty("recorder.type", SIG_TEST_RECORDER);
+    Recorder recorder = getRecorder(type, args);
+    recorder.batchRecord();
+
+  } // END main
+
+}
diff --git a/tck/tck-tests/src/main/java/jakarta/jsonp/tck/signaturetest/SigTest.java b/tck/tck-tests/src/main/java/jakarta/jsonp/tck/signaturetest/SigTest.java
new file mode 100644
index 0000000..e263aa0
--- /dev/null
+++ b/tck/tck-tests/src/main/java/jakarta/jsonp/tck/signaturetest/SigTest.java
@@ -0,0 +1,392 @@
+/*
+ * Copyright (c) 2021 Oracle and/or its affiliates and others.
+ * All rights reserved.
+ *
+ * This program and the accompanying materials are made available under the
+ * terms of the Eclipse Public License v. 2.0, which is available at
+ * http://www.eclipse.org/legal/epl-2.0.
+ *
+ * This Source Code may also be made available under the following Secondary
+ * Licenses when the conditions for such availability set forth in the
+ * Eclipse Public License v. 2.0 are satisfied: GNU General Public License,
+ * version 2 with the GNU Classpath Exception, which is available at
+ * https://www.gnu.org/software/classpath/license.html.
+ *
+ * SPDX-License-Identifier: EPL-2.0 OR GPL-2.0 WITH Classpath-exception-2.0
+ */
+
+/*
+ * $Id$
+ */
+
+package jakarta.jsonp.tck.signaturetest;
+
+import java.io.BufferedReader;
+import java.io.File;
+import java.io.InputStreamReader;
+import java.io.PrintWriter;
+import java.io.PrintStream;
+
+import java.util.ArrayList;
+import java.util.Properties;
+
+
+/**
+ * This class should be extended by TCK developers that wish to create a set of
+ * signature tests that run outside of any Java EE container. Developers must
+ * implement the getPackages method to specify which packages are to be tested
+ * by the signature test framework.
+ */
+public abstract class SigTest {
+
+  protected SignatureTestDriver driver;
+
+  /**
+   * <p>
+   * Returns a {@link SignatureTestDriver} appropriate for the particular TCK
+   * (using API check or the Signature Test Framework).
+   * </p>
+   *
+   * <p>
+   * The default implementation of this method will return a
+   * {@link SignatureTestDriver} that will use API Check. TCK developers can
+   * override this to return the desired {@link SignatureTestDriver} for their
+   * TCK.
+   */
+  protected SignatureTestDriver getSigTestDriver() {
+
+    if (driver == null) {
+      driver = SignatureTestDriverFactory.getInstance(SignatureTestDriverFactory.SIG_TEST);
+    }
+
+    return driver;
+
+  } // END getSigTestDriver
+
+  /**
+   * Returns the location of the package list file. This file denotes the valid
+   * sub-packages of any package being verified in the signature tests.
+   *
+   * Sub-classes are free to override this method if they use a different path
+   * or filename for their package list file. Most users should be able to use
+   * this default implementation.
+   *
+   * @return String The path and name of the package list file.
+   */
+  protected String getPackageFile() {
+    return getSigTestDriver().getPackageFileImpl(testInfo.getBinDir());
+  }
+
+  /**
+   * Returns the path and name of the signature map file that this TCK uses when
+   * conducting signature tests. The signature map file tells the signature test
+   * framework which API versions of tested packages to use. To keep this code
+   * platform independent, be sure to use the File.separator string (or the
+   * File.separatorChar) to denote path separators.
+   *
+   * Sub-classes are free to override this method if they use a different path
+   * or filename for their signature map file. Most users should be able to use
+   * this default implementation.
+   *
+   * @return String The path and name of the signature map file.
+   */
+  protected String getMapFile() {
+    return getSigTestDriver().getMapFileImpl(testInfo.getBinDir());
+  }
+
+  /**
+   * Returns the directory that contains the signature files.
+   *
+   * Sub-classes are free to override this method if they use a different
+   * signature repository directory. Most users should be able to use this
+   * default implementation.
+   *
+   * @return String The signature repository directory.
+   */
+  protected String getRepositoryDir() {
+    return getSigTestDriver().getRepositoryDirImpl(testInfo.getTSHome());
+  }
+
+  /**
+   * Returns the list of Optional Packages which are not accounted for. By
+   * 'unlisted optional' we mean the packages which are Optional to the
+   * technology under test that the user did NOT specifically list for testing.
+   * For example, with Java EE 7 implementation, a user could additionally opt
+   * to test a JSR-88 technology along with the Java EE technology. But if the
+   * user chooses NOT to list this optional technology for testing (via ts.jte
+   * javaee.level prop) then this method will return the packages for JSR-88
+   * technology with this method call.
+   * <p/>
+   * This is useful for checking for a scenarios when a user may have forgotten
+   * to identify a whole or partial technology implementation and in such cases,
+   * Java EE platform still requires testing it.
+   * <p/>
+   * Any partial or complete impl of an unlistedOptionalPackage sends up a red
+   * flag indicating that the user must also pass tests for this optional
+   * technology area.
+   * <p/>
+   * Sub-classes are free to override this method if they use a different
+   * signature repository directory. Most users should be able to use this
+   * default implementation - which means that there was NO optional technology
+   * packages that need to be tested.
+   *
+   * @return ArrayList<String>
+   */
+  protected ArrayList<String> getUnlistedOptionalPackages() {
+    return null;
+  }
+
+  /**
+   * Returns the list of packages that must be tested by the siganture test
+   * framework. TCK developers must implement this method in their signature
+   * test sub-class.
+   *
+   * @return String A list of packages that the developer wishes to test using
+   *         the signature test framework.
+   */
+  protected abstract String[] getPackages();
+
+  /**
+   * Returns an array of individual classes that must be tested by the signature
+   * test framwork. TCK developers may override this method when this
+   * functionality is needed. Most will only need package level granularity.
+   *
+   * @return an Array of Strings containing the individual classes the framework
+   *         should test. The default implementation of this method returns a
+   *         zero-length array.
+   */
+  protected String[] getClasses() {
+
+    return new String[] {};
+
+  } // END getClasses
+
+  protected SigTestData testInfo; // holds the bin.dir property
+
+  /**
+   * Called by the test framework to initialize this test. The method simply
+   * retrieves some state information that is necessary to run the test when
+   * when the test framework invokes the run method (actually the test1 method).
+   *
+   * @param args
+   *          List of arguments passed to this test.
+   * @param p
+   *          Properties specified by the test user and passed to this test via
+   *          the test framework.
+   * @throws Fault
+   *           When an error occurs reading or saving the state information
+   *           processed by this method.
+   */
+  public void setup() {
+    try {
+      System.out.println("$$$ SigTest.setup() called");
+      this.testInfo = new SigTestData();
+      System.out.println("$$$ SigTest.setup() complete");
+    } catch (Exception e) {
+      System.out.println("Unexpected exception " + e.getMessage());
+      //throw new Fault("setup failed!", e);
+    }
+  }
+
+
+  /**
+   * Called by the test framework to cleanup any outstanding state. This method
+   * simply passes the message through to the utility class so the
+   * implementation can be used by both framework base classes.
+   *
+   * @throws Fault
+   *           When an error occurs cleaning up the state of this test.
+   */
+  public void cleanup() throws Fault {
+    System.out.println("$$$ SigTest.cleanup() called");
+    try {
+      getSigTestDriver().cleanupImpl();
+      System.out.println("$$$ SigTest.cleanup() returning");
+    } catch (Exception e) {
+      throw new Fault("Cleanup failed!", e);
+    }
+  }
+
+  public static class Fault extends Exception {
+    private static final long serialVersionUID = -1574745208867827913L;
+
+    public Throwable t;
+
+    /**
+     * creates a Fault with a message
+     */
+    public Fault(String msg) {
+      super(msg);
+      System.out.println(msg);
+    }
+
+    /**
+     * creates a Fault with a message.
+     *
+     * @param msg
+     *          the message
+     * @param t
+     *          prints this exception's stacktrace
+     */
+    public Fault(String msg, Throwable t) {
+      super(msg);
+      this.t = t;
+      // System.out.println(msg, t);
+    }
+
+    /**
+     * creates a Fault with a Throwable.
+     *
+     * @param t
+     *          the Throwable
+     */
+    public Fault(Throwable t) {
+      super(t);
+      this.t = t;
+    }
+
+    /**
+     * Prints this Throwable and its backtrace to the standard error stream.
+     *
+     */
+    public void printStackTrace() {
+      if (this.t != null) {
+        this.t.printStackTrace();
+      } else {
+        super.printStackTrace();
+      }
+    }
+
+    /**
+     * Prints this throwable and its backtrace to the specified print stream.
+     *
+     * @param s
+     *          <code>PrintStream</code> to use for output
+     */
+    public void printStackTrace(PrintStream s) {
+      if (this.t != null) {
+        this.t.printStackTrace(s);
+      } else {
+        super.printStackTrace(s);
+      }
+    }
+
+    /**
+     * Prints this throwable and its backtrace to the specified print writer.
+     *
+     * @param s
+     *          <code>PrintWriter</code> to use for output
+     */
+    public void printStackTrace(PrintWriter s) {
+      if (this.t != null) {
+        this.t.printStackTrace(s);
+      } else {
+        super.printStackTrace(s);
+      }
+    }
+
+    @Override
+    public Throwable getCause() {
+      return t;
+    }
+
+    @Override
+    public synchronized Throwable initCause(Throwable cause) {
+      if (t != null)
+        throw new IllegalStateException("Can't overwrite cause");
+      if (!Exception.class.isInstance(cause))
+        throw new IllegalArgumentException("Cause not permitted");
+      this.t = (Exception) cause;
+      return this;
+    }
+  }
+
+  /**
+   * This exception is used only by EETest. Overrides 3 printStackTrace methods
+   * to preserver the original stack trace. Using setStackTraceElement() would
+   * be more elegant but it is not available prior to j2se 1.4.
+   *
+   * @author Kyle Grucci
+   */
+  public static class SetupException extends Exception {
+    private static final long serialVersionUID = -7616313680616499158L;
+
+    public Exception e;
+
+    /**
+     * creates a Fault with a message
+     */
+    public SetupException(String msg) {
+      super(msg);
+    }
+
+    /**
+     * creates a SetupException with a message
+     *
+     * @param msg
+     *          the message
+     * @param e
+     *          prints this exception's stacktrace
+     */
+    public SetupException(String msg, Exception e) {
+      super(msg);
+      this.e = e;
+    }
+
+    /**
+     * Prints this Throwable and its backtrace to the standard error stream.
+     *
+     */
+    public void printStackTrace() {
+      if (this.e != null) {
+        this.e.printStackTrace();
+      } else {
+        super.printStackTrace();
+      }
+    }
+
+    /**
+     * Prints this throwable and its backtrace to the specified print stream.
+     *
+     * @param s
+     *          <code>PrintStream</code> to use for output
+     */
+    public void printStackTrace(PrintStream s) {
+      if (this.e != null) {
+        this.e.printStackTrace(s);
+      } else {
+        super.printStackTrace(s);
+      }
+    }
+
+    /**
+     * Prints this throwable and its backtrace to the specified print writer.
+     *
+     * @param s
+     *          <code>PrintWriter</code> to use for output
+     */
+    public void printStackTrace(PrintWriter s) {
+      if (this.e != null) {
+        this.e.printStackTrace(s);
+      } else {
+        super.printStackTrace(s);
+      }
+    }
+
+    @Override
+    public Throwable getCause() {
+      return e;
+    }
+
+    @Override
+    public synchronized Throwable initCause(Throwable cause) {
+      if (e != null)
+        throw new IllegalStateException("Can't overwrite cause");
+      if (!Exception.class.isInstance(cause))
+        throw new IllegalArgumentException("Cause not permitted");
+      this.e = (Exception) cause;
+      return this;
+    }
+  }
+
+} // end class SigTest
diff --git a/tck/tck-tests/src/main/java/jakarta/jsonp/tck/signaturetest/SigTestData.java b/tck/tck-tests/src/main/java/jakarta/jsonp/tck/signaturetest/SigTestData.java
new file mode 100644
index 0000000..8c2d157
--- /dev/null
+++ b/tck/tck-tests/src/main/java/jakarta/jsonp/tck/signaturetest/SigTestData.java
@@ -0,0 +1,77 @@
+/*
+ * Copyright (c) 2021 Oracle and/or its affiliates. All rights reserved.
+ *
+ * This program and the accompanying materials are made available under the
+ * terms of the Eclipse Public License v. 2.0, which is available at
+ * http://www.eclipse.org/legal/epl-2.0.
+ *
+ * This Source Code may also be made available under the following Secondary
+ * Licenses when the conditions for such availability set forth in the
+ * Eclipse Public License v. 2.0 are satisfied: GNU General Public License,
+ * version 2 with the GNU Classpath Exception, which is available at
+ * https://www.gnu.org/software/classpath/license.html.
+ *
+ * SPDX-License-Identifier: EPL-2.0 OR GPL-2.0 WITH Classpath-exception-2.0
+ */
+
+/*
+ * $Id$
+ */
+
+package jakarta.jsonp.tck.signaturetest;
+
+import java.util.Properties;
+
+/**
+ * This class holds the data passed to a signature test invocation during the
+ * setup phase. This allows us to keep the passed data separate and reuse the
+ * data between the signature test framework base classes.
+ */
+public class SigTestData {
+
+  private Properties props;
+
+  public SigTestData() {
+    this.props = System.getProperties();;
+  }
+
+  public String getVehicle() {
+    return props.getProperty("vehicle", "");
+  }
+
+  public String getBinDir() {
+    return props.getProperty("bin.dir", "");
+  }
+
+  public String getTSHome() {
+    return props.getProperty("ts_home", "");
+  }
+
+  public String getTestClasspath() {
+    return props.getProperty("sigTestClasspath", "");
+  }
+
+  public String getJavaeeLevel() {
+    return props.getProperty("javaee.level", "");
+  }
+
+  public String getCurrentKeywords() {
+    return props.getProperty("current.keywords", "");
+  }
+
+  public String getProperty(String prop) {
+    return props.getProperty(prop);
+  }
+
+  public String getOptionalTechPackagesToIgnore() {
+    return props.getProperty("optional.tech.packages.to.ignore", "jakarta.xml.bind");
+  }
+
+  public String getJtaJarClasspath() {
+    return props.getProperty("jtaJarClasspath", "");
+  }
+
+  public String getJImageDir() {
+    return props.getProperty("jimage.dir", "");
+  }
+} // end class SigTestData
diff --git a/tck/tck-tests/src/main/java/jakarta/jsonp/tck/signaturetest/SigTestDriver.java b/tck/tck-tests/src/main/java/jakarta/jsonp/tck/signaturetest/SigTestDriver.java
new file mode 100644
index 0000000..db58ff0
--- /dev/null
+++ b/tck/tck-tests/src/main/java/jakarta/jsonp/tck/signaturetest/SigTestDriver.java
@@ -0,0 +1,281 @@
+/*
+ * Copyright (c) 2021 Oracle and/or its affiliates. All rights reserved.
+ *
+ * This program and the accompanying materials are made available under the
+ * terms of the Eclipse Public License v. 2.0, which is available at
+ * http://www.eclipse.org/legal/epl-2.0.
+ *
+ * This Source Code may also be made available under the following Secondary
+ * Licenses when the conditions for such availability set forth in the
+ * Eclipse Public License v. 2.0 are satisfied: GNU General Public License,
+ * version 2 with the GNU Classpath Exception, which is available at
+ * https://www.gnu.org/software/classpath/license.html.
+ *
+ * SPDX-License-Identifier: EPL-2.0 OR GPL-2.0 WITH Classpath-exception-2.0
+ */
+
+package jakarta.jsonp.tck.signaturetest;
+
+import java.io.ByteArrayOutputStream;
+import java.io.File;
+import java.io.PrintWriter;
+import java.lang.reflect.Method;
+import java.util.ArrayList;
+import java.util.List;
+
+
+/**
+ * <p>
+ * Wrapper for the <code>Sig Test</code> framework.
+ * </p>
+ */
+public class SigTestDriver extends SignatureTestDriver {
+
+  private static final String CLASSPATH_FLAG = "-Classpath";
+
+  private static final String FILENAME_FLAG = "-FileName";
+
+  private static final String PACKAGE_FLAG = "-Package";
+
+  private static final String PACKAGE_NO_SUBS_FLAG = "-PackageWithoutSubpackages";
+
+  private static final String API_VERSION_FLAG = "-ApiVersion";
+
+  private static final String EXCLUDE_FLAG = "-Exclude";
+  
+  private static final String STATIC_FLAG = "-Static";
+
+  private static final String CHECKVALUE_FLAG = "-CheckValue"; // only valid w/
+                                                               // -static
+
+  private static final String NO_CHECKVALUE_FLAG = "-NoCheckValue";
+
+  private static final String SMODE_FLAG = "-mode"; // requires arg of bin or
+                                                    // src
+
+  private static final String DEBUG_FLAG = "-Debug";
+
+  private static final String FORMATPLAIN_FLAG = "-FormatPlain";
+  
+  private static final String EXCLUDE_JDK_CLASS_FLAG = "-IgnoreJDKClass";
+
+  private static String[] excludeJdkClasses = {
+          "java.util.Map",
+          "java.lang.Object",
+          "java.io.ByteArrayInputStream",
+          "java.io.InputStream",
+          "java.lang.Deprecated",
+          "java.io.Writer",
+          "java.io.OutputStream",
+          "java.util.List",
+          "java.util.Collection",
+          "java.lang.instrument.IllegalClassFormatException",
+          "javax.transaction.xa.XAException",
+          "java.lang.annotation.Repeatable",
+          "java.lang.InterruptedException",
+          "java.lang.CloneNotSupportedException",
+          "java.lang.Throwable",
+          "java.lang.Thread",
+          "java.lang.Enum"
+  };
+          
+  // ---------------------------------------- Methods from SignatureTestDriver
+
+  @Override
+  protected String normalizeFileName(File f) {
+    String sURL = null;
+    try {
+      sURL = f.toURI().toURL().toExternalForm();
+    } catch (Exception e) {
+      throw new RuntimeException(e);
+    }
+    return sURL;
+  }
+
+  @Override
+  protected String[] createTestArguments(String packageListFile, String mapFile,
+      String signatureRepositoryDir, String packageOrClassUnderTest,
+      String classpath, boolean bStaticMode) throws Exception {
+
+    SignatureFileInfo info = getSigFileInfo(packageOrClassUnderTest, mapFile,
+        signatureRepositoryDir);
+
+    PackageList packageList = new PackageList(packageListFile);
+    String[] subPackages = packageList.getSubPackages(packageOrClassUnderTest);
+
+    List command = new ArrayList();
+
+    if (bStaticMode) {
+      // static mode allows finer level of constants checking
+      // -CheckValue says to check the actual const values
+      System.out.println("Setting static mode flag to allow constant checking.");
+      command.add(STATIC_FLAG);
+      command.add(CHECKVALUE_FLAG);
+
+      // specifying "-mode src" allows stricter 2 way verification of constant
+      // vals
+      // (note that using "-mode bin" mode is less strict)
+      command.add(SMODE_FLAG);
+      // command.add("bin");
+      command.add("src");
+    } else {
+      System.out.println("Not Setting static mode flag to allow constant checking.");
+    }
+
+    command.add("-Verbose");
+
+    command.add(FILENAME_FLAG);
+    command.add(info.getFile());
+
+    command.add(CLASSPATH_FLAG);
+    command.add(classpath);
+
+    command.add(PACKAGE_FLAG);
+    command.add(packageOrClassUnderTest);
+
+    for (int i = 0; i < subPackages.length; i++) {
+      command.add(EXCLUDE_FLAG);
+      command.add(subPackages[i]);
+    }
+
+    for(String jdkClassName:excludeJdkClasses) {
+      command.add(EXCLUDE_JDK_CLASS_FLAG);
+      command.add(jdkClassName);
+    }
+    
+            
+    command.add(API_VERSION_FLAG);
+    command.add(info.getVersion());
+
+    return ((String[]) command.toArray(new String[command.size()]));
+
+  } // END createTestArguments
+
+  @Override
+  protected boolean runSignatureTest(String packageOrClassName,
+      String[] testArguments) throws Exception {
+
+    Class sigTestClass = Class
+        .forName("com.sun.tdk.signaturetest.SignatureTest");
+    Object sigTestInstance = sigTestClass.newInstance();
+
+    ByteArrayOutputStream output = new ByteArrayOutputStream();
+
+    // do some logging to help with troubleshooting
+    System.out.println(
+        "\nCalling:  com.sun.tdk.signaturetest.SignatureTest() with following args:");
+    for (int ii = 0; ii < testArguments.length; ii++) {
+      System.out.println("   testArguments[" + ii + "] = " + testArguments[ii]);
+    }
+
+    @SuppressWarnings("unchecked")
+    Method runMethod = sigTestClass.getDeclaredMethod("run",
+        new Class[] { String[].class, PrintWriter.class, PrintWriter.class });
+    runMethod.invoke(sigTestInstance,
+        new Object[] { testArguments, new PrintWriter(output, true), null });
+
+    String rawMessages = output.toString();
+
+    // currently, there is no way to determine if there are error msgs in
+    // the rawmessages, so we will always dump this and call it a status.
+    System.out.println(
+        "********** Status Report '" + packageOrClassName + "' **********\n");
+    System.out.println(rawMessages);
+
+    return sigTestInstance.toString().substring(7).startsWith("Passed.");
+  } // END runSignatureTest
+
+  /*
+   * 
+   * @return This returns true if the packageOrClassName is found in the impl.
+   */
+  @Override
+  protected boolean runPackageSearch(String packageOrClassName,
+      String[] testArguments) throws Exception {
+
+    Class sigTestClass = Class
+        .forName("com.sun.tdk.signaturetest.SignatureTest");
+    Object sigTestInstance = sigTestClass.newInstance();
+
+    ByteArrayOutputStream output = new ByteArrayOutputStream();
+
+    // we want to replace the PACKAGE_FLAG with PACKAGE_NO_SUBS_FLAG
+    for (int ii = 0; ii < testArguments.length; ii++) {
+      if (testArguments[ii].equals(PACKAGE_FLAG)) {
+        testArguments[ii] = PACKAGE_NO_SUBS_FLAG;
+      }
+    }
+
+    // dump args for debugging aid
+    System.out.println(
+        "\nCalling:  com.sun.tdk.signaturetest.SignatureTest() with following args:");
+    for (int ii = 0; ii < testArguments.length; ii++) {
+      System.out.println("	  testArguments[" + ii + "] = " + testArguments[ii]);
+    }
+
+    @SuppressWarnings("unchecked")
+    Method runMethod = sigTestClass.getDeclaredMethod("run",
+        new Class[] { String[].class, PrintWriter.class, PrintWriter.class });
+    runMethod.invoke(sigTestInstance,
+        new Object[] { testArguments, new PrintWriter(output, true), null });
+
+    String rawMessages = output.toString();
+
+    // currently, there is no way to determine if there are error msgs in
+    // the rawmessages, so we will always dump this and call it a status.
+    System.out.println(
+        "********** Status Report '" + packageOrClassName + "' **********\n");
+    System.out.println(rawMessages);
+
+    return sigTestInstance.toString().substring(7).startsWith("Passed.");
+  }
+
+  /*
+   * @return This returns true if javax.transaction.xa is not found in the
+   * JTA API jar
+   */
+  protected boolean verifyJTAJarForNoXA(String classpath, String repositoryDir) throws Exception  {
+
+    System.out.println("SigTestDriver#verifyJTAJarForNoXA - Starting:");
+    boolean result = false;
+    List command = new ArrayList();
+
+    // Build Commandline for com.sun.tdk.signaturetest.SignatureTest
+    command.add(STATIC_FLAG);
+    command.add(FILENAME_FLAG);
+    command.add(repositoryDir  + "empty.sig");
+    command.add(PACKAGE_FLAG);
+    command.add("javax.transaction.xa");
+    command.add(CLASSPATH_FLAG);
+    command.add(classpath);
+
+    String testArguments [] = (String[]) command.toArray(new String[command.size()]);
+
+    // do some logging to help with troubleshooting
+    System.out.println("\nCalling:  com.sun.tdk.signaturetest.SignatureTest() with following args:");
+    for (int ii=0; ii < testArguments.length; ii++) {
+      System.out.println("   testArguments[" +ii+ "] = " + testArguments[ii]);
+    }
+
+    Class sigTestClass = Class.forName("com.sun.tdk.signaturetest.SignatureTest");
+    Object sigTestInstance = sigTestClass.newInstance();
+    ByteArrayOutputStream output = new ByteArrayOutputStream();
+
+    @SuppressWarnings("unchecked")
+    Method runMethod = sigTestClass.getDeclaredMethod("run",
+                                           new Class[] { String[].class,
+                                                         PrintWriter.class,
+                                                         PrintWriter.class });
+    runMethod.invoke(sigTestInstance,
+                         new Object[] { testArguments, 
+                                        new PrintWriter(output, true), 
+                                        null });
+    String rawMessages = output.toString();
+
+    // currently, there is no way to determine if there are error msgs in 
+    // the rawmessages, so we will always dump this and call it a status.
+    System.out.println("********** Status Report JTA JAR validation **********\n");
+    System.out.println(rawMessages);
+    return sigTestInstance.toString().substring(7).startsWith("Passed.");
+  }
+}
diff --git a/tck/tck-tests/src/main/java/jakarta/jsonp/tck/signaturetest/SigTestEE.java b/tck/tck-tests/src/main/java/jakarta/jsonp/tck/signaturetest/SigTestEE.java
new file mode 100644
index 0000000..aafa354
--- /dev/null
+++ b/tck/tck-tests/src/main/java/jakarta/jsonp/tck/signaturetest/SigTestEE.java
@@ -0,0 +1,486 @@
+/*
+ * Copyright (c) 2021 Oracle and/or its affiliates. All rights reserved.
+ *
+ * This program and the accompanying materials are made available under the
+ * terms of the Eclipse Public License v. 2.0, which is available at
+ * http://www.eclipse.org/legal/epl-2.0.
+ *
+ * This Source Code may also be made available under the following Secondary
+ * Licenses when the conditions for such availability set forth in the
+ * Eclipse Public License v. 2.0 are satisfied: GNU General Public License,
+ * version 2 with the GNU Classpath Exception, which is available at
+ * https://www.gnu.org/software/classpath/license.html.
+ *
+ * SPDX-License-Identifier: EPL-2.0 OR GPL-2.0 WITH Classpath-exception-2.0
+ */
+
+package jakarta.jsonp.tck.signaturetest;
+
+import java.io.BufferedReader;
+import java.io.File;
+import java.io.InputStreamReader;
+import java.io.IOException;
+import java.io.PrintWriter;
+import java.io.PrintStream;
+
+import java.util.ArrayList;
+import java.util.Properties;
+
+
+/**
+ * This class should be extended by TCK developers that wish to create a set of
+ * signature tests that run inside all the Java EE containers. Developers must
+ * implement the getPackages method to specify which packages are to be tested
+ * by the signature test framework within which container.
+ */
+public abstract class SigTestEE {
+
+  String[] sVehicles;
+
+  private Object theSharedObject;
+
+  private Object theSharedObjectArray[];
+
+
+  protected SignatureTestDriver driver;
+
+  /**
+   * <p>
+   * Returns a {@link SignatureTestDriver} appropriate for the particular TCK
+   * (using API check or the Signature Test Framework).
+   * </p>
+   *
+   * <p>
+   * The default implementation of this method will return a
+   * {@link SignatureTestDriver} that will use API Check. TCK developers can
+   * override this to return the desired {@link SignatureTestDriver} for their
+   * TCK.
+   */
+  protected SignatureTestDriver getSigTestDriver() {
+
+    if (driver == null) {
+        driver = SignatureTestDriverFactory.getInstance(SignatureTestDriverFactory.SIG_TEST);
+    }
+
+    return driver;
+
+  } // END getSigTestDriver
+
+  /**
+   * Returns the location of the package list file. This file denotes the valid
+   * sub-packages of any package being verified in the signature tests.
+   * <p/>
+   * Sub-classes are free to override this method if they use a different path
+   * or filename for their package list file. Most users should be able to use
+   * this default implementation.
+   *
+   * @return String The path and name of the package list file.
+   */
+  protected String getPackageFile() {
+    return getSigTestDriver().getPackageFileImpl(testInfo.getBinDir());
+  }
+
+  /**
+   * Returns the path and name of the signature map file that this TCK uses when
+   * conducting signature tests. The signature map file tells the signature test
+   * framework which API versions of tested packages to use. To keep this code
+   * platform independent, be sure to use the File.separator string (or the
+   * File.separatorChar) to denote path separators.
+   * <p/>
+   * Sub-classes are free to override this method if they use a different path
+   * or filename for their signature map file. Most users should be able to use
+   * this default implementation.
+   *
+   * @return String The path and name of the signature map file.
+   */
+  protected String getMapFile() {
+    return getSigTestDriver().getMapFileImpl(testInfo.getBinDir());
+  }
+
+  /**
+   * Returns the directory that contains the signature files.
+   * <p/>
+   * Sub-classes are free to override this method if they use a different
+   * signature repository directory. Most users should be able to use this
+   * default implementation.
+   *
+   * @return String The signature repository directory.
+   */
+  protected String getRepositoryDir() {
+    return getSigTestDriver().getRepositoryDirImpl(testInfo.getTSHome());
+  }
+
+  /**
+   * Returns the list of Optional Packages which are not accounted for. By
+   * 'unlisted optional' we mean the packages which are Optional to the
+   * technology under test that the user did NOT specifically list for testing.
+   * For example, with Java EE 7 implementation, a user could additionally opt
+   * to test a JSR-88 technology along with the Java EE technology. But if the
+   * user chooses NOT to list this optional technology for testing (via ts.jte
+   * javaee.level prop) then this method will return the packages for JSR-88
+   * technology with this method call.
+   * <p/>
+   * This is useful for checking for a scenarios when a user may have forgotten
+   * to identify a whole or partial technology implementation and in such cases,
+   * Java EE platform still requires testing it.
+   * <p/>
+   * Any partial or complete impl of an unlistedOptionalPackage sends up a red
+   * flag indicating that the user must also pass tests for this optional
+   * technology area.
+   * <p/>
+   * Sub-classes are free to override this method if they use a different
+   * signature repository directory. Most users should be able to use this
+   * default implementation - which means that there was NO optional technology
+   * packages that need to be tested.
+   *
+   * @return ArrayList<String>
+   */
+  protected ArrayList<String> getUnlistedOptionalPackages() {
+    return null;
+  }
+
+  /**
+   * Returns the list of packages that must be tested by the signature test
+   * framework. TCK developers must implement this method in their signature
+   * test sub-class.
+   *
+   * @param vehicleName
+   *          The name of the vehicle the signature tests should be conducted
+   *          in. Valid values for this property are ejb, servlet, ejb and
+   *          appclient.
+   *
+   * @return String[] A list of packages that the developer wishes to test using
+   *         the signature test framework. If the developer does not wish to
+   *         test any package signatures in the specified vehicle this method
+   *         should return null.
+   *         <p>
+   *         Note, The proper way to insure that this method is not called with
+   *         a vehicle name that has no package signatures to verify is to
+   *         modify the vehicle.properties in the $TS_HOME/src directory. This
+   *         file provides a mapping that maps test directories to a list of
+   *         vehicles where the tests in those directory should be run. As an
+   *         extra precaution users are encouraged to return null from this
+   *         method if the specified vehicle has no package signatures to be
+   *         verified within it.
+   */
+  protected abstract String[] getPackages(String vehicleName);
+
+  /**
+   * <p>
+   * Returns an array of individual classes that must be tested by the signature
+   * test framwork within the specified vehicle. TCK developers may override
+   * this method when this functionality is needed. Most will only need package
+   * level granularity.
+   * </p>
+   *
+   * <p>
+   * If the developer doesn't wish to test certain classes within a particular
+   * vehicle, the implementation of this method must return a zero-length array.
+   * </p>
+   *
+   * @param vehicleName
+   *          The name of the vehicle the signature tests should be conducted
+   *          in. Valid values for this property are ejb, servlet, ejb and
+   *          appclient.
+   *
+   * @return an Array of Strings containing the individual classes the framework
+   *         should test based on the specifed vehicle. The default
+   *         implementation of this method returns a zero-length array no matter
+   *         the vehicle specified.
+   */
+  protected String[] getClasses(String vehicleName) {
+
+    return new String[] {};
+
+  } // END getClasses
+
+  protected SigTestData testInfo; // holds the bin.dir and vehicle properties
+
+  /**
+   * Called by the test framework to initialize this test. The method simply
+   * retrieves some state information that is necessary to run the test when
+   * when the test framework invokes the run method (actually the test1 method).
+   *
+   * @param args
+   *          List of arguments passed to this test.
+   * @param p
+   *          Properties specified by the test user and passed to this test via
+   *          the test framework.
+   *
+   * @throws Fault
+   *           When an error occurs reading or saving the state information
+   *           processed by this method.
+   */
+  public void setup() {
+    try {
+      System.out.println("$$$ SigTestEE.setup() called");
+      this.testInfo = new SigTestData();
+      System.out.println("$$$ SigTestEE.setup() complete");
+    } catch (Exception e) {
+      System.out.println("Unexpected exception " + e.getMessage());
+    }
+  }
+
+  /**
+   * Called by the test framework to run this test. This method utilizes the
+   * state information set in the setup method to run the signature tests. All
+   * signature test code resides in the utility class so it can be reused by the
+   * signature test framework base classes.
+   *
+   * @throws Fault
+   *           When an error occurs executing the signature tests.
+   */
+  public void signatureTest() throws Fault {
+    System.out.println("$$$ SigTestEE.signatureTest() called");
+    SigTestResult results = null;
+    String mapFile = getMapFile();
+    String repositoryDir = getRepositoryDir();
+    String[] packages = getPackages(testInfo.getVehicle());
+    String[] classes = getClasses(testInfo.getVehicle());
+    String packageFile = getPackageFile();
+    String testClasspath = testInfo.getTestClasspath();
+    String optionalPkgToIgnore = testInfo.getOptionalTechPackagesToIgnore();
+
+    // unlisted optional packages are technology packages for those optional
+    // technologies (e.g. jsr-88) that might not have been specified by the
+    // user.
+    // We want to ensure there are no full or partial implementations of an
+    // optional technology which were not declared
+    ArrayList<String> unlistedTechnologyPkgs = getUnlistedOptionalPackages();
+
+    // If testing with Java 9+, extract the JDK's modules so they can be used
+    // on the testcase's classpath.
+    Properties sysProps = System.getProperties();
+    String version = (String) sysProps.get("java.version");
+    if (!version.startsWith("1.")) {
+      String jimageDir = testInfo.getJImageDir();
+      File f = new File(jimageDir);
+      f.mkdirs();
+
+      String javaHome = (String) sysProps.get("java.home");
+      System.out.println("Executing JImage");
+
+      try {
+        ProcessBuilder pb = new ProcessBuilder(javaHome + "/bin/jimage", "extract", "--dir=" + jimageDir, javaHome + "/lib/modules");
+        System.out.println(javaHome + "/bin/jimage extract --dir=" + jimageDir + " " + javaHome + "/lib/modules");
+        pb.redirectErrorStream(true);
+        Process proc = pb.start();
+        BufferedReader out = new BufferedReader(new InputStreamReader(proc.getInputStream()));
+        String line = null;
+        while ((line = out.readLine()) != null) {
+          System.out.println(line);
+        }
+
+        int rc = proc.waitFor();
+        System.out.println("JImage RC = " + rc);
+        out.close();
+      } catch (Exception e) {
+        System.out.println("Exception while executing JImage!  Some tests may fail.");
+        e.printStackTrace();
+      }
+    }
+
+    try {
+      results = getSigTestDriver().executeSigTest(packageFile, mapFile,
+          repositoryDir, packages, classes, testClasspath,
+          unlistedTechnologyPkgs, optionalPkgToIgnore);
+      System.out.println(results.toString());
+      if (!results.passed()) {
+        System.out.println("results.passed() returned false");
+        throw new Exception();
+      }
+
+      // Call verifyJtaJarTest based on some conditions, please check the
+      // comment for verifyJtaJarTest.
+      if ("standalone".equalsIgnoreCase(testInfo.getVehicle())) {
+        Properties mapFileAsProps = getSigTestDriver().loadMapFile(mapFile);
+        if (mapFileAsProps == null || mapFileAsProps.size() == 0) {
+          // empty signature file, something unusual
+          System.out.println("SigTestEE.signatureTest() returning, " +
+              "as signature map file is empty.");
+          return;
+        }
+
+        boolean isJTASigTest = false;
+
+        // Determine whether the signature map file contains package 
+        // jakarta.transaction
+        String jtaVersion = mapFileAsProps.getProperty("jakarta.transaction");
+        if (jtaVersion == null || "".equals(jtaVersion.trim())) {
+          System.out.println("SigTestEE.signatureTest() returning, " +
+              "as this is neither JTA TCK run, not Java EE CTS run.");
+          return;
+        }
+
+        System.out.println("jtaVersion " + jtaVersion);  
+        // Signature map packaged in JTA TCK will contain a single package 
+        // jakarta.transaction
+        if (mapFileAsProps.size() == 1) {
+            isJTASigTest = true;
+        }
+
+        if (isJTASigTest || !jtaVersion.startsWith("1.2")) {
+          verifyJtaJarTest();
+        }
+      }
+      System.out.println("$$$ SigTestEE.signatureTest() returning");
+    } catch (Exception e) {
+      if (results != null && !results.passed()) {
+        throw new Fault("SigTestEE.signatureTest() failed!, diffs found");
+      } else {
+        System.out.println("Unexpected exception " + e.getMessage());
+        throw new Fault("signatureTest failed with an unexpected exception", e);
+      }
+    }
+  }
+
+  /**
+   * Called by the test framework to run this test.  This method utilizes the
+   * state information set in the setup method to run.  This test validates
+   * that the javax.transaction.xa type is not in the JTA API jar
+   *
+   * This method is called only for standaone vehicle, as calling the same
+   * for all the vehicles in the CTS run is not necessary.
+   *
+   * This method is called always from JTA 1.3 TCK. The test will be run as
+   * part of Java EE Signature Test only when the signature map in the CTS
+   * bundle is using JTA 1.3 (or higher) signature file.
+   *
+   * If property ts.jte jtaJarClasspath is removed in ts.jte of the JTA 1.3 TCK,
+   * this test will display the available options to call SignatureTest and
+   * fail. Similar failure will be seen in CTS run, if the signature map points
+   * to JTA 1.3 signature file and the property jtaJarClasspath is removed from
+   * ts.jte of CTS bundle.
+   *
+   * @throws Fault When an error occurs executing the signature tests.
+   */
+  public void verifyJtaJarTest() throws Exception {
+    System.out.println("SigTestEE#verifyJtaJarTest - Starting:");
+    String repositoryDir = getRepositoryDir();
+    String jtaJarClasspath = testInfo.getJtaJarClasspath();
+    boolean result = getSigTestDriver().verifyJTAJarForNoXA(
+                testInfo.getJtaJarClasspath(), repositoryDir);
+    if(result) {
+      System.out.println("PASS: javax.transaction.xa not found in API jar");
+    } else {
+      System.out.println("FAIL: javax.transaction.xa found in API jar");
+      throw new Fault("javax.transaction.xa validation failed");
+    }
+    System.out.println("SigTestEE#verifyJtaJarTest returning");
+  }
+
+  /**
+   * Called by the test framework to cleanup any outstanding state. This method
+   * simply passes the message through to the utility class so the
+   * implementation can be used by both framework base classes.
+   *
+   * @throws Fault
+   *           When an error occurs cleaning up the state of this test.
+   */
+  public void cleanup() throws Fault {
+    System.out.println("$$$ SigTestEE.cleanup() called");
+    try {
+      getSigTestDriver().cleanupImpl();
+      System.out.println("$$$ SigTestEE.cleanup() returning");
+    } catch (Exception e) {
+      throw new Fault("Cleanup failed!", e);
+    }
+  }
+
+
+  public static class Fault extends Exception {
+    private static final long serialVersionUID = -1574745208867827913L;
+
+    public Throwable t;
+
+    /**
+     * creates a Fault with a message
+     */
+    public Fault(String msg) {
+      super(msg);
+      System.out.println(msg);
+    }
+
+    /**
+     * creates a Fault with a message.
+     *
+     * @param msg
+     *          the message
+     * @param t
+     *          prints this exception's stacktrace
+     */
+    public Fault(String msg, Throwable t) {
+      super(msg);
+      this.t = t;
+      System.out.println(msg);
+      t.printStackTrace();
+    }
+
+    /**
+     * creates a Fault with a Throwable.
+     *
+     * @param t
+     *          the Throwable
+     */
+    public Fault(Throwable t) {
+      super(t);
+      this.t = t;
+    }
+
+    /**
+     * Prints this Throwable and its backtrace to the standard error stream.
+     *
+     */
+    public void printStackTrace() {
+      if (this.t != null) {
+        this.t.printStackTrace();
+      } else {
+        super.printStackTrace();
+      }
+    }
+
+    /**
+     * Prints this throwable and its backtrace to the specified print stream.
+     *
+     * @param s
+     *          <code>PrintStream</code> to use for output
+     */
+    public void printStackTrace(PrintStream s) {
+      if (this.t != null) {
+        this.t.printStackTrace(s);
+      } else {
+        super.printStackTrace(s);
+      }
+    }
+
+    /**
+     * Prints this throwable and its backtrace to the specified print writer.
+     *
+     * @param s
+     *          <code>PrintWriter</code> to use for output
+     */
+    public void printStackTrace(PrintWriter s) {
+      if (this.t != null) {
+        this.t.printStackTrace(s);
+      } else {
+        super.printStackTrace(s);
+      }
+    }
+
+    @Override
+    public Throwable getCause() {
+      return t;
+    }
+
+    @Override
+    public synchronized Throwable initCause(Throwable cause) {
+      if (t != null)
+        throw new IllegalStateException("Can't overwrite cause");
+      if (!Exception.class.isInstance(cause))
+        throw new IllegalArgumentException("Cause not permitted");
+      this.t = (Exception) cause;
+      return this;
+    }
+  }
+
+} // end class SigTestEE
diff --git a/tck/tck-tests/src/main/java/jakarta/jsonp/tck/signaturetest/SigTestRecorder.java b/tck/tck-tests/src/main/java/jakarta/jsonp/tck/signaturetest/SigTestRecorder.java
new file mode 100644
index 0000000..81513e4
--- /dev/null
+++ b/tck/tck-tests/src/main/java/jakarta/jsonp/tck/signaturetest/SigTestRecorder.java
@@ -0,0 +1,96 @@
+/*
+ * Copyright (c) 2021 Oracle and/or its affiliates. All rights reserved.
+ *
+ * This program and the accompanying materials are made available under the
+ * terms of the Eclipse Public License v. 2.0, which is available at
+ * http://www.eclipse.org/legal/epl-2.0.
+ *
+ * This Source Code may also be made available under the following Secondary
+ * Licenses when the conditions for such availability set forth in the
+ * Eclipse Public License v. 2.0 are satisfied: GNU General Public License,
+ * version 2 with the GNU Classpath Exception, which is available at
+ * https://www.gnu.org/software/classpath/license.html.
+ *
+ * SPDX-License-Identifier: EPL-2.0 OR GPL-2.0 WITH Classpath-exception-2.0
+ */
+
+/*
+ * @(#)SigTestRecorder.java	1.1 03/03/05
+ */
+package jakarta.jsonp.tck.signaturetest;
+
+import java.io.File;
+import java.io.PrintWriter;
+import java.lang.reflect.Method;
+import java.util.ArrayList;
+import java.util.List;
+
+/**
+ * <p>
+ * This implementation of {@link Recorder} will record signatures using the
+ * <code>Signature Test</code> framework.
+ * </p>
+ */
+public class SigTestRecorder extends Recorder {
+
+  // ------------------------------------------------------------ Constructors
+
+  public SigTestRecorder(String[] args) {
+
+    super(args);
+
+  } // END SigTestRecorder
+
+  // ------------------------------------------------------- Protected Methods
+
+  protected String[] createCommandLine(String version, String classpath,
+      String outputFileName, String packageName) {
+
+    List command = new ArrayList();
+
+    // command.add("-xReflection");
+    command.add("-static");
+    command.add("-debug");
+    command.add("-verbose");
+    command.add("-classpath");
+    command.add(classpath);
+
+    command.add("-FileName");
+    try {
+      command.add(new File(outputFileName).toURI().toURL().toExternalForm());
+    } catch (Exception e) {
+      throw new RuntimeException(e);
+    }
+
+    command.add("-package");
+    command.add(packageName);
+
+    command.add("-apiVersion");
+    command.add(version);
+
+    return ((String[]) command.toArray(new String[command.size()]));
+
+  } // END getCommandLine
+
+  protected void writePackageListFile(String basePackageName,
+      String signatureFile, String packageListFile) throws Exception {
+
+    PackageList packageList = new PackageList(basePackageName, signatureFile,
+        packageListFile);
+    packageList.writePkgListFile();
+
+  } // END writePackageListFile
+
+  protected void doRecord(String[] commandLine) throws Exception {
+
+    Class batchSetup = Class.forName("com.sun.tdk.signaturetest.Setup");
+    Object batchSetupInstance = batchSetup.newInstance();
+    Method runMethod = batchSetup.getDeclaredMethod("run",
+        new Class[] { String[].class, PrintWriter.class, PrintWriter.class });
+
+    runMethod.invoke(batchSetupInstance, new Object[] { commandLine,
+        new PrintWriter(System.out, true), new PrintWriter(System.err, true) });
+
+  } // END doRecord
+
+} // END SigTestRecorder
diff --git a/tck/tck-tests/src/main/java/jakarta/jsonp/tck/signaturetest/SigTestResult.java b/tck/tck-tests/src/main/java/jakarta/jsonp/tck/signaturetest/SigTestResult.java
new file mode 100644
index 0000000..b97819f
--- /dev/null
+++ b/tck/tck-tests/src/main/java/jakarta/jsonp/tck/signaturetest/SigTestResult.java
@@ -0,0 +1,134 @@
+/*
+ * Copyright (c) 2021 Oracle and/or its affiliates. All rights reserved.
+ *
+ * This program and the accompanying materials are made available under the
+ * terms of the Eclipse Public License v. 2.0, which is available at
+ * http://www.eclipse.org/legal/epl-2.0.
+ *
+ * This Source Code may also be made available under the following Secondary
+ * Licenses when the conditions for such availability set forth in the
+ * Eclipse Public License v. 2.0 are satisfied: GNU General Public License,
+ * version 2 with the GNU Classpath Exception, which is available at
+ * https://www.gnu.org/software/classpath/license.html.
+ *
+ * SPDX-License-Identifier: EPL-2.0 OR GPL-2.0 WITH Classpath-exception-2.0
+ */
+
+/*
+ * $Id$
+ */
+package jakarta.jsonp.tck.signaturetest;
+
+import java.io.Serializable;
+import java.util.ArrayList;
+import java.util.List;
+
+public class SigTestResult implements Serializable {
+
+  private static final String NL = System.getProperty("line.separator", "\n");
+
+  private List failedPkgs = new ArrayList();
+
+  private List passedPkgs = new ArrayList();
+
+  private List failedClasses = new ArrayList();
+
+  private List passedClasses = new ArrayList();
+
+  // ---------------------------------------------------------- Public Methods
+
+  public synchronized boolean passed() {
+
+    return (failedPkgs.size() == 0 && failedClasses.size() == 0);
+
+  } // end passed
+
+  public synchronized void addFailedPkg(String pkg) {
+
+    failedPkgs.add(pkg);
+
+  } // END addFailedPkg
+
+  public synchronized void addPassedPkg(String pkg) {
+
+    passedPkgs.add(pkg);
+
+  } // END addPassedPkg
+
+  public synchronized void addFailedClass(String className) {
+
+    failedClasses.add(className);
+
+  } // END addFailedClass
+
+  public synchronized void addPassedClass(String className) {
+
+    passedClasses.add(className);
+
+  } // END addPassedClass
+
+  public String toString() {
+
+    String delim = "******************************************************"
+        + NL;
+    if (!pkgsTested() && !classesTested()) {
+      return (delim + "******** No packages or classes were tested **********"
+          + NL + delim);
+    }
+    StringBuffer buf = new StringBuffer();
+    buf.append(delim);
+    buf.append(delim);
+    if (passed()) {
+      buf.append("All package signatures passed.").append(NL);
+    } else {
+      buf.append("Some signatures failed.").append(NL);
+      if (failedPkgs.size() > 0) {
+        buf.append("\tFailed packages listed below: ").append(NL);
+        formatList(failedPkgs, buf);
+      }
+      if (failedClasses.size() > 0) {
+        buf.append("\tFailed classes listed below: ").append(NL);
+        formatList(failedClasses, buf);
+      }
+    }
+    if (passedPkgs.size() > 0) {
+      buf.append("\tPassed packages listed below: ").append(NL);
+      formatList(passedPkgs, buf);
+    }
+    if (passedClasses.size() > 0) {
+      buf.append("\tPassed classes listed below: ").append(NL);
+      formatList(passedClasses, buf);
+    }
+    buf.append("\t");
+    buf.append(delim);
+    buf.append(delim);
+    return buf.toString();
+
+  } // END toString
+
+  // --------------------------------------------------------- Private Methods
+
+  private synchronized void formatList(List list, StringBuffer buf) {
+
+    synchronized (this) {
+      for (int i = 0; i < list.size(); i++) {
+        String pkg = (String) (list.get(i));
+        buf.append("\t\t").append(pkg).append(NL);
+      }
+    }
+
+  } // END formatList
+
+  private synchronized boolean pkgsTested() {
+
+    return (failedPkgs.size() != 0 || passedPkgs.size() != 0);
+
+  } // END pkgsTested
+
+  private synchronized boolean classesTested() {
+
+    return (failedClasses.size() != 0 || passedClasses.size() != 0);
+
+  } // END classesTested
+
+} // end class SigTestResult
diff --git a/tck/tck-tests/src/main/java/jakarta/jsonp/tck/signaturetest/SignatureTestDriver.java b/tck/tck-tests/src/main/java/jakarta/jsonp/tck/signaturetest/SignatureTestDriver.java
new file mode 100644
index 0000000..1f2a8a3
--- /dev/null
+++ b/tck/tck-tests/src/main/java/jakarta/jsonp/tck/signaturetest/SignatureTestDriver.java
@@ -0,0 +1,690 @@
+/*
+ * Copyright (c) 2021 Oracle and/or its affiliates and others.
+ * All rights reserved.
+ *
+ * This program and the accompanying materials are made available under the
+ * terms of the Eclipse Public License v. 2.0, which is available at
+ * http://www.eclipse.org/legal/epl-2.0.
+ *
+ * This Source Code may also be made available under the following Secondary
+ * Licenses when the conditions for such availability set forth in the
+ * Eclipse Public License v. 2.0 are satisfied: GNU General Public License,
+ * version 2 with the GNU Classpath Exception, which is available at
+ * https://www.gnu.org/software/classpath/license.html.
+ *
+ * SPDX-License-Identifier: EPL-2.0 OR GPL-2.0 WITH Classpath-exception-2.0
+ */
+
+package jakarta.jsonp.tck.signaturetest;
+
+import java.io.File;
+import java.io.FileInputStream;
+import java.io.FileNotFoundException;
+import java.io.IOException;
+import java.util.ArrayList;
+import java.util.Enumeration;
+import java.util.Properties;
+
+
+/**
+ * Allows the sigtest framework to be extended using different signature test
+ * implementations (e.g. ApiCheck, or SigTest)
+ */
+public abstract class SignatureTestDriver {
+
+  private static final String SIG_FILE_EXT = ".sig";
+
+  private static final String SIG_FILE_VER_SEP = "_";
+
+  // ---------------------------------------------------------- Public Methods
+
+  /**
+   * Implementation of the getPackageFile method defined in both the SigTest and
+   * SigTestEE class.
+   */
+  public String getPackageFileImpl(String binDir) {
+
+    String thePkgListFile = "sig-test-pkg-list.txt";
+
+    System.out.println(
+        "Using the following as the SigTest Package file: " + thePkgListFile);
+
+    String theFile = binDir + File.separator + thePkgListFile;
+    File ff = new File(theFile);
+    if (!ff.exists()) {
+      // we could not find the map file that coresponded to our SE version so
+      // lets
+      // try to default to use the sig-test-pkg-list.txt
+      System.out.println("The SigTest Package file does not exist: " + thePkgListFile);
+      theFile = binDir + File.separator + "sig-test-pkg-list.txt";
+      File ff2 = new File(theFile);
+      if (!ff2.exists()) {
+        System.out.println("The Default SigTest Package file does not exist either: "
+                + theFile);
+      } else {
+        System.out.println("Defaulting to using SigTest Package file: " + theFile);
+      }
+    }
+
+    return (theFile);
+
+  } // END getPackageFileImpl
+
+  /**
+   * Implementation of the getMapFile method defined in both the SigTest and
+   * SigTestEE class.
+   */
+  public String getMapFileImpl(String binDir) {
+
+    String  theMapFile = "sig-test.map";
+
+    System.out.println("Using the following as the sig-Test map file: " + theMapFile);
+
+    String theFile = binDir + File.separator + theMapFile;
+    File ff = new File(theFile);
+    if (!ff.exists()) {
+      // we could not find the map file that coresponded to our SE version so
+      // lets
+      // try to default to use the sig-test.map
+      System.out.println("The SigTest Map file does not exist: " + theMapFile);
+      theFile = binDir + File.separator + "sig-test.map";
+      File ff2 = new File(theFile);
+      if (!ff2.exists()) {
+        System.out.println("The SigTest Map file does not exist either: " + theFile);
+      } else {
+        System.out.println("Defaulting to using SigTest Map file: " + theFile);
+      }
+    }
+
+    return (theFile);
+
+  } // END getMapFileImpl
+
+  /**
+   * Returns true if the passed in version matches the current Java version
+   * being used.
+   * 
+   */
+  public Boolean isJavaSEVersion(String ver) {
+
+    String strOSVersion = System.getProperty("java.version");
+    if (strOSVersion.startsWith(ver)) {
+      return true;
+    } else {
+      return false;
+    }
+  }
+
+  /**
+   * Implementation of the getRepositoryDir method defined in both the SigTest
+   * and SigTestEE class.
+   */
+  public String getRepositoryDirImpl(String tsHome) {
+
+    return (tsHome + File.separator + "src" + File.separator + "com"
+        + File.separator + "sun" + File.separator + "ts" + File.separator
+        + "tests" + File.separator + "signaturetest" + File.separator
+        + "signature-repository" + File.separator);
+
+  } // END getRepositoryDirImpl
+
+  /**
+   * Implementation of the cleanup method defined in both the SigTest and
+   * SigTestEE class.
+   */
+  public void cleanupImpl() throws Exception {
+
+    try {
+      System.out.println("cleanup");
+    } catch (Exception e) {
+      System.out.println("Exception in cleanup method" + e);
+      throw e;
+    }
+
+  } // END cleanupImpl
+
+  /**
+   * <p>
+   * Execute the signature test. By default, this method passes the result of
+   * {@link #createTestArguments(String, String, String, String, String)} and
+   * passes the result to {@link #runSignatureTest(String, String[])}.
+   *
+   * @param packageListFile
+   *          - file containing the packages/classes that are to be verified
+   * @param mapFile
+   *          sig-test.map file
+   * @param signatureRepositoryDir
+   *          directory containing the recorded signatures
+   * @param packagesUnderTest
+   *          packages, defined by the test client, that should be tested
+   * @param classesUnderTest
+   *          classes, defined by the test client, that should be tested
+   * @param classpath
+   *          The location of the API being verified. Normally the checked API
+   *          will be available in the test environment and testClasspath will
+   *          be null. In some rare cases the tested API may not be part of the
+   *          test environment and will have to specified using this parameter.
+   * @param unaccountedTechPkgs
+   *          packages that should not exist within the technology under test.
+   *          These will be searched for and if found, will be flagged as error
+   *          since they were not explicitly declared as being under test. Their
+   *          existence requires explicit testing.
+   *
+   * @return a {@link SigTestResult} containing the result of the test execution
+   */
+  public SigTestResult executeSigTest(String packageListFile, String mapFile,
+      String signatureRepositoryDir, String[] packagesUnderTest,
+      String[] classesUnderTest, String classpath,
+      ArrayList<String> unaccountedTechPkgs, String optionalPkgToIgnore)
+      throws Exception {
+
+    SigTestResult result = new SigTestResult();
+
+    System.out.println("optionalPkgToIgnore = " + optionalPkgToIgnore);
+    String[] arrayOptionalPkgsToIgnore = null;
+    if (optionalPkgToIgnore != null) {
+      arrayOptionalPkgsToIgnore = optionalPkgToIgnore.split(",");
+    }
+
+    if (packagesUnderTest != null && packagesUnderTest.length > 0) {
+      System.out.println("********** BEGIN PACKAGE LEVEL SIGNATURE "
+          + "VALIDATION **********\n\n");
+      for (int i = 0; i < packagesUnderTest.length; i++) {
+
+        String packageName = packagesUnderTest[i];
+
+        System.out.println("********** BEGIN VALIDATE PACKAGE '"
+            + packagesUnderTest[i] + "' **********\n");
+
+        System.out.println(
+            "********** VALIDATE IN STATIC MODE - TO CHECK CONSANT VALUES ****");
+        System.out.println("Static mode supports checks of static constants values ");
+
+        String[] args = createTestArguments(packageListFile, mapFile,
+            signatureRepositoryDir, packageName, classpath, true);
+        dumpTestArguments(args);
+
+        if (runSignatureTest(packageName, args)) {
+          System.out.println("********** Package '" + packageName
+              + "' - PASSED (STATIC MODE) **********");
+          result.addPassedPkg(packageName + "(static mode)");
+        } else {
+          result.addFailedPkg(packageName + "(static mode)");
+          System.out.println("********** Package '" + packageName
+              + "' - FAILED (STATIC MODE) **********");
+        }
+
+        System.out.println("\n\n");
+        System.out.println("********** VALIDATE IN REFLECTIVE MODE  ****");
+        System.out.println(
+            "Reflective mode supports verification within containers (ie ejb, servlet, etc)");
+
+        String[] args2 = createTestArguments(packageListFile, mapFile,
+            signatureRepositoryDir, packageName, classpath, false);
+        dumpTestArguments(args2);
+
+        if (runSignatureTest(packageName, args2)) {
+          System.out.println("********** Package '" + packageName
+              + "' - PASSED (REFLECTION MODE) **********");
+          result.addPassedPkg(packageName + "(reflection mode)");
+        } else {
+          result.addFailedPkg(packageName + "(reflection mode)");
+          System.out.println("********** Package '" + packageName
+              + "' - FAILED (REFLECTION MODE) **********");
+        }
+
+        System.out.println("********** END VALIDATE PACKAGE '"
+            + packagesUnderTest[i] + "' **********\n");
+
+        System.out.println("\n");
+        System.out.println("\n");
+
+      }
+    }
+
+    if (classesUnderTest != null && classesUnderTest.length > 0) {
+      System.out.println("********** BEGIN CLASS LEVEL SIGNATURE "
+          + "VALIDATION **********\n\n");
+
+      for (int i = 0; i < classesUnderTest.length; i++) {
+
+        String className = classesUnderTest[i];
+
+        System.out.println("********** BEGIN VALIDATE CLASS '"
+            + classesUnderTest[i] + "' **********\n");
+
+        System.out.println(
+            "********** VALIDATE IN STATIC MODE - TO CHECK CONSANT VALUES ****");
+        System.out.println("Static mode supports checks of static constants values ");
+
+        String[] args = createTestArguments(packageListFile, mapFile,
+            signatureRepositoryDir, className, classpath, true);
+        dumpTestArguments(args);
+
+        if (runSignatureTest(className, args)) {
+          System.out.println("********** Class '" + className
+              + "' - PASSED (STATIC MODE) **********");
+          result.addPassedClass(className + "(static mode)");
+        } else {
+          System.out.println("********** Class '" + className
+              + "' - FAILED (STATIC MODE) **********");
+          result.addFailedClass(className + "(static mode)");
+        }
+
+        System.out.println("\n\n");
+        System.out.println("********** VALIDATE IN REFLECTIVE MODE  ****");
+        System.out.println(
+            "Reflective mode supports verification within containers (ie ejb, servlet, etc)");
+
+        String[] args2 = createTestArguments(packageListFile, mapFile,
+            signatureRepositoryDir, className, classpath, false);
+        dumpTestArguments(args2);
+
+        if (runSignatureTest(className, args2)) {
+          System.out.println("********** Class '" + className
+              + "' - PASSED (REFLECTION MODE) **********");
+          result.addPassedClass(className + "(reflection mode)");
+        } else {
+          System.out.println("********** Class '" + className
+              + "' - FAILED (REFLECTION MODE) **********");
+          result.addFailedClass(className + "(reflection mode)");
+        }
+
+        System.out.println("********** END VALIDATE CLASS '" + classesUnderTest[i]
+            + "' **********\n");
+
+        System.out.println("\n");
+        System.out.println("\n");
+
+      }
+    }
+
+    /*
+     * The following will check if there are Optional Technologies being
+     * implemented but not explicitly defined thru (ts.jte) javaee.level
+     * property. This is a problem because if an optional technolgy is defined
+     * (either whole or partially) than the TCK tests (and sig tests) for those
+     * Optional Technology(s) MUST be run according to related specs.
+     */
+    if (unaccountedTechPkgs != null) {
+      for (int ii = 0; ii < unaccountedTechPkgs.size(); ii++) {
+        // 'unaccountedTechPkgs' are t hose packages which do not beling to
+        // base technology nor one of the *declared* optionalal technologies.
+        // 'unaccountedTechPkgs' refers to packages for Optional Technologies
+        // which were not defined thru (ts.jte) javaee.level property.
+        // So, make sure there are no whole or partial implementations of
+        // undeclared optional technologies in the implementation
+
+        String packageName = unaccountedTechPkgs.get(ii);
+
+        // this is a special case exception to our validation of Optional
+        // Technologies. Normally any partial technology implementations
+        // would be a compatibility failure. HOWEVER, EE 7 Spec (see section
+        // EE 6.1.2 of the Platform spec in the footnote on p. 156.)
+        // requires us to add special handling to avoid testing 'certain' pkgs
+        // within an optional technology.
+        if (isIgnorePackageUnderTest(packageName, arrayOptionalPkgsToIgnore)) {
+          System.out.println(
+              "Ignoring special optional technology package: " + packageName);
+          continue;
+        }
+
+        System.out.println("\n\n");
+        System.out.println(
+            "********** CHECK IF OPTIONAL TECHNOLOGIES EXIST IN REFLECTIVE MODE  ****");
+        System.out.println(
+            "Reflective mode supports verification within containers (ie ejb, servlet, etc)");
+
+        String[] args3 = createTestArguments(packageListFile, mapFile,
+            signatureRepositoryDir, packageName, classpath, false);
+        dumpTestArguments(args3);
+
+        // - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
+        // - - - -
+        // NOTE: this is the opposite of above in that *if* we find that an
+        // undeclared
+        // optional technology package exists - then we want to raise a red
+        // flag.
+        // The user would have to either remove the technology from the impl if
+        // they do not want to include it in their impl -OR- they must
+        // explicitly
+        // set javaee.level (in ts.jte) to include that Optional Technology AND
+        // after setting this property, they have to pass all related TCK tests.
+        if (runPackageSearch(packageName, args3)) {
+          // if this passed we have an issue because it should not exist - thus
+          // should NOT pass.
+          System.out.println("********** Package '" + packageName
+              + "' - WAS FOUND BUT SHOULD NOT BE (REFLECTION MODE) **********");
+          String err = "ERROR:  An area of concern has been identified.  ";
+          err += "You must run sigtests with (ts.jte) javaee.level set to ";
+          err += "include all optional technology keywords.  Whole and/or ";
+          err += "partial implementations of Optional Technologies ";
+          err += "must be implemented according to the specs AND must pass ";
+          err += "all related TCK tests.  To properly pass the ";
+          err += "signature tests - you must identify all Optional Technology ";
+          err += "areas (via javaee.level) that you wish to pass signature tests for.";
+          System.out.println(err);
+          result.addFailedPkg(packageName
+              + " (Undeclared Optional Technology package found in reflection mode)");
+        } else {
+          System.out.println("********** Undeclared Optional Technology package '"
+              + packageName + "' - PASSED (REFLECTION MODE) **********");
+        }
+      }
+    }
+
+    return result;
+
+  } // END executeSigTest
+
+  // ------------------------------------------------------- Protected Methods
+
+  /**
+   * Using a common set of information, create arguments that are appropriate to
+   * be used with the underlying signature test framework.
+   *
+   * @param packageListFile
+   *          - file containing the packages/classes that are to be verified
+   * @param mapFile
+   *          sig-test.map file
+   * @param signatureRepositoryDir
+   *          directory containing the recorded signatures
+   * @param packageOrClassUnderTest
+   *          the class or package
+   * @param classpath
+   *          The location of the API being verified. Normally the checked API
+   *          will be available in the test environment and testClasspath will
+   *          be null. In some rare cases the tested API may not be part of the
+   *          test environment and will have to specified using this parameter.
+   */
+  protected abstract String[] createTestArguments(String packageListFile,
+      String mapFile, String signatureRepositoryDir,
+      String packageOrClassUnderTest, String classpath, boolean bStaticMode)
+      throws Exception;
+
+  /**
+   * Invoke the underlying signature test framework for the specified package or
+   * class.
+   *
+   * @param packageOrClassName
+   *          the package or class to be validated
+   * @param testArguments
+   *          the arguments necessary to invoke the signature test framework
+   *
+   * @return <code>true</code> if the test passed, otherwise <code>false</code>
+   */
+  protected abstract boolean runSignatureTest(String packageOrClassName,
+      String[] testArguments) throws Exception;
+
+  /**
+   * This checks if a class exists or not within the impl.
+   *
+   * @param packageOrClassName
+   *          the package or class to be validated
+   *
+   * @return <code>true</code> if the package was found to exist, otherwise
+   *         <code>false</code>
+   */
+  protected abstract boolean runPackageSearch(String packageOrClassName,
+      String[] testArguments) throws Exception;
+
+
+  /**
+   * This method checks whether JTA API jar contains classes from
+   * javax.transaction.xa package
+   *
+   * @param classpath
+   *           the classpath, pointing JTA API jar
+   * @param repositoryDir
+   *           the directory containing an empty signature file
+   *
+   * @return <code>true</code> if the package javax.transaction.xa is not
+   *        found in the JTA API jar, otherwise <code>false</code>
+   */
+   protected  abstract boolean verifyJTAJarForNoXA(String classpath,
+            String repositoryDir) throws Exception;
+
+  /**
+   * Loads the specified file into a Properties object provided the specified
+   * file exists and is a regular file. The call to new FileInputStream verifies
+   * that the specfied file is a regular file and exists.
+   *
+   * @param mapFile
+   *          the path and name of the map file to be loaded
+   *
+   * @return Properties The Properties object initialized with the contents of
+   *         the specified file
+   *
+   * @throws java.io.IOException
+   *           If the specified map file does not exist or is not a regular
+   *           file, can also be thrown if there is an error creating an input
+   *           stream from the specified file.
+   */
+  public Properties loadMapFile(String mapFile)
+      throws IOException, FileNotFoundException {
+
+    FileInputStream in = null;
+    try {
+      File map = new File(mapFile);
+      Properties props = new Properties();
+      in = new FileInputStream(map);
+      props.load(in);
+      return props;
+    } finally {
+      try {
+        if (in != null) {
+          in.close();
+        }
+      } catch (Throwable t) {
+        // do nothing
+      }
+    }
+
+  } // END loadMapFile
+
+  /**
+   * This method will attempt to build a fully-qualified filename in the format
+   * of <code>respositoryDir</code> + </code>baseName</code> +
+   * <code>.sig_</code> + </code>version</code>.
+   *
+   * @param baseName
+   *          the base portion of the signature filename
+   * @param repositoryDir
+   *          the directory in which the signatures are stored
+   * @param version
+   *          the version of the signature file
+   * @throws FileNotFoundException
+   *           if the file cannot be validated as existing and is in fact a file
+   * @return a valid, fully qualified filename, appropriate for the system the
+   *         test is being run on
+   */
+  protected String getSigFileName(String baseName, String repositoryDir,
+      String version) throws FileNotFoundException {
+
+    String sigFile;
+    if (repositoryDir.endsWith(File.separator)) {
+      sigFile = repositoryDir + baseName + SIG_FILE_EXT + SIG_FILE_VER_SEP
+          + version;
+    } else {
+      sigFile = repositoryDir + File.separator + baseName + SIG_FILE_EXT
+          + SIG_FILE_VER_SEP + version;
+    }
+
+    File testFile = new File(sigFile);
+
+    if (!testFile.exists() && !testFile.isFile()) {
+      throw new FileNotFoundException(
+          "Signature file \"" + sigFile + "\" does not exist.");
+    }
+
+    // we are actually requiring this normalizeFileName call to get
+    // things working on Windows. Without this, if we just return the
+    // testFile; we will fail on windows. (Solaris works either way)
+    // IMPORTANT UPDATE!! (4/5/2011)
+    // in sigtest 2.2: they stopped supporting the normalized version which
+    // created a string filename =
+    // "file://com/sun/ts/tests/signaturetest/foo.sig"
+    // so now use file path and name only.
+    // return normalizeFileName(testFile);
+    return testFile.toString();
+
+  } // END getSigFileName
+
+  protected abstract String normalizeFileName(File f);
+
+  /**
+   * Returns the name and path to the signature file that contains the specified
+   * package's signatures.
+   *
+   * @param packageName
+   *          The package under test
+   * @param mapFile
+   *          The name of the file that maps package names to versions
+   * @param repositoryDir
+   *          The directory that conatisn all signature files
+   *
+   * @return String The path and name of the siganture file that contains the
+   *         specified package's signatures
+   *
+   * @throws Exception
+   *           if the determined signature file is not a regular file or does
+   *           not exist
+   */
+  protected SignatureFileInfo getSigFileInfo(String packageName, String mapFile,
+      String repositoryDir) throws Exception {
+
+    String originalPackage = packageName;
+    String name = null;
+    String version = null;
+    Properties props = loadMapFile(mapFile);
+
+    while (true) {
+      boolean packageFound = false;
+      for (Enumeration<?> e = props.propertyNames(); e.hasMoreElements();) {
+        name = (String) (e.nextElement());
+        if (name.equals(packageName)) {
+          version = props.getProperty(name);
+          packageFound = true;
+          break;
+        } // end if
+      } // end for
+
+      if (packageFound) {
+        break;
+      }
+
+      /*
+       * If we get here we did not find a package name in the properties file
+       * that matches the package name under test. So we look for a package name
+       * in the properties file that could be the parent package for the package
+       * under test. We do this by removing the specified packages last package
+       * name section. So jakarta.ejb.spi would become jakarta.ejb
+       */
+      int index = packageName.lastIndexOf(".");
+      if (index <= 0) {
+        throw new Exception("Package \"" + originalPackage
+            + "\" not specified in mapping file \"" + mapFile + "\".");
+      }
+      packageName = packageName.substring(0, index);
+    } // end while
+
+    /* Return the expected name of the signature file */
+
+    return new SignatureFileInfo(getSigFileName(name, repositoryDir, version),
+        version);
+
+  } // END getSigFileInfo
+
+  // --------------------------------------------------------- Private Methods
+
+  /*
+   * This returns true is the passed in packageName matches one of the packages
+   * that are listed in the arrayOptionalPkgsToIgnore. arrayOptionalPkgsToIgnore
+   * is ultimately defined in the ts.jte property
+   * 'optional.tech.packages.to.ignore' If one of the entries in
+   * arrayOptionalPkgsToIgnore matches the packageName then that means we return
+   * TRUE to indicate we should ignore and NOT TEST that particular package.
+   */
+  private static boolean isIgnorePackageUnderTest(String packageName,
+      String[] arrayOptionalPkgsToIgnore) {
+
+    // if anything is null - consider no match
+    if ((packageName == null) || (arrayOptionalPkgsToIgnore == null)) {
+      return false;
+    }
+
+    for (int ii = 0; ii < arrayOptionalPkgsToIgnore.length; ii++) {
+      if (packageName.equals(arrayOptionalPkgsToIgnore[ii])) {
+        // we found a match -
+        return true;
+      }
+    }
+
+    return false;
+  }
+
+  /**
+   * Prints the specified list of parameters to the message log. Used for
+   * debugging purposes only.
+   *
+   * @param params
+   *          The list of parameters to dump.
+   */
+  private static void dumpTestArguments(String[] params) {
+
+    if (params != null && params.length > 0) {
+      System.out.println("----------------- BEGIN SIG PARAM DUMP -----------------");
+      for (int i = 0; i < params.length; i++) {
+        System.out.println("   Param[" + i + "]: " + params[i]);
+      }
+      System.out.println("------------------ END SIG PARAM DUMP ------------------");
+    }
+
+  } // END dumpTestArguments
+
+  // ----------------------------------------------------------- Inner Classes
+
+  /**
+   * A simple data structure containing the fully qualified path to the
+   * signature file as well as the version being tested.
+   */
+  protected static class SignatureFileInfo {
+
+    private String file;
+
+    private String version;
+
+    // -------------------------------------------------------- Constructors
+
+    public SignatureFileInfo(String file, String version) {
+
+      if (file == null) {
+        throw new IllegalArgumentException("'file' argument cannot be null");
+      }
+
+      if (version == null) {
+        throw new IllegalArgumentException("'version' argument cannot be null");
+      }
+
+      this.file = file;
+      this.version = version;
+
+    } // END SignatureFileInfo
+
+    // ------------------------------------------------------ Public Methods
+
+    public String getFile() {
+
+      return file;
+
+    } // END getFileIncludingPath
+
+    public String getVersion() {
+
+      return version;
+
+    } // END getVersion
+
+  }
+
+} // END SigTestDriver
diff --git a/tck/tck-tests/src/main/java/jakarta/jsonp/tck/signaturetest/SignatureTestDriverFactory.java b/tck/tck-tests/src/main/java/jakarta/jsonp/tck/signaturetest/SignatureTestDriverFactory.java
new file mode 100644
index 0000000..4ec4908
--- /dev/null
+++ b/tck/tck-tests/src/main/java/jakarta/jsonp/tck/signaturetest/SignatureTestDriverFactory.java
@@ -0,0 +1,79 @@
+/*
+ * Copyright (c) 2021 Oracle and/or its affiliates. All rights reserved.
+ *
+ * This program and the accompanying materials are made available under the
+ * terms of the Eclipse Public License v. 2.0, which is available at
+ * http://www.eclipse.org/legal/epl-2.0.
+ *
+ * This Source Code may also be made available under the following Secondary
+ * Licenses when the conditions for such availability set forth in the
+ * Eclipse Public License v. 2.0 are satisfied: GNU General Public License,
+ * version 2 with the GNU Classpath Exception, which is available at
+ * https://www.gnu.org/software/classpath/license.html.
+ *
+ * SPDX-License-Identifier: EPL-2.0 OR GPL-2.0 WITH Classpath-exception-2.0
+ */
+
+/*
+ * $Id$
+ */
+
+package jakarta.jsonp.tck.signaturetest;
+
+/**
+ * <p>
+ * Factory to obtain SignatureTestDriver implementations.
+ * </p>
+ */
+public class SignatureTestDriverFactory {
+
+  /**
+   * <p>
+   * Identifier for the driver that uses API Check to perform signature
+   * validation.
+   * </p>
+   */
+  public static final String API_CHECK = "apicheck";
+
+  /**
+   * <p>
+   * Identifier for the driver that uses the Signature Test framwork for
+   * signature validation.
+   * </p>
+   */
+  public static final String SIG_TEST = "sigtest";
+
+  // ------------------------------------------------------------ Constructors
+
+  // Access via factory method
+  private SignatureTestDriverFactory() {
+  } // END SignatureTestDriverFactory
+
+  // ---------------------------------------------------------- Public Methods
+
+  /**
+   * <p>
+   * Obtain a {@link SignatureTestDriver} instance based on the
+   * <code>type</code> argument.
+   *
+   * @param type
+   *          the driver type to create
+   * @return a {@link SignatureTestDriver} implementation
+   */
+  public static SignatureTestDriver getInstance(String type) {
+
+    if (type == null || type.length() == 0) {
+      throw new IllegalArgumentException("Type was null or empty");
+    }
+
+    if (API_CHECK.equals(type)) {
+      return new ApiCheckDriver();
+    } else if (SIG_TEST.equals(type)) {
+      return new SigTestDriver();
+    } else {
+      throw new IllegalArgumentException("Unknown Type: '" + type + '\'');
+    }
+
+  } // END getInstance
+
+} // END SignatureTestDriverFactory
diff --git a/tck/tck-tests/src/main/java/jakarta/jsonp/tck/signaturetest/jsonp/JSONPSigTest.java b/tck/tck-tests/src/main/java/jakarta/jsonp/tck/signaturetest/jsonp/JSONPSigTest.java
new file mode 100644
index 0000000..e09f542
--- /dev/null
+++ b/tck/tck-tests/src/main/java/jakarta/jsonp/tck/signaturetest/jsonp/JSONPSigTest.java
@@ -0,0 +1,213 @@
+/*
+ * Copyright (c) 2021 Oracle and/or its affiliates. All rights reserved.
+ *
+ * This program and the accompanying materials are made available under the
+ * terms of the Eclipse Public License v. 2.0, which is available at
+ * http://www.eclipse.org/legal/epl-2.0.
+ *
+ * This Source Code may also be made available under the following Secondary
+ * Licenses when the conditions for such availability set forth in the
+ * Eclipse Public License v. 2.0 are satisfied: GNU General Public License,
+ * version 2 with the GNU Classpath Exception, which is available at
+ * https://www.gnu.org/software/classpath/license.html.
+ *
+ * SPDX-License-Identifier: EPL-2.0 OR GPL-2.0 WITH Classpath-exception-2.0
+ */
+
+/*
+ * $Id$
+ */
+
+package jakarta.jsonp.tck.signaturetest.jsonp;
+
+import java.io.PrintWriter;
+import java.util.Properties;
+
+import org.junit.jupiter.api.Test;
+
+import jakarta.jsonp.tck.signaturetest.SigTestEE;
+import jakarta.jsonp.tck.signaturetest.SignatureTestDriver;
+import jakarta.jsonp.tck.signaturetest.SignatureTestDriverFactory;
+import jakarta.jsonp.tck.signaturetest.SigTestResult;
+
+
+import java.io.BufferedReader;
+import java.io.File;
+import java.io.InputStreamReader;
+import java.io.IOException;
+import java.io.PrintWriter;
+import java.io.PrintStream;
+
+import java.util.ArrayList;
+import java.util.Properties;
+
+
+/*
+ * This class is a simple example of a signature test that extends the
+ * SigTest framework class.  This signature test is run outside of the
+ * Java EE containers.  This class also contains the boilerplate
+ * code necessary to create a signature test using the test framework.
+ * To see a complete TCK example see the javaee directory for the Java EE
+ * TCK signature test class.
+ */
+public class JSONPSigTest extends SigTestEE {
+
+  public JSONPSigTest(){
+    setup();
+  }
+
+  /***** Abstract Method Implementation *****/
+
+  /**
+   * Returns a list of strings where each string represents a package name. Each
+   * package name will have it's signature tested by the signature test
+   * framework.
+   * 
+   * @return String[] The names of the packages whose signatures should be
+   *         verified.
+   */
+  protected String[] getPackages(String vehicleName) {
+    return new String[] { "jakarta.json", "jakarta.json.spi",
+        "jakarta.json.stream", };
+
+  }
+
+  /***** Boilerplate Code *****/
+
+
+  /*
+   * The following comments are specified in the base class that defines the
+   * signature tests. This is done so the test finders will find the right class
+   * to run. The implementation of these methods is inherited from the super
+   * class which is part of the signature test framework.
+   */
+
+  // NOTE: If the API under test is not part of your testing runtime
+  // environment, you may use the property sigTestClasspath to specify
+  // where the API under test lives. This should almost never be used.
+  // Normally the API under test should be specified in the classpath
+  // of the VM running the signature tests. Use either the first
+  // comment or the one below it depending on which properties your
+  // signature tests need. Please do not use both comments.
+
+  /*
+   * @class.setup_props: ts_home, The base path of this TCK; sigTestClasspath;
+   */
+  /*
+   * @testName: signatureTest
+   * 
+   * @assertion: A JSONB container must implement the required classes and APIs
+   * specified in the JSONB Specification.
+   * 
+   * @test_Strategy: Using reflection, gather the implementation specific
+   * classes and APIs. Compare these results with the expected (required)
+   * classes and APIs.
+   *
+   */
+  @Test
+  public void signatureTest() throws Fault {
+    System.out.println("$$$ JSONBSigTest.signatureTest() called");
+    SigTestResult results = null;
+    String mapFile = System.getProperty("signature.mapfile");
+    String repositoryDir = System.getProperty("signature.repositoryDir");
+    String[] packages = getPackages(testInfo.getVehicle());
+    String[] classes = getClasses(testInfo.getVehicle());
+    String packageFile = System.getProperty("signature.packagelist");
+    String testClasspath = System.getProperty("signature.sigTestClasspath");
+    String optionalPkgToIgnore = testInfo.getOptionalTechPackagesToIgnore();
+
+    // unlisted optional packages are technology packages for those optional
+    // technologies (e.g. jsr-88) that might not have been specified by the
+    // user.
+    // We want to ensure there are no full or partial implementations of an
+    // optional technology which were not declared
+    ArrayList<String> unlistedTechnologyPkgs = getUnlistedOptionalPackages();
+
+    // If testing with Java 9+, extract the JDK's modules so they can be used
+    // on the testcase's classpath.
+    Properties sysProps = System.getProperties();
+    String version = (String) sysProps.get("java.version");
+    if (!version.startsWith("1.")) {
+      String jimageDir = testInfo.getJImageDir();
+      File f = new File(jimageDir);
+      f.mkdirs();
+
+      String javaHome = (String) sysProps.get("java.home");
+      System.out.println("Executing JImage");
+
+      try {
+        ProcessBuilder pb = new ProcessBuilder(javaHome + "/bin/jimage", "extract", "--dir=" + jimageDir, javaHome + "/lib/modules");
+        System.out.println(javaHome + "/bin/jimage extract --dir=" + jimageDir + " " + javaHome + "/lib/modules");
+        pb.redirectErrorStream(true);
+        Process proc = pb.start();
+        BufferedReader out = new BufferedReader(new InputStreamReader(proc.getInputStream()));
+        String line = null;
+        while ((line = out.readLine()) != null) {
+          System.out.println(line);
+        }
+
+        int rc = proc.waitFor();
+        System.out.println("JImage RC = " + rc);
+        out.close();
+      } catch (Exception e) {
+        System.out.println("Exception while executing JImage!  Some tests may fail.");
+        e.printStackTrace();
+      }
+    }
+
+    try {
+      results = getSigTestDriver().executeSigTest(packageFile, mapFile,
+          repositoryDir, packages, classes, testClasspath,
+          unlistedTechnologyPkgs, optionalPkgToIgnore);
+      System.out.println(results.toString());
+      if (!results.passed()) {
+        System.out.println("results.passed() returned false");
+        throw new Exception();
+      }
+
+      // Call verifyJtaJarTest based on some conditions, please check the
+      // comment for verifyJtaJarTest.
+      if ("standalone".equalsIgnoreCase(testInfo.getVehicle())) {
+        Properties mapFileAsProps = getSigTestDriver().loadMapFile(mapFile);
+        if (mapFileAsProps == null || mapFileAsProps.size() == 0) {
+          // empty signature file, something unusual
+          System.out.println("JSONBSigTest.signatureTest() returning, " +
+              "as signature map file is empty.");
+          return;
+        }
+
+        boolean isJTASigTest = false;
+
+        // Determine whether the signature map file contains package 
+        // jakarta.transaction
+        String jtaVersion = mapFileAsProps.getProperty("jakarta.transaction");
+        if (jtaVersion == null || "".equals(jtaVersion.trim())) {
+          System.out.println("JSONBSigTest.signatureTest() returning, " +
+              "as this is neither JTA TCK run, not Java EE CTS run.");
+          return;
+        }
+
+        System.out.println("jtaVersion " + jtaVersion);  
+        // Signature map packaged in JTA TCK will contain a single package 
+        // jakarta.transaction
+        if (mapFileAsProps.size() == 1) {
+            isJTASigTest = true;
+        }
+
+        if (isJTASigTest || !jtaVersion.startsWith("1.2")) {
+          verifyJtaJarTest();
+        }
+      }
+      System.out.println("$$$ JSONBSigTest.signatureTest() returning");
+    } catch (Exception e) {
+      if (results != null && !results.passed()) {
+        throw new Fault("JSONBSigTest.signatureTest() failed!, diffs found");
+      } else {
+        System.out.println("Unexpected exception " + e.getMessage());
+        throw new Fault("signatureTest failed with an unexpected exception", e);
+      }
+    }
+  }
+
+
+} // end class JSONBSigTest
diff --git a/tck/tck-tests/src/main/resources/jakarta/jsonp/tck/signaturetest/jakarta.json.sig_2.1.0 b/tck/tck-tests/src/main/resources/jakarta/jsonp/tck/signaturetest/jakarta.json.sig_2.1.0
new file mode 100644
index 0000000..52d5b4b
--- /dev/null
+++ b/tck/tck-tests/src/main/resources/jakarta/jsonp/tck/signaturetest/jakarta.json.sig_2.1.0
@@ -0,0 +1,640 @@
+#Signature file v4.1
+#Version 2.1_se11
+
+CLSS public final jakarta.json.Json
+meth public static jakarta.json.JsonArrayBuilder createArrayBuilder()
+meth public static jakarta.json.JsonArrayBuilder createArrayBuilder(jakarta.json.JsonArray)
+meth public static jakarta.json.JsonArrayBuilder createArrayBuilder(java.util.Collection<?>)
+meth public static jakarta.json.JsonBuilderFactory createBuilderFactory(java.util.Map<java.lang.String,?>)
+meth public static jakarta.json.JsonMergePatch createMergeDiff(jakarta.json.JsonValue,jakarta.json.JsonValue)
+meth public static jakarta.json.JsonMergePatch createMergePatch(jakarta.json.JsonValue)
+meth public static jakarta.json.JsonNumber createValue(double)
+meth public static jakarta.json.JsonNumber createValue(int)
+meth public static jakarta.json.JsonNumber createValue(java.lang.Number)
+meth public static jakarta.json.JsonNumber createValue(java.math.BigDecimal)
+meth public static jakarta.json.JsonNumber createValue(java.math.BigInteger)
+meth public static jakarta.json.JsonNumber createValue(long)
+meth public static jakarta.json.JsonObjectBuilder createObjectBuilder()
+meth public static jakarta.json.JsonObjectBuilder createObjectBuilder(jakarta.json.JsonObject)
+meth public static jakarta.json.JsonObjectBuilder createObjectBuilder(java.util.Map<java.lang.String,?>)
+meth public static jakarta.json.JsonPatch createDiff(jakarta.json.JsonStructure,jakarta.json.JsonStructure)
+meth public static jakarta.json.JsonPatch createPatch(jakarta.json.JsonArray)
+meth public static jakarta.json.JsonPatchBuilder createPatchBuilder()
+meth public static jakarta.json.JsonPatchBuilder createPatchBuilder(jakarta.json.JsonArray)
+meth public static jakarta.json.JsonPointer createPointer(java.lang.String)
+meth public static jakarta.json.JsonReader createReader(java.io.InputStream)
+meth public static jakarta.json.JsonReader createReader(java.io.Reader)
+meth public static jakarta.json.JsonReaderFactory createReaderFactory(java.util.Map<java.lang.String,?>)
+meth public static jakarta.json.JsonString createValue(java.lang.String)
+meth public static jakarta.json.JsonWriter createWriter(java.io.OutputStream)
+meth public static jakarta.json.JsonWriter createWriter(java.io.Writer)
+meth public static jakarta.json.JsonWriterFactory createWriterFactory(java.util.Map<java.lang.String,?>)
+meth public static jakarta.json.stream.JsonGenerator createGenerator(java.io.OutputStream)
+meth public static jakarta.json.stream.JsonGenerator createGenerator(java.io.Writer)
+meth public static jakarta.json.stream.JsonGeneratorFactory createGeneratorFactory(java.util.Map<java.lang.String,?>)
+meth public static jakarta.json.stream.JsonParser createParser(java.io.InputStream)
+meth public static jakarta.json.stream.JsonParser createParser(java.io.Reader)
+meth public static jakarta.json.stream.JsonParserFactory createParserFactory(java.util.Map<java.lang.String,?>)
+meth public static java.lang.String decodePointer(java.lang.String)
+meth public static java.lang.String encodePointer(java.lang.String)
+supr java.lang.Object
+
+CLSS public abstract interface jakarta.json.JsonArray
+intf jakarta.json.JsonStructure
+intf java.util.List<jakarta.json.JsonValue>
+meth public <%0 extends java.lang.Object, %1 extends jakarta.json.JsonValue> java.util.List<{%%0}> getValuesAs(java.util.function.Function<{%%1},{%%0}>)
+meth public abstract <%0 extends jakarta.json.JsonValue> java.util.List<{%%0}> getValuesAs(java.lang.Class<{%%0}>)
+meth public abstract boolean getBoolean(int)
+meth public abstract boolean getBoolean(int,boolean)
+meth public abstract boolean isNull(int)
+meth public abstract int getInt(int)
+meth public abstract int getInt(int,int)
+meth public abstract jakarta.json.JsonArray getJsonArray(int)
+meth public abstract jakarta.json.JsonNumber getJsonNumber(int)
+meth public abstract jakarta.json.JsonObject getJsonObject(int)
+meth public abstract jakarta.json.JsonString getJsonString(int)
+meth public abstract java.lang.String getString(int)
+meth public abstract java.lang.String getString(int,java.lang.String)
+
+CLSS public abstract interface jakarta.json.JsonArrayBuilder
+meth public abstract jakarta.json.JsonArray build()
+meth public abstract jakarta.json.JsonArrayBuilder add(boolean)
+meth public abstract jakarta.json.JsonArrayBuilder add(double)
+meth public abstract jakarta.json.JsonArrayBuilder add(int)
+meth public abstract jakarta.json.JsonArrayBuilder add(jakarta.json.JsonArrayBuilder)
+meth public abstract jakarta.json.JsonArrayBuilder add(jakarta.json.JsonObjectBuilder)
+meth public abstract jakarta.json.JsonArrayBuilder add(jakarta.json.JsonValue)
+meth public abstract jakarta.json.JsonArrayBuilder add(java.lang.String)
+meth public abstract jakarta.json.JsonArrayBuilder add(java.math.BigDecimal)
+meth public abstract jakarta.json.JsonArrayBuilder add(java.math.BigInteger)
+meth public abstract jakarta.json.JsonArrayBuilder add(long)
+meth public abstract jakarta.json.JsonArrayBuilder addNull()
+meth public jakarta.json.JsonArrayBuilder add(int,boolean)
+meth public jakarta.json.JsonArrayBuilder add(int,double)
+meth public jakarta.json.JsonArrayBuilder add(int,int)
+meth public jakarta.json.JsonArrayBuilder add(int,jakarta.json.JsonArrayBuilder)
+meth public jakarta.json.JsonArrayBuilder add(int,jakarta.json.JsonObjectBuilder)
+meth public jakarta.json.JsonArrayBuilder add(int,jakarta.json.JsonValue)
+meth public jakarta.json.JsonArrayBuilder add(int,java.lang.String)
+meth public jakarta.json.JsonArrayBuilder add(int,java.math.BigDecimal)
+meth public jakarta.json.JsonArrayBuilder add(int,java.math.BigInteger)
+meth public jakarta.json.JsonArrayBuilder add(int,long)
+meth public jakarta.json.JsonArrayBuilder addAll(jakarta.json.JsonArrayBuilder)
+meth public jakarta.json.JsonArrayBuilder addNull(int)
+meth public jakarta.json.JsonArrayBuilder remove(int)
+meth public jakarta.json.JsonArrayBuilder set(int,boolean)
+meth public jakarta.json.JsonArrayBuilder set(int,double)
+meth public jakarta.json.JsonArrayBuilder set(int,int)
+meth public jakarta.json.JsonArrayBuilder set(int,jakarta.json.JsonArrayBuilder)
+meth public jakarta.json.JsonArrayBuilder set(int,jakarta.json.JsonObjectBuilder)
+meth public jakarta.json.JsonArrayBuilder set(int,jakarta.json.JsonValue)
+meth public jakarta.json.JsonArrayBuilder set(int,java.lang.String)
+meth public jakarta.json.JsonArrayBuilder set(int,java.math.BigDecimal)
+meth public jakarta.json.JsonArrayBuilder set(int,java.math.BigInteger)
+meth public jakarta.json.JsonArrayBuilder set(int,long)
+meth public jakarta.json.JsonArrayBuilder setNull(int)
+
+CLSS public abstract interface jakarta.json.JsonBuilderFactory
+meth public abstract jakarta.json.JsonArrayBuilder createArrayBuilder()
+meth public abstract jakarta.json.JsonObjectBuilder createObjectBuilder()
+meth public abstract java.util.Map<java.lang.String,?> getConfigInUse()
+meth public jakarta.json.JsonArrayBuilder createArrayBuilder(jakarta.json.JsonArray)
+meth public jakarta.json.JsonArrayBuilder createArrayBuilder(java.util.Collection<?>)
+meth public jakarta.json.JsonObjectBuilder createObjectBuilder(jakarta.json.JsonObject)
+meth public jakarta.json.JsonObjectBuilder createObjectBuilder(java.util.Map<java.lang.String,java.lang.Object>)
+
+CLSS public final jakarta.json.JsonConfig
+fld public final static java.lang.String KEY_STRATEGY = "jakarta.json.JsonConfig.keyStrategy"
+innr public final static !enum KeyStrategy
+supr java.lang.Object
+
+CLSS public final static !enum jakarta.json.JsonConfig$KeyStrategy
+ outer jakarta.json.JsonConfig
+fld public final static jakarta.json.JsonConfig$KeyStrategy FIRST
+fld public final static jakarta.json.JsonConfig$KeyStrategy LAST
+fld public final static jakarta.json.JsonConfig$KeyStrategy NONE
+meth public static jakarta.json.JsonConfig$KeyStrategy valueOf(java.lang.String)
+meth public static jakarta.json.JsonConfig$KeyStrategy[] values()
+supr java.lang.Enum<jakarta.json.JsonConfig$KeyStrategy>
+
+CLSS public jakarta.json.JsonException
+cons public init(java.lang.String)
+cons public init(java.lang.String,java.lang.Throwable)
+supr java.lang.RuntimeException
+hfds serialVersionUID
+
+CLSS public abstract interface jakarta.json.JsonMergePatch
+meth public abstract jakarta.json.JsonValue apply(jakarta.json.JsonValue)
+meth public abstract jakarta.json.JsonValue toJsonValue()
+
+CLSS public abstract interface jakarta.json.JsonNumber
+intf jakarta.json.JsonValue
+meth public abstract boolean equals(java.lang.Object)
+meth public abstract boolean isIntegral()
+meth public abstract double doubleValue()
+meth public abstract int hashCode()
+meth public abstract int intValue()
+meth public abstract int intValueExact()
+meth public abstract java.lang.String toString()
+meth public abstract java.math.BigDecimal bigDecimalValue()
+meth public abstract java.math.BigInteger bigIntegerValue()
+meth public abstract java.math.BigInteger bigIntegerValueExact()
+meth public abstract long longValue()
+meth public abstract long longValueExact()
+meth public java.lang.Number numberValue()
+
+CLSS public abstract interface jakarta.json.JsonObject
+intf jakarta.json.JsonStructure
+intf java.util.Map<java.lang.String,jakarta.json.JsonValue>
+meth public abstract boolean getBoolean(java.lang.String)
+meth public abstract boolean getBoolean(java.lang.String,boolean)
+meth public abstract boolean isNull(java.lang.String)
+meth public abstract int getInt(java.lang.String)
+meth public abstract int getInt(java.lang.String,int)
+meth public abstract jakarta.json.JsonArray getJsonArray(java.lang.String)
+meth public abstract jakarta.json.JsonNumber getJsonNumber(java.lang.String)
+meth public abstract jakarta.json.JsonObject getJsonObject(java.lang.String)
+meth public abstract jakarta.json.JsonString getJsonString(java.lang.String)
+meth public abstract java.lang.String getString(java.lang.String)
+meth public abstract java.lang.String getString(java.lang.String,java.lang.String)
+
+CLSS public abstract interface jakarta.json.JsonObjectBuilder
+meth public abstract jakarta.json.JsonObject build()
+meth public abstract jakarta.json.JsonObjectBuilder add(java.lang.String,boolean)
+meth public abstract jakarta.json.JsonObjectBuilder add(java.lang.String,double)
+meth public abstract jakarta.json.JsonObjectBuilder add(java.lang.String,int)
+meth public abstract jakarta.json.JsonObjectBuilder add(java.lang.String,jakarta.json.JsonArrayBuilder)
+meth public abstract jakarta.json.JsonObjectBuilder add(java.lang.String,jakarta.json.JsonObjectBuilder)
+meth public abstract jakarta.json.JsonObjectBuilder add(java.lang.String,jakarta.json.JsonValue)
+meth public abstract jakarta.json.JsonObjectBuilder add(java.lang.String,java.lang.String)
+meth public abstract jakarta.json.JsonObjectBuilder add(java.lang.String,java.math.BigDecimal)
+meth public abstract jakarta.json.JsonObjectBuilder add(java.lang.String,java.math.BigInteger)
+meth public abstract jakarta.json.JsonObjectBuilder add(java.lang.String,long)
+meth public abstract jakarta.json.JsonObjectBuilder addNull(java.lang.String)
+meth public jakarta.json.JsonObjectBuilder addAll(jakarta.json.JsonObjectBuilder)
+meth public jakarta.json.JsonObjectBuilder remove(java.lang.String)
+
+CLSS public abstract interface jakarta.json.JsonPatch
+innr public final static !enum Operation
+meth public abstract <%0 extends jakarta.json.JsonStructure> {%%0} apply({%%0})
+meth public abstract jakarta.json.JsonArray toJsonArray()
+
+CLSS public final static !enum jakarta.json.JsonPatch$Operation
+ outer jakarta.json.JsonPatch
+fld public final static jakarta.json.JsonPatch$Operation ADD
+fld public final static jakarta.json.JsonPatch$Operation COPY
+fld public final static jakarta.json.JsonPatch$Operation MOVE
+fld public final static jakarta.json.JsonPatch$Operation REMOVE
+fld public final static jakarta.json.JsonPatch$Operation REPLACE
+fld public final static jakarta.json.JsonPatch$Operation TEST
+meth public java.lang.String operationName()
+meth public static jakarta.json.JsonPatch$Operation fromOperationName(java.lang.String)
+meth public static jakarta.json.JsonPatch$Operation valueOf(java.lang.String)
+meth public static jakarta.json.JsonPatch$Operation[] values()
+supr java.lang.Enum<jakarta.json.JsonPatch$Operation>
+hfds operationName
+
+CLSS public abstract interface jakarta.json.JsonPatchBuilder
+meth public abstract jakarta.json.JsonPatch build()
+meth public abstract jakarta.json.JsonPatchBuilder add(java.lang.String,boolean)
+meth public abstract jakarta.json.JsonPatchBuilder add(java.lang.String,int)
+meth public abstract jakarta.json.JsonPatchBuilder add(java.lang.String,jakarta.json.JsonValue)
+meth public abstract jakarta.json.JsonPatchBuilder add(java.lang.String,java.lang.String)
+meth public abstract jakarta.json.JsonPatchBuilder copy(java.lang.String,java.lang.String)
+meth public abstract jakarta.json.JsonPatchBuilder move(java.lang.String,java.lang.String)
+meth public abstract jakarta.json.JsonPatchBuilder remove(java.lang.String)
+meth public abstract jakarta.json.JsonPatchBuilder replace(java.lang.String,boolean)
+meth public abstract jakarta.json.JsonPatchBuilder replace(java.lang.String,int)
+meth public abstract jakarta.json.JsonPatchBuilder replace(java.lang.String,jakarta.json.JsonValue)
+meth public abstract jakarta.json.JsonPatchBuilder replace(java.lang.String,java.lang.String)
+meth public abstract jakarta.json.JsonPatchBuilder test(java.lang.String,boolean)
+meth public abstract jakarta.json.JsonPatchBuilder test(java.lang.String,int)
+meth public abstract jakarta.json.JsonPatchBuilder test(java.lang.String,jakarta.json.JsonValue)
+meth public abstract jakarta.json.JsonPatchBuilder test(java.lang.String,java.lang.String)
+
+CLSS public abstract interface jakarta.json.JsonPointer
+meth public abstract <%0 extends jakarta.json.JsonStructure> {%%0} add({%%0},jakarta.json.JsonValue)
+meth public abstract <%0 extends jakarta.json.JsonStructure> {%%0} remove({%%0})
+meth public abstract <%0 extends jakarta.json.JsonStructure> {%%0} replace({%%0},jakarta.json.JsonValue)
+meth public abstract boolean containsValue(jakarta.json.JsonStructure)
+meth public abstract jakarta.json.JsonValue getValue(jakarta.json.JsonStructure)
+meth public abstract java.lang.String toString()
+
+CLSS public abstract interface jakarta.json.JsonReader
+intf java.io.Closeable
+meth public abstract jakarta.json.JsonArray readArray()
+meth public abstract jakarta.json.JsonObject readObject()
+meth public abstract jakarta.json.JsonStructure read()
+meth public abstract void close()
+meth public jakarta.json.JsonValue readValue()
+
+CLSS public abstract interface jakarta.json.JsonReaderFactory
+meth public abstract jakarta.json.JsonReader createReader(java.io.InputStream)
+meth public abstract jakarta.json.JsonReader createReader(java.io.InputStream,java.nio.charset.Charset)
+meth public abstract jakarta.json.JsonReader createReader(java.io.Reader)
+meth public abstract java.util.Map<java.lang.String,?> getConfigInUse()
+
+CLSS public abstract interface jakarta.json.JsonString
+intf jakarta.json.JsonValue
+meth public abstract boolean equals(java.lang.Object)
+meth public abstract int hashCode()
+meth public abstract java.lang.CharSequence getChars()
+meth public abstract java.lang.String getString()
+
+CLSS public abstract interface jakarta.json.JsonStructure
+intf jakarta.json.JsonValue
+meth public jakarta.json.JsonValue getValue(java.lang.String)
+
+CLSS public abstract interface jakarta.json.JsonValue
+fld public final static jakarta.json.JsonArray EMPTY_JSON_ARRAY
+fld public final static jakarta.json.JsonObject EMPTY_JSON_OBJECT
+fld public final static jakarta.json.JsonValue FALSE
+fld public final static jakarta.json.JsonValue NULL
+fld public final static jakarta.json.JsonValue TRUE
+innr public final static !enum ValueType
+meth public abstract jakarta.json.JsonValue$ValueType getValueType()
+meth public abstract java.lang.String toString()
+meth public jakarta.json.JsonArray asJsonArray()
+meth public jakarta.json.JsonObject asJsonObject()
+
+CLSS public final static !enum jakarta.json.JsonValue$ValueType
+ outer jakarta.json.JsonValue
+fld public final static jakarta.json.JsonValue$ValueType ARRAY
+fld public final static jakarta.json.JsonValue$ValueType FALSE
+fld public final static jakarta.json.JsonValue$ValueType NULL
+fld public final static jakarta.json.JsonValue$ValueType NUMBER
+fld public final static jakarta.json.JsonValue$ValueType OBJECT
+fld public final static jakarta.json.JsonValue$ValueType STRING
+fld public final static jakarta.json.JsonValue$ValueType TRUE
+meth public static jakarta.json.JsonValue$ValueType valueOf(java.lang.String)
+meth public static jakarta.json.JsonValue$ValueType[] values()
+supr java.lang.Enum<jakarta.json.JsonValue$ValueType>
+
+CLSS public abstract interface jakarta.json.JsonWriter
+intf java.io.Closeable
+meth public abstract void close()
+meth public abstract void write(jakarta.json.JsonStructure)
+meth public abstract void writeArray(jakarta.json.JsonArray)
+meth public abstract void writeObject(jakarta.json.JsonObject)
+meth public void write(jakarta.json.JsonValue)
+
+CLSS public abstract interface jakarta.json.JsonWriterFactory
+meth public abstract jakarta.json.JsonWriter createWriter(java.io.OutputStream)
+meth public abstract jakarta.json.JsonWriter createWriter(java.io.OutputStream,java.nio.charset.Charset)
+meth public abstract jakarta.json.JsonWriter createWriter(java.io.Writer)
+meth public abstract java.util.Map<java.lang.String,?> getConfigInUse()
+
+CLSS public abstract jakarta.json.spi.JsonProvider
+cons protected init()
+meth public abstract jakarta.json.JsonArrayBuilder createArrayBuilder()
+meth public abstract jakarta.json.JsonBuilderFactory createBuilderFactory(java.util.Map<java.lang.String,?>)
+meth public abstract jakarta.json.JsonObjectBuilder createObjectBuilder()
+meth public abstract jakarta.json.JsonReader createReader(java.io.InputStream)
+meth public abstract jakarta.json.JsonReader createReader(java.io.Reader)
+meth public abstract jakarta.json.JsonReaderFactory createReaderFactory(java.util.Map<java.lang.String,?>)
+meth public abstract jakarta.json.JsonWriter createWriter(java.io.OutputStream)
+meth public abstract jakarta.json.JsonWriter createWriter(java.io.Writer)
+meth public abstract jakarta.json.JsonWriterFactory createWriterFactory(java.util.Map<java.lang.String,?>)
+meth public abstract jakarta.json.stream.JsonGenerator createGenerator(java.io.OutputStream)
+meth public abstract jakarta.json.stream.JsonGenerator createGenerator(java.io.Writer)
+meth public abstract jakarta.json.stream.JsonGeneratorFactory createGeneratorFactory(java.util.Map<java.lang.String,?>)
+meth public abstract jakarta.json.stream.JsonParser createParser(java.io.InputStream)
+meth public abstract jakarta.json.stream.JsonParser createParser(java.io.Reader)
+meth public abstract jakarta.json.stream.JsonParserFactory createParserFactory(java.util.Map<java.lang.String,?>)
+meth public jakarta.json.JsonArrayBuilder createArrayBuilder(jakarta.json.JsonArray)
+meth public jakarta.json.JsonArrayBuilder createArrayBuilder(java.util.Collection<?>)
+meth public jakarta.json.JsonMergePatch createMergeDiff(jakarta.json.JsonValue,jakarta.json.JsonValue)
+meth public jakarta.json.JsonMergePatch createMergePatch(jakarta.json.JsonValue)
+meth public jakarta.json.JsonNumber createValue(double)
+meth public jakarta.json.JsonNumber createValue(int)
+meth public jakarta.json.JsonNumber createValue(java.lang.Number)
+meth public jakarta.json.JsonNumber createValue(java.math.BigDecimal)
+meth public jakarta.json.JsonNumber createValue(java.math.BigInteger)
+meth public jakarta.json.JsonNumber createValue(long)
+meth public jakarta.json.JsonObjectBuilder createObjectBuilder(jakarta.json.JsonObject)
+meth public jakarta.json.JsonObjectBuilder createObjectBuilder(java.util.Map<java.lang.String,?>)
+meth public jakarta.json.JsonPatch createDiff(jakarta.json.JsonStructure,jakarta.json.JsonStructure)
+meth public jakarta.json.JsonPatch createPatch(jakarta.json.JsonArray)
+meth public jakarta.json.JsonPatchBuilder createPatchBuilder()
+meth public jakarta.json.JsonPatchBuilder createPatchBuilder(jakarta.json.JsonArray)
+meth public jakarta.json.JsonPointer createPointer(java.lang.String)
+meth public jakarta.json.JsonString createValue(java.lang.String)
+meth public static jakarta.json.spi.JsonProvider provider()
+supr java.lang.Object
+hfds DEFAULT_PROVIDER,JSONP_PROVIDER_FACTORY,OSGI_SERVICE_LOADER_CLASS_NAME
+hcls LazyFactoryLoader
+
+CLSS public final jakarta.json.stream.JsonCollectors
+meth public static <%0 extends jakarta.json.JsonArrayBuilder> java.util.stream.Collector<jakarta.json.JsonValue,java.util.Map<java.lang.String,{%%0}>,jakarta.json.JsonObject> groupingBy(java.util.function.Function<jakarta.json.JsonValue,java.lang.String>,java.util.stream.Collector<jakarta.json.JsonValue,{%%0},jakarta.json.JsonArray>)
+meth public static java.util.stream.Collector<jakarta.json.JsonValue,jakarta.json.JsonArrayBuilder,jakarta.json.JsonArray> toJsonArray()
+meth public static java.util.stream.Collector<jakarta.json.JsonValue,jakarta.json.JsonObjectBuilder,jakarta.json.JsonObject> toJsonObject(java.util.function.Function<jakarta.json.JsonValue,java.lang.String>,java.util.function.Function<jakarta.json.JsonValue,jakarta.json.JsonValue>)
+meth public static java.util.stream.Collector<jakarta.json.JsonValue,java.util.Map<java.lang.String,jakarta.json.JsonArrayBuilder>,jakarta.json.JsonObject> groupingBy(java.util.function.Function<jakarta.json.JsonValue,java.lang.String>)
+meth public static java.util.stream.Collector<java.util.Map$Entry<java.lang.String,jakarta.json.JsonValue>,jakarta.json.JsonObjectBuilder,jakarta.json.JsonObject> toJsonObject()
+supr java.lang.Object
+
+CLSS public jakarta.json.stream.JsonGenerationException
+cons public init(java.lang.String)
+cons public init(java.lang.String,java.lang.Throwable)
+supr jakarta.json.JsonException
+hfds serialVersionUID
+
+CLSS public abstract interface jakarta.json.stream.JsonGenerator
+fld public final static java.lang.String PRETTY_PRINTING = "jakarta.json.stream.JsonGenerator.prettyPrinting"
+intf java.io.Closeable
+intf java.io.Flushable
+meth public abstract jakarta.json.stream.JsonGenerator write(boolean)
+meth public abstract jakarta.json.stream.JsonGenerator write(double)
+meth public abstract jakarta.json.stream.JsonGenerator write(int)
+meth public abstract jakarta.json.stream.JsonGenerator write(jakarta.json.JsonValue)
+meth public abstract jakarta.json.stream.JsonGenerator write(java.lang.String)
+meth public abstract jakarta.json.stream.JsonGenerator write(java.lang.String,boolean)
+meth public abstract jakarta.json.stream.JsonGenerator write(java.lang.String,double)
+meth public abstract jakarta.json.stream.JsonGenerator write(java.lang.String,int)
+meth public abstract jakarta.json.stream.JsonGenerator write(java.lang.String,jakarta.json.JsonValue)
+meth public abstract jakarta.json.stream.JsonGenerator write(java.lang.String,java.lang.String)
+meth public abstract jakarta.json.stream.JsonGenerator write(java.lang.String,java.math.BigDecimal)
+meth public abstract jakarta.json.stream.JsonGenerator write(java.lang.String,java.math.BigInteger)
+meth public abstract jakarta.json.stream.JsonGenerator write(java.lang.String,long)
+meth public abstract jakarta.json.stream.JsonGenerator write(java.math.BigDecimal)
+meth public abstract jakarta.json.stream.JsonGenerator write(java.math.BigInteger)
+meth public abstract jakarta.json.stream.JsonGenerator write(long)
+meth public abstract jakarta.json.stream.JsonGenerator writeEnd()
+meth public abstract jakarta.json.stream.JsonGenerator writeKey(java.lang.String)
+meth public abstract jakarta.json.stream.JsonGenerator writeNull()
+meth public abstract jakarta.json.stream.JsonGenerator writeNull(java.lang.String)
+meth public abstract jakarta.json.stream.JsonGenerator writeStartArray()
+meth public abstract jakarta.json.stream.JsonGenerator writeStartArray(java.lang.String)
+meth public abstract jakarta.json.stream.JsonGenerator writeStartObject()
+meth public abstract jakarta.json.stream.JsonGenerator writeStartObject(java.lang.String)
+meth public abstract void close()
+meth public abstract void flush()
+
+CLSS public abstract interface jakarta.json.stream.JsonGeneratorFactory
+meth public abstract jakarta.json.stream.JsonGenerator createGenerator(java.io.OutputStream)
+meth public abstract jakarta.json.stream.JsonGenerator createGenerator(java.io.OutputStream,java.nio.charset.Charset)
+meth public abstract jakarta.json.stream.JsonGenerator createGenerator(java.io.Writer)
+meth public abstract java.util.Map<java.lang.String,?> getConfigInUse()
+
+CLSS public abstract interface jakarta.json.stream.JsonLocation
+meth public abstract long getColumnNumber()
+meth public abstract long getLineNumber()
+meth public abstract long getStreamOffset()
+
+CLSS public abstract interface jakarta.json.stream.JsonParser
+innr public final static !enum Event
+intf java.io.Closeable
+meth public abstract boolean hasNext()
+meth public abstract boolean isIntegralNumber()
+meth public abstract int getInt()
+meth public abstract jakarta.json.stream.JsonLocation getLocation()
+meth public abstract jakarta.json.stream.JsonParser$Event next()
+meth public abstract java.lang.String getString()
+meth public abstract java.math.BigDecimal getBigDecimal()
+meth public abstract long getLong()
+meth public abstract void close()
+meth public jakarta.json.JsonArray getArray()
+meth public jakarta.json.JsonObject getObject()
+meth public jakarta.json.JsonValue getValue()
+meth public jakarta.json.stream.JsonParser$Event currentEvent()
+meth public java.util.stream.Stream<jakarta.json.JsonValue> getArrayStream()
+meth public java.util.stream.Stream<jakarta.json.JsonValue> getValueStream()
+meth public java.util.stream.Stream<java.util.Map$Entry<java.lang.String,jakarta.json.JsonValue>> getObjectStream()
+meth public void skipArray()
+meth public void skipObject()
+
+CLSS public final static !enum jakarta.json.stream.JsonParser$Event
+ outer jakarta.json.stream.JsonParser
+fld public final static jakarta.json.stream.JsonParser$Event END_ARRAY
+fld public final static jakarta.json.stream.JsonParser$Event END_OBJECT
+fld public final static jakarta.json.stream.JsonParser$Event KEY_NAME
+fld public final static jakarta.json.stream.JsonParser$Event START_ARRAY
+fld public final static jakarta.json.stream.JsonParser$Event START_OBJECT
+fld public final static jakarta.json.stream.JsonParser$Event VALUE_FALSE
+fld public final static jakarta.json.stream.JsonParser$Event VALUE_NULL
+fld public final static jakarta.json.stream.JsonParser$Event VALUE_NUMBER
+fld public final static jakarta.json.stream.JsonParser$Event VALUE_STRING
+fld public final static jakarta.json.stream.JsonParser$Event VALUE_TRUE
+meth public static jakarta.json.stream.JsonParser$Event valueOf(java.lang.String)
+meth public static jakarta.json.stream.JsonParser$Event[] values()
+supr java.lang.Enum<jakarta.json.stream.JsonParser$Event>
+
+CLSS public abstract interface jakarta.json.stream.JsonParserFactory
+meth public abstract jakarta.json.stream.JsonParser createParser(jakarta.json.JsonArray)
+meth public abstract jakarta.json.stream.JsonParser createParser(jakarta.json.JsonObject)
+meth public abstract jakarta.json.stream.JsonParser createParser(java.io.InputStream)
+meth public abstract jakarta.json.stream.JsonParser createParser(java.io.InputStream,java.nio.charset.Charset)
+meth public abstract jakarta.json.stream.JsonParser createParser(java.io.Reader)
+meth public abstract java.util.Map<java.lang.String,?> getConfigInUse()
+
+CLSS public jakarta.json.stream.JsonParsingException
+cons public init(java.lang.String,jakarta.json.stream.JsonLocation)
+cons public init(java.lang.String,java.lang.Throwable,jakarta.json.stream.JsonLocation)
+meth public jakarta.json.stream.JsonLocation getLocation()
+supr jakarta.json.JsonException
+hfds location,serialVersionUID
+
+CLSS public abstract interface java.io.Closeable
+intf java.lang.AutoCloseable
+meth public abstract void close() throws java.io.IOException
+
+CLSS public abstract interface java.io.Flushable
+meth public abstract void flush() throws java.io.IOException
+
+CLSS public abstract interface java.io.Serializable
+
+CLSS public abstract interface java.lang.AutoCloseable
+meth public abstract void close() throws java.lang.Exception
+
+CLSS public abstract interface java.lang.Comparable<%0 extends java.lang.Object>
+meth public abstract int compareTo({java.lang.Comparable%0})
+
+CLSS public abstract java.lang.Enum<%0 extends java.lang.Enum<{java.lang.Enum%0}>>
+cons protected init(java.lang.String,int)
+intf java.io.Serializable
+intf java.lang.Comparable<{java.lang.Enum%0}>
+meth protected final java.lang.Object clone() throws java.lang.CloneNotSupportedException
+meth protected final void finalize()
+meth public final boolean equals(java.lang.Object)
+meth public final int compareTo({java.lang.Enum%0})
+meth public final int hashCode()
+meth public final int ordinal()
+meth public final java.lang.Class<{java.lang.Enum%0}> getDeclaringClass()
+meth public final java.lang.String name()
+meth public java.lang.String toString()
+meth public static <%0 extends java.lang.Enum<{%%0}>> {%%0} valueOf(java.lang.Class<{%%0}>,java.lang.String)
+supr java.lang.Object
+hfds name,ordinal
+
+CLSS public java.lang.Exception
+cons protected init(java.lang.String,java.lang.Throwable,boolean,boolean)
+cons public init()
+cons public init(java.lang.String)
+cons public init(java.lang.String,java.lang.Throwable)
+cons public init(java.lang.Throwable)
+supr java.lang.Throwable
+hfds serialVersionUID
+
+CLSS public abstract interface java.lang.Iterable<%0 extends java.lang.Object>
+meth public abstract java.util.Iterator<{java.lang.Iterable%0}> iterator()
+meth public java.util.Spliterator<{java.lang.Iterable%0}> spliterator()
+meth public void forEach(java.util.function.Consumer<? super {java.lang.Iterable%0}>)
+
+CLSS public java.lang.Object
+cons public init()
+meth protected java.lang.Object clone() throws java.lang.CloneNotSupportedException
+meth protected void finalize() throws java.lang.Throwable
+ anno 0 java.lang.Deprecated(boolean forRemoval=false, java.lang.String since="9")
+meth public boolean equals(java.lang.Object)
+meth public final java.lang.Class<?> getClass()
+meth public final void notify()
+meth public final void notifyAll()
+meth public final void wait() throws java.lang.InterruptedException
+meth public final void wait(long) throws java.lang.InterruptedException
+meth public final void wait(long,int) throws java.lang.InterruptedException
+meth public int hashCode()
+meth public java.lang.String toString()
+
+CLSS public java.lang.RuntimeException
+cons protected init(java.lang.String,java.lang.Throwable,boolean,boolean)
+cons public init()
+cons public init(java.lang.String)
+cons public init(java.lang.String,java.lang.Throwable)
+cons public init(java.lang.Throwable)
+supr java.lang.Exception
+hfds serialVersionUID
+
+CLSS public java.lang.Throwable
+cons protected init(java.lang.String,java.lang.Throwable,boolean,boolean)
+cons public init()
+cons public init(java.lang.String)
+cons public init(java.lang.String,java.lang.Throwable)
+cons public init(java.lang.Throwable)
+intf java.io.Serializable
+meth public final java.lang.Throwable[] getSuppressed()
+meth public final void addSuppressed(java.lang.Throwable)
+meth public java.lang.StackTraceElement[] getStackTrace()
+meth public java.lang.String getLocalizedMessage()
+meth public java.lang.String getMessage()
+meth public java.lang.String toString()
+meth public java.lang.Throwable fillInStackTrace()
+meth public java.lang.Throwable getCause()
+meth public java.lang.Throwable initCause(java.lang.Throwable)
+meth public void printStackTrace()
+meth public void printStackTrace(java.io.PrintStream)
+meth public void printStackTrace(java.io.PrintWriter)
+meth public void setStackTrace(java.lang.StackTraceElement[])
+supr java.lang.Object
+hfds CAUSE_CAPTION,EMPTY_THROWABLE_ARRAY,NULL_CAUSE_MESSAGE,SELF_SUPPRESSION_MESSAGE,SUPPRESSED_CAPTION,SUPPRESSED_SENTINEL,UNASSIGNED_STACK,backtrace,cause,depth,detailMessage,serialVersionUID,stackTrace,suppressedExceptions
+hcls PrintStreamOrWriter,SentinelHolder,WrappedPrintStream,WrappedPrintWriter
+
+CLSS public abstract interface java.util.Collection<%0 extends java.lang.Object>
+intf java.lang.Iterable<{java.util.Collection%0}>
+meth public <%0 extends java.lang.Object> {%%0}[] toArray(java.util.function.IntFunction<{%%0}[]>)
+meth public abstract <%0 extends java.lang.Object> {%%0}[] toArray({%%0}[])
+meth public abstract boolean add({java.util.Collection%0})
+meth public abstract boolean addAll(java.util.Collection<? extends {java.util.Collection%0}>)
+meth public abstract boolean contains(java.lang.Object)
+meth public abstract boolean containsAll(java.util.Collection<?>)
+meth public abstract boolean equals(java.lang.Object)
+meth public abstract boolean isEmpty()
+meth public abstract boolean remove(java.lang.Object)
+meth public abstract boolean removeAll(java.util.Collection<?>)
+meth public abstract boolean retainAll(java.util.Collection<?>)
+meth public abstract int hashCode()
+meth public abstract int size()
+meth public abstract java.lang.Object[] toArray()
+meth public abstract java.util.Iterator<{java.util.Collection%0}> iterator()
+meth public abstract void clear()
+meth public boolean removeIf(java.util.function.Predicate<? super {java.util.Collection%0}>)
+meth public java.util.Spliterator<{java.util.Collection%0}> spliterator()
+meth public java.util.stream.Stream<{java.util.Collection%0}> parallelStream()
+meth public java.util.stream.Stream<{java.util.Collection%0}> stream()
+
+CLSS public abstract interface java.util.List<%0 extends java.lang.Object>
+intf java.util.Collection<{java.util.List%0}>
+meth public !varargs static <%0 extends java.lang.Object> java.util.List<{%%0}> of({%%0}[])
+ anno 0 java.lang.SafeVarargs()
+meth public abstract <%0 extends java.lang.Object> {%%0}[] toArray({%%0}[])
+meth public abstract boolean add({java.util.List%0})
+meth public abstract boolean addAll(int,java.util.Collection<? extends {java.util.List%0}>)
+meth public abstract boolean addAll(java.util.Collection<? extends {java.util.List%0}>)
+meth public abstract boolean contains(java.lang.Object)
+meth public abstract boolean containsAll(java.util.Collection<?>)
+meth public abstract boolean equals(java.lang.Object)
+meth public abstract boolean isEmpty()
+meth public abstract boolean remove(java.lang.Object)
+meth public abstract boolean removeAll(java.util.Collection<?>)
+meth public abstract boolean retainAll(java.util.Collection<?>)
+meth public abstract int hashCode()
+meth public abstract int indexOf(java.lang.Object)
+meth public abstract int lastIndexOf(java.lang.Object)
+meth public abstract int size()
+meth public abstract java.lang.Object[] toArray()
+meth public abstract java.util.Iterator<{java.util.List%0}> iterator()
+meth public abstract java.util.List<{java.util.List%0}> subList(int,int)
+meth public abstract java.util.ListIterator<{java.util.List%0}> listIterator()
+meth public abstract java.util.ListIterator<{java.util.List%0}> listIterator(int)
+meth public abstract void add(int,{java.util.List%0})
+meth public abstract void clear()
+meth public abstract {java.util.List%0} get(int)
+meth public abstract {java.util.List%0} remove(int)
+meth public abstract {java.util.List%0} set(int,{java.util.List%0})
+meth public java.util.Spliterator<{java.util.List%0}> spliterator()
+meth public static <%0 extends java.lang.Object> java.util.List<{%%0}> copyOf(java.util.Collection<? extends {%%0}>)
+meth public static <%0 extends java.lang.Object> java.util.List<{%%0}> of()
+meth public static <%0 extends java.lang.Object> java.util.List<{%%0}> of({%%0})
+meth public static <%0 extends java.lang.Object> java.util.List<{%%0}> of({%%0},{%%0})
+meth public static <%0 extends java.lang.Object> java.util.List<{%%0}> of({%%0},{%%0},{%%0})
+meth public static <%0 extends java.lang.Object> java.util.List<{%%0}> of({%%0},{%%0},{%%0},{%%0})
+meth public static <%0 extends java.lang.Object> java.util.List<{%%0}> of({%%0},{%%0},{%%0},{%%0},{%%0})
+meth public static <%0 extends java.lang.Object> java.util.List<{%%0}> of({%%0},{%%0},{%%0},{%%0},{%%0},{%%0})
+meth public static <%0 extends java.lang.Object> java.util.List<{%%0}> of({%%0},{%%0},{%%0},{%%0},{%%0},{%%0},{%%0})
+meth public static <%0 extends java.lang.Object> java.util.List<{%%0}> of({%%0},{%%0},{%%0},{%%0},{%%0},{%%0},{%%0},{%%0})
+meth public static <%0 extends java.lang.Object> java.util.List<{%%0}> of({%%0},{%%0},{%%0},{%%0},{%%0},{%%0},{%%0},{%%0},{%%0})
+meth public static <%0 extends java.lang.Object> java.util.List<{%%0}> of({%%0},{%%0},{%%0},{%%0},{%%0},{%%0},{%%0},{%%0},{%%0},{%%0})
+meth public void replaceAll(java.util.function.UnaryOperator<{java.util.List%0}>)
+meth public void sort(java.util.Comparator<? super {java.util.List%0}>)
+
+CLSS public abstract interface java.util.Map<%0 extends java.lang.Object, %1 extends java.lang.Object>
+innr public abstract interface static Entry
+meth public !varargs static <%0 extends java.lang.Object, %1 extends java.lang.Object> java.util.Map<{%%0},{%%1}> ofEntries(java.util.Map$Entry<? extends {%%0},? extends {%%1}>[])
+ anno 0 java.lang.SafeVarargs()
+meth public abstract boolean containsKey(java.lang.Object)
+meth public abstract boolean containsValue(java.lang.Object)
+meth public abstract boolean equals(java.lang.Object)
+meth public abstract boolean isEmpty()
+meth public abstract int hashCode()
+meth public abstract int size()
+meth public abstract java.util.Collection<{java.util.Map%1}> values()
+meth public abstract java.util.Set<java.util.Map$Entry<{java.util.Map%0},{java.util.Map%1}>> entrySet()
+meth public abstract java.util.Set<{java.util.Map%0}> keySet()
+meth public abstract void clear()
+meth public abstract void putAll(java.util.Map<? extends {java.util.Map%0},? extends {java.util.Map%1}>)
+meth public abstract {java.util.Map%1} get(java.lang.Object)
+meth public abstract {java.util.Map%1} put({java.util.Map%0},{java.util.Map%1})
+meth public abstract {java.util.Map%1} remove(java.lang.Object)
+meth public boolean remove(java.lang.Object,java.lang.Object)
+meth public boolean replace({java.util.Map%0},{java.util.Map%1},{java.util.Map%1})
+meth public static <%0 extends java.lang.Object, %1 extends java.lang.Object> java.util.Map$Entry<{%%0},{%%1}> entry({%%0},{%%1})
+meth public static <%0 extends java.lang.Object, %1 extends java.lang.Object> java.util.Map<{%%0},{%%1}> copyOf(java.util.Map<? extends {%%0},? extends {%%1}>)
+meth public static <%0 extends java.lang.Object, %1 extends java.lang.Object> java.util.Map<{%%0},{%%1}> of()
+meth public static <%0 extends java.lang.Object, %1 extends java.lang.Object> java.util.Map<{%%0},{%%1}> of({%%0},{%%1})
+meth public static <%0 extends java.lang.Object, %1 extends java.lang.Object> java.util.Map<{%%0},{%%1}> of({%%0},{%%1},{%%0},{%%1})
+meth public static <%0 extends java.lang.Object, %1 extends java.lang.Object> java.util.Map<{%%0},{%%1}> of({%%0},{%%1},{%%0},{%%1},{%%0},{%%1})
+meth public static <%0 extends java.lang.Object, %1 extends java.lang.Object> java.util.Map<{%%0},{%%1}> of({%%0},{%%1},{%%0},{%%1},{%%0},{%%1},{%%0},{%%1})
+meth public static <%0 extends java.lang.Object, %1 extends java.lang.Object> java.util.Map<{%%0},{%%1}> of({%%0},{%%1},{%%0},{%%1},{%%0},{%%1},{%%0},{%%1},{%%0},{%%1})
+meth public static <%0 extends java.lang.Object, %1 extends java.lang.Object> java.util.Map<{%%0},{%%1}> of({%%0},{%%1},{%%0},{%%1},{%%0},{%%1},{%%0},{%%1},{%%0},{%%1},{%%0},{%%1})
+meth public static <%0 extends java.lang.Object, %1 extends java.lang.Object> java.util.Map<{%%0},{%%1}> of({%%0},{%%1},{%%0},{%%1},{%%0},{%%1},{%%0},{%%1},{%%0},{%%1},{%%0},{%%1},{%%0},{%%1})
+meth public static <%0 extends java.lang.Object, %1 extends java.lang.Object> java.util.Map<{%%0},{%%1}> of({%%0},{%%1},{%%0},{%%1},{%%0},{%%1},{%%0},{%%1},{%%0},{%%1},{%%0},{%%1},{%%0},{%%1},{%%0},{%%1})
+meth public static <%0 extends java.lang.Object, %1 extends java.lang.Object> java.util.Map<{%%0},{%%1}> of({%%0},{%%1},{%%0},{%%1},{%%0},{%%1},{%%0},{%%1},{%%0},{%%1},{%%0},{%%1},{%%0},{%%1},{%%0},{%%1},{%%0},{%%1})
+meth public static <%0 extends java.lang.Object, %1 extends java.lang.Object> java.util.Map<{%%0},{%%1}> of({%%0},{%%1},{%%0},{%%1},{%%0},{%%1},{%%0},{%%1},{%%0},{%%1},{%%0},{%%1},{%%0},{%%1},{%%0},{%%1},{%%0},{%%1},{%%0},{%%1})
+meth public void forEach(java.util.function.BiConsumer<? super {java.util.Map%0},? super {java.util.Map%1}>)
+meth public void replaceAll(java.util.function.BiFunction<? super {java.util.Map%0},? super {java.util.Map%1},? extends {java.util.Map%1}>)
+meth public {java.util.Map%1} compute({java.util.Map%0},java.util.function.BiFunction<? super {java.util.Map%0},? super {java.util.Map%1},? extends {java.util.Map%1}>)
+meth public {java.util.Map%1} computeIfAbsent({java.util.Map%0},java.util.function.Function<? super {java.util.Map%0},? extends {java.util.Map%1}>)
+meth public {java.util.Map%1} computeIfPresent({java.util.Map%0},java.util.function.BiFunction<? super {java.util.Map%0},? super {java.util.Map%1},? extends {java.util.Map%1}>)
+meth public {java.util.Map%1} getOrDefault(java.lang.Object,{java.util.Map%1})
+meth public {java.util.Map%1} merge({java.util.Map%0},{java.util.Map%1},java.util.function.BiFunction<? super {java.util.Map%1},? super {java.util.Map%1},? extends {java.util.Map%1}>)
+meth public {java.util.Map%1} putIfAbsent({java.util.Map%0},{java.util.Map%1})
+meth public {java.util.Map%1} replace({java.util.Map%0},{java.util.Map%1})
+
diff --git a/tck/tck-tests/src/main/resources/jakarta/jsonp/tck/signaturetest/sig-test-pkg-list.txt b/tck/tck-tests/src/main/resources/jakarta/jsonp/tck/signaturetest/sig-test-pkg-list.txt
new file mode 100644
index 0000000..d3704d0
--- /dev/null
+++ b/tck/tck-tests/src/main/resources/jakarta/jsonp/tck/signaturetest/sig-test-pkg-list.txt
@@ -0,0 +1,31 @@
+#
+# Copyright (c) 2021 Oracle and/or its affiliates. All rights reserved.
+#
+# This program and the accompanying materials are made available under the
+# terms of the Eclipse Public License v. 2.0, which is available at
+# http://www.eclipse.org/legal/epl-2.0.
+#
+# This Source Code may also be made available under the following Secondary
+# Licenses when the conditions for such availability set forth in the
+# Eclipse Public License v. 2.0 are satisfied: GNU General Public License,
+# version 2 with the GNU Classpath Exception, which is available at
+# https://www.gnu.org/software/classpath/license.html.
+#
+# SPDX-License-Identifier: EPL-2.0 OR GPL-2.0 WITH Classpath-exception-2.0
+#
+
+#
+# $Id$
+#
+
+##
+# This file contains a list of all the packages
+# contained in the signature files for this
+# deliverable.  This file is used to exclude valid
+# sub-packages from being verified when their
+# parent package's signature is checked.
+##
+
+jakarta.json
+jakarta.json.spi
+jakarta.json.stream
diff --git a/tck/tck-tests/src/main/resources/jakarta/jsonp/tck/signaturetest/sig-test.map b/tck/tck-tests/src/main/resources/jakarta/jsonp/tck/signaturetest/sig-test.map
new file mode 100644
index 0000000..cc71d4e
--- /dev/null
+++ b/tck/tck-tests/src/main/resources/jakarta/jsonp/tck/signaturetest/sig-test.map
@@ -0,0 +1,49 @@
+#
+# Copyright (c) 2021 Oracle and/or its affiliates. All rights reserved.
+#
+# This program and the accompanying materials are made available under the
+# terms of the Eclipse Public License v. 2.0, which is available at
+# http://www.eclipse.org/legal/epl-2.0.
+#
+# This Source Code may also be made available under the following Secondary
+# Licenses when the conditions for such availability set forth in the
+# Eclipse Public License v. 2.0 are satisfied: GNU General Public License,
+# version 2 with the GNU Classpath Exception, which is available at
+# https://www.gnu.org/software/classpath/license.html.
+#
+# SPDX-License-Identifier: EPL-2.0 OR GPL-2.0 WITH Classpath-exception-2.0
+#
+
+#
+# $Id$
+#
+
+###############################################################
+#
+# IMPORTANT:  this sig-test.map file for use with JDK 8 only!
+#             Using this file with other version of JDK will yield errors.
+#
+# The signature test mapping file for the JSON-P 2.0.0 TCK.  This file
+# should be formatted as a standard java properties file.  The
+# name is the package name and the value is the version of the
+# package that should be tested by the signature tests.
+#
+# The resultant signature file name has a name that complies
+# with the following format:
+# <package>.sig_<technology_version>_<JavaSE_version_these_work_with>
+# Given this format, the following example breaks down as follows:
+#    jakarta.json.sig_2.0.0_se8:
+#    jakarta.json.sig_2.0.0_se11:
+#      <package> = jakarta.json
+#      <technology_version> = 2.0.0  (for JSON-P) 
+#      <JavaSE_version_these_work_with> = se8 and se11
+#
+# For this release valid versions are:  "_se8", "_se11", or "_se8_se11"
+# This sig-test.map file is designed to be run using JDK 8 so any
+# signature file that ends with "_se8"  or "se8_se11" will be valid.
+# if a signature file contains only "_se8"  and no reference to "_se11" 
+# in the signature name, than that means that signature file MUST only
+# be referenced when using JDK 8.  
+#
+###############################################################
+jakarta.json=2.1.0