test/hotspot/jtreg/runtime/cds/appcds/test-classes/Util.java
branchdatagramsocketimpl-branch
changeset 58678 9cf78a70fa4f
parent 48403 6d4e1efac80a
child 58679 9c3209ff7550
equal deleted inserted replaced
58677:13588c901957 58678:9cf78a70fa4f
       
     1 /*
       
     2  * Copyright (c) 2015, 2019, Oracle and/or its affiliates. All rights reserved.
       
     3  * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
       
     4  *
       
     5  * This code is free software; you can redistribute it and/or modify it
       
     6  * under the terms of the GNU General Public License version 2 only, as
       
     7  * published by the Free Software Foundation.
       
     8  *
       
     9  * This code is distributed in the hope that it will be useful, but WITHOUT
       
    10  * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
       
    11  * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
       
    12  * version 2 for more details (a copy is included in the LICENSE file that
       
    13  * accompanied this code).
       
    14  *
       
    15  * You should have received a copy of the GNU General Public License version
       
    16  * 2 along with this work; if not, write to the Free Software Foundation,
       
    17  * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
       
    18  *
       
    19  * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
       
    20  * or visit www.oracle.com if you need additional information or have any
       
    21  * questions.
       
    22  *
       
    23  */
       
    24 
       
    25 import java.io.*;
       
    26 import java.lang.invoke.MethodHandles;
       
    27 import java.lang.invoke.MethodHandles.Lookup;
       
    28 import java.lang.reflect.*;
       
    29 import java.util.jar.*;
       
    30 
       
    31 public class Util {
       
    32     /**
       
    33      * Define the class as stored in clsFile with the provided lookup instance,
       
    34      * with the following modification:
       
    35      * <ul>
       
    36      *  <li> All ASCII strings in the class file bytes that matches fromString will be replaced with toString.
       
    37      *       NOTE: the two strings must be the exact same length.
       
    38      * </ul>
       
    39      */
       
    40     public static Class<?> defineModifiedClass(Lookup lookup, File clsFile, String fromString, String toString)
       
    41         throws FileNotFoundException, IOException, NoSuchMethodException, IllegalAccessException,
       
    42                InvocationTargetException
       
    43     {
       
    44       try (DataInputStream dis = new DataInputStream(new FileInputStream(clsFile))) {
       
    45         byte[] buff = new byte[(int)clsFile.length()];
       
    46         dis.readFully(buff);
       
    47         replace(buff, fromString, toString);
       
    48 
       
    49         System.out.println("Loading from: " + clsFile + " (" + buff.length + " bytes)");
       
    50 
       
    51 
       
    52         // We directly call into Lookup.defineClass() to define the "Super" class. Also,
       
    53         // rewrite its classfile so that it returns ___yyy___ instead of ___xxx___. Changing the
       
    54         // classfile will guarantee that this class will NOT be loaded from the CDS archive.
       
    55         Class<?> cls = lookup.defineClass(buff);
       
    56         System.out.println("Loaded : " + cls);
       
    57 
       
    58         return cls;
       
    59       }
       
    60     }
       
    61 
       
    62     /**
       
    63      * @return the number of occurrences of the <code>from</code> string that
       
    64      * have been replaced.
       
    65      */
       
    66     public static int replace(byte buff[], String from, String to) {
       
    67         if (to.length() != from.length()) {
       
    68             throw new RuntimeException("bad strings");
       
    69         }
       
    70         byte f[] = asciibytes(from);
       
    71         byte t[] = asciibytes(to);
       
    72         byte f0 = f[0];
       
    73 
       
    74         int numReplaced = 0;
       
    75         int max = buff.length - f.length;
       
    76         for (int i=0; i<max; ) {
       
    77             if (buff[i] == f0 && replace(buff, f, t, i)) {
       
    78                 i += f.length;
       
    79                 numReplaced ++;
       
    80             } else {
       
    81                 i++;
       
    82             }
       
    83         }
       
    84         return numReplaced;
       
    85     }
       
    86 
       
    87     public static boolean replace(byte buff[], byte f[], byte t[], int i) {
       
    88         for (int x=0; x<f.length; x++) {
       
    89             if (buff[x+i] != f[x]) {
       
    90                 return false;
       
    91             }
       
    92         }
       
    93         for (int x=0; x<f.length; x++) {
       
    94             buff[x+i] = t[x];
       
    95         }
       
    96         return true;
       
    97     }
       
    98 
       
    99     static byte[] asciibytes(String s) {
       
   100         byte b[] = new byte[s.length()];
       
   101         for (int i=0; i<b.length; i++) {
       
   102             b[i] = (byte)s.charAt(i);
       
   103         }
       
   104         return b;
       
   105     }
       
   106 
       
   107     public static byte[] getClassFileFromJar(File jarFile, String className) throws FileNotFoundException, IOException {
       
   108         JarFile jf = new JarFile(jarFile);
       
   109         JarEntry ent = jf.getJarEntry(className.replace('.', '/') + ".class");
       
   110 
       
   111         try (DataInputStream dis = new DataInputStream(jf.getInputStream(ent))) {
       
   112             byte[] buff = new byte[(int)ent.getSize()];
       
   113             dis.readFully(buff);
       
   114             return buff;
       
   115         }
       
   116     }
       
   117 }