test/hotspot/jtreg/runtime/appcds/cacheObject/RedefineClassApp.java
branchJDK-8200758-branch
changeset 57588 dac8f245de8e
parent 57587 16c4975e9e09
parent 57586 f459f98aa30d
child 57591 6805e0ef7453
equal deleted inserted replaced
57587:16c4975e9e09 57588:dac8f245de8e
     1 /*
       
     2  * Copyright (c) 2017, 2018, 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.lang.instrument.ClassDefinition;
       
    26 import java.lang.instrument.Instrumentation;
       
    27 import java.lang.instrument.UnmodifiableClassException;
       
    28 import java.net.URL;
       
    29 import java.net.URLClassLoader;
       
    30 import java.io.File;
       
    31 import java.security.CodeSigner;
       
    32 import java.security.CodeSource;
       
    33 import java.security.ProtectionDomain;
       
    34 import sun.hotspot.WhiteBox;
       
    35 
       
    36 public class RedefineClassApp {
       
    37     static WhiteBox wb = WhiteBox.getWhiteBox();
       
    38 
       
    39     public static interface Intf {            // Loaded from Boot class loader (-Xbootclasspath/a).
       
    40         public String get();
       
    41     }
       
    42     public static class Bar implements Intf { // Loaded from Boot class loader.
       
    43         public String get() {
       
    44             return "buzz";
       
    45         }
       
    46     }
       
    47     public static class Foo implements Intf { // Loaded from AppClassLoader
       
    48         public String get() {
       
    49             return "buzz";
       
    50         }
       
    51     }
       
    52 
       
    53     static int numTests = 0;
       
    54     static int failed = 0;
       
    55     static Instrumentation instrumentation;
       
    56 
       
    57     public static void main(String args[]) throws Throwable {
       
    58         if (wb.areSharedStringsIgnored()) {
       
    59           System.out.println("Shared strings are ignored.");
       
    60           return;
       
    61         }
       
    62 
       
    63         File bootJar = new File(args[0]);
       
    64         File appJar  = new File(args[1]);
       
    65 
       
    66         instrumentation = InstrumentationRegisterClassFileTransformer.getInstrumentation();
       
    67         System.out.println("INFO: instrumentation = " + instrumentation);
       
    68 
       
    69         testBootstrapCDS("Bootstrap Loader", bootJar);
       
    70         testAppCDSv1("Application Loader", appJar);
       
    71 
       
    72         if (failed > 0) {
       
    73             throw new RuntimeException("FINAL RESULT: " + failed + " out of " + numTests + " test case(s) have failed");
       
    74         } else {
       
    75             System.out.println("FINAL RESULT: All " + numTests + " test case(s) have passed!");
       
    76         }
       
    77 
       
    78         // Full GC. The cached objects in adjustable archive heap regions are
       
    79         // scanned. The archive regions are verified. No error should be
       
    80         // reported.
       
    81         wb.fullGC();
       
    82     }
       
    83 
       
    84     static void testBootstrapCDS(String group, File jar) throws Throwable {
       
    85         doTest(group, new Bar(), jar);
       
    86     }
       
    87 
       
    88     static void testAppCDSv1(String group, File jar) throws Throwable {
       
    89         doTest(group, new Foo(), jar);
       
    90     }
       
    91 
       
    92     static void checkArchivedMirrorObject(Class klass) {
       
    93         if (wb.areOpenArchiveHeapObjectsMapped()) {
       
    94             if (!wb.isShared(klass)) {
       
    95                 failed ++;
       
    96                 System.out.println("FAILED. " + klass + " mirror object is not archived");
       
    97                 return;
       
    98             }
       
    99         }
       
   100     }
       
   101 
       
   102     static void doTest(String group, Intf object, File jar) throws Throwable {
       
   103         numTests ++;
       
   104 
       
   105         Class klass = object.getClass();
       
   106         System.out.println();
       
   107         System.out.println("++++++++++++++++++++++++++");
       
   108         System.out.println("Test group: " + group);
       
   109         System.out.println("Testing with classloader = " + klass.getClassLoader());
       
   110         System.out.println("Testing with class       = " + klass);
       
   111         System.out.println("Test is shared           = " + wb.isSharedClass(klass));
       
   112         System.out.println("++++++++++++++++++++++++++");
       
   113 
       
   114         // Check archived mirror object before redefine
       
   115         checkArchivedMirrorObject(klass);
       
   116 
       
   117         // Call get() before redefine. All strings in archived classes are shared.
       
   118         String res = object.get();
       
   119         System.out.println("get() returns " + res);
       
   120         if (res.equals("buzz") && wb.isShared(res)) {
       
   121             System.out.println("get() returns " + res + ", string is shared");
       
   122         } else {
       
   123             if (!res.equals("buzz")) {
       
   124                 System.out.println("FAILED. buzz is expected but got " + res);
       
   125             } else {
       
   126                 System.out.println("FAILED. " + res + " is not shared");
       
   127             }
       
   128             failed ++;
       
   129             return;
       
   130         }
       
   131         res = null; // release the local reference to the string
       
   132 
       
   133         // Run GC
       
   134         System.gc();
       
   135         System.gc();
       
   136         System.gc();
       
   137 
       
   138         // Redefine the shared class
       
   139         byte[] buff = Util.getClassFileFromJar(jar, klass.getName());
       
   140         Util.replace(buff, "buzz", "huzz");
       
   141         String f = "(failed)";
       
   142         try {
       
   143             instrumentation.redefineClasses(new ClassDefinition(klass, buff));
       
   144             f = object.get();
       
   145         } catch (UnmodifiableClassException|UnsupportedOperationException e) {
       
   146             e.printStackTrace();
       
   147         }
       
   148         if (f.equals("huzz")) {
       
   149             System.out.println("PASSED: object.get() after redefinition returns " + f);
       
   150         } else {
       
   151             System.out.println("FAILED: object.get() after redefinition returns " + f);
       
   152             failed ++;
       
   153         }
       
   154 
       
   155         // Run GC. Should not crash.
       
   156         System.gc();
       
   157         System.gc();
       
   158         System.gc();
       
   159 
       
   160         // Check archived mirror object after redefine and GC
       
   161         checkArchivedMirrorObject(klass);
       
   162 
       
   163         System.out.println("++++++++++++++++++++++++++++++++++++++++++++++++ (done)\n\n");
       
   164     }
       
   165 }