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 /*
  26  * @test
  27  * @summary test reflection on value types
  28  * @compile -XDallowWithFieldOperator Point.java Line.java
  29  * @run main/othervm -XX:+EnableValhalla Reflection
  30  */
  31 
  32 import java.lang.reflect.*;
  33 
  34 public class Reflection {
  35     public static void main(String... args) throws Exception {
  36         testPointClass();
  37         testLineClass();
  38     }
  39 
  40     static void testPointClass() throws Exception  {
  41         Point o = Point.makePoint(10, 20);
  42         Reflection test = new Reflection("Point", o);
  43         test.newInstance();
  44         test.constructor();
  45         test.accessFieldX(o.x);
  46         test.setAccessible();
  47         test.trySetAccessible();
  48         test.staticField();
  49     }
  50 
  51     static void testLineClass() throws Exception {
  52         Line l = Line.makeLine(10, 20, 30, 40);
  53         Reflection test = new Reflection("Line", l);
  54         test.getDeclaredFields();
  55     }
  56 
  57     private final Class<?> c;
  58     private final Constructor<?> ctor;
  59     private final Object o;
  60     Reflection(String cn, Object o) throws Exception {
  61         this.c = Class.forName(cn);
  62         if (!c.isValue()) {
  63             throw new RuntimeException(cn + " is not a value class");
  64         }
  65 
  66         this.ctor = c.getDeclaredConstructor();
  67         this.o = o;
  68     }
  69 
  70     void accessFieldX(int x) throws Exception {
  71         Field field = c.getField("x");
  72         if (field.getInt(o) != x) {
  73             throw new RuntimeException("Unexpected Point.x value: " +  field.getInt(o));
  74         }
  75 
  76         try {
  77             field.setInt(o, 100);
  78             throw new RuntimeException("IllegalAccessException not thrown");
  79         } catch (IllegalAccessException e) {}
  80     }
  81 
  82     void newInstance() throws Exception {
  83         try {
  84             Object o = c.newInstance();
  85             throw new RuntimeException("newInstance expected to be unsupported on value class");
  86         } catch (IllegalAccessException e) {}
  87     }
  88 
  89     void constructor() throws Exception {
  90         try {
  91             ctor.newInstance();
  92             throw new RuntimeException("IllegalAccessException not thrown");
  93         } catch (IllegalAccessException e) { }
  94     }
  95 
  96     void setAccessible() throws Exception {
  97         try {
  98             ctor.setAccessible(true);
  99             throw new RuntimeException("InaccessibleObjectException not thrown");
 100         } catch (InaccessibleObjectException e) { e.printStackTrace(); }
 101         Field field = c.getField("x");
 102         try {
 103             field.setAccessible(true);
 104             throw new RuntimeException("InaccessibleObjectException not thrown");
 105         } catch (InaccessibleObjectException e) { e.printStackTrace(); }
 106     }
 107 
 108     void trySetAccessible() throws Exception {
 109         if (ctor.trySetAccessible()) {
 110             throw new RuntimeException("trySetAccessible should not succeed");
 111         }
 112         Field field = c.getField("x");
 113         if (field.trySetAccessible()) {
 114             throw new RuntimeException("trySetAccessible should not succeed");
 115         }
 116     }
 117 
 118     void staticField() throws Exception {
 119         Field f = c.getDeclaredField("STATIC_FIELD");
 120         if (f.trySetAccessible()) {
 121             throw new RuntimeException("trySetAccessible should not succeed");
 122         }
 123         try {
 124             f.setAccessible(true);
 125             throw new RuntimeException("IllegalAccessException not thrown");
 126         } catch (InaccessibleObjectException e) { }
 127     }
 128 
 129     void getDeclaredFields() throws Exception {
 130         for (Field f : c.getDeclaredFields()) {
 131             System.out.println(f.getName() + " = " + f.get(o));
 132         }
 133     }
 134 }