diff --git a/src/java.base/share/classes/java/security/SecureClassLoader.java b/src/java.base/share/classes/java/security/SecureClassLoader.java
index 7b0420ec60154..ea3523cfbe711 100644
--- a/src/java.base/share/classes/java/security/SecureClassLoader.java
+++ b/src/java.base/share/classes/java/security/SecureClassLoader.java
@@ -31,6 +31,8 @@
import java.util.function.Function;
import jdk.internal.misc.CDS;
+import jdk.internal.event.ClassFileDefineEvent;
+
/**
* This class extends {@code ClassLoader} with additional support for defining
* classes with an associated code source and permissions.
@@ -138,11 +140,16 @@ protected SecureClassLoader(String name, ClassLoader parent) {
* a different set of certificates than this class, or if
* the class name begins with "java.".
*/
- protected final Class> defineClass(String name,
- byte[] b, int off, int len,
- CodeSource cs)
- {
- return defineClass(name, b, off, len, getProtectionDomain(cs));
+ protected final Class> defineClass(String name, byte[] b, int off, int len, CodeSource cs) {
+ final var cls = defineClass(name, b, off, len, getProtectionDomain(cs));
+
+ final var evt = new ClassFileDefineEvent();
+
+ evt.definedClass = cls;
+ evt.path = cs.getLocation().toExternalForm();
+ evt.commit();
+
+ return cls;
}
/**
@@ -171,10 +178,17 @@ protected final Class> defineClass(String name,
*
* @since 1.5
*/
- protected final Class> defineClass(String name, java.nio.ByteBuffer b,
- CodeSource cs)
+ protected final Class> defineClass(String name, java.nio.ByteBuffer b, CodeSource cs)
{
- return defineClass(name, b, getProtectionDomain(cs));
+ final var cls = defineClass(name, b, getProtectionDomain(cs));
+
+ final var evt = new ClassFileDefineEvent();
+
+ evt.definedClass = cls;
+ evt.path = cs.getLocation().toExternalForm();
+ evt.commit();
+
+ return cls;
}
/**
diff --git a/src/java.base/share/classes/jdk/internal/event/ClassFileDefineEvent.java b/src/java.base/share/classes/jdk/internal/event/ClassFileDefineEvent.java
new file mode 100644
index 0000000000000..b83e7f5748c62
--- /dev/null
+++ b/src/java.base/share/classes/jdk/internal/event/ClassFileDefineEvent.java
@@ -0,0 +1,35 @@
+/*
+ * Copyright (c) 2025, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation. Oracle designates this
+ * particular file as subject to the "Classpath" exception as provided
+ * by Oracle in the LICENSE file that accompanied this code.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ */
+package jdk.internal.event;
+
+import java.net.URL;
+
+/**
+ * Event recording that a Class has been loaded and defined by a ClassLoader.
+ */
+public final class ClassFileDefineEvent extends Event {
+ public Class> definedClass;
+ public String path;
+}
diff --git a/src/jdk.jfr/share/classes/jdk/jfr/events/ClassFileDefineEvent.java b/src/jdk.jfr/share/classes/jdk/jfr/events/ClassFileDefineEvent.java
new file mode 100644
index 0000000000000..d592edf9767c7
--- /dev/null
+++ b/src/jdk.jfr/share/classes/jdk/jfr/events/ClassFileDefineEvent.java
@@ -0,0 +1,45 @@
+/*
+ * Copyright (c) 2025, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation. Oracle designates this
+ * particular file as subject to the "Classpath" exception as provided
+ * by Oracle in the LICENSE file that accompanied this code.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ */
+
+package jdk.jfr.events;
+
+import jdk.jfr.Category;
+import jdk.jfr.Description;
+import jdk.jfr.Label;
+import jdk.jfr.Name;
+import jdk.jfr.internal.MirrorEvent;
+import jdk.jfr.internal.Type;
+
+@Category("Java Virtual Machine, Class Loading")
+@Label("ClassFile Define")
+@Name("jdk.ClassFileDefine")
+public final class ClassFileDefineEvent extends MirrorEvent {
+ @Label("Defined Class Name")
+ public Class> definedClass;
+
+ @Label("Path")
+ @Description("The path/url location of the classfile loaded")
+ public String path;
+}
diff --git a/src/jdk.jfr/share/classes/jdk/jfr/internal/JDKEvents.java b/src/jdk.jfr/share/classes/jdk/jfr/internal/JDKEvents.java
index 503a7955e0022..d048fb95274cf 100644
--- a/src/jdk.jfr/share/classes/jdk/jfr/internal/JDKEvents.java
+++ b/src/jdk.jfr/share/classes/jdk/jfr/internal/JDKEvents.java
@@ -35,6 +35,7 @@
import jdk.jfr.Event;
import jdk.jfr.events.ActiveRecordingEvent;
import jdk.jfr.events.ActiveSettingEvent;
+import jdk.jfr.events.ClassFileDefineEvent;
import jdk.jfr.events.ContainerCPUThrottlingEvent;
import jdk.jfr.events.ContainerCPUUsageEvent;
import jdk.jfr.events.ContainerConfigurationEvent;
@@ -56,6 +57,7 @@ public final class JDKEvents {
ActiveRecordingEvent.class,
// jdk.internal.event.* classes need their mirror
// event class to be listed in the MirrorEvents class.
+ jdk.internal.event.ClassFileDefineEvent.class,
jdk.internal.event.DeserializationEvent.class,
jdk.internal.event.ErrorThrownEvent.class,
jdk.internal.event.ExceptionStatisticsEvent.class,
diff --git a/src/jdk.jfr/share/classes/jdk/jfr/internal/MirrorEvents.java b/src/jdk.jfr/share/classes/jdk/jfr/internal/MirrorEvents.java
index 48dc0d22cea3a..4a6bd2713d1a8 100644
--- a/src/jdk.jfr/share/classes/jdk/jfr/internal/MirrorEvents.java
+++ b/src/jdk.jfr/share/classes/jdk/jfr/internal/MirrorEvents.java
@@ -27,6 +27,7 @@
import java.util.Map;
import java.util.concurrent.ConcurrentHashMap;
+import jdk.jfr.events.ClassFileDefineEvent;
import jdk.jfr.events.DeserializationEvent;
import jdk.jfr.events.ErrorThrownEvent;
import jdk.jfr.events.ExceptionStatisticsEvent;
@@ -57,6 +58,7 @@ final class MirrorEvents {
// Add mirror event mapping here. See MirrorEvent class for details.
static {
+ register("jdk.internal.event.ClassFileDefineEvent", ClassFileDefineEvent.class);
register("jdk.internal.event.DeserializationEvent", DeserializationEvent.class);
register("jdk.internal.event.FileForceEvent", FileForceEvent.class);
register("jdk.internal.event.FileReadEvent", FileReadEvent.class);
diff --git a/src/jdk.jfr/share/conf/jfr/default.jfc b/src/jdk.jfr/share/conf/jfr/default.jfc
index eb3b8626722c0..113175ca24833 100644
--- a/src/jdk.jfr/share/conf/jfr/default.jfc
+++ b/src/jdk.jfr/share/conf/jfr/default.jfc
@@ -166,6 +166,10 @@
true
+
+ false
+
+
true
true