diff --git a/src/java.base/share/classes/jdk/internal/module/Checks.java b/src/java.base/share/classes/jdk/internal/module/Checks.java
index 3b7dd137225..7965391f049 100644
--- a/src/java.base/share/classes/jdk/internal/module/Checks.java
+++ b/src/java.base/share/classes/jdk/internal/module/Checks.java
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2009, 2017, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2009, 2021, 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
@@ -168,7 +168,7 @@ public final class Checks {
* Returns true if the given string is a legal Java identifier,
* otherwise false.
*/
- private static boolean isJavaIdentifier(String str) {
+ public static boolean isJavaIdentifier(String str) {
if (str.isEmpty() || RESERVED.contains(str))
return false;
diff --git a/src/jdk.jfr/share/classes/jdk/jfr/EventFactory.java b/src/jdk.jfr/share/classes/jdk/jfr/EventFactory.java
index bbda1be7490..71b08e74baa 100644
--- a/src/jdk.jfr/share/classes/jdk/jfr/EventFactory.java
+++ b/src/jdk.jfr/share/classes/jdk/jfr/EventFactory.java
@@ -33,6 +33,7 @@ import java.util.List;
import java.util.Objects;
import java.util.Set;
+import jdk.internal.module.Checks;
import jdk.jfr.internal.EventClassBuilder;
import jdk.jfr.internal.JVMSupport;
import jdk.jfr.internal.MetadataRepository;
@@ -135,7 +136,7 @@ public final class EventFactory {
if (!Type.isValidJavaFieldType(v.getTypeName())) {
throw new IllegalArgumentException(v.getTypeName() + " is not a valid type for an event field");
}
- if (!Type.isValidJavaIdentifier(v.getName())) {
+ if (!Checks.isJavaIdentifier(v.getName())) {
throw new IllegalArgumentException(name + " is not a valid name for an event field");
}
if (nameSet.contains(name)) {
diff --git a/src/jdk.jfr/share/classes/jdk/jfr/Name.java b/src/jdk.jfr/share/classes/jdk/jfr/Name.java
index 7c43911f01c..26d1b84c436 100644
--- a/src/jdk.jfr/share/classes/jdk/jfr/Name.java
+++ b/src/jdk.jfr/share/classes/jdk/jfr/Name.java
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2016, 2020, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2016, 2021, 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
@@ -33,9 +33,13 @@ import java.lang.annotation.Target;
/**
* Annotation that sets the default name for an element.
*
- * The name must be a valid identifier as specified in the Java language (for
- * example, {@code "com.example.Transaction"} for an event class or
- * {@code "message"} for an event field).
+ * For event classes, the name must be a legal class name as specified in the Java
+ * language, (for example, {@code "com.example.Transaction"}. For event fields
+ * or event settings, the name must be a valid identifier (for example,
+ * {@code "message"}). See section 3.8 and 3.9 of the Java Language
+ * Specification for more information.
+ *
+ * If the specified name is invalid, the annotation is ignored.
*
* A stable and easy-to-use event name is of the form:
*
diff --git a/src/jdk.jfr/share/classes/jdk/jfr/ValueDescriptor.java b/src/jdk.jfr/share/classes/jdk/jfr/ValueDescriptor.java
index 3132d2b050e..26e523ed40c 100644
--- a/src/jdk.jfr/share/classes/jdk/jfr/ValueDescriptor.java
+++ b/src/jdk.jfr/share/classes/jdk/jfr/ValueDescriptor.java
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2016, 2018, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2016, 2021, 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
@@ -83,12 +83,14 @@ public final class ValueDescriptor {
*
*
*
- * The name must be a valid Java identifier (for example, {@code "maxThroughput"}). See 3.8
- * Java Language Specification for more information.
+ * The name must be a valid Java identifier (for example, {@code "maxThroughput"}). See
+ * section 3.8 and 3.9 of the Java Language Specification for more information.
*
* @param type the type, not {@code null}
* @param name the name, not {@code null}
*
+ * @throws IllegalArgumentException if the name is not a valid Java identifier
+ *
* @throws SecurityException if a security manager is present and the caller
* doesn't have {@code FlightRecorderPermission("registerEvent")}
*
@@ -118,14 +120,16 @@ public final class ValueDescriptor {
*
*
*
- * The name must be a valid Java identifier (for example, {@code "maxThroughput"}). See 3.8
- * Java Language Specification for more information.
+ * The name must be a valid Java identifier (for example, {@code "maxThroughput"}). See
+ * section 3.8 and 3.9 of the Java Language Specification for more information.
*
* @param type the type, not {@code null}
* @param name the name, not {@code null}
* @param annotations the annotations on the value descriptors, not
* {@code null}
*
+ * @throws IllegalArgumentException if the name is not a valid Java identifier
+ *
* @throws SecurityException if a security manager is present and the caller
* doesn't have {@code FlightRecorderPermission("registerEvent")}
*/
@@ -143,6 +147,7 @@ public final class ValueDescriptor {
}
}
this.name = Objects.requireNonNull(name, "Name of value descriptor can't be null");
+ Utils.ensureJavaIdentifier(name);
this.type = Objects.requireNonNull(Utils.getValidType(Objects.requireNonNull(type), Objects.requireNonNull(name)));
this.annotationConstruct = new AnnotationConstruct(annotations);
this.javaFieldName = name; // Needed for dynamic events
diff --git a/src/jdk.jfr/share/classes/jdk/jfr/internal/EventControl.java b/src/jdk.jfr/share/classes/jdk/jfr/internal/EventControl.java
index 3ef0948a8b3..6a89ce02d1e 100644
--- a/src/jdk.jfr/share/classes/jdk/jfr/internal/EventControl.java
+++ b/src/jdk.jfr/share/classes/jdk/jfr/internal/EventControl.java
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2016, 2020, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2016, 2021, 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
@@ -150,7 +150,7 @@ public final class EventControl {
String name = m.getName();
Name n = m.getAnnotation(Name.class);
if (n != null) {
- name = n.value();
+ name = Utils.validJavaIdentifier(n.value(), name);
}
if (!hasControl(name)) {
diff --git a/src/jdk.jfr/share/classes/jdk/jfr/internal/EventInstrumentation.java b/src/jdk.jfr/share/classes/jdk/jfr/internal/EventInstrumentation.java
index e59458a9cc0..9320bb83229 100644
--- a/src/jdk.jfr/share/classes/jdk/jfr/internal/EventInstrumentation.java
+++ b/src/jdk.jfr/share/classes/jdk/jfr/internal/EventInstrumentation.java
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2016, 2020, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2016, 2021, 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
@@ -213,6 +213,7 @@ public final class EventInstrumentation {
Set methodSet = new HashSet<>();
List settingInfos = new ArrayList<>();
String settingDescriptor = Type.getType(SettingDefinition.class).getDescriptor();
+ String nameDescriptor = Type.getType(Name.class).getDescriptor();
for (MethodNode m : classNode.methods) {
if (m.visibleAnnotations != null) {
for (AnnotationNode an : m.visibleAnnotations) {
@@ -220,6 +221,15 @@ public final class EventInstrumentation {
// stage. We would need to check that the parameter
// is an instance of SettingControl.
if (settingDescriptor.equals(an.desc)) {
+ String name = m.name;
+ for (AnnotationNode nameCandidate : m.visibleAnnotations) {
+ if (nameDescriptor.equals(nameCandidate.desc)) {
+ List