8043278: Add initial unit tests for javax.sql.rowset.serial

Reviewed-by: rriggs
diff --git a/jdk/test/java/sql/util/BaseTest.java b/jdk/test/java/sql/util/BaseTest.java
index 2668c48..130dae8 100644
--- a/jdk/test/java/sql/util/BaseTest.java
+++ b/jdk/test/java/sql/util/BaseTest.java
@@ -61,29 +61,31 @@
     public void tearDownMethod() throws Exception {
     }
 
-    /**
+    /*
      * Take some form of SQLException, serialize and deserialize it
-     *
-     * @param <T> SQLException
-     * @param ex SQLException
-     * @return deserialized SQLException
-     * @throws IOException
-     * @throws ClassNotFoundException
      */
     @SuppressWarnings("unchecked")
     protected <T extends SQLException> T
             createSerializedException(T ex)
             throws IOException, ClassNotFoundException {
-        T ex1;
-        ByteArrayOutputStream baos = new ByteArrayOutputStream();
-        try (ObjectOutputStream oos = new ObjectOutputStream(baos) ) {
-            oos.writeObject(ex);
-        }
-        try (ObjectInputStream ois =
-                new ObjectInputStream(new ByteArrayInputStream(baos.toByteArray()))) {
-            ex1 = (T) ois.readObject();
-        }
-        return ex1;
+        return (T) serializeDeserializeObject(ex);
     }
 
+    /*
+     * Utility method to serialize and deserialize an object
+     */
+    @SuppressWarnings("unchecked")
+    protected <T> T serializeDeserializeObject(T o)
+            throws IOException, ClassNotFoundException {
+        T o1;
+        ByteArrayOutputStream baos = new ByteArrayOutputStream();
+        try (ObjectOutputStream oos = new ObjectOutputStream(baos)) {
+            oos.writeObject(o);
+        }
+        try (ObjectInputStream ois
+                = new ObjectInputStream(new ByteArrayInputStream(baos.toByteArray()))) {
+            o1 = (T) ois.readObject();
+        }
+        return o1;
+    }
 }
diff --git a/jdk/test/javax/sql/testng/TEST.properties b/jdk/test/javax/sql/testng/TEST.properties
new file mode 100644
index 0000000..97d1bc3
--- /dev/null
+++ b/jdk/test/javax/sql/testng/TEST.properties
@@ -0,0 +1,2 @@
+# JDBC unit tests uses TestNG
+TestNG.dirs= .
\ No newline at end of file
diff --git a/jdk/test/javax/sql/testng/test/rowset/serial/SerialArrayTests.java b/jdk/test/javax/sql/testng/test/rowset/serial/SerialArrayTests.java
new file mode 100644
index 0000000..077ce43
--- /dev/null
+++ b/jdk/test/javax/sql/testng/test/rowset/serial/SerialArrayTests.java
@@ -0,0 +1,236 @@
+/*
+ * Copyright (c) 2014, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ */
+package test.rowset.serial;
+
+import java.sql.Array;
+import java.sql.SQLException;
+import java.util.Arrays;
+import java.util.HashMap;
+import java.util.Map;
+import javax.sql.rowset.serial.SerialArray;
+import javax.sql.rowset.serial.SerialException;
+import static org.testng.Assert.*;
+import org.testng.annotations.BeforeMethod;
+import org.testng.annotations.Test;
+import util.BaseTest;
+import util.StubArray;
+
+public class SerialArrayTests extends BaseTest {
+
+    private Object[] coffees;
+    private final String sqlType = "VARCHAR";
+    private Array a;
+    private Map<String, Class<?>> map;
+
+    @BeforeMethod
+    public void setUpMethod() throws Exception {
+        coffees = new Object[]{"Espresso", "Colombian", "French Roast",
+            "Cappuccino"};
+        a = new StubArray(sqlType, coffees);
+        map = new HashMap<>();
+    }
+
+    /*
+     * Validate a SerialArray can be created from an Array
+     */
+    @Test
+    public void test01() throws Exception {
+        SerialArray sa = new SerialArray(a);
+    }
+
+    /*
+     * Validate a SQLException is thrown if the map is null
+     */
+    @Test(expectedExceptions = SQLException.class)
+    public void test02() throws Exception {
+        SerialArray sa = new SerialArray(a, null);
+    }
+
+    /*
+     * Validate a SerialException is thrown when getResultSet() is called
+     */
+    @Test(expectedExceptions = SerialException.class)
+    public void test03() throws Exception {
+        SerialArray sa = new SerialArray(a);
+        sa.getResultSet();
+    }
+
+    /*
+     * Validate a SerialException is thrown when getResultSet() is called
+     */
+    @Test(expectedExceptions = SerialException.class)
+    public void test04() throws Exception {
+        SerialArray sa = new SerialArray(a);
+        sa.getResultSet(null);
+    }
+
+    /*
+     * Validate a SerialException is thrown when getResultSet() is called
+     */
+    @Test(expectedExceptions = SerialException.class)
+    public void test05() throws Exception {
+        SerialArray sa = new SerialArray(a);
+        sa.getResultSet(1, 1);
+    }
+
+    /*
+     * Validate a SerialException is thrown when getResultSet() is called
+     */
+    @Test(expectedExceptions = SerialException.class)
+    public void test06() throws Exception {
+        SerialArray sa = new SerialArray(a);
+        sa.getResultSet(1, 1, null);
+    }
+
+    /*
+     * Validate a SerialException is thrown when  getArray() is invoked after
+     * free() is called
+     */
+    @Test(expectedExceptions = SerialException.class)
+    public void test07() throws Exception {
+        SerialArray sa = new SerialArray(a);
+        sa.free();
+        sa.getArray();
+    }
+
+    /*
+     * Validate a SerialException is thrown when  getArray() is invoked after
+     * free() is called
+     */
+    @Test(expectedExceptions = SerialException.class)
+    public void test08() throws Exception {
+        SerialArray sa = new SerialArray(a);
+        sa.free();
+        sa.getArray(map);
+    }
+
+    /*
+     * Validate a SerialException is thrown when  getArray() is invoked after
+     * free() is called
+     */
+    @Test(expectedExceptions = SerialException.class)
+    public void test09() throws Exception {
+        SerialArray sa = new SerialArray(a);
+        sa.free();
+        sa.getArray(1, 1, map);
+    }
+
+    /*
+     * Validate a SerialException is thrown when  getArray() is invoked after
+     * free() is called
+     */
+    @Test(expectedExceptions = SerialException.class)
+    public void test10() throws Exception {
+        SerialArray sa = new SerialArray(a);
+        sa.free();
+        sa.getArray(1, 1);
+    }
+
+    /*
+     * Validate a SerialException is thrown when  getBaseType() is invoked after
+     * free() is called
+     */
+    @Test(expectedExceptions = SerialException.class)
+    public void test11() throws Exception {
+        SerialArray sa = new SerialArray(a);
+        sa.free();
+        sa.getBaseType();
+    }
+
+    /*
+     * Validate a SerialException is thrown when  getBaseTypeName() is invoked after
+     * free() is called
+     */
+    @Test(expectedExceptions = SerialException.class)
+    public void test12() throws Exception {
+        SerialArray sa = new SerialArray(a);
+        sa.free();
+        sa.getBaseTypeName();
+    }
+
+    /*
+     * Validate getArray() returns the same Object[] used to create the
+     * SerialArray
+     */
+    @Test
+    public void test13() throws Exception {
+        SerialArray sa = new SerialArray(a);
+        Object[] o = (Object[]) sa.getArray();
+        assertTrue(Arrays.equals(o, coffees));
+    }
+
+    /*
+     * Validate getArray() returns the same Object[] used to create the
+     * SerialArray
+     */
+    @Test
+    public void test14() throws Exception {
+        SerialArray sa = new SerialArray(a);
+        Object[] o = (Object[]) sa.getArray(map);
+        assertTrue(Arrays.equals(o, coffees));
+    }
+
+    /*
+     * Validate getArray() returns the same Object[] used to create the
+     * SerialArray
+     */
+    @Test
+    public void test15() throws Exception {
+        SerialArray sa = new SerialArray(a);
+        Object[] o = (Object[]) sa.getArray(1, 2);
+        assertTrue(Arrays.equals(o, Arrays.copyOfRange(coffees, 1, 3)));
+    }
+
+    /*
+     * Validate getArray() returns the same Object[] used to create the
+     * SerialArray
+     */
+    @Test
+    public void test16() throws Exception {
+        SerialArray sa = new SerialArray(a);
+        Object[] o = (Object[]) sa.getArray(1, 2, map);
+        assertTrue(Arrays.equals(o, Arrays.copyOfRange(coffees, 1, 3)));
+    }
+
+    /*
+     * clone() a SerialArray and check that it is equal to the
+     * object it was cloned from
+     */
+    @Test
+    public void test17() throws Exception {
+        SerialArray sa = new SerialArray(a);
+        SerialArray sa1 = (SerialArray) sa.clone();
+        assertTrue(sa.equals(sa1));
+    }
+
+    /*
+     * Validate that a SerialArray that is serialized & deserialized is equal to
+     * itself
+     */
+    @Test
+    public void test18() throws Exception {
+        SerialArray sa = new SerialArray(a);
+        SerialArray sa1 = serializeDeserializeObject(sa);;
+        assertTrue(sa.equals(sa1));
+    }
+}
diff --git a/jdk/test/javax/sql/testng/test/rowset/serial/SerialBlobTests.java b/jdk/test/javax/sql/testng/test/rowset/serial/SerialBlobTests.java
new file mode 100644
index 0000000..e080b1c
--- /dev/null
+++ b/jdk/test/javax/sql/testng/test/rowset/serial/SerialBlobTests.java
@@ -0,0 +1,399 @@
+/*
+ * Copyright (c) 2014, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ */
+package test.rowset.serial;
+
+import java.io.InputStream;
+import java.io.OutputStream;
+import java.util.Arrays;
+import javax.sql.rowset.serial.SerialBlob;
+import javax.sql.rowset.serial.SerialException;
+import static org.testng.Assert.*;
+import org.testng.annotations.Test;
+import util.BaseTest;
+import util.StubBlob;
+
+public class SerialBlobTests extends BaseTest {
+
+    // byte[] used to populate SerialBlob
+    private byte[] bytes = new byte[]{1, 2, 3, 4, 5};
+
+    /*
+     * Validate calling free() does not throw an Exception
+     */
+    @Test
+    public void test() throws Exception {
+        SerialBlob sb = new SerialBlob(new StubBlob());
+        sb.free();
+    }
+
+    /*
+     * Validate calling getBinaryStream() after calling free() throws an
+     * SerialException
+     */
+    @Test(expectedExceptions = SerialException.class)
+    public void test01() throws Exception {
+        SerialBlob sb = new SerialBlob(new StubBlob());
+        sb.free();
+        sb.getBinaryStream();
+    }
+
+    /*
+     * Validate calling getBinaryStream() after calling free() throws an
+     * SerialException
+     */
+    @Test(expectedExceptions = SerialException.class)
+    public void test02() throws Exception {
+        SerialBlob sb = new SerialBlob(new StubBlob());
+        sb.free();
+        sb.getBinaryStream(1, 5);
+    }
+
+    /*
+     * Validate calling getBytes() after calling free() throws an
+     * SerialException
+     */
+    @Test(expectedExceptions = SerialException.class)
+    public void test03() throws Exception {
+        SerialBlob sb = new SerialBlob(new StubBlob());
+        sb.free();
+        sb.getBytes(1, 1);
+    }
+
+    /*
+     * Validate calling getLength() after calling free() throws an
+     * SerialException
+     */
+    @Test(expectedExceptions = SerialException.class)
+    public void test04() throws Exception {
+        SerialBlob sb = new SerialBlob(new StubBlob());
+        sb.free();
+        sb.length();
+    }
+
+    /*
+     * Validate calling position() after calling free() throws an
+     * SerialException
+     */
+    @Test(expectedExceptions = SerialException.class)
+    public void test05() throws Exception {
+        SerialBlob sb = new SerialBlob(new StubBlob());
+        sb.free();
+        sb.position(new byte[5], 1);
+    }
+
+    /*
+     * Validate calling position() after calling free() throws an
+     * SerialException
+     */
+    @Test(expectedExceptions = SerialException.class)
+    public void test06() throws Exception {
+        SerialBlob sb = new SerialBlob(new StubBlob());
+        sb.free();
+        sb.position(new StubBlob(), 1);
+    }
+
+    /*
+     * Validate calling free() after calling setBinaryStream() throws an
+     * SerialException
+     */
+    @Test(expectedExceptions = SerialException.class)
+    public void test07() throws Exception {
+        SerialBlob sb = new SerialBlob(new StubBlob());
+        sb.free();
+        sb.setBinaryStream(5);
+    }
+
+    /*
+     * Validate calling free() after calling setBytes() throws an
+     * SerialException
+     */
+    @Test(expectedExceptions = SerialException.class)
+    public void test08() throws Exception {
+        SerialBlob sb = new SerialBlob(new StubBlob());
+        sb.free();
+        sb.setBytes(1, new byte[5]);
+    }
+
+    /*
+     * Validate calling setBytes() after calling free() throws an
+     * SerialException
+     */
+    @Test(expectedExceptions = SerialException.class)
+    public void test09() throws Exception {
+        SerialBlob sb = new SerialBlob(new StubBlob());
+        sb.free();
+        sb.setBytes(1, new byte[10], 0, 5);
+    }
+
+    /*
+     * Validate calling truncate() after calling free() throws an
+     * SerialException
+     */
+    @Test(expectedExceptions = SerialException.class)
+    public void test10() throws Exception {
+        SerialBlob sb = new SerialBlob(new StubBlob());
+        sb.free();
+        sb.truncate(1);
+    }
+
+    /*
+     * Validate getBinaryStream returns the correct bytes
+     */
+    @Test
+    public void test11() throws Exception {
+        byte[] expected = new byte[]{1, 2, 3};
+        SerialBlob sb = new SerialBlob(bytes);
+        InputStream is = sb.getBinaryStream(1, 3);
+        for (byte b : expected) {
+            byte val = (byte) is.read();
+            assertTrue(b == val, val + " does not match " + b);
+        }
+    }
+
+    /*
+     * Validate a SerialException is thrown if pos < 0 for getBinaryStream
+     */
+    @Test(expectedExceptions = SerialException.class)
+    public void test12() throws Exception {
+        SerialBlob sb = new SerialBlob(bytes);
+        InputStream is = sb.getBinaryStream(-1, 3);
+    }
+
+    /*
+     * Validate a SerialException is thrown if pos = 0 for getBinaryStream
+     */
+    @Test(expectedExceptions = SerialException.class)
+    public void test13() throws Exception {
+        SerialBlob sb = new SerialBlob(bytes);
+        InputStream is = sb.getBinaryStream(0, 3);
+    }
+
+    /*
+     * Validate a SerialException is thrown if len > the length of the stream
+     * for getBinaryStream
+     */
+    @Test(expectedExceptions = SerialException.class)
+    public void test14() throws Exception {
+        SerialBlob sb = new SerialBlob(bytes);
+        InputStream is = sb.getBinaryStream(0, 3);
+    }
+
+    /*
+     * Validate a SerialException is thrown if length < 1
+     */
+    @Test(expectedExceptions = SerialException.class)
+    public void test15() throws Exception {
+        SerialBlob sb = new SerialBlob(bytes);
+        InputStream is = sb.getBinaryStream(1, 0);
+    }
+
+    /*
+     * Validate a SerialException is thrown if length > byte array length
+     */
+    @Test(expectedExceptions = SerialException.class)
+    public void test16() throws Exception {
+        SerialBlob sb = new SerialBlob(bytes);
+        InputStream is = sb.getBinaryStream(1, 6);
+    }
+
+    /*
+     * Validate a SerialException is thrown if pos > byte array length
+     */
+    @Test(expectedExceptions = SerialException.class)
+    public void test17() throws Exception {
+        SerialBlob sb = new SerialBlob(bytes);
+        InputStream is = sb.getBinaryStream(bytes.length + 2, 6);
+    }
+
+    /*
+     * Validate that a cloned SerializedBlob bytes match the original
+     */
+    @Test
+    public void test18() throws Exception {
+        SerialBlob sb = new SerialBlob(bytes);
+        SerialBlob sb2 = (SerialBlob) sb.clone();
+        assertTrue(
+                Arrays.equals(sb.getBytes(1, (int) sb.length()),
+                        sb2.getBytes(1, (int) sb2.length())),
+                "arrays do not match ");
+    }
+
+    /*
+     * Test clone after free has been called that the clone is not accessible
+     */
+    @Test(expectedExceptions = SerialException.class)
+    public void test19() throws Exception {
+        SerialBlob sb = new SerialBlob(bytes);
+        sb.free();
+        SerialBlob sb2 = (SerialBlob) sb.clone();
+        InputStream is = sb2.getBinaryStream(1, 3);
+    }
+
+    /*
+     * Validate that a SerialBlob that is serialized & deserialized is equal to
+     * itself
+     */
+    @Test
+    public void test20() throws Exception {
+        SerialBlob sb = new SerialBlob(bytes);
+        SerialBlob sb2 = serializeDeserializeObject(sb);
+        assertTrue(sb.equals(sb2), "SerialBlob not equal");
+    }
+
+    /*
+     * Validate a SerialException is thrown if byte[] is used to
+     * create the SeriablBlob and setBinaryStream is called
+     */
+    @Test(expectedExceptions = SerialException.class)
+    public void test21() throws Exception {
+        SerialBlob sb = new SerialBlob(bytes);
+        sb.setBinaryStream(3);
+    }
+
+    /*
+     * Validate that setBytes will properly write a set of bytes to the
+     * specified location in the SerialBlob and the correct count is returned
+     * for bytes written
+     */
+    @Test
+    public void test22() throws Exception {
+        byte[] diff = new byte[]{7, 8, 9};
+        byte[] expected = new byte[]{1, 7, 8, 9, 5};
+        SerialBlob sb = new SerialBlob(bytes);
+        int written = sb.setBytes(2, diff);
+        assertEquals(written, diff.length);
+        assertTrue(
+                Arrays.equals(sb.getBytes(1, (int) sb.length()),
+                        expected),
+                "arrays do not match ");
+    }
+
+    /*
+     * Validate that setBytes will properly write a set of bytes to the
+     * specified location in the SerialBlob and the correct count is returned
+     * for bytes written
+     */
+    @Test
+    public void test23() throws Exception {
+        int bytesToWrite = 3;
+        byte[] diff = new byte[]{7, 8, 9, 0};
+        byte[] expected = new byte[]{1, 8, 9, 0, 5};
+        SerialBlob sb = new SerialBlob(bytes);
+        int written = sb.setBytes(2, diff, 1, bytesToWrite);
+        assertEquals(written, bytesToWrite);
+        assertTrue(
+                Arrays.equals(sb.getBytes(1, (int) sb.length()),
+                        expected),
+                "arrays do not match ");
+    }
+
+    /*
+     * Validate that truncate reduces the length of the SerlizedBlob to the
+     * specified value
+     */
+    @Test
+    public void test24() throws Exception {
+        SerialBlob sb = new SerialBlob(bytes);
+        sb.truncate(0);
+        assertTrue(sb.length() == 0);
+        sb = new SerialBlob(bytes);
+        sb.truncate(3);
+        assertTrue(sb.length() == 3);
+    }
+
+    /*
+     * Validate getBinaryStream returns the correct bytes
+     */
+    @Test
+    public void test25() throws Exception {
+        byte[] expected = bytes;
+        SerialBlob sb = new SerialBlob(bytes);
+        InputStream is = sb.getBinaryStream();
+        for (byte b : expected) {
+            byte val = (byte) is.read();
+            assertTrue(b == val, val + " does not match " + b);
+        }
+    }
+
+    /*
+     * Validate setBinaryStream returns an OutputStream when passed a Blob
+     */
+    @Test
+    public void test26() throws Exception {
+        SerialBlob sb = new SerialBlob(new StubBlob());
+        OutputStream os = sb.setBinaryStream(0);
+        assertTrue(os != null);
+    }
+
+    /*
+     * Validate that position returns the correct starting location for a
+     * pattern in the SerialBlob
+     */
+    @Test
+    public void test27() throws Exception {
+        long expectedPos = 3; // starting offset is 1 vs 0
+        byte[] pattern = new byte[]{3, 4};
+        SerialBlob sb = new SerialBlob(bytes);
+        long pos = sb.position(pattern, 1);
+        assertEquals(pos, expectedPos);
+    }
+
+    /*
+     * Validate that position returns the correct starting location for a
+     * pattern in the SerialBlob
+     */
+    @Test
+    public void test28() throws Exception {
+        long expectedPos = 3; // starting offset is 1 vs 0
+        byte[] pattern = new byte[]{3, 4, 5};
+        SerialBlob sb = new SerialBlob(bytes);
+        long pos = sb.position(pattern, 2);
+        assertEquals(pos, expectedPos);
+    }
+
+    /*
+     * Validate that position returns the correct starting location for a
+     * pattern in the SerialBlob
+     */
+    @Test
+    public void test29() throws Exception {
+        long expectedPos = 2; // starting offset is 1 vs 0
+        byte[] pattern = new byte[]{4, 6};
+        SerialBlob sb = new SerialBlob(new StubBlob());
+        long pos = sb.position(pattern, 1);
+        assertEquals(pos, expectedPos);
+    }
+
+    /*
+     * Validate that position returns the correct starting location for a
+     * pattern in the SerialBlob
+     */
+    @Test
+    public void test30() throws Exception {
+        long expectedPos = 3; // starting offset is 1 vs 0
+        byte[] pattern = new byte[]{6, 8};
+        SerialBlob sb = new SerialBlob(new StubBlob());
+        long pos = sb.position(pattern, 2);
+        assertEquals(pos, expectedPos);
+    }
+}
diff --git a/jdk/test/javax/sql/testng/test/rowset/serial/SerialClobTests.java b/jdk/test/javax/sql/testng/test/rowset/serial/SerialClobTests.java
new file mode 100644
index 0000000..72f4267
--- /dev/null
+++ b/jdk/test/javax/sql/testng/test/rowset/serial/SerialClobTests.java
@@ -0,0 +1,499 @@
+/*
+ * Copyright (c) 2014, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ */
+package test.rowset.serial;
+
+import java.io.InputStream;
+import java.io.OutputStream;
+import java.io.Reader;
+import java.io.Writer;
+import javax.sql.rowset.serial.SerialClob;
+import javax.sql.rowset.serial.SerialException;
+import static org.testng.Assert.*;
+import org.testng.annotations.Test;
+import util.BaseTest;
+import util.StubClob;
+
+public class SerialClobTests extends BaseTest {
+
+    // char[] used to populate SerialClob
+    private final char[] chars;
+
+    public SerialClobTests() {
+        this.chars = new char[]{'h', 'e', 'l', 'l', 'o', ' ', 'w',
+            'o', 'r', 'l', 'd'};
+    }
+
+    /*
+     * Validate calling free() does not throw an Exception
+     */
+    @Test
+    public void test() throws Exception {
+        SerialClob sc = new SerialClob(new StubClob());
+        sc.free();
+    }
+
+    /*
+     * Validate calling getCharacterStream() after calling free() throws an
+     * SerialException
+     */
+    @Test(expectedExceptions = SerialException.class)
+    public void test01() throws Exception {
+        SerialClob sc = new SerialClob(new StubClob());
+        sc.free();
+        sc.getCharacterStream();
+    }
+
+    /*
+     * Validate calling getCharacterStream() after calling free() throws an
+     * SerialException
+     */
+    @Test(expectedExceptions = SerialException.class)
+    public void test02() throws Exception {
+        SerialClob sc = new SerialClob(chars);
+        sc.free();
+        sc.getCharacterStream();
+    }
+
+    /*
+     * Validate calling getCharacterStream() after calling free() throws an
+     * SerialException
+     */
+    @Test(expectedExceptions = SerialException.class)
+    public void test03() throws Exception {
+        SerialClob sc = new SerialClob(new StubClob());
+        sc.free();
+        sc.getCharacterStream(1, 5);
+    }
+
+    /*
+     * Validate calling getSubString() after calling free() throws an
+     * SerialException
+     */
+    @Test(expectedExceptions = SerialException.class)
+    public void test04() throws Exception {
+        SerialClob sc = new SerialClob(new StubClob());
+        sc.free();
+        sc.getSubString(1, 1);
+    }
+
+    /*
+     * Validate calling truncate() after calling free() throws an
+     * SerialException
+     */
+    @Test(expectedExceptions = SerialException.class)
+    public void test05() throws Exception {
+        SerialClob sc = new SerialClob(new StubClob());
+        sc.free();
+        sc.truncate(1);
+    }
+
+    /*
+     * Validate calling getAsciiStream() after calling free() throws an
+     * SerialException
+     */
+    @Test(expectedExceptions = SerialException.class)
+    public void test06() throws Exception {
+        SerialClob sc = new SerialClob(new StubClob());
+        sc.free();
+        sc.getAsciiStream();
+    }
+
+    /*
+     * Validate calling length() after calling free() throws an SerialException
+     */
+    @Test(expectedExceptions = SerialException.class)
+    public void test07() throws Exception {
+        SerialClob sc = new SerialClob(new StubClob());
+        sc.free();
+        sc.length();
+    }
+
+    /*
+     * Validate calling position() after calling free() throws an
+     * SerialException
+     */
+    @Test(expectedExceptions = SerialException.class)
+    public void test08() throws Exception {
+        SerialClob sc = new SerialClob(new StubClob());
+        sc.free();
+        sc.position("hello", 1);
+    }
+
+    /*
+     * Validate calling position() after calling free() throws an
+     * SerialException
+     */
+    @Test(expectedExceptions = SerialException.class)
+    public void test09() throws Exception {
+        SerialClob sc = new SerialClob(new StubClob());
+        sc.free();
+        sc.position(new StubClob(), 1);
+    }
+
+    /*
+     * Validate calling setAsciiStream() after calling free() throws an
+     * SerialException
+     */
+    @Test(expectedExceptions = SerialException.class)
+    public void test10() throws Exception {
+        SerialClob sc = new SerialClob(new StubClob());
+        sc.free();
+        sc.setAsciiStream(5);
+    }
+
+    /*
+     * Validate calling setCharacterStream() after calling free() throws an
+     * SerialException
+     */
+    @Test(expectedExceptions = SerialException.class)
+    public void test11() throws Exception {
+        SerialClob sc = new SerialClob(new StubClob());
+        sc.free();
+        sc.setCharacterStream(5);
+    }
+
+    /*
+     * Validate calling setString() after calling free() throws an
+     * SerialException
+     */
+    @Test(expectedExceptions = SerialException.class)
+    public void test12() throws Exception {
+        SerialClob sc = new SerialClob(new StubClob());
+        sc.free();
+        sc.setString(1, "hello");
+    }
+
+    /*
+     * Validate calling setString() after calling free() throws an
+     * SerialException
+     */
+    @Test(expectedExceptions = SerialException.class)
+    public void test13() throws Exception {
+        SerialClob sc = new SerialClob(new StubClob());
+        sc.free();
+        sc.setString(1, "hello", 0, 5);
+    }
+
+    /*
+     * Test that SerialException is thrown if pos < 0 on a call to
+     * getCharacterStream
+     */
+    @Test(expectedExceptions = SerialException.class)
+    public void test14() throws Exception {
+        SerialClob sc = new SerialClob(chars);
+        sc.getCharacterStream(-1, 5);
+    }
+
+    /*
+     * Test that SerialException is thrown if pos = 0 on a call to
+     * getCharacterStream
+     */
+    @Test(expectedExceptions = SerialException.class)
+    public void test15() throws Exception {
+        SerialClob sc = new SerialClob(chars);
+        sc.getCharacterStream(0, 5);
+    }
+
+    /*
+     * Test that SerialException is thrown if pos = 0 on a call to
+     * getCharacterStream
+     */
+    @Test(expectedExceptions = SerialException.class)
+    public void test16() throws Exception {
+        SerialClob sc = new SerialClob(chars);
+        sc.getCharacterStream(1, 100);
+    }
+
+    /*
+     * Test that SerialException is thrown if length = 0 on a call to
+     * getCharacterStream
+     */
+    @Test(expectedExceptions = SerialException.class)
+    public void test17() throws Exception {
+        SerialClob sc = new SerialClob(chars);
+        sc.getCharacterStream(1, 0);
+    }
+
+    /*
+     * Test that SerialException is thrown if pos > length on a call to
+     * getCharacterStream
+     */
+    @Test(expectedExceptions = SerialException.class)
+    public void test18() throws Exception {
+        SerialClob sc = new SerialClob(chars);
+        sc.getCharacterStream(100, 5);
+    }
+
+    /*
+     * Clone a SerialClob and check that it is equal to itself
+     */
+    @Test
+    public void test19() throws Exception {
+        SerialClob sc = new SerialClob(chars);
+        SerialClob sc1 = (SerialClob) sc.clone();
+        assertTrue(sc.equals(sc1), "SerialClobs not equal");
+    }
+
+    /*
+     * Validate that a getAsciiStream() returns an InputStream when a Clob is
+     * used to create the SerialClob
+     */
+    @Test
+    public void test20() throws Exception {
+        SerialClob sc = new SerialClob(new StubClob());
+        InputStream is = sc.getAsciiStream();
+        assertTrue(is != null);
+    }
+
+    /*
+     * Validate that a getCharacterStream() returns an Reader when a Clob is
+     * used to create the SerialClob
+     */
+    @Test
+    public void test21() throws Exception {
+        SerialClob sc = new SerialClob(new StubClob());
+        Reader is = sc.getCharacterStream();
+        assertTrue(is != null);
+    }
+
+    /*
+     * Validate that a getCharacterStream() returns an Reader when a char[] is
+     * used to create the SerialClob
+     */
+    @Test
+    public void test22() throws Exception {
+        SerialClob sc = new SerialClob(chars);
+        Reader is = sc.getCharacterStream();
+        assertTrue(is != null);
+    }
+
+    /*
+     * Validate that a getSubString() returns the correct value when a char[] is
+     * used to create the SerialClob
+     */
+    @Test
+    public void test23() throws Exception {
+        SerialClob sc = new SerialClob(chars);
+        String expected = "world";
+        assertEquals(expected, sc.getSubString(7, 5));
+    }
+
+    /*
+     * Validate that a getSubString() returns the correct value when a Clob is
+     * used to create the SerialClob
+     */
+    @Test
+    public void test24() throws Exception {
+        SerialClob sc = new SerialClob(new StubClob());
+        String expected = "test string";
+        assertEquals(expected, sc.getSubString(5, 11));
+    }
+
+    /*
+     * Validate that position() returns the correct value when a Clob is used to
+     * create the SerialClob
+     */
+    @Test
+    public void test25() throws Exception {
+        long expectedPos = 5;
+        SerialClob sc = new SerialClob(new StubClob());
+        String expected = "test string";
+        long pos = sc.position(expected, 1);
+        assertEquals(expectedPos, pos);
+    }
+
+    /*
+     * Validate that position returned is -1 when an the search string is not
+     * part of the SerialClob
+     */
+    @Test
+    public void test26() throws Exception {
+        long expectedPos = -1;
+        SerialClob sc = new SerialClob(chars);
+        String expected = "test string";
+        long pos = sc.position(expected, 1);
+        assertEquals(expectedPos, pos);
+    }
+
+    /*
+     * Validate that position() returned is -1 when an the search string is not
+     * part of the SerialClob
+     */
+    @Test
+    public void test27() throws Exception {
+        long expectedPos = -1;
+        SerialClob sc = new SerialClob(new StubClob());
+        String expected = "I am Batman";
+        long pos = sc.position(expected, 2);
+        assertEquals(expectedPos, pos);
+    }
+
+    /*
+     * Validate that position() returns the correct value when a char[] is used
+     * to create the SerialClob
+     */
+    @Test
+    public void test28() throws Exception {
+        long expectedPos = 2;
+        SerialClob sc = new SerialClob(chars);
+        String expected = "ello";
+        long pos = sc.position(expected, 1);
+        assertEquals(expectedPos, pos);
+    }
+
+    /*
+     * Validate that position() returns the correct value when a SerialClob is
+     * used for the search argument
+     */
+    @Test
+    public void test29() throws Exception {
+        long expectedPos = 21;
+        String expected = "Batman";
+        String buf = "I am Joker, not the Batman, hahaha";
+        SerialClob sc = new SerialClob(expected.toCharArray());
+        SerialClob sc1 = new SerialClob(buf.toCharArray());
+        long pos = sc1.position(sc, 1);
+        assertEquals(expectedPos, pos);
+    }
+
+    /*
+     * Validate that position() returns the correct value when a SerialClob is
+     * used for the search argument
+     */
+    @Test
+    public void test30() throws Exception {
+        long expectedPos = 17;
+        String expected = "012";
+        SerialClob sc = new SerialClob(expected.toCharArray());
+        SerialClob sc1 = new SerialClob(new StubClob());
+        long pos = sc1.position(sc, 1);
+        assertEquals(expectedPos, pos);
+    }
+
+    /*
+     * Check that setString() updates the appropriate characters in the
+     * SerialClob
+     */
+    @Test
+    public void test31() throws Exception {
+        String val = "Hello, I am Bruce Wayne";
+        String val1 = "the Batman!";
+        String expected = "Hello, I am the Batman!";
+        SerialClob sc = new SerialClob(val.toCharArray());
+        int written = sc.setString(13, val1);
+        assertEquals(val1.length(), written);
+        assertTrue(expected.equals(sc.getSubString(1, (int) sc.length())));
+    }
+
+    /*
+     * Check that setString() updates the appropriate characters in the
+     * SerialClob
+     */
+    @Test(enabled = false)
+    public void test32() throws Exception {
+        int expectedWritten = 9;
+        String val = "Hi, I am Catwoman!!!!!!";
+        String val1 = "Hahaha the Joker, who are you?!";
+        String expected = "Hi, I am the Joker!";
+        SerialClob sc = new SerialClob(val.toCharArray());
+        int written = sc.setString(10, val1, 8, expectedWritten+1);
+        assertEquals(written, expectedWritten);
+
+    }
+
+    /*
+     * Check that setCharacterStream() returns a non-null Writer for an
+     * SerialClob created from a Clob
+     */
+    @Test
+    public void test33() throws Exception {
+        SerialClob sc = new SerialClob(new StubClob());
+        Writer w = sc.setCharacterStream(1);
+        assertTrue(w != null);
+    }
+
+    /*
+     * Check that setAsciiStream() returns a non-null OutputStream for an SerialClob
+     * created from a Clob
+     */
+    @Test
+    public void test34() throws Exception {
+        SerialClob sc = new SerialClob(new StubClob());
+        OutputStream os = sc.setAsciiStream(1);
+        assertTrue(os != null);
+    }
+
+    /*
+     * Check that truncate() truncates the length of the SerialClob to the
+     * specified size
+     */
+    @Test
+    public void test35() throws Exception {
+        SerialClob sc = new SerialClob(new StubClob());
+        sc.truncate(0);
+        assertTrue(sc.length() == 0);
+        sc = new SerialClob(chars);
+        sc.truncate(5);
+        assertTrue(sc.length() == 5);
+    }
+
+    /*
+     * Check that getCharacterStream() returns a Reader and that the char[] that
+     * was specified to create the SerialClob can be returned via the Reader
+     */
+    @Test
+    public void test36() throws Exception {
+        SerialClob sc = new SerialClob(chars);
+        Reader r = sc.getCharacterStream();
+        for (char c : chars) {
+            char val = (char) r.read();
+            assertTrue(c == val, val + " does not match " + c);
+        }
+    }
+
+    /*
+     * Check that getCharacterStream() returns a Reader and that the char[] that
+     * was specified to create the SerialClob can be returned via the Reader
+     */
+    @Test(enabled = false)
+    public void test37() throws Exception {
+        SerialClob sc = new SerialClob(chars);
+        String expected = "ello w";
+        Reader r = sc.getCharacterStream(2, 6);
+        for (char c : expected.toCharArray()) {
+            char val = (char) r.read();
+            assertTrue(c == val, val + " does not match " + c);
+        }
+    }
+
+    /*
+     * Validate that a SerialClob that is serialized & deserialized is equal to
+     * itself
+     */
+    @Test
+    public void test38() throws Exception {
+        SerialClob sc = new SerialClob(chars);
+        SerialClob sc2 = serializeDeserializeObject(sc);
+        assertTrue(sc.equals(sc2), "SerialClobs not equal");
+    }
+}
diff --git a/jdk/test/javax/sql/testng/test/rowset/serial/SerialDataLinkTests.java b/jdk/test/javax/sql/testng/test/rowset/serial/SerialDataLinkTests.java
new file mode 100644
index 0000000..8e86d4a
--- /dev/null
+++ b/jdk/test/javax/sql/testng/test/rowset/serial/SerialDataLinkTests.java
@@ -0,0 +1,110 @@
+/*
+ * Copyright (c) 2014, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ */
+package test.rowset.serial;
+
+import java.net.URL;
+import javax.sql.rowset.serial.SerialDatalink;
+import javax.sql.rowset.serial.SerialException;
+import static org.testng.Assert.*;
+import org.testng.annotations.BeforeMethod;
+import org.testng.annotations.Test;
+import util.BaseTest;
+
+public class SerialDataLinkTests extends BaseTest {
+
+    private URL u;
+    private URL u1;
+    private SerialDatalink dl;
+
+    @BeforeMethod
+    public void setUpMethod() throws Exception {
+        u = new URL("http://www.oracle.com/");
+        u1 = new URL("http://www.usatoday.com/");
+        dl = new SerialDatalink(u);
+    }
+
+    /*
+     * Validate that a SerialException is thrown if the URL is null
+     */
+    @Test(expectedExceptions = SerialException.class)
+    public void test() throws Exception {
+        SerialDatalink dl1 = new SerialDatalink(null);
+    }
+
+    /*
+     * Validate that getDatalink() returns the same URL used to create the
+     * SerialDatalink object
+     */
+    @Test
+    public void test01() throws Exception {
+        URL u2 = dl.getDatalink();
+        assertTrue(u2.equals(u));
+        assertTrue(u2.sameFile(u));
+    }
+
+    /*
+     * Validate that URL returned from getDatalink() differs from a URL that was
+     * not used to create the SerialDatalink
+     */
+    @Test
+    public void test02() throws Exception {
+        URL u2 = dl.getDatalink();
+        assertFalse(u2.equals(u1));
+        assertFalse(u2.sameFile(u1));
+    }
+
+    /*
+     * Create a clone of a SerialDatalink and validate that it is equal to the
+     * SerialDatalink it was cloned from
+     */
+    @Test
+    public void test03() throws Exception {
+        SerialDatalink dl2 = (SerialDatalink) dl.clone();
+        assertTrue(dl.equals(dl2));
+        SerialDatalink dl3 = new SerialDatalink(u1);
+        assertFalse(dl2.equals(dl3));
+    }
+
+    /*
+     * Validate that a SerialDatalink that is serialized & deserialized is
+     * equal to itself
+     */
+    @Test
+    public void test04() throws Exception {
+        SerialDatalink dl2 = serializeDeserializeObject(dl);
+        SerialDatalink dl3 = new SerialDatalink(u);
+        assertTrue(dl.equals(dl2));
+        assertTrue(dl3.equals(dl2));
+    }
+
+    /**
+     * Validate that a SerialDatalink that is serialized & deserialized is not equal
+     * to to a SerialDatalink created using a different URL
+     */
+    @Test
+    public void test05() throws Exception {
+        SerialDatalink dl2 = serializeDeserializeObject(dl);
+        SerialDatalink d3 = new SerialDatalink(u1);
+        assertFalse(d3.equals(dl2));
+    }
+}
diff --git a/jdk/test/javax/sql/testng/test/rowset/serial/SerialExceptionTests.java b/jdk/test/javax/sql/testng/test/rowset/serial/SerialExceptionTests.java
new file mode 100644
index 0000000..ff963ae
--- /dev/null
+++ b/jdk/test/javax/sql/testng/test/rowset/serial/SerialExceptionTests.java
@@ -0,0 +1,113 @@
+/*
+ * Copyright (c) 2014, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ */
+package test.rowset.serial;
+
+import java.sql.SQLException;
+import javax.sql.rowset.serial.SerialException;
+import static org.testng.Assert.*;
+import org.testng.annotations.Test;
+import util.BaseTest;
+
+public class SerialExceptionTests extends BaseTest {
+
+    /*
+     * Create SerialException with no-arg constructor
+     */
+    @Test
+    public void test01() {
+        SerialException ex = new SerialException();
+        assertTrue(ex.getMessage() == null
+                && ex.getSQLState() == null
+                && ex.getCause() == null
+                && ex.getErrorCode() == 0);
+    }
+
+    /*
+     * Create SerialException with message
+     */
+    @Test
+    public void test02() {
+        SerialException ex = new SerialException(reason);
+        assertTrue(ex.getMessage().equals(reason)
+                && ex.getSQLState() == null
+                && ex.getCause() == null
+                && ex.getErrorCode() == 0);
+    }
+
+    /*
+     * Validate that the ordering of the returned Exceptions is correct using
+     * for-each loop
+     */
+    @Test
+    public void test03() {
+        SerialException ex = new SerialException("Exception 1");
+        ex.initCause(t1);
+        SerialException ex1 = new SerialException("Exception 2");
+        SerialException ex2 = new SerialException("Exception 3");
+        ex2.initCause(t2);
+        ex.setNextException(ex1);
+        ex.setNextException(ex2);
+        int num = 0;
+        for (Throwable e : ex) {
+            assertTrue(msgs[num++].equals(e.getMessage()));
+        }
+    }
+
+    /*
+     * Validate that the ordering of the returned Exceptions is correct using
+     * traditional while loop
+     */
+    @Test
+    public void test04() {
+        SQLException ex = new SerialException("Exception 1");
+        ex.initCause(t1);
+        SerialException ex1 = new SerialException("Exception 2");
+        SerialException ex2 = new SerialException("Exception 3");
+        ex2.initCause(t2);
+        ex.setNextException(ex1);
+        ex.setNextException(ex2);
+        int num = 0;
+        while (ex != null) {
+            assertTrue(msgs[num++].equals(ex.getMessage()));
+            Throwable c = ex.getCause();
+            while (c != null) {
+                assertTrue(msgs[num++].equals(c.getMessage()));
+                c = c.getCause();
+            }
+            ex = ex.getNextException();
+        }
+    }
+
+    /*
+     * Serialize a SerialException and make sure you can read it back properly
+     */
+    @Test
+    public void test05() throws Exception {
+        SerialException e = new SerialException(reason);
+        SerialException ex1 = createSerializedException(e);
+        assertTrue(ex1.getMessage().equals(reason)
+                && ex1.getSQLState() == null
+                && ex1.getCause() == null
+                && ex1.getErrorCode() == 0);;
+    }
+}
diff --git a/jdk/test/javax/sql/testng/test/rowset/serial/SerialJavaObjectTests.java b/jdk/test/javax/sql/testng/test/rowset/serial/SerialJavaObjectTests.java
new file mode 100644
index 0000000..cc2d184
--- /dev/null
+++ b/jdk/test/javax/sql/testng/test/rowset/serial/SerialJavaObjectTests.java
@@ -0,0 +1,100 @@
+/*
+ * Copyright (c) 2014, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ */
+package test.rowset.serial;
+
+import java.lang.reflect.Field;
+import java.util.Arrays;
+import javax.sql.rowset.RowSetMetaDataImpl;
+import javax.sql.rowset.serial.SerialException;
+import javax.sql.rowset.serial.SerialJavaObject;
+import static org.testng.Assert.*;
+import org.testng.annotations.Test;
+import util.BaseTest;
+
+public class SerialJavaObjectTests extends BaseTest {
+
+    /*
+     * Validate that an NPE is thrown when null is specified to create
+     * the SerialJavaObject
+     */
+    @Test(expectedExceptions = NullPointerException.class)
+    public void test() throws Exception {
+        SerialJavaObject sjo = new SerialJavaObject(null);
+    }
+
+    /*
+     * Validate that an SerialExcepion is thrown when the object specified
+     * contains public static fields
+     */
+    @Test(expectedExceptions = SerialException.class, enabled = false)
+    public void test01() throws Exception {
+        SerialJavaObject sjo = new SerialJavaObject(new RowSetMetaDataImpl());
+    }
+
+    /*
+     * Validate that an getFields()s returns the same Field[] for the object
+     * used to create the SerialJavaObject
+     */
+    @Test
+    public void test02() throws Exception {
+        SerialException e = new SerialException();
+        SerialJavaObject sjo = new SerialJavaObject(e);
+        Field[] f = e.getClass().getFields();
+        assertTrue(Arrays.equals(f, sjo.getFields()));
+        assertFalse(Arrays.equals("hello".getClass().getFields(),
+                sjo.getFields()));
+    }
+
+    /*
+     * clone() a SerialJavaObject and check that it is equal to the
+     * object it was cloned from
+     */
+    @Test
+    public void test03() throws Exception {
+        SerialJavaObject sjo = new SerialJavaObject("Hello");
+        SerialJavaObject sjo2 = (SerialJavaObject) sjo.clone();
+        assertTrue(sjo.equals(sjo2));
+    }
+
+    /**
+     * Validate that a SerialJavaObject that is serialized & deserialized is
+     * equal to itself
+     */
+    @Test
+    public void test04() throws Exception {
+        SerialJavaObject sjo = new SerialJavaObject("Hello");
+        SerialJavaObject sjo2 = serializeDeserializeObject(sjo);
+        assertTrue(sjo.equals(sjo2));
+    }
+
+    /*
+     * Validate that a getObject() returns an object used to create the
+     * SerialJavaObject
+     */
+    @Test
+    public void test05() throws Exception {
+        String s = "Hello world";
+        SerialJavaObject sjo = new SerialJavaObject(s);
+        assertTrue(s.equals(sjo.getObject()));
+    }
+}
diff --git a/jdk/test/javax/sql/testng/test/rowset/serial/SerialRefTests.java b/jdk/test/javax/sql/testng/test/rowset/serial/SerialRefTests.java
new file mode 100644
index 0000000..8f23de7
--- /dev/null
+++ b/jdk/test/javax/sql/testng/test/rowset/serial/SerialRefTests.java
@@ -0,0 +1,131 @@
+/*
+ * Copyright (c) 2014, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ */
+package test.rowset.serial;
+
+import java.sql.Ref;
+import java.sql.SQLException;
+import java.util.HashMap;
+import java.util.Map;
+import javax.sql.rowset.serial.SerialRef;
+import static org.testng.Assert.*;
+import org.testng.annotations.BeforeMethod;
+import org.testng.annotations.Test;
+import util.BaseTest;
+import util.StubRef;
+import util.SuperHero;
+
+public class SerialRefTests extends BaseTest {
+
+    private static Map<String, Class<?>> map = new HashMap<>();
+    private Ref ref;
+    private final String sqlType = "SUPERHERO";
+    private SuperHero hero;
+
+    @BeforeMethod
+    public void setUpMethod() throws Exception {
+        map.put(sqlType, Class.forName("util.SuperHero"));
+        hero = new SuperHero(sqlType, "Bruce", "Wayne", 1939, "Batman");
+        ref = new StubRef(sqlType, hero);
+    }
+
+    /*
+     * Validate that a SQLException() is thrown if the Ref is null
+     */
+    @Test(expectedExceptions = SQLException.class)
+    public void test01() throws Exception {
+        SerialRef sr = new SerialRef(null);
+    }
+
+    /*
+     * Validate that a SQLException() is thrown if the typeName is null in the
+     * Ref used to create the SerialRef
+     */
+    @Test(expectedExceptions = SQLException.class)
+    public void test02() throws Exception {
+        SerialRef sr = new SerialRef(new StubRef(null, hero));
+    }
+
+    /*
+     * Validate that getBaseTypeName() returns the same SQLType specified
+     * to create the Ref
+     */
+    @Test
+    public void test03() throws Exception {
+        SerialRef sr = new SerialRef(ref);
+        assertEquals(sr.getBaseTypeName(), sqlType);
+    }
+
+    /*
+     * Validate that getObject() returns the same object used to create the Ref
+     */
+    @Test
+    public void test04() throws Exception {
+        SerialRef sr = new SerialRef(ref);
+        assertTrue(hero.equals(sr.getObject()));
+    }
+
+    /*
+     * Validate that getObject() returns the same object used to create the Ref
+     */
+    @Test(enabled = false)
+    public void test05() throws Exception {
+        SerialRef sr = new SerialRef(ref);
+        assertTrue(hero.equals(sr.getObject(map)));
+    }
+
+    /*
+     * Validate that setObject() can be used to change the value of the object
+     * pointed to by the SerialRef
+     */
+    @Test
+    public void test06() throws Exception {
+        SerialRef sr = new SerialRef(ref);
+        assertTrue(hero.equals(sr.getObject()));
+        SuperHero h = new SuperHero(sqlType, "Dick", "Grayson", 1940, "Robin");
+        sr.setObject(h);
+        assertFalse(hero.equals(sr.getObject()));
+    }
+
+    /*
+     * clone() a SerialRef and check that it is equal to the
+     * object it was cloned from
+     */
+    @Test
+    public void test09() throws Exception {
+        SerialRef sr = new SerialRef(ref);
+        SerialRef sr1 = (SerialRef) sr.clone();
+        assertTrue(sr.equals(sr1));
+    }
+
+    /**
+     * Validate that a SerialRef that is serialized & deserialized is equal to
+     * itself for the Object & baseTypeName
+     */
+    @Test
+    public void test10() throws Exception {
+        SerialRef sr = new SerialRef(ref);
+        SerialRef sr1 = serializeDeserializeObject(sr);
+        assertTrue(sr1.getObject().equals(sr.getObject())
+                && sr1.getBaseTypeName().equals(sr.getBaseTypeName()));
+    }
+}
diff --git a/jdk/test/javax/sql/testng/test/rowset/serial/SerialStructTests.java b/jdk/test/javax/sql/testng/test/rowset/serial/SerialStructTests.java
new file mode 100644
index 0000000..84a0ff2
--- /dev/null
+++ b/jdk/test/javax/sql/testng/test/rowset/serial/SerialStructTests.java
@@ -0,0 +1,140 @@
+/*
+ * Copyright (c) 2014, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ */
+package test.rowset.serial;
+
+import java.sql.Struct;
+import java.util.Arrays;
+import java.util.HashMap;
+import java.util.Map;
+import javax.sql.rowset.serial.SerialStruct;
+import static org.testng.Assert.*;
+import org.testng.annotations.BeforeMethod;
+import org.testng.annotations.Test;
+import util.BaseTest;
+import util.StubStruct;
+import util.SuperHero;
+
+public class SerialStructTests extends BaseTest {
+
+    private static Map<String, Class<?>> map = new HashMap<>();
+    private Object[] attributes;
+    private Struct struct;
+    private final String sqlType = "SUPERHERO";
+    private SuperHero hero;
+
+    @BeforeMethod
+    public void setUpMethod() throws Exception {
+        attributes = new Object[]{"Bruce", "Wayne", 1939,
+            "Batman"};
+        map.put(sqlType, Class.forName("util.SuperHero"));
+        struct = new StubStruct(sqlType, attributes);
+        hero = new SuperHero(sqlType, "Bruce", "Wayne", 1939, "Batman");
+    }
+
+    /*
+     * Validate that getSQLTypeName() returns the same SQLType specified by
+     * the Struct used to create the object
+     */
+    @Test
+    public void test01() throws Exception {
+        SerialStruct ss = new SerialStruct(struct, map);
+        assertEquals(ss.getSQLTypeName(), sqlType);
+    }
+
+    /*
+     * Validate that getSQLTypeName() returns the same SQLType specified by
+     * the Struct used to create the object
+     */
+    @Test
+    public void test02() throws Exception {
+        SerialStruct ss = new SerialStruct(hero, map);
+        assertEquals(ss.getSQLTypeName(), sqlType);
+    }
+
+    /*
+     * Validate that getAttributes() returns the same attributes specified by
+     * the Struct used to create the object
+     */
+    @Test
+    public void test03() throws Exception {
+        SerialStruct ss = new SerialStruct(struct, map);
+        assertTrue(Arrays.equals(attributes,
+                ss.getAttributes()));
+    }
+
+    /*
+     * Validate that getAttributes() returns the same attributes specified by
+     * the Struct used to create the object
+     */
+    @Test
+    public void test04() throws Exception {
+        SerialStruct ss = new SerialStruct(hero, map);
+        assertTrue(Arrays.equals(attributes,
+                ss.getAttributes()));
+    }
+
+    /*
+     * Validate that getAttributes() returns the
+     same attributes specified by
+     * the Struct used to create the object
+     */
+    @Test
+    public void test05() throws Exception {
+        SerialStruct ss = new SerialStruct(struct, map);
+        assertTrue(Arrays.equals(attributes,
+                ss.getAttributes(map)));
+    }
+
+    /*
+     * Validate that getAttributes() returns the same attributes specified by
+     * the Struct used to create the object
+     */
+    @Test
+    public void test06() throws Exception {
+        SerialStruct ss = new SerialStruct(hero, map);
+        assertTrue(Arrays.equals(attributes,
+                ss.getAttributes(map)));
+    }
+
+    /*
+     * clone() a SerialStruct and check that it is equal to the
+     * object it was cloned from
+     */
+    @Test
+    public void test07() throws Exception {
+        SerialStruct ss = new SerialStruct(struct, map);
+        SerialStruct ss1 = (SerialStruct) ss.clone();
+        assertTrue(ss.equals(ss1));
+    }
+
+    /**
+     * Validate that a SerialStruct that is serialized & deserialized is equal
+     * to itself
+     */
+    @Test
+    public void test08() throws Exception {
+        SerialStruct ss = new SerialStruct(struct, map);
+        SerialStruct ss1 = serializeDeserializeObject(ss);;
+        assertTrue(ss.equals(ss1));
+    }
+}
diff --git a/jdk/test/javax/sql/testng/util/BaseTest.java b/jdk/test/javax/sql/testng/util/BaseTest.java
new file mode 100644
index 0000000..130dae8
--- /dev/null
+++ b/jdk/test/javax/sql/testng/util/BaseTest.java
@@ -0,0 +1,91 @@
+/*
+ * Copyright (c) 2014, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ */
+package util;
+
+import java.io.ByteArrayInputStream;
+import java.io.ByteArrayOutputStream;
+import java.io.IOException;
+import java.io.ObjectInputStream;
+import java.io.ObjectOutputStream;
+import java.sql.SQLException;
+import org.testng.annotations.AfterClass;
+import org.testng.annotations.AfterMethod;
+import org.testng.annotations.BeforeClass;
+import org.testng.annotations.BeforeMethod;
+
+public class BaseTest {
+
+    protected final String reason = "reason";
+    protected final String state = "SQLState";
+    protected final String cause = "java.lang.Throwable: cause";
+    protected final Throwable t = new Throwable("cause");
+    protected final Throwable t1 = new Throwable("cause 1");
+    protected final Throwable t2 = new Throwable("cause 2");
+    protected final int errorCode = 21;
+    protected final String[] msgs = {"Exception 1", "cause 1", "Exception 2",
+        "Exception 3", "cause 2"};
+
+    @BeforeClass
+    public static void setUpClass() throws Exception {
+    }
+
+    @AfterClass
+    public static void tearDownClass() throws Exception {
+    }
+
+    @BeforeMethod
+    public void setUpMethod() throws Exception {
+    }
+
+    @AfterMethod
+    public void tearDownMethod() throws Exception {
+    }
+
+    /*
+     * Take some form of SQLException, serialize and deserialize it
+     */
+    @SuppressWarnings("unchecked")
+    protected <T extends SQLException> T
+            createSerializedException(T ex)
+            throws IOException, ClassNotFoundException {
+        return (T) serializeDeserializeObject(ex);
+    }
+
+    /*
+     * Utility method to serialize and deserialize an object
+     */
+    @SuppressWarnings("unchecked")
+    protected <T> T serializeDeserializeObject(T o)
+            throws IOException, ClassNotFoundException {
+        T o1;
+        ByteArrayOutputStream baos = new ByteArrayOutputStream();
+        try (ObjectOutputStream oos = new ObjectOutputStream(baos)) {
+            oos.writeObject(o);
+        }
+        try (ObjectInputStream ois
+                = new ObjectInputStream(new ByteArrayInputStream(baos.toByteArray()))) {
+            o1 = (T) ois.readObject();
+        }
+        return o1;
+    }
+}
diff --git a/jdk/test/javax/sql/testng/util/StubArray.java b/jdk/test/javax/sql/testng/util/StubArray.java
new file mode 100644
index 0000000..1d2ef0e
--- /dev/null
+++ b/jdk/test/javax/sql/testng/util/StubArray.java
@@ -0,0 +1,99 @@
+/*
+ * Copyright (c) 2014, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ */
+package util;
+
+import java.sql.Array;
+import java.sql.JDBCType;
+import java.sql.ResultSet;
+import java.sql.SQLException;
+import java.util.Arrays;
+import java.util.Map;
+
+public class StubArray implements Array {
+
+    private String typeName;
+    Object[] elements;
+
+    public StubArray(String name, Object[] values) {
+        typeName = name;
+        elements = Arrays.copyOf(values, values.length);
+
+    }
+
+    @Override
+    public String getBaseTypeName() throws SQLException {
+        return typeName;
+    }
+
+    @Override
+    public int getBaseType() throws SQLException {
+        return JDBCType.valueOf(typeName).getVendorTypeNumber();
+    }
+
+    @Override
+    public Object getArray() throws SQLException {
+        return Arrays.copyOf(elements, elements.length);
+    }
+
+    @Override
+    public Object getArray(Map<String, Class<?>> map) throws SQLException {
+        return getArray();
+    }
+
+    @Override
+    public Object getArray(long index, int count) throws SQLException {
+        return getArray();
+    }
+
+    @Override
+    public Object getArray(long index, int count, Map<String, Class<?>> map) throws SQLException {
+        return getArray();
+    }
+
+    @Override
+    public ResultSet getResultSet() throws SQLException {
+        throw new UnsupportedOperationException("Not supported yet.");
+    }
+
+    @Override
+    public ResultSet getResultSet(Map<String, Class<?>> map) throws SQLException {
+        throw new UnsupportedOperationException("Not supported yet.");
+    }
+
+    @Override
+    public ResultSet getResultSet(long index, int count) throws SQLException {
+        throw new UnsupportedOperationException("Not supported yet.");
+    }
+
+    @Override
+    public ResultSet getResultSet(long index, int count, Map<String, Class<?>> map) throws SQLException {
+        throw new UnsupportedOperationException("Not supported yet.");
+    }
+
+    @Override
+    public void free() throws SQLException {
+        elements = null;
+        typeName = null;
+    }
+
+}
diff --git a/jdk/test/javax/sql/testng/util/StubBlob.java b/jdk/test/javax/sql/testng/util/StubBlob.java
new file mode 100644
index 0000000..727e8a9
--- /dev/null
+++ b/jdk/test/javax/sql/testng/util/StubBlob.java
@@ -0,0 +1,100 @@
+/*
+ * Copyright (c) 2014, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ */
+package util;
+
+import java.io.ByteArrayOutputStream;
+import java.io.IOException;
+import java.io.InputStream;
+import java.io.ObjectOutputStream;
+import java.io.OutputStream;
+import java.sql.Blob;
+import java.sql.SQLException;
+import java.util.Arrays;
+import java.util.logging.Level;
+import java.util.logging.Logger;
+
+public class StubBlob implements Blob {
+
+    private byte[] bytes;
+
+    public StubBlob() {
+        bytes = new byte[]{2, 4, 6, 8};
+    }
+
+    public long length() throws SQLException {
+        return bytes.length;
+    }
+
+    public byte[] getBytes(long pos, int length)
+            throws SQLException {
+        return Arrays.copyOfRange(bytes, (int) pos - 1, length);
+    }
+
+    public InputStream getBinaryStream()
+            throws SQLException {
+        return null;
+    }
+
+    public long position(byte[] pattern, long start)
+            throws SQLException {
+        return 0;
+    }
+
+    public long position(Blob pattern, long start)
+            throws SQLException {
+        return 0;
+    }
+
+    public int setBytes(long pos, byte[] bytes)
+            throws SQLException {
+        return 0;
+    }
+
+    public int setBytes(long pos, byte[] bytes, int offset, int len)
+            throws SQLException {
+        return 0;
+    }
+
+    public OutputStream setBinaryStream(long pos)
+            throws SQLException {
+        ByteArrayOutputStream baos = new ByteArrayOutputStream();
+        ObjectOutputStream oos = null;
+        try {
+            oos = new ObjectOutputStream(baos);
+        } catch (IOException ex) {
+            Logger.getLogger(StubBlob.class.getName()).log(Level.SEVERE, null, ex);
+        }
+        return oos;
+    }
+
+    public void truncate(long len)
+            throws SQLException {
+    }
+
+    public void free() throws SQLException {
+    }
+
+    public InputStream getBinaryStream(long pos, long length) throws SQLException {
+        return null;
+    }
+}
diff --git a/jdk/test/javax/sql/testng/util/StubClob.java b/jdk/test/javax/sql/testng/util/StubClob.java
new file mode 100644
index 0000000..cb1e0c0
--- /dev/null
+++ b/jdk/test/javax/sql/testng/util/StubClob.java
@@ -0,0 +1,113 @@
+/*
+ * Copyright (c) 2014, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ */
+package util;
+
+import java.io.ByteArrayOutputStream;
+import java.io.IOException;
+import java.io.InputStream;
+import java.io.ObjectOutputStream;
+import java.io.OutputStream;
+import java.io.Reader;
+import java.io.StringReader;
+import java.io.StringWriter;
+import java.io.Writer;
+import java.sql.Clob;
+import java.sql.SQLException;
+import java.util.logging.Level;
+import java.util.logging.Logger;
+
+public class StubClob implements Clob {
+
+    public String buf = "The test string 0123456789";
+
+    @Override
+    public String getSubString(long pos, int length) throws SQLException {
+        return buf;
+    }
+
+    @Override
+    public long length() throws SQLException {
+        return buf.length();
+    }
+
+    @Override
+    public Reader getCharacterStream() throws SQLException {
+        return new StringReader(buf);
+    }
+
+    @Override
+    public InputStream getAsciiStream() throws SQLException {
+        return new java.io.StringBufferInputStream(buf);
+    }
+
+    @Override
+    public int setString(long pos, String str) throws SQLException {
+        return str.length();
+    }
+
+    @Override
+    public int setString(long pos, String str, int offset, int len) throws SQLException {
+        return len;
+    }
+
+    @Override
+    public long position(String searchstr, long start) throws SQLException {
+        throw new UnsupportedOperationException("Not supported yet.");
+    }
+
+    @Override
+    public long position(Clob searchstr, long start) throws SQLException {
+        throw new UnsupportedOperationException("Not supported yet.");
+    }
+
+    @Override
+    public OutputStream setAsciiStream(long pos) throws SQLException {
+        ByteArrayOutputStream baos = new ByteArrayOutputStream();
+        ObjectOutputStream oos = null;
+        try {
+            oos = new ObjectOutputStream(baos);
+        } catch (IOException ex) {
+            Logger.getLogger(StubBlob.class.getName()).log(Level.SEVERE, null, ex);
+        }
+        return oos;
+    }
+
+    @Override
+    public Writer setCharacterStream(long pos) throws SQLException {
+        return new StringWriter();
+    }
+
+    @Override
+    public void truncate(long len) throws SQLException {
+        throw new UnsupportedOperationException("Not supported yet.");
+    }
+
+    @Override
+    public void free() throws SQLException {
+    }
+
+    @Override
+    public Reader getCharacterStream(long pos, long length) throws SQLException {
+        throw new UnsupportedOperationException("Not supported yet.");
+    }
+}
diff --git a/jdk/test/javax/sql/testng/util/StubRef.java b/jdk/test/javax/sql/testng/util/StubRef.java
new file mode 100644
index 0000000..052bd92
--- /dev/null
+++ b/jdk/test/javax/sql/testng/util/StubRef.java
@@ -0,0 +1,60 @@
+/*
+ * Copyright (c) 2014, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ */
+package util;
+
+import java.io.Serializable;
+import java.sql.Ref;
+import java.sql.SQLException;
+import java.util.Map;
+
+public class StubRef implements Ref, Serializable {
+
+    private final String baseTypeName;
+    private Object obj;
+
+    public StubRef(String type, Object o) {
+        baseTypeName = type;
+        obj = o;
+    }
+
+    @Override
+    public String getBaseTypeName() throws SQLException {
+        return baseTypeName;
+    }
+
+    @Override
+    public Object getObject(Map<String, Class<?>> map) throws SQLException {
+        return obj;
+    }
+
+    @Override
+    public Object getObject() throws SQLException {
+        return getObject(null);
+    }
+
+    @Override
+    public void setObject(Object value) throws SQLException {
+        obj = value;
+    }
+
+}
diff --git a/jdk/test/javax/sql/testng/util/StubStruct.java b/jdk/test/javax/sql/testng/util/StubStruct.java
new file mode 100644
index 0000000..1dee802
--- /dev/null
+++ b/jdk/test/javax/sql/testng/util/StubStruct.java
@@ -0,0 +1,55 @@
+/*
+ * Copyright (c) 2014, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ */
+package util;
+
+import java.sql.SQLException;
+import java.sql.Struct;
+import java.util.Arrays;
+import java.util.Map;
+
+public class StubStruct implements Struct {
+
+    private final String type;
+    private final Object[] attribs;
+
+    public StubStruct(String type, Object[] o) {
+        this.type = type;
+        this.attribs = Arrays.copyOf(o, o.length);
+    }
+
+    @Override
+    public String getSQLTypeName() throws SQLException {
+        return type;
+    }
+
+    @Override
+    public Object[] getAttributes() throws SQLException {
+        return attribs;
+    }
+
+    @Override
+    public Object[] getAttributes(Map<String, Class<?>> map) throws SQLException {
+        return attribs;
+    }
+
+}
diff --git a/jdk/test/javax/sql/testng/util/SuperHero.java b/jdk/test/javax/sql/testng/util/SuperHero.java
new file mode 100644
index 0000000..8588f50
--- /dev/null
+++ b/jdk/test/javax/sql/testng/util/SuperHero.java
@@ -0,0 +1,106 @@
+/*
+ * Copyright (c) 2014, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ */
+package util;
+
+import java.io.Serializable;
+import java.sql.SQLData;
+import java.sql.SQLException;
+import java.sql.SQLInput;
+import java.sql.SQLOutput;
+
+public class SuperHero implements SQLData, Serializable {
+
+    private String first;
+    private String last;
+    private final String type;
+    private Integer firstYear;
+    private String secretIdentity;
+
+    public SuperHero(String sqlType, String fname, String lname, Integer year,
+            String identity) {
+        first = fname;
+        last = lname;
+        type = sqlType;
+        firstYear = year;
+        secretIdentity = identity;
+    }
+
+    @Override
+    public String getSQLTypeName() throws SQLException {
+        return type;
+    }
+
+    @Override
+    public void readSQL(SQLInput stream, String typeName) throws SQLException {
+        first = stream.readString();
+        last = stream.readString();
+        firstYear = stream.readInt();
+        secretIdentity = stream.readString();
+    }
+
+    @Override
+    public void writeSQL(SQLOutput stream) throws SQLException {
+        stream.writeString(first);
+        stream.writeString(last);
+        stream.writeInt(firstYear);
+        stream.writeString(secretIdentity);
+    }
+
+    @Override
+    public String toString() {
+        return "[ name =" + first + " " + last + " "
+                + firstYear + " " + secretIdentity + " ]";
+    }
+
+    public void setIdentity(String identity) {
+        secretIdentity = identity;
+    }
+
+    public String getIdentity() {
+        return secretIdentity;
+    }
+
+    @Override
+    public boolean equals(Object obj) {
+        if (this == obj) {
+            return true;
+        }
+        if (obj instanceof SuperHero) {
+            SuperHero ss = (SuperHero) obj;
+            return first.equals(ss.first) && last.equals(ss.last)
+                    && firstYear.equals(ss.firstYear)
+                    && type.equals(ss.type)
+                    && secretIdentity.equals(ss.secretIdentity);
+        }
+        return false;
+    }
+
+    @Override
+    public int hashCode() {
+        return ((31 + first.hashCode()) * 31) * 31
+                + ((31 + last.hashCode()) * 31) * 31
+                + ((31 + firstYear.hashCode()) * 31) * 31
+                + ((31 + type.hashCode()) * 31) * 31
+                + secretIdentity.hashCode();
+    }
+}