test/jdk/com/sun/jdi/RedefineNestmateAttr/TestNestmateAttr.java
author dholmes
Sat, 23 Jun 2018 01:32:41 -0400
changeset 50735 2f2af62dfac7
child 50952 529e8aec67bd
permissions -rw-r--r--
8010319: Implementation of JEP 181: Nest-Based Access Control Reviewed-by: alanb, psandoz, mchung, coleenp, acorn, mcimadamore, forax, jlahoda, sspitsyn, abuckley Contributed-by: alex.buckley@oracle.com, maurizio.mimadamore@oracle.com, mandy.chung@oracle.com, tobias.hartmann@oracle.com, david.holmes@oracle.com, vladimir.x.ivanov@oracle.com, karen.kinnear@oracle.com, vladimir.kozlov@oracle.com, john.r.rose@oracle.com, daniel.smith@oracle.com, serguei.spitsyn@oracle.com, kumardotsrinivasan@gmail.com, boris.ulasevich@bell-sw.com
Ignore whitespace changes - Everywhere: Within whitespace: At end of lines:
50735
2f2af62dfac7 8010319: Implementation of JEP 181: Nest-Based Access Control
dholmes
parents:
diff changeset
     1
/*
2f2af62dfac7 8010319: Implementation of JEP 181: Nest-Based Access Control
dholmes
parents:
diff changeset
     2
 * Copyright (c) 2018, Oracle and/or its affiliates. All rights reserved.
2f2af62dfac7 8010319: Implementation of JEP 181: Nest-Based Access Control
dholmes
parents:
diff changeset
     3
 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
2f2af62dfac7 8010319: Implementation of JEP 181: Nest-Based Access Control
dholmes
parents:
diff changeset
     4
 *
2f2af62dfac7 8010319: Implementation of JEP 181: Nest-Based Access Control
dholmes
parents:
diff changeset
     5
 * This code is free software; you can redistribute it and/or modify it
2f2af62dfac7 8010319: Implementation of JEP 181: Nest-Based Access Control
dholmes
parents:
diff changeset
     6
 * under the terms of the GNU General Public License version 2 only, as
2f2af62dfac7 8010319: Implementation of JEP 181: Nest-Based Access Control
dholmes
parents:
diff changeset
     7
 * published by the Free Software Foundation.
2f2af62dfac7 8010319: Implementation of JEP 181: Nest-Based Access Control
dholmes
parents:
diff changeset
     8
 *
2f2af62dfac7 8010319: Implementation of JEP 181: Nest-Based Access Control
dholmes
parents:
diff changeset
     9
 * This code is distributed in the hope that it will be useful, but WITHOUT
2f2af62dfac7 8010319: Implementation of JEP 181: Nest-Based Access Control
dholmes
parents:
diff changeset
    10
 * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
2f2af62dfac7 8010319: Implementation of JEP 181: Nest-Based Access Control
dholmes
parents:
diff changeset
    11
 * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
2f2af62dfac7 8010319: Implementation of JEP 181: Nest-Based Access Control
dholmes
parents:
diff changeset
    12
 * version 2 for more details (a copy is included in the LICENSE file that
2f2af62dfac7 8010319: Implementation of JEP 181: Nest-Based Access Control
dholmes
parents:
diff changeset
    13
 * accompanied this code).
2f2af62dfac7 8010319: Implementation of JEP 181: Nest-Based Access Control
dholmes
parents:
diff changeset
    14
 *
2f2af62dfac7 8010319: Implementation of JEP 181: Nest-Based Access Control
dholmes
parents:
diff changeset
    15
 * You should have received a copy of the GNU General Public License version
2f2af62dfac7 8010319: Implementation of JEP 181: Nest-Based Access Control
dholmes
parents:
diff changeset
    16
 * 2 along with this work; if not, write to the Free Software Foundation,
2f2af62dfac7 8010319: Implementation of JEP 181: Nest-Based Access Control
dholmes
parents:
diff changeset
    17
 * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
2f2af62dfac7 8010319: Implementation of JEP 181: Nest-Based Access Control
dholmes
parents:
diff changeset
    18
 *
2f2af62dfac7 8010319: Implementation of JEP 181: Nest-Based Access Control
dholmes
parents:
diff changeset
    19
 * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
2f2af62dfac7 8010319: Implementation of JEP 181: Nest-Based Access Control
dholmes
parents:
diff changeset
    20
 * or visit www.oracle.com if you need additional information or have any
2f2af62dfac7 8010319: Implementation of JEP 181: Nest-Based Access Control
dholmes
parents:
diff changeset
    21
 * questions.
2f2af62dfac7 8010319: Implementation of JEP 181: Nest-Based Access Control
dholmes
parents:
diff changeset
    22
 */
2f2af62dfac7 8010319: Implementation of JEP 181: Nest-Based Access Control
dholmes
parents:
diff changeset
    23
2f2af62dfac7 8010319: Implementation of JEP 181: Nest-Based Access Control
dholmes
parents:
diff changeset
    24
/*
2f2af62dfac7 8010319: Implementation of JEP 181: Nest-Based Access Control
dholmes
parents:
diff changeset
    25
 * @test
2f2af62dfac7 8010319: Implementation of JEP 181: Nest-Based Access Control
dholmes
parents:
diff changeset
    26
 * @bug 8046171
2f2af62dfac7 8010319: Implementation of JEP 181: Nest-Based Access Control
dholmes
parents:
diff changeset
    27
 * @summary Class redefinition must preclude changes to nest attributes
2f2af62dfac7 8010319: Implementation of JEP 181: Nest-Based Access Control
dholmes
parents:
diff changeset
    28
 * @comment This is a copy of test/jdk/java/lang/instrument/RedefineNestmateAttr/
2f2af62dfac7 8010319: Implementation of JEP 181: Nest-Based Access Control
dholmes
parents:
diff changeset
    29
 * @comment modified for JDI
2f2af62dfac7 8010319: Implementation of JEP 181: Nest-Based Access Control
dholmes
parents:
diff changeset
    30
 * @library /test/lib ..
2f2af62dfac7 8010319: Implementation of JEP 181: Nest-Based Access Control
dholmes
parents:
diff changeset
    31
 * @modules java.compiler
2f2af62dfac7 8010319: Implementation of JEP 181: Nest-Based Access Control
dholmes
parents:
diff changeset
    32
 * @run build TestScaffold VMConnection TargetListener TargetAdapter
2f2af62dfac7 8010319: Implementation of JEP 181: Nest-Based Access Control
dholmes
parents:
diff changeset
    33
 * @compile NamedBuffer.java
2f2af62dfac7 8010319: Implementation of JEP 181: Nest-Based Access Control
dholmes
parents:
diff changeset
    34
 * @compile Host/Host.java
2f2af62dfac7 8010319: Implementation of JEP 181: Nest-Based Access Control
dholmes
parents:
diff changeset
    35
 * @run main/othervm TestNestmateAttr Host
2f2af62dfac7 8010319: Implementation of JEP 181: Nest-Based Access Control
dholmes
parents:
diff changeset
    36
 * @compile HostA/Host.java
2f2af62dfac7 8010319: Implementation of JEP 181: Nest-Based Access Control
dholmes
parents:
diff changeset
    37
 * @run main/othervm TestNestmateAttr HostA
2f2af62dfac7 8010319: Implementation of JEP 181: Nest-Based Access Control
dholmes
parents:
diff changeset
    38
 * @compile HostAB/Host.java
2f2af62dfac7 8010319: Implementation of JEP 181: Nest-Based Access Control
dholmes
parents:
diff changeset
    39
 * @run main/othervm TestNestmateAttr HostAB
2f2af62dfac7 8010319: Implementation of JEP 181: Nest-Based Access Control
dholmes
parents:
diff changeset
    40
 * @compile HostABC/Host.java
2f2af62dfac7 8010319: Implementation of JEP 181: Nest-Based Access Control
dholmes
parents:
diff changeset
    41
 * @run main/othervm TestNestmateAttr HostABC
2f2af62dfac7 8010319: Implementation of JEP 181: Nest-Based Access Control
dholmes
parents:
diff changeset
    42
 */
2f2af62dfac7 8010319: Implementation of JEP 181: Nest-Based Access Control
dholmes
parents:
diff changeset
    43
2f2af62dfac7 8010319: Implementation of JEP 181: Nest-Based Access Control
dholmes
parents:
diff changeset
    44
/* Test Description
2f2af62dfac7 8010319: Implementation of JEP 181: Nest-Based Access Control
dholmes
parents:
diff changeset
    45
2f2af62dfac7 8010319: Implementation of JEP 181: Nest-Based Access Control
dholmes
parents:
diff changeset
    46
The basic test class is called Host and we have variants that have zero or more
2f2af62dfac7 8010319: Implementation of JEP 181: Nest-Based Access Control
dholmes
parents:
diff changeset
    47
nested classes named A, B, C etc. Each variant of Host is defined in source
2f2af62dfac7 8010319: Implementation of JEP 181: Nest-Based Access Control
dholmes
parents:
diff changeset
    48
code in its own directory i.e.
2f2af62dfac7 8010319: Implementation of JEP 181: Nest-Based Access Control
dholmes
parents:
diff changeset
    49
2f2af62dfac7 8010319: Implementation of JEP 181: Nest-Based Access Control
dholmes
parents:
diff changeset
    50
Host/Host.java defines zero nested classes
2f2af62dfac7 8010319: Implementation of JEP 181: Nest-Based Access Control
dholmes
parents:
diff changeset
    51
HostA/Host.java defines one nested class A
2f2af62dfac7 8010319: Implementation of JEP 181: Nest-Based Access Control
dholmes
parents:
diff changeset
    52
HostAB/Host.java defines two nested classes A and B (in that order)
2f2af62dfac7 8010319: Implementation of JEP 181: Nest-Based Access Control
dholmes
parents:
diff changeset
    53
etc.
2f2af62dfac7 8010319: Implementation of JEP 181: Nest-Based Access Control
dholmes
parents:
diff changeset
    54
2f2af62dfac7 8010319: Implementation of JEP 181: Nest-Based Access Control
dholmes
parents:
diff changeset
    55
Each Host class has the form:
2f2af62dfac7 8010319: Implementation of JEP 181: Nest-Based Access Control
dholmes
parents:
diff changeset
    56
2f2af62dfac7 8010319: Implementation of JEP 181: Nest-Based Access Control
dholmes
parents:
diff changeset
    57
  public class Host {
2f2af62dfac7 8010319: Implementation of JEP 181: Nest-Based Access Control
dholmes
parents:
diff changeset
    58
    public static String getID() { return "<directory name>/Host.java"; }
2f2af62dfac7 8010319: Implementation of JEP 181: Nest-Based Access Control
dholmes
parents:
diff changeset
    59
2f2af62dfac7 8010319: Implementation of JEP 181: Nest-Based Access Control
dholmes
parents:
diff changeset
    60
    < zero or more empty nested classes>
2f2af62dfac7 8010319: Implementation of JEP 181: Nest-Based Access Control
dholmes
parents:
diff changeset
    61
2f2af62dfac7 8010319: Implementation of JEP 181: Nest-Based Access Control
dholmes
parents:
diff changeset
    62
    public int m() {
2f2af62dfac7 8010319: Implementation of JEP 181: Nest-Based Access Control
dholmes
parents:
diff changeset
    63
        return 1; // original class
2f2af62dfac7 8010319: Implementation of JEP 181: Nest-Based Access Control
dholmes
parents:
diff changeset
    64
    }
2f2af62dfac7 8010319: Implementation of JEP 181: Nest-Based Access Control
dholmes
parents:
diff changeset
    65
  }
2f2af62dfac7 8010319: Implementation of JEP 181: Nest-Based Access Control
dholmes
parents:
diff changeset
    66
2f2af62dfac7 8010319: Implementation of JEP 181: Nest-Based Access Control
dholmes
parents:
diff changeset
    67
Under each directory is a directory "redef" with a modified version of the Host
2f2af62dfac7 8010319: Implementation of JEP 181: Nest-Based Access Control
dholmes
parents:
diff changeset
    68
class that changes the ID to e.g. Host/redef/Host.java, and the method m()
2f2af62dfac7 8010319: Implementation of JEP 181: Nest-Based Access Control
dholmes
parents:
diff changeset
    69
returns 2. This allows us to check we have the redefined class loaded.
2f2af62dfac7 8010319: Implementation of JEP 181: Nest-Based Access Control
dholmes
parents:
diff changeset
    70
2f2af62dfac7 8010319: Implementation of JEP 181: Nest-Based Access Control
dholmes
parents:
diff changeset
    71
Using Host' to represent the redefined version we test redefinition
2f2af62dfac7 8010319: Implementation of JEP 181: Nest-Based Access Control
dholmes
parents:
diff changeset
    72
combinations as follows:
2f2af62dfac7 8010319: Implementation of JEP 181: Nest-Based Access Control
dholmes
parents:
diff changeset
    73
2f2af62dfac7 8010319: Implementation of JEP 181: Nest-Based Access Control
dholmes
parents:
diff changeset
    74
Host:
2f2af62dfac7 8010319: Implementation of JEP 181: Nest-Based Access Control
dholmes
parents:
diff changeset
    75
  Host -> Host'  - succeeds m() returns 2
2f2af62dfac7 8010319: Implementation of JEP 181: Nest-Based Access Control
dholmes
parents:
diff changeset
    76
  Host -> HostA' - fails - added a nest member
2f2af62dfac7 8010319: Implementation of JEP 181: Nest-Based Access Control
dholmes
parents:
diff changeset
    77
2f2af62dfac7 8010319: Implementation of JEP 181: Nest-Based Access Control
dholmes
parents:
diff changeset
    78
HostA:
2f2af62dfac7 8010319: Implementation of JEP 181: Nest-Based Access Control
dholmes
parents:
diff changeset
    79
  HostA -> HostA'  - succeeds m() returns 2
2f2af62dfac7 8010319: Implementation of JEP 181: Nest-Based Access Control
dholmes
parents:
diff changeset
    80
  HostA -> Host'   - fails - removed a nest member
2f2af62dfac7 8010319: Implementation of JEP 181: Nest-Based Access Control
dholmes
parents:
diff changeset
    81
  HostA -> HostAB' - fails - added a nest member
2f2af62dfac7 8010319: Implementation of JEP 181: Nest-Based Access Control
dholmes
parents:
diff changeset
    82
  HostA -> HostB'  - fails - replaced a nest member
2f2af62dfac7 8010319: Implementation of JEP 181: Nest-Based Access Control
dholmes
parents:
diff changeset
    83
2f2af62dfac7 8010319: Implementation of JEP 181: Nest-Based Access Control
dholmes
parents:
diff changeset
    84
HostAB:
2f2af62dfac7 8010319: Implementation of JEP 181: Nest-Based Access Control
dholmes
parents:
diff changeset
    85
  HostAB -> HostAB'  - succeeds m() returns 2
2f2af62dfac7 8010319: Implementation of JEP 181: Nest-Based Access Control
dholmes
parents:
diff changeset
    86
  HostAB -> HostBA'  - succeeds m() returns 2
2f2af62dfac7 8010319: Implementation of JEP 181: Nest-Based Access Control
dholmes
parents:
diff changeset
    87
  HostAB -> HostA'   - fails - removed a nest member
2f2af62dfac7 8010319: Implementation of JEP 181: Nest-Based Access Control
dholmes
parents:
diff changeset
    88
  HostAB -> HostABC' - fails - added a nest member
2f2af62dfac7 8010319: Implementation of JEP 181: Nest-Based Access Control
dholmes
parents:
diff changeset
    89
  HostAB -> HostAC'  - fails - replaced a nest member
2f2af62dfac7 8010319: Implementation of JEP 181: Nest-Based Access Control
dholmes
parents:
diff changeset
    90
2f2af62dfac7 8010319: Implementation of JEP 181: Nest-Based Access Control
dholmes
parents:
diff changeset
    91
HostABC:
2f2af62dfac7 8010319: Implementation of JEP 181: Nest-Based Access Control
dholmes
parents:
diff changeset
    92
  HostABC -> HostABC'  - succeeds m() returns 2
2f2af62dfac7 8010319: Implementation of JEP 181: Nest-Based Access Control
dholmes
parents:
diff changeset
    93
  HostABC -> HostACB'  - succeeds m() returns 2
2f2af62dfac7 8010319: Implementation of JEP 181: Nest-Based Access Control
dholmes
parents:
diff changeset
    94
  HostABC -> HostBAC'  - succeeds m() returns 2
2f2af62dfac7 8010319: Implementation of JEP 181: Nest-Based Access Control
dholmes
parents:
diff changeset
    95
  HostABC -> HostBCA'  - succeeds m() returns 2
2f2af62dfac7 8010319: Implementation of JEP 181: Nest-Based Access Control
dholmes
parents:
diff changeset
    96
  HostABC -> HostCAB'  - succeeds m() returns 2
2f2af62dfac7 8010319: Implementation of JEP 181: Nest-Based Access Control
dholmes
parents:
diff changeset
    97
  HostABC -> HostCBA'  - succeeds m() returns 2
2f2af62dfac7 8010319: Implementation of JEP 181: Nest-Based Access Control
dholmes
parents:
diff changeset
    98
  HostABC -> HostAB'   - fails - removed a nest member
2f2af62dfac7 8010319: Implementation of JEP 181: Nest-Based Access Control
dholmes
parents:
diff changeset
    99
  HostABC -> HostABCD' - fails - added a nest member
2f2af62dfac7 8010319: Implementation of JEP 181: Nest-Based Access Control
dholmes
parents:
diff changeset
   100
  HostABC -> HostABD'  - fails - replaced a nest member
2f2af62dfac7 8010319: Implementation of JEP 181: Nest-Based Access Control
dholmes
parents:
diff changeset
   101
2f2af62dfac7 8010319: Implementation of JEP 181: Nest-Based Access Control
dholmes
parents:
diff changeset
   102
More than three nested classes doesn't add to the code coverage so
2f2af62dfac7 8010319: Implementation of JEP 181: Nest-Based Access Control
dholmes
parents:
diff changeset
   103
we stop here.
2f2af62dfac7 8010319: Implementation of JEP 181: Nest-Based Access Control
dholmes
parents:
diff changeset
   104
2f2af62dfac7 8010319: Implementation of JEP 181: Nest-Based Access Control
dholmes
parents:
diff changeset
   105
Note that we always try to load the redefined version even when we expect it
2f2af62dfac7 8010319: Implementation of JEP 181: Nest-Based Access Control
dholmes
parents:
diff changeset
   106
to fail.
2f2af62dfac7 8010319: Implementation of JEP 181: Nest-Based Access Control
dholmes
parents:
diff changeset
   107
2f2af62dfac7 8010319: Implementation of JEP 181: Nest-Based Access Control
dholmes
parents:
diff changeset
   108
We can only directly load one class Host per classloader, so to run all the
2f2af62dfac7 8010319: Implementation of JEP 181: Nest-Based Access Control
dholmes
parents:
diff changeset
   109
groups we either need to use new classloaders, or we reinvoke the test
2f2af62dfac7 8010319: Implementation of JEP 181: Nest-Based Access Control
dholmes
parents:
diff changeset
   110
requesting a different primary directory. We chose the latter using
2f2af62dfac7 8010319: Implementation of JEP 181: Nest-Based Access Control
dholmes
parents:
diff changeset
   111
multiple @run tags. So we proceed as follows:
2f2af62dfac7 8010319: Implementation of JEP 181: Nest-Based Access Control
dholmes
parents:
diff changeset
   112
2f2af62dfac7 8010319: Implementation of JEP 181: Nest-Based Access Control
dholmes
parents:
diff changeset
   113
 @compile Host/Host.java
2f2af62dfac7 8010319: Implementation of JEP 181: Nest-Based Access Control
dholmes
parents:
diff changeset
   114
 @run TestNestmateAttr Host
2f2af62dfac7 8010319: Implementation of JEP 181: Nest-Based Access Control
dholmes
parents:
diff changeset
   115
 @compile HostA/Host.java  - replaces previous Host.class
2f2af62dfac7 8010319: Implementation of JEP 181: Nest-Based Access Control
dholmes
parents:
diff changeset
   116
 @run TestNestmateAttr HostA
2f2af62dfac7 8010319: Implementation of JEP 181: Nest-Based Access Control
dholmes
parents:
diff changeset
   117
 @compile HostAB/Host.java  - replaces previous Host.class
2f2af62dfac7 8010319: Implementation of JEP 181: Nest-Based Access Control
dholmes
parents:
diff changeset
   118
 @run TestNestmateAttr HostAB
2f2af62dfac7 8010319: Implementation of JEP 181: Nest-Based Access Control
dholmes
parents:
diff changeset
   119
etc.
2f2af62dfac7 8010319: Implementation of JEP 181: Nest-Based Access Control
dholmes
parents:
diff changeset
   120
2f2af62dfac7 8010319: Implementation of JEP 181: Nest-Based Access Control
dholmes
parents:
diff changeset
   121
Within the test we directly compile redefined versions of the classes,
2f2af62dfac7 8010319: Implementation of JEP 181: Nest-Based Access Control
dholmes
parents:
diff changeset
   122
using CompilerUtil, and then read the .class file directly as a byte[].
2f2af62dfac7 8010319: Implementation of JEP 181: Nest-Based Access Control
dholmes
parents:
diff changeset
   123
2f2af62dfac7 8010319: Implementation of JEP 181: Nest-Based Access Control
dholmes
parents:
diff changeset
   124
Finally we test redefinition of the NestHost attribute - which is
2f2af62dfac7 8010319: Implementation of JEP 181: Nest-Based Access Control
dholmes
parents:
diff changeset
   125
conceptually simple, but in fact very tricky to do. We do that
2f2af62dfac7 8010319: Implementation of JEP 181: Nest-Based Access Control
dholmes
parents:
diff changeset
   126
when testing HostA so we can reuse the Host$A class.
2f2af62dfac7 8010319: Implementation of JEP 181: Nest-Based Access Control
dholmes
parents:
diff changeset
   127
2f2af62dfac7 8010319: Implementation of JEP 181: Nest-Based Access Control
dholmes
parents:
diff changeset
   128
*/
2f2af62dfac7 8010319: Implementation of JEP 181: Nest-Based Access Control
dholmes
parents:
diff changeset
   129
2f2af62dfac7 8010319: Implementation of JEP 181: Nest-Based Access Control
dholmes
parents:
diff changeset
   130
import com.sun.jdi.*;
2f2af62dfac7 8010319: Implementation of JEP 181: Nest-Based Access Control
dholmes
parents:
diff changeset
   131
import com.sun.jdi.event.*;
2f2af62dfac7 8010319: Implementation of JEP 181: Nest-Based Access Control
dholmes
parents:
diff changeset
   132
import com.sun.jdi.request.*;
2f2af62dfac7 8010319: Implementation of JEP 181: Nest-Based Access Control
dholmes
parents:
diff changeset
   133
2f2af62dfac7 8010319: Implementation of JEP 181: Nest-Based Access Control
dholmes
parents:
diff changeset
   134
import java.io.File;
2f2af62dfac7 8010319: Implementation of JEP 181: Nest-Based Access Control
dholmes
parents:
diff changeset
   135
import java.io.FileInputStream;
2f2af62dfac7 8010319: Implementation of JEP 181: Nest-Based Access Control
dholmes
parents:
diff changeset
   136
import java.util.ArrayList;
2f2af62dfac7 8010319: Implementation of JEP 181: Nest-Based Access Control
dholmes
parents:
diff changeset
   137
import java.util.Arrays;
2f2af62dfac7 8010319: Implementation of JEP 181: Nest-Based Access Control
dholmes
parents:
diff changeset
   138
import java.util.Collections;
2f2af62dfac7 8010319: Implementation of JEP 181: Nest-Based Access Control
dholmes
parents:
diff changeset
   139
import java.util.HashMap;
2f2af62dfac7 8010319: Implementation of JEP 181: Nest-Based Access Control
dholmes
parents:
diff changeset
   140
import java.util.List;
2f2af62dfac7 8010319: Implementation of JEP 181: Nest-Based Access Control
dholmes
parents:
diff changeset
   141
import java.util.Map;
2f2af62dfac7 8010319: Implementation of JEP 181: Nest-Based Access Control
dholmes
parents:
diff changeset
   142
2f2af62dfac7 8010319: Implementation of JEP 181: Nest-Based Access Control
dholmes
parents:
diff changeset
   143
import jdk.test.lib.ByteCodeLoader;
2f2af62dfac7 8010319: Implementation of JEP 181: Nest-Based Access Control
dholmes
parents:
diff changeset
   144
import jdk.test.lib.compiler.CompilerUtils;
2f2af62dfac7 8010319: Implementation of JEP 181: Nest-Based Access Control
dholmes
parents:
diff changeset
   145
import jdk.test.lib.compiler.InMemoryJavaCompiler;
2f2af62dfac7 8010319: Implementation of JEP 181: Nest-Based Access Control
dholmes
parents:
diff changeset
   146
import static jdk.test.lib.Asserts.assertTrue;
2f2af62dfac7 8010319: Implementation of JEP 181: Nest-Based Access Control
dholmes
parents:
diff changeset
   147
2f2af62dfac7 8010319: Implementation of JEP 181: Nest-Based Access Control
dholmes
parents:
diff changeset
   148
/* For JDI the test is split across two VMs and so split into
2f2af62dfac7 8010319: Implementation of JEP 181: Nest-Based Access Control
dholmes
parents:
diff changeset
   149
   two main classes. This is the class we will run under the debugger.
2f2af62dfac7 8010319: Implementation of JEP 181: Nest-Based Access Control
dholmes
parents:
diff changeset
   150
   Package access so we can define in the same source file for ease of
2f2af62dfac7 8010319: Implementation of JEP 181: Nest-Based Access Control
dholmes
parents:
diff changeset
   151
   reference.
2f2af62dfac7 8010319: Implementation of JEP 181: Nest-Based Access Control
dholmes
parents:
diff changeset
   152
*/
2f2af62dfac7 8010319: Implementation of JEP 181: Nest-Based Access Control
dholmes
parents:
diff changeset
   153
class Target {
2f2af62dfac7 8010319: Implementation of JEP 181: Nest-Based Access Control
dholmes
parents:
diff changeset
   154
    // We have to load all of the variants of the classes that we will
2f2af62dfac7 8010319: Implementation of JEP 181: Nest-Based Access Control
dholmes
parents:
diff changeset
   155
    // attempt to redefine. This requires some in-memory compilation
2f2af62dfac7 8010319: Implementation of JEP 181: Nest-Based Access Control
dholmes
parents:
diff changeset
   156
    // and use of additional classloaders.
2f2af62dfac7 8010319: Implementation of JEP 181: Nest-Based Access Control
dholmes
parents:
diff changeset
   157
    public static void main(String[] args) throws Throwable {
2f2af62dfac7 8010319: Implementation of JEP 181: Nest-Based Access Control
dholmes
parents:
diff changeset
   158
        String origin = args[0];
2f2af62dfac7 8010319: Implementation of JEP 181: Nest-Based Access Control
dholmes
parents:
diff changeset
   159
        System.out.println("Target: Testing original Host class from " + origin);
2f2af62dfac7 8010319: Implementation of JEP 181: Nest-Based Access Control
dholmes
parents:
diff changeset
   160
2f2af62dfac7 8010319: Implementation of JEP 181: Nest-Based Access Control
dholmes
parents:
diff changeset
   161
        // Make sure the Host class loaded directly is an original version
2f2af62dfac7 8010319: Implementation of JEP 181: Nest-Based Access Control
dholmes
parents:
diff changeset
   162
        // and from the expected location
2f2af62dfac7 8010319: Implementation of JEP 181: Nest-Based Access Control
dholmes
parents:
diff changeset
   163
        Host h = new Host();
2f2af62dfac7 8010319: Implementation of JEP 181: Nest-Based Access Control
dholmes
parents:
diff changeset
   164
        assertTrue(h.m() == 1);
2f2af62dfac7 8010319: Implementation of JEP 181: Nest-Based Access Control
dholmes
parents:
diff changeset
   165
        assertTrue(Host.getID().startsWith(origin + "/"));
2f2af62dfac7 8010319: Implementation of JEP 181: Nest-Based Access Control
dholmes
parents:
diff changeset
   166
2f2af62dfac7 8010319: Implementation of JEP 181: Nest-Based Access Control
dholmes
parents:
diff changeset
   167
        // The rest of this setup is only needed for the case
2f2af62dfac7 8010319: Implementation of JEP 181: Nest-Based Access Control
dholmes
parents:
diff changeset
   168
        // when we perform the checkNestHostChanges() test.
2f2af62dfac7 8010319: Implementation of JEP 181: Nest-Based Access Control
dholmes
parents:
diff changeset
   169
        if (origin.equals("HostA")) {
2f2af62dfac7 8010319: Implementation of JEP 181: Nest-Based Access Control
dholmes
parents:
diff changeset
   170
            String name = "Host$A";
2f2af62dfac7 8010319: Implementation of JEP 181: Nest-Based Access Control
dholmes
parents:
diff changeset
   171
2f2af62dfac7 8010319: Implementation of JEP 181: Nest-Based Access Control
dholmes
parents:
diff changeset
   172
            // Have to do this reflectively as there is no Host$A
2f2af62dfac7 8010319: Implementation of JEP 181: Nest-Based Access Control
dholmes
parents:
diff changeset
   173
            // when compiling the "Host/" case.
2f2af62dfac7 8010319: Implementation of JEP 181: Nest-Based Access Control
dholmes
parents:
diff changeset
   174
            Class<?> nestedA = Class.forName(name); // triggers initialization
2f2af62dfac7 8010319: Implementation of JEP 181: Nest-Based Access Control
dholmes
parents:
diff changeset
   175
2f2af62dfac7 8010319: Implementation of JEP 181: Nest-Based Access Control
dholmes
parents:
diff changeset
   176
            // This is compiled as a top-level class: the $ in the name is not
2f2af62dfac7 8010319: Implementation of JEP 181: Nest-Based Access Control
dholmes
parents:
diff changeset
   177
            // significant to the compiler.
2f2af62dfac7 8010319: Implementation of JEP 181: Nest-Based Access Control
dholmes
parents:
diff changeset
   178
            String hostA = "public class " + name + " {}";
2f2af62dfac7 8010319: Implementation of JEP 181: Nest-Based Access Control
dholmes
parents:
diff changeset
   179
            byte[] bytes = InMemoryJavaCompiler.compile(name, hostA);
2f2af62dfac7 8010319: Implementation of JEP 181: Nest-Based Access Control
dholmes
parents:
diff changeset
   180
            // And we have to load this into a new classloader
2f2af62dfac7 8010319: Implementation of JEP 181: Nest-Based Access Control
dholmes
parents:
diff changeset
   181
            Class<?> topLevelHostA = ByteCodeLoader.load(name, bytes);
2f2af62dfac7 8010319: Implementation of JEP 181: Nest-Based Access Control
dholmes
parents:
diff changeset
   182
            // The loaded class has not been linked (as per ClassLoader.resolveClass)
2f2af62dfac7 8010319: Implementation of JEP 181: Nest-Based Access Control
dholmes
parents:
diff changeset
   183
            // and so will be filtered out by VirtualMachine.allClasses(). There are
2f2af62dfac7 8010319: Implementation of JEP 181: Nest-Based Access Control
dholmes
parents:
diff changeset
   184
            // a number of ways to force linking - this is the simplest.
2f2af62dfac7 8010319: Implementation of JEP 181: Nest-Based Access Control
dholmes
parents:
diff changeset
   185
            Object o = topLevelHostA.newInstance();
2f2af62dfac7 8010319: Implementation of JEP 181: Nest-Based Access Control
dholmes
parents:
diff changeset
   186
2f2af62dfac7 8010319: Implementation of JEP 181: Nest-Based Access Control
dholmes
parents:
diff changeset
   187
            // sanity check
2f2af62dfac7 8010319: Implementation of JEP 181: Nest-Based Access Control
dholmes
parents:
diff changeset
   188
            assertTrue(nestedA.getClassLoader() != topLevelHostA.getClassLoader());
2f2af62dfac7 8010319: Implementation of JEP 181: Nest-Based Access Control
dholmes
parents:
diff changeset
   189
2f2af62dfac7 8010319: Implementation of JEP 181: Nest-Based Access Control
dholmes
parents:
diff changeset
   190
        }
2f2af62dfac7 8010319: Implementation of JEP 181: Nest-Based Access Control
dholmes
parents:
diff changeset
   191
2f2af62dfac7 8010319: Implementation of JEP 181: Nest-Based Access Control
dholmes
parents:
diff changeset
   192
        allowRedefine(); // debugger stops us here to attempt redefinitions
2f2af62dfac7 8010319: Implementation of JEP 181: Nest-Based Access Control
dholmes
parents:
diff changeset
   193
2f2af62dfac7 8010319: Implementation of JEP 181: Nest-Based Access Control
dholmes
parents:
diff changeset
   194
        System.out.println("Target executed okay");
2f2af62dfac7 8010319: Implementation of JEP 181: Nest-Based Access Control
dholmes
parents:
diff changeset
   195
    }
2f2af62dfac7 8010319: Implementation of JEP 181: Nest-Based Access Control
dholmes
parents:
diff changeset
   196
2f2af62dfac7 8010319: Implementation of JEP 181: Nest-Based Access Control
dholmes
parents:
diff changeset
   197
    public static void allowRedefine() { }
2f2af62dfac7 8010319: Implementation of JEP 181: Nest-Based Access Control
dholmes
parents:
diff changeset
   198
}
2f2af62dfac7 8010319: Implementation of JEP 181: Nest-Based Access Control
dholmes
parents:
diff changeset
   199
2f2af62dfac7 8010319: Implementation of JEP 181: Nest-Based Access Control
dholmes
parents:
diff changeset
   200
public class TestNestmateAttr extends TestScaffold {
2f2af62dfac7 8010319: Implementation of JEP 181: Nest-Based Access Control
dholmes
parents:
diff changeset
   201
2f2af62dfac7 8010319: Implementation of JEP 181: Nest-Based Access Control
dholmes
parents:
diff changeset
   202
    static final String SRC = System.getProperty("test.src");
2f2af62dfac7 8010319: Implementation of JEP 181: Nest-Based Access Control
dholmes
parents:
diff changeset
   203
    static final String DEST = System.getProperty("test.classes");
2f2af62dfac7 8010319: Implementation of JEP 181: Nest-Based Access Control
dholmes
parents:
diff changeset
   204
    static final boolean VERBOSE = Boolean.getBoolean("verbose");
2f2af62dfac7 8010319: Implementation of JEP 181: Nest-Based Access Control
dholmes
parents:
diff changeset
   205
2f2af62dfac7 8010319: Implementation of JEP 181: Nest-Based Access Control
dholmes
parents:
diff changeset
   206
    static String origin;
2f2af62dfac7 8010319: Implementation of JEP 181: Nest-Based Access Control
dholmes
parents:
diff changeset
   207
2f2af62dfac7 8010319: Implementation of JEP 181: Nest-Based Access Control
dholmes
parents:
diff changeset
   208
    // override this to correct a bug so arguments can be passed to
2f2af62dfac7 8010319: Implementation of JEP 181: Nest-Based Access Control
dholmes
parents:
diff changeset
   209
    // the Target class
2f2af62dfac7 8010319: Implementation of JEP 181: Nest-Based Access Control
dholmes
parents:
diff changeset
   210
    protected void startUp(String targetName) {
2f2af62dfac7 8010319: Implementation of JEP 181: Nest-Based Access Control
dholmes
parents:
diff changeset
   211
        List<String> argList = new ArrayList<>(Arrays.asList(args));
2f2af62dfac7 8010319: Implementation of JEP 181: Nest-Based Access Control
dholmes
parents:
diff changeset
   212
        argList.add(0, targetName); // pre-pend so it becomes the first "app" arg
2f2af62dfac7 8010319: Implementation of JEP 181: Nest-Based Access Control
dholmes
parents:
diff changeset
   213
        println("run args: " + argList);
2f2af62dfac7 8010319: Implementation of JEP 181: Nest-Based Access Control
dholmes
parents:
diff changeset
   214
        connect((String[]) argList.toArray(args));
2f2af62dfac7 8010319: Implementation of JEP 181: Nest-Based Access Control
dholmes
parents:
diff changeset
   215
        waitForVMStart();
2f2af62dfac7 8010319: Implementation of JEP 181: Nest-Based Access Control
dholmes
parents:
diff changeset
   216
    }
2f2af62dfac7 8010319: Implementation of JEP 181: Nest-Based Access Control
dholmes
parents:
diff changeset
   217
2f2af62dfac7 8010319: Implementation of JEP 181: Nest-Based Access Control
dholmes
parents:
diff changeset
   218
    TestNestmateAttr (String[] args) {
2f2af62dfac7 8010319: Implementation of JEP 181: Nest-Based Access Control
dholmes
parents:
diff changeset
   219
        super(args);
2f2af62dfac7 8010319: Implementation of JEP 181: Nest-Based Access Control
dholmes
parents:
diff changeset
   220
    }
2f2af62dfac7 8010319: Implementation of JEP 181: Nest-Based Access Control
dholmes
parents:
diff changeset
   221
2f2af62dfac7 8010319: Implementation of JEP 181: Nest-Based Access Control
dholmes
parents:
diff changeset
   222
    public static void main(String[] args) throws Throwable {
2f2af62dfac7 8010319: Implementation of JEP 181: Nest-Based Access Control
dholmes
parents:
diff changeset
   223
        origin = args[0];
2f2af62dfac7 8010319: Implementation of JEP 181: Nest-Based Access Control
dholmes
parents:
diff changeset
   224
        new TestNestmateAttr(args).startTests();
2f2af62dfac7 8010319: Implementation of JEP 181: Nest-Based Access Control
dholmes
parents:
diff changeset
   225
    }
2f2af62dfac7 8010319: Implementation of JEP 181: Nest-Based Access Control
dholmes
parents:
diff changeset
   226
2f2af62dfac7 8010319: Implementation of JEP 181: Nest-Based Access Control
dholmes
parents:
diff changeset
   227
    public void runTests() throws Exception {
2f2af62dfac7 8010319: Implementation of JEP 181: Nest-Based Access Control
dholmes
parents:
diff changeset
   228
        // Get Target into debuggable state
2f2af62dfac7 8010319: Implementation of JEP 181: Nest-Based Access Control
dholmes
parents:
diff changeset
   229
        BreakpointEvent bpe = startToMain("Target");
2f2af62dfac7 8010319: Implementation of JEP 181: Nest-Based Access Control
dholmes
parents:
diff changeset
   230
        EventRequestManager erm = vm().eventRequestManager();
2f2af62dfac7 8010319: Implementation of JEP 181: Nest-Based Access Control
dholmes
parents:
diff changeset
   231
        MethodEntryRequest mee = erm.createMethodEntryRequest();
2f2af62dfac7 8010319: Implementation of JEP 181: Nest-Based Access Control
dholmes
parents:
diff changeset
   232
        mee.addClassFilter("Target");
2f2af62dfac7 8010319: Implementation of JEP 181: Nest-Based Access Control
dholmes
parents:
diff changeset
   233
        mee.enable();
2f2af62dfac7 8010319: Implementation of JEP 181: Nest-Based Access Control
dholmes
parents:
diff changeset
   234
2f2af62dfac7 8010319: Implementation of JEP 181: Nest-Based Access Control
dholmes
parents:
diff changeset
   235
        // Allow application to complete and shut down
2f2af62dfac7 8010319: Implementation of JEP 181: Nest-Based Access Control
dholmes
parents:
diff changeset
   236
        listenUntilVMDisconnect();
2f2af62dfac7 8010319: Implementation of JEP 181: Nest-Based Access Control
dholmes
parents:
diff changeset
   237
2f2af62dfac7 8010319: Implementation of JEP 181: Nest-Based Access Control
dholmes
parents:
diff changeset
   238
        if (getExceptionCaught()) {
2f2af62dfac7 8010319: Implementation of JEP 181: Nest-Based Access Control
dholmes
parents:
diff changeset
   239
            throw new Exception("TestNestmateAttr: failed due to unexpected exception - check logs for details");
2f2af62dfac7 8010319: Implementation of JEP 181: Nest-Based Access Control
dholmes
parents:
diff changeset
   240
        }
2f2af62dfac7 8010319: Implementation of JEP 181: Nest-Based Access Control
dholmes
parents:
diff changeset
   241
        else if (!testFailed) {
2f2af62dfac7 8010319: Implementation of JEP 181: Nest-Based Access Control
dholmes
parents:
diff changeset
   242
            println("TestNestmateAttr: passed");
2f2af62dfac7 8010319: Implementation of JEP 181: Nest-Based Access Control
dholmes
parents:
diff changeset
   243
        } else {
2f2af62dfac7 8010319: Implementation of JEP 181: Nest-Based Access Control
dholmes
parents:
diff changeset
   244
            throw new Exception("TestNestmateAttr: failure reported - check log for details");
2f2af62dfac7 8010319: Implementation of JEP 181: Nest-Based Access Control
dholmes
parents:
diff changeset
   245
        }
2f2af62dfac7 8010319: Implementation of JEP 181: Nest-Based Access Control
dholmes
parents:
diff changeset
   246
    }
2f2af62dfac7 8010319: Implementation of JEP 181: Nest-Based Access Control
dholmes
parents:
diff changeset
   247
2f2af62dfac7 8010319: Implementation of JEP 181: Nest-Based Access Control
dholmes
parents:
diff changeset
   248
    // All the actual work is done from here once we see we've entered Target.allowRedefine()
2f2af62dfac7 8010319: Implementation of JEP 181: Nest-Based Access Control
dholmes
parents:
diff changeset
   249
    public void methodEntered(MethodEntryEvent event) {
2f2af62dfac7 8010319: Implementation of JEP 181: Nest-Based Access Control
dholmes
parents:
diff changeset
   250
        Method meth = event.location().method();
2f2af62dfac7 8010319: Implementation of JEP 181: Nest-Based Access Control
dholmes
parents:
diff changeset
   251
2f2af62dfac7 8010319: Implementation of JEP 181: Nest-Based Access Control
dholmes
parents:
diff changeset
   252
        if (!meth.name().equals("allowRedefine")) {
2f2af62dfac7 8010319: Implementation of JEP 181: Nest-Based Access Control
dholmes
parents:
diff changeset
   253
            return;
2f2af62dfac7 8010319: Implementation of JEP 181: Nest-Based Access Control
dholmes
parents:
diff changeset
   254
        }
2f2af62dfac7 8010319: Implementation of JEP 181: Nest-Based Access Control
dholmes
parents:
diff changeset
   255
2f2af62dfac7 8010319: Implementation of JEP 181: Nest-Based Access Control
dholmes
parents:
diff changeset
   256
        System.out.println("TestNestmateAttr: Testing original Host class from " + origin);
2f2af62dfac7 8010319: Implementation of JEP 181: Nest-Based Access Control
dholmes
parents:
diff changeset
   257
2f2af62dfac7 8010319: Implementation of JEP 181: Nest-Based Access Control
dholmes
parents:
diff changeset
   258
        String[] badTransforms;  // directories of bad classes
2f2af62dfac7 8010319: Implementation of JEP 181: Nest-Based Access Control
dholmes
parents:
diff changeset
   259
        String[] goodTransforms; // directories of good classes
2f2af62dfac7 8010319: Implementation of JEP 181: Nest-Based Access Control
dholmes
parents:
diff changeset
   260
2f2af62dfac7 8010319: Implementation of JEP 181: Nest-Based Access Control
dholmes
parents:
diff changeset
   261
        boolean testNestHostChanges = false;
2f2af62dfac7 8010319: Implementation of JEP 181: Nest-Based Access Control
dholmes
parents:
diff changeset
   262
2f2af62dfac7 8010319: Implementation of JEP 181: Nest-Based Access Control
dholmes
parents:
diff changeset
   263
        switch (origin) {
2f2af62dfac7 8010319: Implementation of JEP 181: Nest-Based Access Control
dholmes
parents:
diff changeset
   264
        case "Host":
2f2af62dfac7 8010319: Implementation of JEP 181: Nest-Based Access Control
dholmes
parents:
diff changeset
   265
            badTransforms = new String[] {
2f2af62dfac7 8010319: Implementation of JEP 181: Nest-Based Access Control
dholmes
parents:
diff changeset
   266
                "HostA" // add member
2f2af62dfac7 8010319: Implementation of JEP 181: Nest-Based Access Control
dholmes
parents:
diff changeset
   267
            };
2f2af62dfac7 8010319: Implementation of JEP 181: Nest-Based Access Control
dholmes
parents:
diff changeset
   268
            goodTransforms = new String[] {
2f2af62dfac7 8010319: Implementation of JEP 181: Nest-Based Access Control
dholmes
parents:
diff changeset
   269
                origin
2f2af62dfac7 8010319: Implementation of JEP 181: Nest-Based Access Control
dholmes
parents:
diff changeset
   270
            };
2f2af62dfac7 8010319: Implementation of JEP 181: Nest-Based Access Control
dholmes
parents:
diff changeset
   271
            break;
2f2af62dfac7 8010319: Implementation of JEP 181: Nest-Based Access Control
dholmes
parents:
diff changeset
   272
2f2af62dfac7 8010319: Implementation of JEP 181: Nest-Based Access Control
dholmes
parents:
diff changeset
   273
        case "HostA":
2f2af62dfac7 8010319: Implementation of JEP 181: Nest-Based Access Control
dholmes
parents:
diff changeset
   274
            badTransforms = new String[] {
2f2af62dfac7 8010319: Implementation of JEP 181: Nest-Based Access Control
dholmes
parents:
diff changeset
   275
                "Host",   // remove member
2f2af62dfac7 8010319: Implementation of JEP 181: Nest-Based Access Control
dholmes
parents:
diff changeset
   276
                "HostAB", // add member
2f2af62dfac7 8010319: Implementation of JEP 181: Nest-Based Access Control
dholmes
parents:
diff changeset
   277
                "HostB"   // change member
2f2af62dfac7 8010319: Implementation of JEP 181: Nest-Based Access Control
dholmes
parents:
diff changeset
   278
            };
2f2af62dfac7 8010319: Implementation of JEP 181: Nest-Based Access Control
dholmes
parents:
diff changeset
   279
            goodTransforms = new String[] {
2f2af62dfac7 8010319: Implementation of JEP 181: Nest-Based Access Control
dholmes
parents:
diff changeset
   280
                origin
2f2af62dfac7 8010319: Implementation of JEP 181: Nest-Based Access Control
dholmes
parents:
diff changeset
   281
            };
2f2af62dfac7 8010319: Implementation of JEP 181: Nest-Based Access Control
dholmes
parents:
diff changeset
   282
            testNestHostChanges = true;
2f2af62dfac7 8010319: Implementation of JEP 181: Nest-Based Access Control
dholmes
parents:
diff changeset
   283
            break;
2f2af62dfac7 8010319: Implementation of JEP 181: Nest-Based Access Control
dholmes
parents:
diff changeset
   284
2f2af62dfac7 8010319: Implementation of JEP 181: Nest-Based Access Control
dholmes
parents:
diff changeset
   285
        case "HostAB":
2f2af62dfac7 8010319: Implementation of JEP 181: Nest-Based Access Control
dholmes
parents:
diff changeset
   286
            badTransforms = new String[] {
2f2af62dfac7 8010319: Implementation of JEP 181: Nest-Based Access Control
dholmes
parents:
diff changeset
   287
                "HostA",   // remove member
2f2af62dfac7 8010319: Implementation of JEP 181: Nest-Based Access Control
dholmes
parents:
diff changeset
   288
                "HostABC", // add member
2f2af62dfac7 8010319: Implementation of JEP 181: Nest-Based Access Control
dholmes
parents:
diff changeset
   289
                "HostAC"   // change member
2f2af62dfac7 8010319: Implementation of JEP 181: Nest-Based Access Control
dholmes
parents:
diff changeset
   290
            };
2f2af62dfac7 8010319: Implementation of JEP 181: Nest-Based Access Control
dholmes
parents:
diff changeset
   291
            goodTransforms = new String[] {
2f2af62dfac7 8010319: Implementation of JEP 181: Nest-Based Access Control
dholmes
parents:
diff changeset
   292
                origin,
2f2af62dfac7 8010319: Implementation of JEP 181: Nest-Based Access Control
dholmes
parents:
diff changeset
   293
                "HostBA"  // reorder members
2f2af62dfac7 8010319: Implementation of JEP 181: Nest-Based Access Control
dholmes
parents:
diff changeset
   294
            };
2f2af62dfac7 8010319: Implementation of JEP 181: Nest-Based Access Control
dholmes
parents:
diff changeset
   295
            break;
2f2af62dfac7 8010319: Implementation of JEP 181: Nest-Based Access Control
dholmes
parents:
diff changeset
   296
2f2af62dfac7 8010319: Implementation of JEP 181: Nest-Based Access Control
dholmes
parents:
diff changeset
   297
        case "HostABC":
2f2af62dfac7 8010319: Implementation of JEP 181: Nest-Based Access Control
dholmes
parents:
diff changeset
   298
            badTransforms = new String[] {
2f2af62dfac7 8010319: Implementation of JEP 181: Nest-Based Access Control
dholmes
parents:
diff changeset
   299
                "HostAB",   // remove member
2f2af62dfac7 8010319: Implementation of JEP 181: Nest-Based Access Control
dholmes
parents:
diff changeset
   300
                "HostABCD", // add member
2f2af62dfac7 8010319: Implementation of JEP 181: Nest-Based Access Control
dholmes
parents:
diff changeset
   301
                "HostABD"   // change member
2f2af62dfac7 8010319: Implementation of JEP 181: Nest-Based Access Control
dholmes
parents:
diff changeset
   302
            };
2f2af62dfac7 8010319: Implementation of JEP 181: Nest-Based Access Control
dholmes
parents:
diff changeset
   303
            goodTransforms = new String[] {
2f2af62dfac7 8010319: Implementation of JEP 181: Nest-Based Access Control
dholmes
parents:
diff changeset
   304
                origin,
2f2af62dfac7 8010319: Implementation of JEP 181: Nest-Based Access Control
dholmes
parents:
diff changeset
   305
                "HostACB",  // reorder members
2f2af62dfac7 8010319: Implementation of JEP 181: Nest-Based Access Control
dholmes
parents:
diff changeset
   306
                "HostBAC",  // reorder members
2f2af62dfac7 8010319: Implementation of JEP 181: Nest-Based Access Control
dholmes
parents:
diff changeset
   307
                "HostBCA",  // reorder members
2f2af62dfac7 8010319: Implementation of JEP 181: Nest-Based Access Control
dholmes
parents:
diff changeset
   308
                "HostCAB",  // reorder members
2f2af62dfac7 8010319: Implementation of JEP 181: Nest-Based Access Control
dholmes
parents:
diff changeset
   309
                "HostCBA"   // reorder members
2f2af62dfac7 8010319: Implementation of JEP 181: Nest-Based Access Control
dholmes
parents:
diff changeset
   310
            };
2f2af62dfac7 8010319: Implementation of JEP 181: Nest-Based Access Control
dholmes
parents:
diff changeset
   311
            break;
2f2af62dfac7 8010319: Implementation of JEP 181: Nest-Based Access Control
dholmes
parents:
diff changeset
   312
2f2af62dfac7 8010319: Implementation of JEP 181: Nest-Based Access Control
dholmes
parents:
diff changeset
   313
        default: throw new Error("Unknown test directory: " + origin);
2f2af62dfac7 8010319: Implementation of JEP 181: Nest-Based Access Control
dholmes
parents:
diff changeset
   314
        }
2f2af62dfac7 8010319: Implementation of JEP 181: Nest-Based Access Control
dholmes
parents:
diff changeset
   315
2f2af62dfac7 8010319: Implementation of JEP 181: Nest-Based Access Control
dholmes
parents:
diff changeset
   316
        // Need to locate the type we will be trying to redefine in Target
2f2af62dfac7 8010319: Implementation of JEP 181: Nest-Based Access Control
dholmes
parents:
diff changeset
   317
        findReferenceTypes();
2f2af62dfac7 8010319: Implementation of JEP 181: Nest-Based Access Control
dholmes
parents:
diff changeset
   318
2f2af62dfac7 8010319: Implementation of JEP 181: Nest-Based Access Control
dholmes
parents:
diff changeset
   319
        try {
2f2af62dfac7 8010319: Implementation of JEP 181: Nest-Based Access Control
dholmes
parents:
diff changeset
   320
            // Compile and check bad transformations
2f2af62dfac7 8010319: Implementation of JEP 181: Nest-Based Access Control
dholmes
parents:
diff changeset
   321
            checkBadTransforms(_Host, badTransforms);
2f2af62dfac7 8010319: Implementation of JEP 181: Nest-Based Access Control
dholmes
parents:
diff changeset
   322
2f2af62dfac7 8010319: Implementation of JEP 181: Nest-Based Access Control
dholmes
parents:
diff changeset
   323
            // Compile and check good transformations
2f2af62dfac7 8010319: Implementation of JEP 181: Nest-Based Access Control
dholmes
parents:
diff changeset
   324
            checkGoodTransforms(_Host, goodTransforms);
2f2af62dfac7 8010319: Implementation of JEP 181: Nest-Based Access Control
dholmes
parents:
diff changeset
   325
2f2af62dfac7 8010319: Implementation of JEP 181: Nest-Based Access Control
dholmes
parents:
diff changeset
   326
            if (testNestHostChanges)
2f2af62dfac7 8010319: Implementation of JEP 181: Nest-Based Access Control
dholmes
parents:
diff changeset
   327
                checkNestHostChanges();
2f2af62dfac7 8010319: Implementation of JEP 181: Nest-Based Access Control
dholmes
parents:
diff changeset
   328
        }
2f2af62dfac7 8010319: Implementation of JEP 181: Nest-Based Access Control
dholmes
parents:
diff changeset
   329
        catch (Throwable t) {
2f2af62dfac7 8010319: Implementation of JEP 181: Nest-Based Access Control
dholmes
parents:
diff changeset
   330
            failure(t);
2f2af62dfac7 8010319: Implementation of JEP 181: Nest-Based Access Control
dholmes
parents:
diff changeset
   331
        }
2f2af62dfac7 8010319: Implementation of JEP 181: Nest-Based Access Control
dholmes
parents:
diff changeset
   332
    }
2f2af62dfac7 8010319: Implementation of JEP 181: Nest-Based Access Control
dholmes
parents:
diff changeset
   333
2f2af62dfac7 8010319: Implementation of JEP 181: Nest-Based Access Control
dholmes
parents:
diff changeset
   334
    // override to give exception details
2f2af62dfac7 8010319: Implementation of JEP 181: Nest-Based Access Control
dholmes
parents:
diff changeset
   335
    protected void failure(Throwable t) {
2f2af62dfac7 8010319: Implementation of JEP 181: Nest-Based Access Control
dholmes
parents:
diff changeset
   336
        super.failure(t.getMessage());
2f2af62dfac7 8010319: Implementation of JEP 181: Nest-Based Access Control
dholmes
parents:
diff changeset
   337
        t.printStackTrace(System.out);
2f2af62dfac7 8010319: Implementation of JEP 181: Nest-Based Access Control
dholmes
parents:
diff changeset
   338
    }
2f2af62dfac7 8010319: Implementation of JEP 181: Nest-Based Access Control
dholmes
parents:
diff changeset
   339
2f2af62dfac7 8010319: Implementation of JEP 181: Nest-Based Access Control
dholmes
parents:
diff changeset
   340
    // These are references to the types in Target
2f2af62dfac7 8010319: Implementation of JEP 181: Nest-Based Access Control
dholmes
parents:
diff changeset
   341
    // that we will be trying to redefine.
2f2af62dfac7 8010319: Implementation of JEP 181: Nest-Based Access Control
dholmes
parents:
diff changeset
   342
    ReferenceType _Host;
2f2af62dfac7 8010319: Implementation of JEP 181: Nest-Based Access Control
dholmes
parents:
diff changeset
   343
    ReferenceType _Host_A_nested;
2f2af62dfac7 8010319: Implementation of JEP 181: Nest-Based Access Control
dholmes
parents:
diff changeset
   344
    ReferenceType _Host_A_topLevel;
2f2af62dfac7 8010319: Implementation of JEP 181: Nest-Based Access Control
dholmes
parents:
diff changeset
   345
2f2af62dfac7 8010319: Implementation of JEP 181: Nest-Based Access Control
dholmes
parents:
diff changeset
   346
    void findReferenceTypes() {
2f2af62dfac7 8010319: Implementation of JEP 181: Nest-Based Access Control
dholmes
parents:
diff changeset
   347
        List<ReferenceType> classes = vm().allClasses();
2f2af62dfac7 8010319: Implementation of JEP 181: Nest-Based Access Control
dholmes
parents:
diff changeset
   348
        ClassLoaderReference cl = null; // track the main loader
2f2af62dfac7 8010319: Implementation of JEP 181: Nest-Based Access Control
dholmes
parents:
diff changeset
   349
        ReferenceType a1 = null;
2f2af62dfac7 8010319: Implementation of JEP 181: Nest-Based Access Control
dholmes
parents:
diff changeset
   350
        ReferenceType a2 = null;
2f2af62dfac7 8010319: Implementation of JEP 181: Nest-Based Access Control
dholmes
parents:
diff changeset
   351
        for (ReferenceType c : classes) {
2f2af62dfac7 8010319: Implementation of JEP 181: Nest-Based Access Control
dholmes
parents:
diff changeset
   352
            String name = c.name();
2f2af62dfac7 8010319: Implementation of JEP 181: Nest-Based Access Control
dholmes
parents:
diff changeset
   353
            if (name.equals("Host")) {
2f2af62dfac7 8010319: Implementation of JEP 181: Nest-Based Access Control
dholmes
parents:
diff changeset
   354
                _Host = c;
2f2af62dfac7 8010319: Implementation of JEP 181: Nest-Based Access Control
dholmes
parents:
diff changeset
   355
                cl = c.classLoader();
2f2af62dfac7 8010319: Implementation of JEP 181: Nest-Based Access Control
dholmes
parents:
diff changeset
   356
            }
2f2af62dfac7 8010319: Implementation of JEP 181: Nest-Based Access Control
dholmes
parents:
diff changeset
   357
            else if (name.equals("Host$A")) {
2f2af62dfac7 8010319: Implementation of JEP 181: Nest-Based Access Control
dholmes
parents:
diff changeset
   358
                if (a1 == null) {
2f2af62dfac7 8010319: Implementation of JEP 181: Nest-Based Access Control
dholmes
parents:
diff changeset
   359
                    a1 = c;
2f2af62dfac7 8010319: Implementation of JEP 181: Nest-Based Access Control
dholmes
parents:
diff changeset
   360
                } else if (a2 == null) {
2f2af62dfac7 8010319: Implementation of JEP 181: Nest-Based Access Control
dholmes
parents:
diff changeset
   361
                    a2 = c;
2f2af62dfac7 8010319: Implementation of JEP 181: Nest-Based Access Control
dholmes
parents:
diff changeset
   362
                }
2f2af62dfac7 8010319: Implementation of JEP 181: Nest-Based Access Control
dholmes
parents:
diff changeset
   363
                else {
2f2af62dfac7 8010319: Implementation of JEP 181: Nest-Based Access Control
dholmes
parents:
diff changeset
   364
                    assertTrue(false); // Too many Host$A classes found!
2f2af62dfac7 8010319: Implementation of JEP 181: Nest-Based Access Control
dholmes
parents:
diff changeset
   365
                }
2f2af62dfac7 8010319: Implementation of JEP 181: Nest-Based Access Control
dholmes
parents:
diff changeset
   366
            }
2f2af62dfac7 8010319: Implementation of JEP 181: Nest-Based Access Control
dholmes
parents:
diff changeset
   367
        }
2f2af62dfac7 8010319: Implementation of JEP 181: Nest-Based Access Control
dholmes
parents:
diff changeset
   368
        assertTrue(_Host != null);
2f2af62dfac7 8010319: Implementation of JEP 181: Nest-Based Access Control
dholmes
parents:
diff changeset
   369
2f2af62dfac7 8010319: Implementation of JEP 181: Nest-Based Access Control
dholmes
parents:
diff changeset
   370
        // The rest of this setup is only needed for the case
2f2af62dfac7 8010319: Implementation of JEP 181: Nest-Based Access Control
dholmes
parents:
diff changeset
   371
        // when we perform the checkNestHostChanges() test.
2f2af62dfac7 8010319: Implementation of JEP 181: Nest-Based Access Control
dholmes
parents:
diff changeset
   372
        if (origin.equals("HostA")) {
2f2af62dfac7 8010319: Implementation of JEP 181: Nest-Based Access Control
dholmes
parents:
diff changeset
   373
            assertTrue(a1 != null);
2f2af62dfac7 8010319: Implementation of JEP 181: Nest-Based Access Control
dholmes
parents:
diff changeset
   374
            assertTrue(a2 != null);
2f2af62dfac7 8010319: Implementation of JEP 181: Nest-Based Access Control
dholmes
parents:
diff changeset
   375
2f2af62dfac7 8010319: Implementation of JEP 181: Nest-Based Access Control
dholmes
parents:
diff changeset
   376
            if (a1.classLoader() == cl) {
2f2af62dfac7 8010319: Implementation of JEP 181: Nest-Based Access Control
dholmes
parents:
diff changeset
   377
                _Host_A_nested = a1;
2f2af62dfac7 8010319: Implementation of JEP 181: Nest-Based Access Control
dholmes
parents:
diff changeset
   378
                assertTrue(a2.classLoader() != cl);
2f2af62dfac7 8010319: Implementation of JEP 181: Nest-Based Access Control
dholmes
parents:
diff changeset
   379
                _Host_A_topLevel = a2;
2f2af62dfac7 8010319: Implementation of JEP 181: Nest-Based Access Control
dholmes
parents:
diff changeset
   380
            }
2f2af62dfac7 8010319: Implementation of JEP 181: Nest-Based Access Control
dholmes
parents:
diff changeset
   381
            else if (a2.classLoader() == cl) {
2f2af62dfac7 8010319: Implementation of JEP 181: Nest-Based Access Control
dholmes
parents:
diff changeset
   382
                _Host_A_nested = a2;
2f2af62dfac7 8010319: Implementation of JEP 181: Nest-Based Access Control
dholmes
parents:
diff changeset
   383
                assertTrue(a1.classLoader() != cl);
2f2af62dfac7 8010319: Implementation of JEP 181: Nest-Based Access Control
dholmes
parents:
diff changeset
   384
                _Host_A_topLevel = a1;
2f2af62dfac7 8010319: Implementation of JEP 181: Nest-Based Access Control
dholmes
parents:
diff changeset
   385
            }
2f2af62dfac7 8010319: Implementation of JEP 181: Nest-Based Access Control
dholmes
parents:
diff changeset
   386
            else {
2f2af62dfac7 8010319: Implementation of JEP 181: Nest-Based Access Control
dholmes
parents:
diff changeset
   387
                assertTrue(false); // Wrong classLoaders found
2f2af62dfac7 8010319: Implementation of JEP 181: Nest-Based Access Control
dholmes
parents:
diff changeset
   388
            }
2f2af62dfac7 8010319: Implementation of JEP 181: Nest-Based Access Control
dholmes
parents:
diff changeset
   389
        }
2f2af62dfac7 8010319: Implementation of JEP 181: Nest-Based Access Control
dholmes
parents:
diff changeset
   390
    }
2f2af62dfac7 8010319: Implementation of JEP 181: Nest-Based Access Control
dholmes
parents:
diff changeset
   391
2f2af62dfac7 8010319: Implementation of JEP 181: Nest-Based Access Control
dholmes
parents:
diff changeset
   392
    void checkNestHostChanges() throws Throwable {
2f2af62dfac7 8010319: Implementation of JEP 181: Nest-Based Access Control
dholmes
parents:
diff changeset
   393
        Map<ReferenceType, byte[]> map = new HashMap<>();
2f2af62dfac7 8010319: Implementation of JEP 181: Nest-Based Access Control
dholmes
parents:
diff changeset
   394
2f2af62dfac7 8010319: Implementation of JEP 181: Nest-Based Access Control
dholmes
parents:
diff changeset
   395
        // case 1: remove NestHost attribute
2f2af62dfac7 8010319: Implementation of JEP 181: Nest-Based Access Control
dholmes
parents:
diff changeset
   396
        //   - try to redefine nested Host$A with a top-level
2f2af62dfac7 8010319: Implementation of JEP 181: Nest-Based Access Control
dholmes
parents:
diff changeset
   397
        //     class called Host$A
2f2af62dfac7 8010319: Implementation of JEP 181: Nest-Based Access Control
dholmes
parents:
diff changeset
   398
        System.out.println("Trying bad retransform that removes the NestHost attribute");
2f2af62dfac7 8010319: Implementation of JEP 181: Nest-Based Access Control
dholmes
parents:
diff changeset
   399
2f2af62dfac7 8010319: Implementation of JEP 181: Nest-Based Access Control
dholmes
parents:
diff changeset
   400
        String name = "Host$A";
2f2af62dfac7 8010319: Implementation of JEP 181: Nest-Based Access Control
dholmes
parents:
diff changeset
   401
2f2af62dfac7 8010319: Implementation of JEP 181: Nest-Based Access Control
dholmes
parents:
diff changeset
   402
        // This is compiled as a top-level class: the $ in the name is not
2f2af62dfac7 8010319: Implementation of JEP 181: Nest-Based Access Control
dholmes
parents:
diff changeset
   403
        // significant to the compiler.
2f2af62dfac7 8010319: Implementation of JEP 181: Nest-Based Access Control
dholmes
parents:
diff changeset
   404
        String hostA = "public class " + name + " {}";
2f2af62dfac7 8010319: Implementation of JEP 181: Nest-Based Access Control
dholmes
parents:
diff changeset
   405
        byte[] bytes = InMemoryJavaCompiler.compile(name, hostA);
2f2af62dfac7 8010319: Implementation of JEP 181: Nest-Based Access Control
dholmes
parents:
diff changeset
   406
2f2af62dfac7 8010319: Implementation of JEP 181: Nest-Based Access Control
dholmes
parents:
diff changeset
   407
        map.put(_Host_A_nested, bytes);
2f2af62dfac7 8010319: Implementation of JEP 181: Nest-Based Access Control
dholmes
parents:
diff changeset
   408
2f2af62dfac7 8010319: Implementation of JEP 181: Nest-Based Access Control
dholmes
parents:
diff changeset
   409
        try {
2f2af62dfac7 8010319: Implementation of JEP 181: Nest-Based Access Control
dholmes
parents:
diff changeset
   410
            vm().redefineClasses(map);
2f2af62dfac7 8010319: Implementation of JEP 181: Nest-Based Access Control
dholmes
parents:
diff changeset
   411
            throw new Error("Retransformation to top-level class " + name +
2f2af62dfac7 8010319: Implementation of JEP 181: Nest-Based Access Control
dholmes
parents:
diff changeset
   412
                            " succeeded unexpectedly");
2f2af62dfac7 8010319: Implementation of JEP 181: Nest-Based Access Control
dholmes
parents:
diff changeset
   413
        }
2f2af62dfac7 8010319: Implementation of JEP 181: Nest-Based Access Control
dholmes
parents:
diff changeset
   414
        catch (UnsupportedOperationException uoe) {
2f2af62dfac7 8010319: Implementation of JEP 181: Nest-Based Access Control
dholmes
parents:
diff changeset
   415
            if (uoe.getMessage().contains("changes to class attribute not implemented")) {
2f2af62dfac7 8010319: Implementation of JEP 181: Nest-Based Access Control
dholmes
parents:
diff changeset
   416
                System.out.println("Got expected exception " + uoe);
2f2af62dfac7 8010319: Implementation of JEP 181: Nest-Based Access Control
dholmes
parents:
diff changeset
   417
            }
2f2af62dfac7 8010319: Implementation of JEP 181: Nest-Based Access Control
dholmes
parents:
diff changeset
   418
            else throw new Error("Wrong UnsupportedOperationException", uoe);
2f2af62dfac7 8010319: Implementation of JEP 181: Nest-Based Access Control
dholmes
parents:
diff changeset
   419
        }
2f2af62dfac7 8010319: Implementation of JEP 181: Nest-Based Access Control
dholmes
parents:
diff changeset
   420
2f2af62dfac7 8010319: Implementation of JEP 181: Nest-Based Access Control
dholmes
parents:
diff changeset
   421
        map.clear();
2f2af62dfac7 8010319: Implementation of JEP 181: Nest-Based Access Control
dholmes
parents:
diff changeset
   422
2f2af62dfac7 8010319: Implementation of JEP 181: Nest-Based Access Control
dholmes
parents:
diff changeset
   423
        // case 2: add NestHost attribute
2f2af62dfac7 8010319: Implementation of JEP 181: Nest-Based Access Control
dholmes
parents:
diff changeset
   424
        //  - This is tricky because the class with no NestHost attribute
2f2af62dfac7 8010319: Implementation of JEP 181: Nest-Based Access Control
dholmes
parents:
diff changeset
   425
        //    has to have the name of a nested class! But we know how to
2f2af62dfac7 8010319: Implementation of JEP 181: Nest-Based Access Control
dholmes
parents:
diff changeset
   426
        //    do that as we already created a top-level Host$A. So now
2f2af62dfac7 8010319: Implementation of JEP 181: Nest-Based Access Control
dholmes
parents:
diff changeset
   427
        //    we try to replace with a really nested Host$A.
2f2af62dfac7 8010319: Implementation of JEP 181: Nest-Based Access Control
dholmes
parents:
diff changeset
   428
2f2af62dfac7 8010319: Implementation of JEP 181: Nest-Based Access Control
dholmes
parents:
diff changeset
   429
        System.out.println("Trying bad retransform that adds the NestHost attribute");
2f2af62dfac7 8010319: Implementation of JEP 181: Nest-Based Access Control
dholmes
parents:
diff changeset
   430
2f2af62dfac7 8010319: Implementation of JEP 181: Nest-Based Access Control
dholmes
parents:
diff changeset
   431
        byte[] nestedBytes;
2f2af62dfac7 8010319: Implementation of JEP 181: Nest-Based Access Control
dholmes
parents:
diff changeset
   432
        File clsfile = new File(DEST + "/" + name + ".class");
2f2af62dfac7 8010319: Implementation of JEP 181: Nest-Based Access Control
dholmes
parents:
diff changeset
   433
        if (VERBOSE) System.out.println("Reading bytes from " + clsfile);
2f2af62dfac7 8010319: Implementation of JEP 181: Nest-Based Access Control
dholmes
parents:
diff changeset
   434
        try (FileInputStream str = new FileInputStream(clsfile)) {
2f2af62dfac7 8010319: Implementation of JEP 181: Nest-Based Access Control
dholmes
parents:
diff changeset
   435
            nestedBytes = NamedBuffer.loadBufferFromStream(str);
2f2af62dfac7 8010319: Implementation of JEP 181: Nest-Based Access Control
dholmes
parents:
diff changeset
   436
        }
2f2af62dfac7 8010319: Implementation of JEP 181: Nest-Based Access Control
dholmes
parents:
diff changeset
   437
2f2af62dfac7 8010319: Implementation of JEP 181: Nest-Based Access Control
dholmes
parents:
diff changeset
   438
        map.put(_Host_A_topLevel, nestedBytes);
2f2af62dfac7 8010319: Implementation of JEP 181: Nest-Based Access Control
dholmes
parents:
diff changeset
   439
2f2af62dfac7 8010319: Implementation of JEP 181: Nest-Based Access Control
dholmes
parents:
diff changeset
   440
        try {
2f2af62dfac7 8010319: Implementation of JEP 181: Nest-Based Access Control
dholmes
parents:
diff changeset
   441
            vm().redefineClasses(map);
2f2af62dfac7 8010319: Implementation of JEP 181: Nest-Based Access Control
dholmes
parents:
diff changeset
   442
            throw new Error("Retransformation to nested class " + name +
2f2af62dfac7 8010319: Implementation of JEP 181: Nest-Based Access Control
dholmes
parents:
diff changeset
   443
                            " succeeded unexpectedly");
2f2af62dfac7 8010319: Implementation of JEP 181: Nest-Based Access Control
dholmes
parents:
diff changeset
   444
        }
2f2af62dfac7 8010319: Implementation of JEP 181: Nest-Based Access Control
dholmes
parents:
diff changeset
   445
        catch (UnsupportedOperationException uoe) {
2f2af62dfac7 8010319: Implementation of JEP 181: Nest-Based Access Control
dholmes
parents:
diff changeset
   446
            if (uoe.getMessage().contains("changes to class attribute not implemented")) {
2f2af62dfac7 8010319: Implementation of JEP 181: Nest-Based Access Control
dholmes
parents:
diff changeset
   447
                System.out.println("Got expected exception " + uoe);
2f2af62dfac7 8010319: Implementation of JEP 181: Nest-Based Access Control
dholmes
parents:
diff changeset
   448
            }
2f2af62dfac7 8010319: Implementation of JEP 181: Nest-Based Access Control
dholmes
parents:
diff changeset
   449
            else throw new Error("Wrong UnsupportedOperationException", uoe);
2f2af62dfac7 8010319: Implementation of JEP 181: Nest-Based Access Control
dholmes
parents:
diff changeset
   450
        }
2f2af62dfac7 8010319: Implementation of JEP 181: Nest-Based Access Control
dholmes
parents:
diff changeset
   451
2f2af62dfac7 8010319: Implementation of JEP 181: Nest-Based Access Control
dholmes
parents:
diff changeset
   452
        map.clear();
2f2af62dfac7 8010319: Implementation of JEP 181: Nest-Based Access Control
dholmes
parents:
diff changeset
   453
2f2af62dfac7 8010319: Implementation of JEP 181: Nest-Based Access Control
dholmes
parents:
diff changeset
   454
        // case 3: replace the NestHost attribute
2f2af62dfac7 8010319: Implementation of JEP 181: Nest-Based Access Control
dholmes
parents:
diff changeset
   455
        //  - the easiest way (perhaps only reasonable way) to do this
2f2af62dfac7 8010319: Implementation of JEP 181: Nest-Based Access Control
dholmes
parents:
diff changeset
   456
        //    is to search for the Utf8 entry used by the Constant_ClassRef,
2f2af62dfac7 8010319: Implementation of JEP 181: Nest-Based Access Control
dholmes
parents:
diff changeset
   457
        //    set in the NestHost attribute, and edit it to refer to a different
2f2af62dfac7 8010319: Implementation of JEP 181: Nest-Based Access Control
dholmes
parents:
diff changeset
   458
        //    name. We reuse nestedBytes from above.
2f2af62dfac7 8010319: Implementation of JEP 181: Nest-Based Access Control
dholmes
parents:
diff changeset
   459
2f2af62dfac7 8010319: Implementation of JEP 181: Nest-Based Access Control
dholmes
parents:
diff changeset
   460
        System.out.println("Trying bad retransform that changes the NestHost attribute");
2f2af62dfac7 8010319: Implementation of JEP 181: Nest-Based Access Control
dholmes
parents:
diff changeset
   461
2f2af62dfac7 8010319: Implementation of JEP 181: Nest-Based Access Control
dholmes
parents:
diff changeset
   462
        int utf8Entry_length = 7;
2f2af62dfac7 8010319: Implementation of JEP 181: Nest-Based Access Control
dholmes
parents:
diff changeset
   463
        boolean found = false;
2f2af62dfac7 8010319: Implementation of JEP 181: Nest-Based Access Control
dholmes
parents:
diff changeset
   464
        for (int i = 0; i < nestedBytes.length - utf8Entry_length; i++) {
2f2af62dfac7 8010319: Implementation of JEP 181: Nest-Based Access Control
dholmes
parents:
diff changeset
   465
            if (nestedBytes[i] == 1 &&   // utf8 tag
2f2af62dfac7 8010319: Implementation of JEP 181: Nest-Based Access Control
dholmes
parents:
diff changeset
   466
                nestedBytes[i+1] == 0 && // msb of length
2f2af62dfac7 8010319: Implementation of JEP 181: Nest-Based Access Control
dholmes
parents:
diff changeset
   467
                nestedBytes[i+2] == 4 && // lsb of length
2f2af62dfac7 8010319: Implementation of JEP 181: Nest-Based Access Control
dholmes
parents:
diff changeset
   468
                nestedBytes[i+3] == (byte) 'H' &&
2f2af62dfac7 8010319: Implementation of JEP 181: Nest-Based Access Control
dholmes
parents:
diff changeset
   469
                nestedBytes[i+4] == (byte) 'o' &&
2f2af62dfac7 8010319: Implementation of JEP 181: Nest-Based Access Control
dholmes
parents:
diff changeset
   470
                nestedBytes[i+5] == (byte) 's' &&
2f2af62dfac7 8010319: Implementation of JEP 181: Nest-Based Access Control
dholmes
parents:
diff changeset
   471
                nestedBytes[i+6] == (byte) 't') {
2f2af62dfac7 8010319: Implementation of JEP 181: Nest-Based Access Control
dholmes
parents:
diff changeset
   472
2f2af62dfac7 8010319: Implementation of JEP 181: Nest-Based Access Control
dholmes
parents:
diff changeset
   473
                if (VERBOSE) System.out.println("Appear to have found Host utf8 entry starting at " + i);
2f2af62dfac7 8010319: Implementation of JEP 181: Nest-Based Access Control
dholmes
parents:
diff changeset
   474
2f2af62dfac7 8010319: Implementation of JEP 181: Nest-Based Access Control
dholmes
parents:
diff changeset
   475
                nestedBytes[i+3] = (byte) 'G';
2f2af62dfac7 8010319: Implementation of JEP 181: Nest-Based Access Control
dholmes
parents:
diff changeset
   476
                found = true;
2f2af62dfac7 8010319: Implementation of JEP 181: Nest-Based Access Control
dholmes
parents:
diff changeset
   477
                break;
2f2af62dfac7 8010319: Implementation of JEP 181: Nest-Based Access Control
dholmes
parents:
diff changeset
   478
            }
2f2af62dfac7 8010319: Implementation of JEP 181: Nest-Based Access Control
dholmes
parents:
diff changeset
   479
        }
2f2af62dfac7 8010319: Implementation of JEP 181: Nest-Based Access Control
dholmes
parents:
diff changeset
   480
2f2af62dfac7 8010319: Implementation of JEP 181: Nest-Based Access Control
dholmes
parents:
diff changeset
   481
        if (!found)
2f2af62dfac7 8010319: Implementation of JEP 181: Nest-Based Access Control
dholmes
parents:
diff changeset
   482
            throw new Error("Could not locate 'Host' name in byte array");
2f2af62dfac7 8010319: Implementation of JEP 181: Nest-Based Access Control
dholmes
parents:
diff changeset
   483
2f2af62dfac7 8010319: Implementation of JEP 181: Nest-Based Access Control
dholmes
parents:
diff changeset
   484
        map.put(_Host_A_nested, nestedBytes);
2f2af62dfac7 8010319: Implementation of JEP 181: Nest-Based Access Control
dholmes
parents:
diff changeset
   485
2f2af62dfac7 8010319: Implementation of JEP 181: Nest-Based Access Control
dholmes
parents:
diff changeset
   486
        try {
2f2af62dfac7 8010319: Implementation of JEP 181: Nest-Based Access Control
dholmes
parents:
diff changeset
   487
            vm().redefineClasses(map);
2f2af62dfac7 8010319: Implementation of JEP 181: Nest-Based Access Control
dholmes
parents:
diff changeset
   488
            throw new Error("Retransformation to modified nested class" +
2f2af62dfac7 8010319: Implementation of JEP 181: Nest-Based Access Control
dholmes
parents:
diff changeset
   489
                            " succeeded unexpectedly");
2f2af62dfac7 8010319: Implementation of JEP 181: Nest-Based Access Control
dholmes
parents:
diff changeset
   490
        }
2f2af62dfac7 8010319: Implementation of JEP 181: Nest-Based Access Control
dholmes
parents:
diff changeset
   491
        catch (UnsupportedOperationException uoe) {
2f2af62dfac7 8010319: Implementation of JEP 181: Nest-Based Access Control
dholmes
parents:
diff changeset
   492
            if (uoe.getMessage().contains("changes to class attribute not implemented")) {
2f2af62dfac7 8010319: Implementation of JEP 181: Nest-Based Access Control
dholmes
parents:
diff changeset
   493
                System.out.println("Got expected exception " + uoe);
2f2af62dfac7 8010319: Implementation of JEP 181: Nest-Based Access Control
dholmes
parents:
diff changeset
   494
            }
2f2af62dfac7 8010319: Implementation of JEP 181: Nest-Based Access Control
dholmes
parents:
diff changeset
   495
            else throw new Error("Wrong UnsupportedOperationException", uoe);
2f2af62dfac7 8010319: Implementation of JEP 181: Nest-Based Access Control
dholmes
parents:
diff changeset
   496
        }
2f2af62dfac7 8010319: Implementation of JEP 181: Nest-Based Access Control
dholmes
parents:
diff changeset
   497
2f2af62dfac7 8010319: Implementation of JEP 181: Nest-Based Access Control
dholmes
parents:
diff changeset
   498
    }
2f2af62dfac7 8010319: Implementation of JEP 181: Nest-Based Access Control
dholmes
parents:
diff changeset
   499
2f2af62dfac7 8010319: Implementation of JEP 181: Nest-Based Access Control
dholmes
parents:
diff changeset
   500
    void checkGoodTransforms(ReferenceType c, String[] dirs) throws Throwable {
2f2af62dfac7 8010319: Implementation of JEP 181: Nest-Based Access Control
dholmes
parents:
diff changeset
   501
        // To verify the redefinition actually took place we will invoke the
2f2af62dfac7 8010319: Implementation of JEP 181: Nest-Based Access Control
dholmes
parents:
diff changeset
   502
        // Host.getID method and check the result. To do that we need to find the
2f2af62dfac7 8010319: Implementation of JEP 181: Nest-Based Access Control
dholmes
parents:
diff changeset
   503
        // main thread in the target VM. We don't check that "(new Host()).m()"
2f2af62dfac7 8010319: Implementation of JEP 181: Nest-Based Access Control
dholmes
parents:
diff changeset
   504
        // returns 2 due to the complexity of setting that up via JDI.
2f2af62dfac7 8010319: Implementation of JEP 181: Nest-Based Access Control
dholmes
parents:
diff changeset
   505
2f2af62dfac7 8010319: Implementation of JEP 181: Nest-Based Access Control
dholmes
parents:
diff changeset
   506
        ThreadReference main = null;
2f2af62dfac7 8010319: Implementation of JEP 181: Nest-Based Access Control
dholmes
parents:
diff changeset
   507
        List<ThreadReference> threads = vm().allThreads();
2f2af62dfac7 8010319: Implementation of JEP 181: Nest-Based Access Control
dholmes
parents:
diff changeset
   508
        for (ThreadReference t : threads) {
2f2af62dfac7 8010319: Implementation of JEP 181: Nest-Based Access Control
dholmes
parents:
diff changeset
   509
            if (t.name().equals("main")) {
2f2af62dfac7 8010319: Implementation of JEP 181: Nest-Based Access Control
dholmes
parents:
diff changeset
   510
                main = t;
2f2af62dfac7 8010319: Implementation of JEP 181: Nest-Based Access Control
dholmes
parents:
diff changeset
   511
                break;
2f2af62dfac7 8010319: Implementation of JEP 181: Nest-Based Access Control
dholmes
parents:
diff changeset
   512
            }
2f2af62dfac7 8010319: Implementation of JEP 181: Nest-Based Access Control
dholmes
parents:
diff changeset
   513
        }
2f2af62dfac7 8010319: Implementation of JEP 181: Nest-Based Access Control
dholmes
parents:
diff changeset
   514
2f2af62dfac7 8010319: Implementation of JEP 181: Nest-Based Access Control
dholmes
parents:
diff changeset
   515
        assertTrue(main != null);
2f2af62dfac7 8010319: Implementation of JEP 181: Nest-Based Access Control
dholmes
parents:
diff changeset
   516
2f2af62dfac7 8010319: Implementation of JEP 181: Nest-Based Access Control
dholmes
parents:
diff changeset
   517
        // Now find the method
2f2af62dfac7 8010319: Implementation of JEP 181: Nest-Based Access Control
dholmes
parents:
diff changeset
   518
        Method getID = null;
2f2af62dfac7 8010319: Implementation of JEP 181: Nest-Based Access Control
dholmes
parents:
diff changeset
   519
        List<Method> methods = _Host.methodsByName("getID");
2f2af62dfac7 8010319: Implementation of JEP 181: Nest-Based Access Control
dholmes
parents:
diff changeset
   520
        assertTrue(methods.size() == 1);
2f2af62dfac7 8010319: Implementation of JEP 181: Nest-Based Access Control
dholmes
parents:
diff changeset
   521
        getID = methods.get(0);
2f2af62dfac7 8010319: Implementation of JEP 181: Nest-Based Access Control
dholmes
parents:
diff changeset
   522
2f2af62dfac7 8010319: Implementation of JEP 181: Nest-Based Access Control
dholmes
parents:
diff changeset
   523
        Map<ReferenceType, byte[]> map = new HashMap<>();
2f2af62dfac7 8010319: Implementation of JEP 181: Nest-Based Access Control
dholmes
parents:
diff changeset
   524
        for (String dir : dirs) {
2f2af62dfac7 8010319: Implementation of JEP 181: Nest-Based Access Control
dholmes
parents:
diff changeset
   525
            dir += "/redef";
2f2af62dfac7 8010319: Implementation of JEP 181: Nest-Based Access Control
dholmes
parents:
diff changeset
   526
            System.out.println("Trying good retransform from " + dir);
2f2af62dfac7 8010319: Implementation of JEP 181: Nest-Based Access Control
dholmes
parents:
diff changeset
   527
            byte[] buf = bytesForHostClass(dir);
2f2af62dfac7 8010319: Implementation of JEP 181: Nest-Based Access Control
dholmes
parents:
diff changeset
   528
            map.put(c, buf);
2f2af62dfac7 8010319: Implementation of JEP 181: Nest-Based Access Control
dholmes
parents:
diff changeset
   529
            vm().redefineClasses(map);
2f2af62dfac7 8010319: Implementation of JEP 181: Nest-Based Access Control
dholmes
parents:
diff changeset
   530
            map.clear();
2f2af62dfac7 8010319: Implementation of JEP 181: Nest-Based Access Control
dholmes
parents:
diff changeset
   531
            // Test redefinition worked
2f2af62dfac7 8010319: Implementation of JEP 181: Nest-Based Access Control
dholmes
parents:
diff changeset
   532
            Value v = ((ClassType)_Host).invokeMethod(main, getID, Collections.emptyList(), 0);
2f2af62dfac7 8010319: Implementation of JEP 181: Nest-Based Access Control
dholmes
parents:
diff changeset
   533
            assertTrue(v instanceof StringReference);
2f2af62dfac7 8010319: Implementation of JEP 181: Nest-Based Access Control
dholmes
parents:
diff changeset
   534
            String id =  ((StringReference)v).value();
2f2af62dfac7 8010319: Implementation of JEP 181: Nest-Based Access Control
dholmes
parents:
diff changeset
   535
            if (VERBOSE) System.out.println("Redefined ID: " + id);
2f2af62dfac7 8010319: Implementation of JEP 181: Nest-Based Access Control
dholmes
parents:
diff changeset
   536
            assertTrue(id.startsWith(dir));
2f2af62dfac7 8010319: Implementation of JEP 181: Nest-Based Access Control
dholmes
parents:
diff changeset
   537
            assertTrue(id.contains("/redef/"));
2f2af62dfac7 8010319: Implementation of JEP 181: Nest-Based Access Control
dholmes
parents:
diff changeset
   538
        }
2f2af62dfac7 8010319: Implementation of JEP 181: Nest-Based Access Control
dholmes
parents:
diff changeset
   539
    }
2f2af62dfac7 8010319: Implementation of JEP 181: Nest-Based Access Control
dholmes
parents:
diff changeset
   540
2f2af62dfac7 8010319: Implementation of JEP 181: Nest-Based Access Control
dholmes
parents:
diff changeset
   541
    void checkBadTransforms(ReferenceType c, String[] dirs) throws Throwable {
2f2af62dfac7 8010319: Implementation of JEP 181: Nest-Based Access Control
dholmes
parents:
diff changeset
   542
        Map<ReferenceType, byte[]> map = new HashMap<>();
2f2af62dfac7 8010319: Implementation of JEP 181: Nest-Based Access Control
dholmes
parents:
diff changeset
   543
        for (String dir : dirs) {
2f2af62dfac7 8010319: Implementation of JEP 181: Nest-Based Access Control
dholmes
parents:
diff changeset
   544
            dir += "/redef";
2f2af62dfac7 8010319: Implementation of JEP 181: Nest-Based Access Control
dholmes
parents:
diff changeset
   545
            System.out.println("Trying bad retransform from " + dir);
2f2af62dfac7 8010319: Implementation of JEP 181: Nest-Based Access Control
dholmes
parents:
diff changeset
   546
            byte[] buf = bytesForHostClass(dir);
2f2af62dfac7 8010319: Implementation of JEP 181: Nest-Based Access Control
dholmes
parents:
diff changeset
   547
            map.put(c, buf);
2f2af62dfac7 8010319: Implementation of JEP 181: Nest-Based Access Control
dholmes
parents:
diff changeset
   548
            try {
2f2af62dfac7 8010319: Implementation of JEP 181: Nest-Based Access Control
dholmes
parents:
diff changeset
   549
                vm().redefineClasses(map);
2f2af62dfac7 8010319: Implementation of JEP 181: Nest-Based Access Control
dholmes
parents:
diff changeset
   550
                throw new Error("Retransformation from directory " + dir +
2f2af62dfac7 8010319: Implementation of JEP 181: Nest-Based Access Control
dholmes
parents:
diff changeset
   551
                                " succeeded unexpectedly");
2f2af62dfac7 8010319: Implementation of JEP 181: Nest-Based Access Control
dholmes
parents:
diff changeset
   552
            }
2f2af62dfac7 8010319: Implementation of JEP 181: Nest-Based Access Control
dholmes
parents:
diff changeset
   553
            catch (UnsupportedOperationException uoe) {
2f2af62dfac7 8010319: Implementation of JEP 181: Nest-Based Access Control
dholmes
parents:
diff changeset
   554
                if (uoe.getMessage().contains("changes to class attribute not implemented")) {
2f2af62dfac7 8010319: Implementation of JEP 181: Nest-Based Access Control
dholmes
parents:
diff changeset
   555
                    System.out.println("Got expected exception " + uoe);
2f2af62dfac7 8010319: Implementation of JEP 181: Nest-Based Access Control
dholmes
parents:
diff changeset
   556
                }
2f2af62dfac7 8010319: Implementation of JEP 181: Nest-Based Access Control
dholmes
parents:
diff changeset
   557
                else throw new Error("Wrong UnsupportedOperationException", uoe);
2f2af62dfac7 8010319: Implementation of JEP 181: Nest-Based Access Control
dholmes
parents:
diff changeset
   558
            }
2f2af62dfac7 8010319: Implementation of JEP 181: Nest-Based Access Control
dholmes
parents:
diff changeset
   559
        }
2f2af62dfac7 8010319: Implementation of JEP 181: Nest-Based Access Control
dholmes
parents:
diff changeset
   560
    }
2f2af62dfac7 8010319: Implementation of JEP 181: Nest-Based Access Control
dholmes
parents:
diff changeset
   561
2f2af62dfac7 8010319: Implementation of JEP 181: Nest-Based Access Control
dholmes
parents:
diff changeset
   562
    static byte[] bytesForHostClass(String dir) throws Throwable {
2f2af62dfac7 8010319: Implementation of JEP 181: Nest-Based Access Control
dholmes
parents:
diff changeset
   563
        compile("/" + dir);
2f2af62dfac7 8010319: Implementation of JEP 181: Nest-Based Access Control
dholmes
parents:
diff changeset
   564
        File clsfile = new File(DEST + "/" + dir + "/Host.class");
2f2af62dfac7 8010319: Implementation of JEP 181: Nest-Based Access Control
dholmes
parents:
diff changeset
   565
        if (VERBOSE) System.out.println("Reading bytes from " + clsfile);
2f2af62dfac7 8010319: Implementation of JEP 181: Nest-Based Access Control
dholmes
parents:
diff changeset
   566
        byte[] buf = null;
2f2af62dfac7 8010319: Implementation of JEP 181: Nest-Based Access Control
dholmes
parents:
diff changeset
   567
        try (FileInputStream str = new FileInputStream(clsfile)) {
2f2af62dfac7 8010319: Implementation of JEP 181: Nest-Based Access Control
dholmes
parents:
diff changeset
   568
            return buf = NamedBuffer.loadBufferFromStream(str);
2f2af62dfac7 8010319: Implementation of JEP 181: Nest-Based Access Control
dholmes
parents:
diff changeset
   569
        }
2f2af62dfac7 8010319: Implementation of JEP 181: Nest-Based Access Control
dholmes
parents:
diff changeset
   570
    }
2f2af62dfac7 8010319: Implementation of JEP 181: Nest-Based Access Control
dholmes
parents:
diff changeset
   571
2f2af62dfac7 8010319: Implementation of JEP 181: Nest-Based Access Control
dholmes
parents:
diff changeset
   572
    static void compile(String dir) throws Throwable {
2f2af62dfac7 8010319: Implementation of JEP 181: Nest-Based Access Control
dholmes
parents:
diff changeset
   573
        File src = new File(SRC + dir);
2f2af62dfac7 8010319: Implementation of JEP 181: Nest-Based Access Control
dholmes
parents:
diff changeset
   574
        File dst = new File(DEST + dir);
2f2af62dfac7 8010319: Implementation of JEP 181: Nest-Based Access Control
dholmes
parents:
diff changeset
   575
        if (VERBOSE) System.out.println("Compiling from: " + src + "\n" +
2f2af62dfac7 8010319: Implementation of JEP 181: Nest-Based Access Control
dholmes
parents:
diff changeset
   576
                                        "            to: " + dst);
2f2af62dfac7 8010319: Implementation of JEP 181: Nest-Based Access Control
dholmes
parents:
diff changeset
   577
        CompilerUtils.compile(src.toPath(),
2f2af62dfac7 8010319: Implementation of JEP 181: Nest-Based Access Control
dholmes
parents:
diff changeset
   578
                              dst.toPath(),
2f2af62dfac7 8010319: Implementation of JEP 181: Nest-Based Access Control
dholmes
parents:
diff changeset
   579
                              false /* don't recurse */,
2f2af62dfac7 8010319: Implementation of JEP 181: Nest-Based Access Control
dholmes
parents:
diff changeset
   580
                              new String[0]);
2f2af62dfac7 8010319: Implementation of JEP 181: Nest-Based Access Control
dholmes
parents:
diff changeset
   581
    }
2f2af62dfac7 8010319: Implementation of JEP 181: Nest-Based Access Control
dholmes
parents:
diff changeset
   582
}