1 /* 2 * Copyright (c) 2014, 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.event.runtime; 27 28 import java.io.File; 29 import java.io.FileInputStream; 30 import java.io.IOException; 31 import java.nio.ByteBuffer; 32 import java.nio.channels.FileChannel; 33 import java.util.List; 34 35 import jdk.jfr.Recording; 36 import jdk.jfr.consumer.RecordedClassLoader; 37 import jdk.jfr.consumer.RecordedEvent; 38 import jdk.test.lib.Asserts; 39 import jdk.test.lib.jfr.EventNames; 40 import jdk.test.lib.jfr.Events; 41 42 /** 43 * @test 44 * @key jfr 45 * @requires vm.hasJFR 46 * @library /test/lib /test/jdk 47 * @build jdk.jfr.event.runtime.TestClasses 48 * @run main/othervm jdk.jfr.event.runtime.TestClassLoaderStatsEvent 49 */ 50 public class TestClassLoaderStatsEvent { 51 private final static String EVENT_NAME = EventNames.ClassLoaderStatistics; 52 private final static String CLASS_LOADER_NAME = "MyDummyClassLoader"; 53 private final static String CLASSLOADER_TYPE_NAME = "jdk.jfr.event.runtime.TestClassLoaderStatsEvent$DummyClassLoader"; 54 public static DummyClassLoader dummyloader; 55 56 public static void main(String[] args) throws Throwable { 57 createDummyClassLoader(CLASS_LOADER_NAME); 58 59 Recording recording = new Recording(); 60 recording.enable(EVENT_NAME); 61 recording.start(); 62 recording.stop(); 63 List<RecordedEvent> consumer = Events.fromRecording(recording); 64 Events.hasEvents(consumer); 65 66 boolean isAnyFound = false; 67 for (RecordedEvent event : consumer) { 68 System.out.println("Event:" + event); 69 if (Events.assertField(event, "classLoader").getValue() == null) { 70 continue; 71 } 72 RecordedClassLoader recordedClassLoader = event.getValue("classLoader"); 73 if (CLASSLOADER_TYPE_NAME.equals(recordedClassLoader.getType().getName())) { 74 Asserts.assertEquals(CLASS_LOADER_NAME, recordedClassLoader.getName(), 75 "Expected class loader name " + CLASS_LOADER_NAME + ", got name " + recordedClassLoader.getName()); 76 Events.assertField(event, "classCount").equal(1L); 77 Events.assertField(event, "chunkSize").above(1L); 78 Events.assertField(event, "blockSize").above(1L); 79 Events.assertField(event, "unsafeAnonymousClassCount").equal(1L); 80 Events.assertField(event, "unsafeAnonymousChunkSize").above(1L); 81 Events.assertField(event, "unsafeAnonymousBlockSize").above(1L); 82 isAnyFound = true; 83 } 84 } 85 Asserts.assertTrue(isAnyFound, "No events found"); 86 } 87 88 private static void createDummyClassLoader(String name) throws Throwable { 89 dummyloader = new DummyClassLoader(name); 90 Class<?> c = Class.forName(TestClass.class.getName(), true, dummyloader); 91 if (c.getClassLoader() != dummyloader) { 92 throw new RuntimeException("TestClass defined by wrong classloader: " + c.getClassLoader()); 93 } 94 } 95 96 public static class DummyClassLoader extends ClassLoader { 97 98 static ByteBuffer readClassFile(String name) { 99 String testClasses = System.getProperty("test.classes"); 100 File f = new File(testClasses, name); 101 try (FileInputStream fin = new FileInputStream(f)) { 102 FileChannel fc = fin.getChannel(); 103 return fc.map(FileChannel.MapMode.READ_ONLY, 0, fc.size()); 104 } catch (IOException e) { 105 throw new RuntimeException("Can't open file: " + f, e); 106 } 107 } 108 109 protected Class<?> loadClass(String name, boolean resolve) throws ClassNotFoundException { 110 Class<?> c; 111 if (TestClass.class.getName().equals(name)) { 112 c = findClass(name); 113 if (resolve) { 114 resolveClass(c); 115 } 116 } else { 117 c = super.loadClass(name, resolve); 118 } 119 return c; 120 } 121 122 protected Class<?> findClass(String name) throws ClassNotFoundException { 123 if (!TestClass.class.getName().equals(name)) { 124 throw new ClassNotFoundException("Unexpected class: " + name); 125 } 126 return defineClass(name, readClassFile(TestClass.class.getName().replace(".", File.separator) + ".class"), null); 127 } 128 129 public DummyClassLoader(String name) { 130 super(name, ClassLoader.getSystemClassLoader()); 131 } 132 } 133 }