1 /* 2 * Copyright (c) 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. 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.test.lib.Asserts; 38 import jdk.test.lib.jfr.Events; 39 40 /** 41 * @test 42 * @summary Test enable/disable event and verify recording has expected events. 43 * @key jfr 44 * 45 * @library /lib / 46 * @run main/othervm jdk.jfr.api.event.TestClinitRegistration 47 */ 48 49 public class TestClinitRegistration { 50 51 public static void main(String[] args) throws Exception { 52 // Test basic registration with or without auto registration 53 assertClinitRegister(AutoRegisteredEvent.class, true, false); 54 assertClinitRegister(NotAutoRegisterededEvent.class, false, false); 55 assertClinitRegister(AutoRegisteredUserClinit.class, true, true); 56 assertClinitRegister(NotAutoRegisteredUserClinit.class, false, true); 57 58 // Test complex <clinit> 59 assertClinitRegister(ComplexClInit.class, true, true); 60 61 // Test hierarchy 62 assertClinitRegister(DerivedClinit.class, true, true); 63 if (!isClinitExecuted(Base.class)) { 64 Asserts.fail("Expected <clinit> of base class to be executed"); 65 } 66 67 // Test committed event in <clinit> 68 Recording r = new Recording(); 69 r.start(); 70 r.enable(EventInClinit.class); 71 triggerClinit(EventInClinit.class); 72 r.stop(); 73 hasEvent(r, EventInClinit.class.getName()); 74 } 75 76 private static void assertClinitRegister(Class<? extends Event> eventClass, boolean shouldExist, boolean setsProperty) throws ClassNotFoundException { 77 String className = eventClass.getName(); 78 triggerClinit(eventClass); 79 boolean hasEventType = hasEventType(className); 80 boolean hasProperty = Boolean.getBoolean(className); 81 if (hasEventType && !shouldExist) { 82 Asserts.fail("Event class " + className + " should not be registered"); 83 } 84 if (!hasEventType && shouldExist) { 85 Asserts.fail("Event class " + className + " is not registered"); 86 } 87 if (setsProperty && !hasProperty) { 88 Asserts.fail("Expected clinit to be executed"); 89 } 90 if (!setsProperty && hasProperty) { 91 Asserts.fail("Property in clinit should not been set. Test bug?"); 92 } 93 } 94 95 private static boolean hasEventType(String name) { 96 for (EventType type : FlightRecorder.getFlightRecorder().getEventTypes()) { 97 if (type.getName().equals(name)) { 98 return true; 99 } 100 } 101 return false; 102 } 103 104 private static void triggerClinit(Class<?> clazz) throws ClassNotFoundException { 105 Class.forName(clazz.getName(), true, clazz.getClassLoader()); 106 } 107 108 private static void setClinitExecuted(Class<? extends Event> eventClass) { 109 System.setProperty(eventClass.getName(), "true"); 110 } 111 112 private static boolean isClinitExecuted(Class<? extends Event> eventClass) { 113 return "true".equals(System.getProperty(eventClass.getName(), "true")); 114 } 115 116 static class AutoRegisteredEvent extends Event { 117 } 118 119 @Registered(false) 120 static class NotAutoRegisterededEvent extends Event { 121 } 122 123 static class AutoRegisteredUserClinit extends Event { 124 static { 125 setClinitExecuted(AutoRegisteredUserClinit.class); 126 } 127 } 128 129 @Registered(false) 130 static class NotAutoRegisteredUserClinit extends Event { 131 static { 132 setClinitExecuted(NotAutoRegisteredUserClinit.class); 133 } 134 } 135 136 static class Base extends Event { 137 static { 138 setClinitExecuted(Base.class); 139 } 140 } 141 142 static class DerivedClinit extends Base { 143 static { 144 setClinitExecuted(DerivedClinit.class); 145 } 146 147 @Deprecated 148 void myVoidMethod() { 149 } 150 } 151 152 static class ComplexClInit extends Event { 153 static { 154 setClinitExecuted(ComplexClInit.class); 155 } 156 public static final long l = Long.parseLong("7"); 157 public static final int i = Integer.parseInt("7"); 158 public static final short s = Short.parseShort("7"); 159 public static final double d = Double.parseDouble("7"); 160 public static final float f = Float.parseFloat("7"); 161 public static final boolean b = Boolean.parseBoolean("true"); 162 public static final char c = (char) Integer.parseInt("48"); 163 public static final String text = "ioio".substring(2); 164 public static final int[] primitivArray = new int[] { 7, 4 }; 165 public static final Class<?> Object = ComplexClInit.class; 166 167 static { 168 String text = ""; 169 long l = 56; 170 long i = 56; 171 if (i != l) { 172 throw new RuntimeException("unexpected result from comparison"); 173 } 174 if (!isClinitExecuted(ComplexClInit.class)) { 175 throw new RuntimeException("Expected clinit flag to be set" + text); 176 } 177 } 178 179 static { 180 try { 181 throw new IllegalStateException("Exception"); 182 } catch (IllegalStateException ise) { 183 // as expected 184 } 185 } 186 } 187 188 static class EventInClinit extends Event { 189 static { 190 EventInClinit eventInClinit = new EventInClinit(); 191 eventInClinit.commit(); 192 } 193 } 194 195 public static void hasEvent(Recording r, String name) throws IOException { 196 List<RecordedEvent> events = Events.fromRecording(r); 197 Events.hasEvents(events); 198 199 for (RecordedEvent event : events) { 200 if (event.getEventType().getName().equals(name)) { 201 return; 202 } 203 } 204 Asserts.fail("Missing event " + name + " in recording " + events.toString()); 205 } 206 }