1 /* 2 * Copyright (c) 2018, 2019, Oracle and/or its affiliates. All rights reserved. 3 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. 4 * 5 * This code is free software; you can redistribute it and/or modify it 6 * under the terms of the GNU General Public License version 2 only, as 7 * published by the Free Software Foundation. Oracle designates this 8 * particular file as subject to the "Classpath" exception as provided 9 * by Oracle in the LICENSE file that accompanied this code. 10 * 11 * This code is distributed in the hope that it will be useful, but WITHOUT 12 * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or 13 * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License 14 * version 2 for more details (a copy is included in the LICENSE file that 15 * accompanied this code). 16 * 17 * You should have received a copy of the GNU General Public License version 18 * 2 along with this work; if not, write to the Free Software Foundation, 19 * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. 20 * 21 * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA 22 * or visit www.oracle.com if you need additional information or have any 23 * questions. 24 */ 25 26 package jdk.jfr.api.event; 27 28 import java.io.IOException; 29 import java.util.List; 30 31 import jdk.jfr.Event; 32 import jdk.jfr.EventType; 33 import jdk.jfr.FlightRecorder; 34 import jdk.jfr.Recording; 35 import jdk.jfr.Registered; 36 import jdk.jfr.consumer.RecordedEvent; 37 import jdk.testlibrary.Asserts; 38 import jdk.testlibrary.jfr.Events; 39 40 /* 41 * @test 42 * @summary Test enable/disable event and verify recording has expected events. 43 * @key jfr 44 * @library /lib/testlibrary 45 * @run main/othervm jdk.jfr.api.event.TestClinitRegistration 46 */ 47 48 public class TestClinitRegistration { 49 50 public static void main(String[] args) throws Exception { 51 // Test basic registration with or without auto registration 52 assertClinitRegister(AutoRegisteredEvent.class, true, false); 53 assertClinitRegister(NotAutoRegisterededEvent.class, false, false); 54 assertClinitRegister(AutoRegisteredUserClinit.class, true, true); 55 assertClinitRegister(NotAutoRegisteredUserClinit.class, false, true); 56 57 // Test complex <clinit> 58 assertClinitRegister(ComplexClInit.class, true, true); 59 60 // Test hierarchy 61 assertClinitRegister(DerivedClinit.class, true, true); 62 if (!isClinitExecuted(Base.class)) { 63 Asserts.fail("Expected <clinit> of base class to be executed"); 64 } 65 66 // Test committed event in <clinit> 67 Recording r = new Recording(); 68 r.start(); 69 r.enable(EventInClinit.class); 70 triggerClinit(EventInClinit.class); 71 r.stop(); 72 hasEvent(r, EventInClinit.class.getName()); 73 } 74 75 private static void assertClinitRegister(Class<? extends Event> eventClass, boolean shouldExist, boolean setsProperty) throws ClassNotFoundException { 76 String className = eventClass.getName(); 77 triggerClinit(eventClass); 78 boolean hasEventType = hasEventType(className); 79 boolean hasProperty = Boolean.getBoolean(className); 80 if (hasEventType && !shouldExist) { 81 Asserts.fail("Event class " + className + " should not be registered"); 82 } 83 if (!hasEventType && shouldExist) { 84 Asserts.fail("Event class " + className + " is not registered"); 85 } 86 if (setsProperty && !hasProperty) { 87 Asserts.fail("Expected clinit to be executed"); 88 } 89 if (!setsProperty && hasProperty) { 90 Asserts.fail("Property in clinit should not been set. Test bug?"); 91 } 92 } 93 94 private static boolean hasEventType(String name) { 95 for (EventType type : FlightRecorder.getFlightRecorder().getEventTypes()) { 96 if (type.getName().equals(name)) { 97 return true; 98 } 99 } 100 return false; 101 } 102 103 private static void triggerClinit(Class<?> clazz) throws ClassNotFoundException { 104 Class.forName(clazz.getName(), true, clazz.getClassLoader()); 105 } 106 107 private static void setClinitExecuted(Class<? extends Event> eventClass) { 108 System.setProperty(eventClass.getName(), "true"); 109 } 110 111 private static boolean isClinitExecuted(Class<? extends Event> eventClass) { 112 return "true".equals(System.getProperty(eventClass.getName(), "true")); 113 } 114 115 static class AutoRegisteredEvent extends Event { 116 } 117 118 @Registered(false) 119 static class NotAutoRegisterededEvent extends Event { 120 } 121 122 static class AutoRegisteredUserClinit extends Event { 123 static { 124 setClinitExecuted(AutoRegisteredUserClinit.class); 125 } 126 } 127 128 @Registered(false) 129 static class NotAutoRegisteredUserClinit extends Event { 130 static { 131 setClinitExecuted(NotAutoRegisteredUserClinit.class); 132 } 133 } 134 135 static class Base extends Event { 136 static { 137 setClinitExecuted(Base.class); 138 } 139 } 140 141 static class DerivedClinit extends Base { 142 static { 143 setClinitExecuted(DerivedClinit.class); 144 } 145 146 @Deprecated 147 void myVoidMethod() { 148 } 149 } 150 151 static class ComplexClInit extends Event { 152 static { 153 setClinitExecuted(ComplexClInit.class); 154 } 155 public static final long l = Long.parseLong("7"); 156 public static final int i = Integer.parseInt("7"); 157 public static final short s = Short.parseShort("7"); 158 public static final double d = Double.parseDouble("7"); 159 public static final float f = Float.parseFloat("7"); 160 public static final boolean b = Boolean.parseBoolean("true"); 161 public static final char c = (char) Integer.parseInt("48"); 162 public static final String text = "ioio".substring(2); 163 public static final int[] primitivArray = new int[] { 7, 4 }; 164 public static final Class<?> Object = ComplexClInit.class; 165 166 static { 167 String text = ""; 168 long l = 56; 169 long i = 56; 170 if (i != l) { 171 throw new RuntimeException("unexpected result from comparison"); 172 } 173 if (!isClinitExecuted(ComplexClInit.class)) { 174 throw new RuntimeException("Expected clinit flag to be set" + text); 175 } 176 } 177 178 static { 179 try { 180 throw new IllegalStateException("Exception"); 181 } catch (IllegalStateException ise) { 182 // as expected 183 } 184 } 185 } 186 187 static class EventInClinit extends Event { 188 static { 189 EventInClinit eventInClinit = new EventInClinit(); 190 eventInClinit.commit(); 191 } 192 } 193 194 public static void hasEvent(Recording r, String name) throws IOException { 195 List<RecordedEvent> events = Events.fromRecording(r); 196 Events.hasEvents(events); 197 198 for (RecordedEvent event : events) { 199 if (event.getEventType().getName().equals(name)) { 200 return; 201 } 202 } 203 Asserts.fail("Missing event " + name + " in recording " + events.toString()); 204 } 205 }