test/sun/security/util/Oid/S11N.java

Print this page

        

@@ -22,23 +22,22 @@
  */
 
 /*
  * @test
  * @bug 4811968 6908628 8006564
- * @modules java.base/sun.misc
- *          java.base/sun.security.util
+ * @modules java.base/sun.security.util
  * @run main S11N check
  * @summary Serialization compatibility with old versions (and fixes)
  */
 
 import java.io.ByteArrayInputStream;
 import java.io.ByteArrayOutputStream;
 import java.io.ObjectInputStream;
 import java.io.ObjectOutputStream;
+import java.lang.reflect.Method;
 import java.util.HashMap;
 import java.util.Map;
-import sun.misc.BASE64Encoder;
 import sun.security.util.ObjectIdentifier;
 
 public class S11N {
     static String[] SMALL= {
         "0.0",

@@ -54,18 +53,10 @@
         "1.2.2147483648.4",
         "2.3.4444444444444444444444",
         "1.2.8888888888888888.33333333333333333.44444444444444",
     };
 
-    // Do not use j.u.Base64, the test needs to run in jdk6
-    static BASE64Encoder encoder = new BASE64Encoder() {
-        @Override
-        protected int bytesPerLine() {
-            return 48;
-        }
-    };
-
     public static void main(String[] args) throws Exception {
         if (args[0].equals("check")) {
             int version = Integer.valueOf(System.getProperty("java.version")
                     .split("\\.")[1]);
             System.out.println("version is " + version);

@@ -112,16 +103,16 @@
         }
     }
 
     // Gets the serialized form for jdk6
     private static byte[] out6(String oid) throws Exception {
-        return new sun.misc.BASE64Decoder().decodeBuffer(dump6.get(oid));
+        return getCoder().decode(dump6.get(oid));
     }
 
     // Gets the serialized form for jdk7
     private static byte[] out7(String oid) throws Exception {
-        return new sun.misc.BASE64Decoder().decodeBuffer(dump7.get(oid));
+        return getCoder().decode(dump7.get(oid));
     }
 
     // Gets the serialized form for this java
     private static byte[] out(String oid) throws Exception {
         ByteArrayOutputStream bout = new ByteArrayOutputStream();

@@ -139,20 +130,81 @@
     }
 
     // dump serialized form to java code style text
     private static void dump(String title, String[] oids) throws Exception {
         for (String oid: oids) {
-            String[] base64 = encoder.encodeBuffer(out(oid)).split("\n");
-            System.out.println("        " + title + ".put(\"" + oid + "\",");
-            for (int i = 0; i<base64.length; i++) {
-                System.out.print("            \"" + base64[i] + "\"");
-                if (i == base64.length - 1) {
-                    System.out.println(");");
-                } else {
-                    System.out.println(" +");
+            String base64 = getCoder().encode(out(oid)).replaceAll("\n", "");
+
+            System.out.format("        %s.put(\"%s\",%n            \"", title, oid);
+            for (int i=0; i<base64.length(); i++) {
+                System.out.format("%s", base64.charAt(i));
+                if (i == base64.length() - 1)
+                    System.out.format("\");%n");
+                else if (i != 0 && (i+1) % 64 == 0)
+                    System.out.format("\" +%n            \"");
+            }
+        }
+    }
+
+    // Reflective use of Base64 coders so the test can compile/run on older JDKs
+    interface Coder {
+        String encode(byte bytes[]) throws Exception;
+        byte[] decode(String src) throws Exception;
+    }
+
+    static Coder getCoder() {
+        try {
+            return new JavaUtilBase64Coder();
+        } catch (ClassNotFoundException x) {
+            return new SunMiscBase64Coder();
+        }
+    }
+
+    static class JavaUtilBase64Coder implements Coder {
+        final Object encoder, decoder;
+        final Method encodeMethod, decodeMethod;
+
+        JavaUtilBase64Coder() throws ClassNotFoundException {
+            Class<?> c = Class.forName("java.util.Base64");
+            try {
+                encoder = c.getDeclaredMethod("getEncoder").invoke(null);
+                decoder = c.getDeclaredMethod("getDecoder").invoke(null);
+                encodeMethod = Class.forName("java.util.Base64$Encoder")
+                                    .getDeclaredMethod("encode", byte[].class);
+                decodeMethod = Class.forName("java.util.Base64$Decoder")
+                                    .getDeclaredMethod("decode", String.class);
+            } catch (Exception x) {
+                throw new AssertionError(x);
+            }
+        }
+        public String encode(byte aBuffer[]) throws Exception {
+            return new String((byte[]) encodeMethod.invoke(encoder, aBuffer));
+        }
+        public byte[] decode(String src) throws Exception{
+            return (byte[]) decodeMethod.invoke(decoder, src);
+        }
+    }
+
+    static class SunMiscBase64Coder implements Coder {
+        final Object encoder, decoder;
+        final Method encodeMethod, decodeMethod;
+
+        SunMiscBase64Coder()  {
+            try {
+                encoder = Class.forName("sun.misc.BASE64Encoder").newInstance();
+                decoder = Class.forName("sun.misc.BASE64Decoder").newInstance();
+                encodeMethod = encoder.getClass().getMethod("encodeBuffer", byte[].class);
+                decodeMethod = decoder.getClass().getMethod("decodeBuffer", String.class);
+            } catch (Exception x) {
+                throw new AssertionError(x);
+            }
                 }
+        public String encode(byte aBuffer[]) throws Exception {
+            return (String) encodeMethod.invoke(encoder, aBuffer);
             }
+        public byte[] decode(String src) throws Exception {
+            return (byte[]) decodeMethod.invoke(decoder, src);
         }
     }
 
     // Do not use diamond operator, this test is also meant to run in jdk6
     private static Map<String,String> dump7 = new HashMap<String,String>();