Skip to content
Permalink
Browse files

8248016: JFR: Remove Javadoc warnings

Reviewed-by: mgronlun
  • Loading branch information
Erik Gahlin
Erik Gahlin committed Jul 8, 2020
1 parent 0853b33 commit 4d2b0b53b4a94440440eedceb6c18a368eedcf37
@@ -67,6 +67,8 @@
* 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
*/
@@ -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 boolean isUnsigned(ValueDescriptor v) {
public PlatformRecorder getPlatformRecorder() {
return FlightRecorder.getFlightRecorder().getInternal();
}

@Override
public AccessControlContext getContext(SettingControl settingControl) {
return settingControl.getContext();
}
}

/**
@@ -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 @@
* @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 @@ protected SettingControl() {
*
* @return the value to use, not {@code null}
*/
@Override
public abstract String combine(Set<String> settingValues);

/**
@@ -192,7 +207,6 @@ protected SettingControl() {
*
* @param settingValue the string value, not {@code null}
*/
@Override
public abstract void setValue(String settingValue);

/**
@@ -208,6 +222,5 @@ protected SettingControl() {
*
* @return the setting value, not {@code null}
*/
@Override
public abstract String getValue();
}
@@ -120,7 +120,7 @@ public Duration getDuration() {
return objectContext.fields;
}

protected final Object objectAt(int index) {
final Object objectAt(int index) {
if (index == 0) {
return startTimeTicks;
}
@@ -254,7 +254,7 @@ public boolean hasField(String name) {
return t;
}

protected Object objectAt(int index) {
Object objectAt(int index) {
return objects[index];
}

@@ -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.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);

// 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();
boolean isType(Class<? extends SettingControl> clazz) {
return delegate.getClass() == clazz;
}

// 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 @@ final String getValueSafe() {
@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 @@ private void apply(String value) {
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 @@ final void setValueSafe(String value) {
@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 @@ public Void run() {
}


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 @@ public String run() {
}, 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 @@ private final String findCombineSafe(Set<String> values) {
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 @@ private final String findCombineSafe(Set<String> values) {
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");
}
}
@@ -167,9 +167,9 @@ private void defineSetting(Class<? extends SettingControl> settingsClass, Method
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 @@ private void defineSetting(Class<? extends SettingControl> settingsClass, Method
}
}
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 @@ private SettingControl instantiateSettingControl(Class<? extends SettingControl>
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 @@ private static Control defineEnabled(PlatformEventType type) {
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 @@ private static Control defineThreshold(PlatformEventType type) {
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 @@ private static Control defineStackTrace(PlatformEventType type) {
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 @@ private static Control defineCutoff(PlatformEventType type) {
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 @@ private static Control definePeriod(PlatformEventType type) {
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;
}
}

0 comments on commit 4d2b0b5

Please sign in to comment.