8248016: JFR: Remove Javadoc warnings

Reviewed-by: mgronlun
This commit is contained in:
Erik Gahlin 2020-07-08 17:37:27 +02:00
parent 0853b33004
commit 4d2b0b53b4
17 changed files with 130 additions and 113 deletions

View File

@ -67,6 +67,8 @@ public final class EventType {
* Returns the field with the specified name, or {@code null} if it doesn't
* exist.
*
* @param name of the field to get, not {@code null}
*
* @return a value descriptor that describes the field, or {@code null} if
* the field with the specified name doesn't exist
*/

View File

@ -1,5 +1,5 @@
/*
* Copyright (c) 2016, 2018, Oracle and/or its affiliates. All rights reserved.
* Copyright (c) 2016, 2020, 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
@ -25,6 +25,7 @@
package jdk.jfr;
import java.security.AccessControlContext;
import java.util.Collections;
import java.util.List;
import java.util.Map;
@ -191,6 +192,11 @@ public final class FlightRecorderPermission extends java.security.BasicPermissio
public PlatformRecorder getPlatformRecorder() {
return FlightRecorder.getFlightRecorder().getInternal();
}
@Override
public AccessControlContext getContext(SettingControl settingControl) {
return settingControl.getContext();
}
}
/**

View File

@ -25,10 +25,11 @@
package jdk.jfr;
import java.security.AccessControlContext;
import java.security.AccessController;
import java.util.Set;
import jdk.jfr.internal.Control;
import jdk.jfr.internal.settings.JDKSettingControl;
/**
* Base class to extend to create setting controls.
@ -139,14 +140,29 @@ import jdk.jfr.internal.Control;
* @since 9
*/
@MetadataDefinition
public abstract class SettingControl extends Control {
public abstract class SettingControl {
private final AccessControlContext context;
private final boolean initialized;
/**
* Constructor for invocation by subclass constructors.
*/
protected SettingControl() {
super(AccessController.getContext());
context = this instanceof JDKSettingControl ? null : AccessController.getContext();
initialized = true;
}
final AccessControlContext getContext() {
// Ensure object state is safe
if (!initialized) {
throw new InternalError("Object must be initialized before security context can be retrieved");
}
AccessControlContext c = this.context;
if (c == null && !(this instanceof JDKSettingControl)) {
throw new InternalError("Security context can only be null for trusted setting controls");
}
return c;
}
/**
@ -181,7 +197,6 @@ public abstract class SettingControl extends Control {
*
* @return the value to use, not {@code null}
*/
@Override
public abstract String combine(Set<String> settingValues);
/**
@ -192,7 +207,6 @@ public abstract class SettingControl extends Control {
*
* @param settingValue the string value, not {@code null}
*/
@Override
public abstract void setValue(String settingValue);
/**
@ -208,6 +222,5 @@ public abstract class SettingControl extends Control {
*
* @return the setting value, not {@code null}
*/
@Override
public abstract String getValue();
}

View File

@ -120,7 +120,7 @@ public final class RecordedEvent extends RecordedObject {
return objectContext.fields;
}
protected final Object objectAt(int index) {
final Object objectAt(int index) {
if (index == 0) {
return startTimeTicks;
}

View File

@ -254,7 +254,7 @@ public class RecordedObject {
return t;
}
protected Object objectAt(int index) {
Object objectAt(int index) {
return objects[index];
}

View File

@ -25,9 +25,6 @@
package jdk.jfr.internal;
import java.io.IOException;
import java.io.ObjectInputStream;
import java.io.ObjectOutputStream;
import java.security.AccessControlContext;
import java.security.AccessController;
import java.security.PrivilegedAction;
@ -36,61 +33,44 @@ import java.util.HashSet;
import java.util.Objects;
import java.util.Set;
// User must never be able to subclass directly.
//
// Never put Control or Setting Control in a collections
// so overridable versions of hashCode or equals are
// executed in the wrong context. TODO: wrap this class
// in SsecureControl directly when it is instantiated and
// forward calls using AccessControlContext
abstract public class Control {
import jdk.jfr.SettingControl;
import jdk.jfr.internal.settings.JDKSettingControl;
public final class Control {
private final AccessControlContext context;
private final static int CACHE_SIZE = 5;
private final Set<?>[] cachedUnions = new HashSet<?>[CACHE_SIZE];
private final String[] cachedValues = new String[CACHE_SIZE];
private final SettingControl delegate;
private String defaultValue;
private String lastValue;
// called by exposed subclass in external API
public Control(AccessControlContext acc) {
Objects.requireNonNull(acc);
this.context = acc;
}
// only to be called by trusted VM code
public Control(String defaultValue) {
public Control(SettingControl delegate, String defaultValue) {
this.context = PrivateAccess.getInstance().getContext(delegate);
this.delegate = delegate;
this.defaultValue = defaultValue;
this.context = null;
if (this.context == null && !(delegate instanceof JDKSettingControl)) {
throw new InternalError("Security context can only be null for trusted setting controls");
}
}
// For user code to override, must never be called from jdk.jfr.internal
// for user defined settings
public abstract String combine(Set<String> values);
boolean isType(Class<? extends SettingControl> clazz) {
return delegate.getClass() == clazz;
}
// For user code to override, must never be called from jdk.jfr.internal
// for user defined settings
public abstract void setValue(String value);
// For user code to override, must never be called from jdk.jfr.internal
// for user defined settings
public abstract String getValue();
// Package private, user code should not have access to this method
final void apply(Set<String> values) {
setValueSafe(findCombineSafe(values));
setValue(findCombine(values));
}
// Package private, user code should not have access to this method.
// Only called during event registration
final void setDefault() {
if (defaultValue == null) {
defaultValue = getValueSafe();
defaultValue = getValue();
}
apply(defaultValue);
}
final String getValueSafe() {
public String getValue() {
if (context == null) {
// VM events requires no access control context
return getValue();
@ -99,7 +79,7 @@ abstract public class Control {
@Override
public String run() {
try {
return getValue();
return delegate.getValue();
} catch (Throwable t) {
// Prevent malicious user to propagate exception callback in the wrong context
Logger.log(LogTag.JFR_SETTING, LogLevel.WARN, "Exception occurred when trying to get value for " + getClass());
@ -114,14 +94,14 @@ abstract public class Control {
if (lastValue != null && Objects.equals(value, lastValue)) {
return;
}
setValueSafe(value);
setValue(value);
}
final void setValueSafe(String value) {
public void setValue(String value) {
if (context == null) {
// VM events requires no access control context
try {
setValue(value);
delegate.setValue(value);
} catch (Throwable t) {
Logger.log(LogTag.JFR_SETTING, LogLevel.WARN, "Exception occurred when setting value \"" + value + "\" for " + getClass());
}
@ -130,7 +110,7 @@ abstract public class Control {
@Override
public Void run() {
try {
setValue(value);
delegate.setValue(value);
} catch (Throwable t) {
// Prevent malicious user to propagate exception callback in the wrong context
Logger.log(LogTag.JFR_SETTING, LogLevel.WARN, "Exception occurred when setting value \"" + value + "\" for " + getClass());
@ -143,16 +123,16 @@ abstract public class Control {
}
private String combineSafe(Set<String> values) {
public String combine(Set<String> values) {
if (context == null) {
// VM events requires no access control context
return combine(values);
return delegate.combine(values);
}
return AccessController.doPrivileged(new PrivilegedAction<String>() {
@Override
public String run() {
try {
combine(Collections.unmodifiableSet(values));
delegate.combine(Collections.unmodifiableSet(values));
} catch (Throwable t) {
// Prevent malicious user to propagate exception callback in the wrong context
Logger.log(LogTag.JFR_SETTING, LogLevel.WARN, "Exception occurred when combining " + values + " for " + getClass());
@ -162,7 +142,7 @@ abstract public class Control {
}, context);
}
private final String findCombineSafe(Set<String> values) {
private final String findCombine(Set<String> values) {
if (values.size() == 1) {
return values.iterator().next();
}
@ -171,7 +151,7 @@ abstract public class Control {
return cachedValues[i];
}
}
String result = combineSafe(values);
String result = combine(values);
for (int i = 0; i < CACHE_SIZE - 1; i++) {
cachedUnions[i + 1] = cachedUnions[i];
cachedValues[i + 1] = cachedValues[i];
@ -181,29 +161,11 @@ abstract public class Control {
return result;
}
// package private, user code should not have access to this method
final String getDefaultValue() {
return defaultValue;
}
// package private, user code should not have access to this method
final String getLastValue() {
return lastValue;
}
// Precaution to prevent a malicious user from instantiating instances
// of a control where the context has not been set up.
@Override
public final Object clone() throws java.lang.CloneNotSupportedException {
throw new CloneNotSupportedException();
}
private final void writeObject(ObjectOutputStream out) throws IOException {
throw new IOException("Object cannot be serialized");
}
private final void readObject(ObjectInputStream in) throws IOException {
throw new IOException("Class cannot be deserialized");
}
}

View File

@ -167,9 +167,9 @@ public final class EventControl {
int index = settingInfos.size();
SettingInfo si = new SettingInfo(FIELD_SETTING_PREFIX + index, index);
si.settingControl = instantiateSettingControl(settingsClass);
Control c = si.settingControl;
Control c = new Control(si.settingControl, null);
c.setDefault();
String defaultValue = c.getValueSafe();
String defaultValue = c.getValue();
if (defaultValue != null) {
Type settingType = TypeLibrary.createType(settingsClass);
ArrayList<AnnotationElement> aes = new ArrayList<>();
@ -180,7 +180,7 @@ public final class EventControl {
}
}
aes.trimToSize();
addControl(settingName, si.settingControl);
addControl(settingName, c);
eventType.add(PrivateAccess.getInstance().newSettingDescriptor(settingType, settingName, defaultValue, aes));
settingInfos.add(si);
}
@ -205,7 +205,7 @@ public final class EventControl {
try {
return (SettingControl) cc.newInstance();
} catch (IllegalArgumentException | InvocationTargetException e) {
throw (Error) new InternalError("Could not instantiate setting for class " + settingControlClass.getName());
throw new InternalError("Could not instantiate setting for class " + settingControlClass.getName());
}
}
@ -219,7 +219,7 @@ public final class EventControl {
def = Boolean.toString(enabled.value());
}
type.add(PrivateAccess.getInstance().newSettingDescriptor(TYPE_ENABLED, Enabled.NAME, def, Collections.emptyList()));
return new EnabledSetting(type, def);
return new Control(new EnabledSetting(type, def), def);
}
private static Control defineThreshold(PlatformEventType type) {
@ -229,7 +229,7 @@ public final class EventControl {
def = threshold.value();
}
type.add(PrivateAccess.getInstance().newSettingDescriptor(TYPE_THRESHOLD, Threshold.NAME, def, Collections.emptyList()));
return new ThresholdSetting(type, def);
return new Control(new ThresholdSetting(type), def);
}
private static Control defineStackTrace(PlatformEventType type) {
@ -239,7 +239,7 @@ public final class EventControl {
def = Boolean.toString(stackTrace.value());
}
type.add(PrivateAccess.getInstance().newSettingDescriptor(TYPE_STACK_TRACE, StackTrace.NAME, def, Collections.emptyList()));
return new StackTraceSetting(type, def);
return new Control(new StackTraceSetting(type, def), def);
}
private static Control defineCutoff(PlatformEventType type) {
@ -249,7 +249,7 @@ public final class EventControl {
def = cutoff.value();
}
type.add(PrivateAccess.getInstance().newSettingDescriptor(TYPE_CUTOFF, Cutoff.NAME, def, Collections.emptyList()));
return new CutoffSetting(type, def);
return new Control(new CutoffSetting(type), def);
}
@ -260,13 +260,13 @@ public final class EventControl {
def = period.value();
}
type.add(PrivateAccess.getInstance().newSettingDescriptor(TYPE_PERIOD, PeriodSetting.NAME, def, Collections.emptyList()));
return new PeriodSetting(type, def);
return new Control(new PeriodSetting(type), def);
}
void disable() {
for (NamedControl nc : namedControls) {
if (nc.control instanceof EnabledSetting) {
nc.control.setValueSafe("false");
if (nc.control.isType(EnabledSetting.class)) {
nc.control.setValue("false");
return;
}
}

View File

@ -64,7 +64,11 @@ public final class EventInstrumentation {
private String settingDescriptor;
final String fieldName;
final int index;
// Used when instantiating Setting
// The settingControl is passed to EventHandler where it is
// used to check enablement before calling commit
// Methods on settingControl must never be invoked
// directly by JFR, instead use jdk.jfr.internal.Control
SettingControl settingControl;
public SettingInfo(String fieldName, int index) {

View File

@ -25,6 +25,7 @@
package jdk.jfr.internal;
import java.security.AccessControlContext;
import java.util.List;
import java.util.Map;
@ -33,6 +34,7 @@ import jdk.jfr.Configuration;
import jdk.jfr.EventType;
import jdk.jfr.FlightRecorderPermission;
import jdk.jfr.Recording;
import jdk.jfr.SettingControl;
import jdk.jfr.SettingDescriptor;
import jdk.jfr.ValueDescriptor;
@ -94,4 +96,6 @@ public abstract class PrivateAccess {
public abstract boolean isUnsigned(ValueDescriptor v);
public abstract PlatformRecorder getPlatformRecorder();
public abstract AccessControlContext getContext(SettingControl sc);
}

View File

@ -53,6 +53,7 @@ import jdk.jfr.Description;
import jdk.jfr.Label;
import jdk.jfr.MetadataDefinition;
import jdk.jfr.Name;
import jdk.jfr.SettingControl;
import jdk.jfr.SettingDescriptor;
import jdk.jfr.Timespan;
import jdk.jfr.Timestamp;
@ -246,7 +247,7 @@ public final class TypeLibrary {
superType = Type.SUPER_TYPE_EVENT;
eventType= true;
}
if (Control.class.isAssignableFrom(clazz)) {
if (SettingControl.class.isAssignableFrom(clazz)) {
superType = Type.SUPER_TYPE_SETTING;
}

View File

@ -518,13 +518,13 @@ public final class Utils {
}
public static boolean isSettingVisible(Control c, boolean hasEventHook) {
if (c instanceof ThresholdSetting) {
if (c.isType(ThresholdSetting.class)) {
return !hasEventHook;
}
if (c instanceof PeriodSetting) {
if (c.isType(PeriodSetting.class)) {
return hasEventHook;
}
if (c instanceof StackTraceSetting) {
if (c.isType(StackTraceSetting.class)) {
return !hasEventHook;
}
return true;

View File

@ -1,5 +1,5 @@
/*
* Copyright (c) 2018, Oracle and/or its affiliates. All rights reserved.
* Copyright (c) 2018, 2020, 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,7 +33,6 @@ import jdk.jfr.Label;
import jdk.jfr.MetadataDefinition;
import jdk.jfr.Name;
import jdk.jfr.Timespan;
import jdk.jfr.internal.Control;
import jdk.jfr.internal.PlatformEventType;
import jdk.jfr.internal.Type;
import jdk.jfr.internal.Utils;
@ -43,14 +42,13 @@ import jdk.jfr.internal.Utils;
@Description("Limit running time of event")
@Name(Type.SETTINGS_PREFIX + "Cutoff")
@Timespan
public final class CutoffSetting extends Control {
public final class CutoffSetting extends JDKSettingControl {
private final static long typeId = Type.getTypeId(CutoffSetting.class);
private String value = "0 ns";
private final PlatformEventType eventType;
public CutoffSetting(PlatformEventType eventType, String defaultValue) {
super(defaultValue);
public CutoffSetting(PlatformEventType eventType) {
this.eventType = Objects.requireNonNull(eventType);
}

View File

@ -1,5 +1,5 @@
/*
* Copyright (c) 2016, 2018, Oracle and/or its affiliates. All rights reserved.
* Copyright (c) 2016, 2020, 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
@ -35,19 +35,17 @@ import jdk.jfr.MetadataDefinition;
import jdk.jfr.Name;
import jdk.jfr.internal.PlatformEventType;
import jdk.jfr.internal.Type;
import jdk.jfr.internal.Control;
@MetadataDefinition
@Label("Enabled")
@Description("Record event")
@Name(Type.SETTINGS_PREFIX + "Enabled")
@BooleanFlag
public final class EnabledSetting extends Control {
public final class EnabledSetting extends JDKSettingControl {
private final BooleanValue booleanValue;
private final PlatformEventType eventType;
public EnabledSetting(PlatformEventType eventType, String defaultValue) {
super(defaultValue);
this.booleanValue = BooleanValue.valueOf(defaultValue);
this.eventType = Objects.requireNonNull(eventType);
}

View File

@ -0,0 +1,35 @@
/*
* Copyright (c) 2020, 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.internal.settings;
import jdk.jfr.SettingControl;
/**
* SettingControls that derive from this class avoids executing settings
* modifications in a AccessController.doPrivilege(...) block.
*/
public abstract class JDKSettingControl extends SettingControl {
}

View File

@ -1,5 +1,5 @@
/*
* Copyright (c) 2016, 2018, Oracle and/or its affiliates. All rights reserved.
* Copyright (c) 2016, 2020, 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,7 +33,6 @@ import jdk.jfr.Label;
import jdk.jfr.MetadataDefinition;
import jdk.jfr.Name;
import jdk.jfr.internal.PlatformEventType;
import jdk.jfr.internal.Control;
import jdk.jfr.internal.Type;
import jdk.jfr.internal.Utils;
@ -41,7 +40,7 @@ import jdk.jfr.internal.Utils;
@Label("Period")
@Description("Record event at interval")
@Name(Type.SETTINGS_PREFIX + "Period")
public final class PeriodSetting extends Control {
public final class PeriodSetting extends JDKSettingControl {
private static final long typeId = Type.getTypeId(PeriodSetting.class);
public static final String EVERY_CHUNK = "everyChunk";
@ -51,8 +50,7 @@ public final class PeriodSetting extends Control {
private final PlatformEventType eventType;
private String value = EVERY_CHUNK;
public PeriodSetting(PlatformEventType eventType, String defaultValue) {
super(defaultValue);
public PeriodSetting(PlatformEventType eventType) {
this.eventType = Objects.requireNonNull(eventType);
}

View File

@ -1,5 +1,5 @@
/*
* Copyright (c) 2016, 2018, Oracle and/or its affiliates. All rights reserved.
* Copyright (c) 2016, 2020, 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
@ -34,7 +34,6 @@ import jdk.jfr.Label;
import jdk.jfr.MetadataDefinition;
import jdk.jfr.Name;
import jdk.jfr.internal.PlatformEventType;
import jdk.jfr.internal.Control;
import jdk.jfr.internal.Type;
@MetadataDefinition
@ -42,13 +41,12 @@ import jdk.jfr.internal.Type;
@Name(Type.SETTINGS_PREFIX + "StackTrace")
@Description("Record stack traces")
@BooleanFlag
public final class StackTraceSetting extends Control {
public final class StackTraceSetting extends JDKSettingControl {
private final static long typeId = Type.getTypeId(StackTraceSetting.class);
private final BooleanValue booleanValue;
private final PlatformEventType eventType;
public StackTraceSetting(PlatformEventType eventType, String defaultValue) {
super(defaultValue);
this.booleanValue = BooleanValue.valueOf(defaultValue);
this.eventType = Objects.requireNonNull(eventType);
}

View File

@ -1,5 +1,5 @@
/*
* Copyright (c) 2016, 2018, Oracle and/or its affiliates. All rights reserved.
* Copyright (c) 2016, 2020, 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
@ -34,7 +34,6 @@ import jdk.jfr.MetadataDefinition;
import jdk.jfr.Name;
import jdk.jfr.Timespan;
import jdk.jfr.internal.PlatformEventType;
import jdk.jfr.internal.Control;
import jdk.jfr.internal.Type;
import jdk.jfr.internal.Utils;
@MetadataDefinition
@ -42,13 +41,12 @@ import jdk.jfr.internal.Utils;
@Name(Type.SETTINGS_PREFIX + "Threshold")
@Description("Record event with duration above or equal to threshold")
@Timespan
public final class ThresholdSetting extends Control {
public final class ThresholdSetting extends JDKSettingControl {
private final static long typeId = Type.getTypeId(ThresholdSetting.class);
private String value = "0 ns";
private final PlatformEventType eventType;
public ThresholdSetting(PlatformEventType eventType, String defaultValue) {
super(defaultValue);
public ThresholdSetting(PlatformEventType eventType) {
this.eventType = Objects.requireNonNull(eventType);
}