/* * Copyright (c) 2016, 2022, 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.
*/
/** * Class for defining an event at runtime. * <p> * It's highly recommended that the event is defined at compile time, if the * field layout is known, so the Java Virtual Machine (JVM) can optimize the * code, possibly remove all instrumentation if Flight Recorder is inactive or * if the enabled setting for this event is set to {@code false}. * <p> * To define an event at compile time, see {@link Event}. * <p> * The following example shows how to implement a dynamic {@code Event} class. * * {@snippet class="Snippets" region="EventFactoryOverview"} * * @since 9
*/ publicfinalclass EventFactory {
/** * Creates an {@code EventFactory} object. * <p> * The order of the value descriptors specifies the index to use when setting * event values. * * @param annotationElements list of annotation elements that describes the * annotations on the event, not {@code null} * * @param fields list of descriptors that describes the fields of the event, not * {@code null} * * @return event factory, not {@code null} * * @throws IllegalArgumentException if the input is not valid. For example, * input might not be valid if the field type or name is not valid in * the Java language or an annotation element references a type that * can't be found. * * @throws SecurityException if a security manager exists and the caller does * not have {@code FlightRecorderPermission("registerEvent")} * * @see Event#set(int, Object)
*/ publicstatic EventFactory create(List<AnnotationElement> annotationElements, List<ValueDescriptor> fields) {
Objects.requireNonNull(annotationElements, "annotationElements");
Objects.requireNonNull(fields, "fields");
JVMSupport.ensureWithInternalError();
Utils.checkRegisterPermission();
List<AnnotationElement> sanitizedAnnotation = Utils.sanitizeNullFreeList(annotationElements, AnnotationElement.class);
List<ValueDescriptor> sanitizedFields = Utils.sanitizeNullFreeList(fields, ValueDescriptor.class);
Set<String> nameSet = HashSet.newHashSet(sanitizedFields.size()); for (ValueDescriptor v : sanitizedFields) {
String name = v.getName(); if (v.isArray()) { thrownew IllegalArgumentException("Array types are not allowed for fields");
} if (!Type.isValidJavaFieldType(v.getTypeName())) { thrownew IllegalArgumentException(v.getTypeName() + " is not a valid type for an event field");
} if (!Checks.isJavaIdentifier(v.getName())) { thrownew IllegalArgumentException(name + " is not a valid name for an event field");
} if (nameSet.contains(name)) { thrownew IllegalArgumentException("Name of fields must be unique. Found two instances of " + name);
}
nameSet.add(name);
}
// Prevent event from being registered in <clinit> // and only use annotations that can be resolved (those in boot class loader) boolean needRegister = true;
List<AnnotationElement> bootAnnotations = new ArrayList<>(); for (AnnotationElement ae : sanitizedAnnotation) { long id = ae.getTypeId(); if (ae.isInBoot()) { if (id == REGISTERED_ID) { if (Boolean.FALSE.equals(ae.getValue("value"))) {
needRegister = false;
}
} else {
bootAnnotations.add(ae);
}
}
}
bootAnnotations.add(new AnnotationElement(Registered.class, false));
if (needRegister) {
MetadataRepository.getInstance().register(eventClass, sanitizedAnnotation, sanitizedFields);
} try { returnnew EventFactory(eventClass, sanitizedAnnotation, sanitizedFields);
} catch (IllegalAccessException e) { thrownew IllegalAccessError("Could not access constructor of generated event class, " + e.getMessage());
} catch (NoSuchMethodException e) { thrownew InternalError("Could not find constructor in generated event class, " + e.getMessage());
}
}
/** * Instantiates an event, so it can be populated with data and written to the * Flight Recorder system. * <p> * Use the {@link Event#set(int, Object)} method to set a value. * * @return an event instance, not {@code null}
*/ public Event newEvent() { try { return (Event) constructorHandle.invoke();
} catch (Throwable e) { thrownew InstantiationError("Could not instantiate dynamically generated event class " + eventClass.getName() + ". " + e.getMessage());
}
}
/** * Returns the event type that is associated with this event factory. * * @return event type that is associated with this event factory, not * {@code null} * * @throws java.lang.IllegalStateException if the event factory is created with * the {@code Registered(false)} annotation and the event class is not * manually registered before the invocation of this method
*/ public EventType getEventType() { return EventType.getEventType(eventClass);
}
/** * Registers an unregistered event. * <p> * By default, the event class associated with this event factory is registered * when the event factory is created, unless the event has the * {@link Registered} annotation. * <p> * A registered event class can write data to Flight Recorder and event metadata * can be obtained by invoking {@link FlightRecorder#getEventTypes()}. * <p> * If the event class associated with this event factory is already registered, * the call to this method is ignored. * * @throws SecurityException if a security manager exists and the caller * does not have {@code FlightRecorderPermission("registerEvent")} * @see Registered * @see FlightRecorder#register(Class)
*/ publicvoid register() {
MetadataRepository.getInstance().register(eventClass, sanitizedAnnotation, sanitizedFields);
}
/** * Unregisters the event that is associated with this event factory. * <p> * A unregistered event class can't write data to Flight Recorder and event * metadata can't be obtained by invoking * {@link FlightRecorder#getEventTypes()}. * <p> * If the event class associated with this event factory is not already * registered, the call to this method is ignored. * * @throws SecurityException if a security manager exists and the caller does * not have {@code FlightRecorderPermission("registerEvent")} * @see Registered * @see FlightRecorder#unregister(Class)
*/ publicvoid unregister() {
MetadataRepository.getInstance().unregister(eventClass);
}
}
Messung V0.5
¤ Dauer der Verarbeitung: 0.0 Sekunden
(vorverarbeitet)
¤
Die Informationen auf dieser Webseite wurden
nach bestem Wissen sorgfältig zusammengestellt. Es wird jedoch weder Vollständigkeit, noch Richtigkeit,
noch Qualität der bereit gestellten Informationen zugesichert.
Bemerkung:
Die farbliche Syntaxdarstellung und die Messung sind noch experimentell.