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