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