Skip to content

Commit

Permalink
Fix substratevm after 'JDK-8347287: JFR: Remove use of Security Manager'
Browse files Browse the repository at this point in the history
  • Loading branch information
simonis committed Jan 21, 2025
1 parent a44c46a commit 0400cf1
Show file tree
Hide file tree
Showing 6 changed files with 136 additions and 29 deletions.
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
/*
* Copyright (c) 2023, 2023, Oracle and/or its affiliates. All rights reserved.
* Copyright (c) 2023, 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
Expand All @@ -26,6 +26,7 @@

import java.lang.reflect.InvocationTargetException;
import java.lang.reflect.Method;
import java.nio.file.Path;
import java.time.Duration;
import java.time.LocalDateTime;

Expand Down Expand Up @@ -117,7 +118,7 @@ public static JVM getJVMOrNull() throws IllegalAccessException, InvocationTarget
}
}

public static void setDumpDirectory(PlatformRecording platformRecording, SecuritySupport.SafePath directory) {
public static void setDumpDirectory(PlatformRecording platformRecording, Target_jdk_jfr_internal_SecuritySupport_SafePath directory) {
Target_jdk_jfr_internal_PlatformRecording pr = SubstrateUtil.cast(platformRecording, Target_jdk_jfr_internal_PlatformRecording.class);
if (JavaVersionUtil.JAVA_SPEC >= 23) {
pr.setDumpDirectory(directory);
Expand Down Expand Up @@ -161,12 +162,16 @@ final class Target_jdk_jfr_internal_util_ValueFormatter {
@TargetClass(className = "jdk.jfr.internal.PlatformRecording")
final class Target_jdk_jfr_internal_PlatformRecording {
@Alias
@TargetElement(onlyWith = JDKLatest.class)
public native void setDumpDirectory(SecuritySupport.SafePath directory);
@TargetElement(onlyWith = SecuritySupportSafePathAbsent.class)
public native void setDumpDirectory(Path directory);

@Alias
@TargetElement(onlyWith = JDK21OrEarlier.class)
public native void setDumpOnExitDirectory(SecuritySupport.SafePath directory);
@TargetElement(onlyWith = {JDKLatest.class, SecuritySupportSafePathPresent.class})
public native void setDumpDirectory(Target_jdk_jfr_internal_SecuritySupport_SafePath directory);

@Alias
@TargetElement(onlyWith = {JDK21OrEarlier.class, SecuritySupportSafePathPresent.class})
public native void setDumpOnExitDirectory(Target_jdk_jfr_internal_SecuritySupport_SafePath directory);
}

final class JfrFilenameUtil {
Expand Down
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
/*
* Copyright (c) 2019, 2024, Oracle and/or its affiliates. All rights reserved.
* Copyright (c) 2019, 2025, Oracle and/or its affiliates. All rights reserved.
* Copyright (c) 2024, 2024, Red Hat Inc. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
Expand Down Expand Up @@ -31,6 +31,7 @@
import static com.oracle.svm.core.jfr.JfrArgumentParser.parseJfrOptions;
import static com.oracle.svm.core.jfr.JfrArgumentParser.parseMaxSize;

import java.nio.file.Paths;
import java.util.Map;

import org.graalvm.nativeimage.ImageSingletons;
Expand Down Expand Up @@ -125,8 +126,12 @@ private static void parseFlightRecorderOptions() throws JfrArgumentParsingFailed

if (repositoryPath != null) {
try {
SecuritySupport.SafePath repositorySafePath = new SecuritySupport.SafePath(repositoryPath);
Repository.getRepository().setBasePath(repositorySafePath);
if (new SecuritySupportSafePathPresent().getAsBoolean()) {
Target_jdk_jfr_internal_SecuritySupport_SafePath repositorySafePath = new Target_jdk_jfr_internal_SecuritySupport_SafePath(repositoryPath);
SubstrateUtil.cast(Repository.getRepository(), Target_jdk_jfr_internal_Repository.class).setBasePath(repositorySafePath);
} else {
SubstrateUtil.cast(Repository.getRepository(), Target_jdk_jfr_internal_Repository.class).setBasePath(Paths.get(repositoryPath));
}
} catch (Throwable e) {
throw new JfrArgumentParsingFailed("Could not use " + repositoryPath + " as repository. " + e.getMessage(), e);
}
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,63 @@
/*
* Copyright (c) 2021, 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 com.oracle.svm.core.jfr;

import com.oracle.svm.core.annotate.Alias;
import com.oracle.svm.core.annotate.TargetClass;
import com.oracle.svm.core.annotate.TargetElement;

import java.util.function.BooleanSupplier;

/**
* A predicate that returns {@code true} if {@code boolean jdk.jfr.internal.SecuritySupport.SafePath} exists.
*/
final class SecuritySupportSafePathPresent implements BooleanSupplier {
@Override
public boolean getAsBoolean() {
try {
Class.forName("jdk.jfr.internal.SecuritySupport$SafePath");
return true;
} catch (ClassNotFoundException e) {
return false;
}
}
}

final class SecuritySupportSafePathAbsent implements BooleanSupplier {
@Override
public boolean getAsBoolean() {
return !new SecuritySupportSafePathPresent().getAsBoolean();
}
}

@TargetClass(className = "jdk.jfr.internal.SecuritySupport$SafePath", onlyWith = SecuritySupportSafePathPresent.class)
final class Target_jdk_jfr_internal_SecuritySupport_SafePath {
public Target_jdk_jfr_internal_SecuritySupport_SafePath(String p) {
originalConstructor(p);
}
@Alias
@TargetElement(name = TargetElement.CONSTRUCTOR_NAME)
native void originalConstructor(String p);
}
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
/*
* Copyright (c) 2021, 2021, Oracle and/or its affiliates. All rights reserved.
* Copyright (c) 2021, 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
Expand All @@ -24,22 +24,46 @@
*/
package com.oracle.svm.core.jfr;

import java.io.IOException;
import java.nio.file.Path;

import com.oracle.svm.core.SubstrateUtil;
import com.oracle.svm.core.annotate.Alias;
import com.oracle.svm.core.annotate.RecomputeFieldValue;
import com.oracle.svm.core.annotate.Substitute;
import com.oracle.svm.core.annotate.TargetClass;
import com.oracle.svm.core.annotate.TargetElement;

import jdk.jfr.internal.SecuritySupport.SafePath;
import jdk.jfr.internal.SecuritySupport;
import jdk.jfr.internal.Repository;

@TargetClass(value = jdk.jfr.internal.Repository.class, onlyWith = HasJfrSupport.class)
public final class Target_jdk_jfr_internal_Repository {
@Alias private SafePath baseLocation;
@Alias @TargetElement(onlyWith = SecuritySupportSafePathAbsent.class)
private static Path JAVA_IO_TMPDIR;
@Alias @TargetElement(name = "baseLocation", onlyWith = SecuritySupportSafePathPresent.class)
private Target_jdk_jfr_internal_SecuritySupport_SafePath baseLocationSafePath;
@Alias @TargetElement(name = "baseLocation", onlyWith = SecuritySupportSafePathAbsent.class)
private Path baseLocationPath;

@Substitute @TargetElement(name = "ensureRepository", onlyWith = SecuritySupportSafePathPresent.class)
synchronized void ensureRepositorySafePath() throws Exception {
if (baseLocationSafePath == null) {
Target_jdk_jfr_internal_SecuritySupport_SafePath path = Target_jdk_jfr_internal_SecuritySupport.getPathInProperty("java.io.tmpdir", null);
setBasePath(path);
}
}

@Substitute
synchronized void ensureRepository() throws Exception {
if (baseLocation == null) {
SafePath path = Target_jdk_jfr_internal_SecuritySupport.getPathInProperty("java.io.tmpdir", null);
SubstrateUtil.cast(this, jdk.jfr.internal.Repository.class).setBasePath(path);
@Substitute @TargetElement(name = "ensureRepository", onlyWith = SecuritySupportSafePathAbsent.class)
synchronized void ensureRepositoryPath() throws Exception {
if (baseLocationPath == null) {
setBasePath(JAVA_IO_TMPDIR);
}
}

@Alias @TargetElement(onlyWith = SecuritySupportSafePathPresent.class)
public synchronized native void setBasePath(Target_jdk_jfr_internal_SecuritySupport_SafePath baseLocation) throws IOException;

@Alias @TargetElement(onlyWith = SecuritySupportSafePathAbsent.class)
public synchronized native void setBasePath(Path baseLocation) throws IOException;
}
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
/*
* Copyright (c) 2021, 2021, Oracle and/or its affiliates. All rights reserved.
* Copyright (c) 2021, 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
Expand Down Expand Up @@ -30,24 +30,25 @@
import com.oracle.svm.core.annotate.RecomputeFieldValue;
import com.oracle.svm.core.annotate.Substitute;
import com.oracle.svm.core.annotate.TargetClass;
import com.oracle.svm.core.annotate.TargetElement;
import com.oracle.svm.core.util.VMError;

import jdk.jfr.internal.SecuritySupport.SafePath;
import jdk.jfr.internal.SecuritySupport;

@TargetClass(value = jdk.jfr.internal.SecuritySupport.class, onlyWith = HasJfrSupport.class)
public final class Target_jdk_jfr_internal_SecuritySupport {
// Checkstyle: stop
@Alias @RecomputeFieldValue(kind = RecomputeFieldValue.Kind.Reset) //
static SafePath JFC_DIRECTORY;
@Alias @RecomputeFieldValue(kind = RecomputeFieldValue.Kind.Reset) //
static SafePath JAVA_IO_TMPDIR;
@Alias @TargetElement(onlyWith = SecuritySupportSafePathPresent.class) @RecomputeFieldValue(kind = RecomputeFieldValue.Kind.Reset) //
static Target_jdk_jfr_internal_SecuritySupport_SafePath JFC_DIRECTORY;
@Alias @TargetElement(onlyWith = SecuritySupportSafePathPresent.class) @RecomputeFieldValue(kind = RecomputeFieldValue.Kind.Reset) //
static Target_jdk_jfr_internal_SecuritySupport_SafePath JAVA_IO_TMPDIR;
// Checkstyle: resume

@Substitute
public static List<SafePath> getPredefinedJFCFiles() {
@Substitute @TargetElement(onlyWith = SecuritySupportSafePathPresent.class)
public static List<Target_jdk_jfr_internal_SecuritySupport_SafePath> getPredefinedJFCFiles() {
throw VMError.shouldNotReachHere("Paths from the image build must not be embedded into the Native Image.");
}

@Alias
static native SafePath getPathInProperty(String prop, String subPath);
@Alias @TargetElement(onlyWith = SecuritySupportSafePathPresent.class)
static native Target_jdk_jfr_internal_SecuritySupport_SafePath getPathInProperty(String prop, String subPath);
}
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
/*
* Copyright (c) 2019, 2021, Oracle and/or its affiliates. All rights reserved.
* Copyright (c) 2019, 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
Expand Down Expand Up @@ -45,6 +45,7 @@

import jdk.graal.compiler.serviceprovider.JavaVersionUtil;
import jdk.jfr.internal.JVM;
import jdk.jfr.internal.MetadataRepository;
import jdk.jfr.internal.SecuritySupport;
import jdk.vm.ci.meta.MetaAccessProvider;
import jdk.vm.ci.meta.ResolvedJavaField;
Expand All @@ -68,6 +69,9 @@ public class JfrEventSubstitution extends SubstitutionProcessor {
private final Map<String, Class<? extends jdk.jfr.Event>> mirrorEventMapping;

private static final Method registerMirror = JavaVersionUtil.JAVA_SPEC < 22 ? ReflectionUtil.lookupMethod(SecuritySupport.class, "registerMirror", Class.class) : null;
private static final Method registerEvent = ReflectionUtil.lookupMethod(true, SecuritySupport.class, "registerEvent", Class.class);
private static final Method register = registerEvent == null ? ReflectionUtil.lookupMethod(true, MetadataRepository.class, "register", Class.class) : null;
private static final Method getInstance = registerEvent == null ? ReflectionUtil.lookupMethod(true, MetadataRepository.class, "getInstance") : null;
private static final Method getConfiguration = ReflectionUtil.lookupMethod(JVM.class, "getConfiguration", Class.class);

JfrEventSubstitution(MetaAccessProvider metaAccess, ImageHeapScanner heapScanner) {
Expand Down Expand Up @@ -171,7 +175,12 @@ private Boolean initEventClass(ResolvedJavaType eventType) throws RuntimeExcepti
}
}

SecuritySupport.registerEvent(newEventClass);
if (registerEvent != null) {
registerEvent.invoke(null, newEventClass);
} else {
MetadataRepository mdr = (MetadataRepository)getInstance.invoke(null);
register.invoke(mdr, newEventClass);
}

JfrJavaEvents.registerEventClass(newEventClass);
// the reflection registration for the event handler field is delayed to the JfrFeature
Expand Down

0 comments on commit 0400cf1

Please sign in to comment.