Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line number Diff line number Diff line change
Expand Up @@ -243,6 +243,18 @@ public AnalysisMetaAccess getMetaAccess() {
return bb.getMetaAccess();
}

public AnalysisType findTypeByName(String className) {
Class<?> clazz = findClassByName(className);
if (clazz == null) {
return null;
}
return getMetaAccess().lookupJavaType(clazz);
}

public List<AnalysisType> findSubtypes(AnalysisType baseClass) {
return imageClassLoader.findSubclasses(baseClass.getJavaClass(), false).stream().map(getMetaAccess()::lookupJavaType).toList();
}

public boolean isReachable(Class<?> clazz) {
return isReachable(getMetaAccess().lookupJavaType(clazz));
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -25,15 +25,17 @@
*/
package com.oracle.svm.hosted.jdk;

import org.graalvm.nativeimage.hosted.RuntimeJNIAccess;
import org.graalvm.nativeimage.hosted.RuntimeReflection;

import com.oracle.graal.pointsto.meta.AnalysisMetaAccess;
import com.oracle.graal.pointsto.meta.AnalysisType;
import com.oracle.svm.core.VMInspectionOptions;
import com.oracle.svm.core.feature.AutomaticallyRegisteredFeature;
import com.oracle.svm.core.feature.InternalFeature;
import com.oracle.svm.core.jdk.JNIRegistrationUtil;
import com.oracle.svm.core.util.VMError;
import com.oracle.svm.util.ReflectionUtil;
import com.oracle.svm.hosted.FeatureImpl.BeforeAnalysisAccessImpl;
import com.oracle.svm.hosted.dynamicaccess.JVMCIRuntimeJNIAccess;
import com.oracle.svm.hosted.dynamicaccess.JVMCIRuntimeReflection;
import com.oracle.svm.util.JVMCIReflectionUtil;

@AutomaticallyRegisteredFeature
public class JmxClientFeature extends JNIRegistrationUtil implements InternalFeature {
Expand All @@ -45,16 +47,19 @@ public boolean isInConfiguration(IsInConfigurationAccess access) {
@Override
public void beforeAnalysis(BeforeAnalysisAccess access) {
try {
configureJNI();
configureReflection(access);
BeforeAnalysisAccessImpl accessImpl = (BeforeAnalysisAccessImpl) access;
configureJNI(accessImpl);
configureReflection(accessImpl);
} catch (Exception e) {
throw VMError.shouldNotReachHere("ManagementClientFeature configuration failed: " + e);
}
}

private static void configureJNI() {
RuntimeJNIAccess.register(Boolean.class);
RuntimeJNIAccess.register(ReflectionUtil.lookupMethod(Boolean.class, "getBoolean", String.class));
private static void configureJNI(BeforeAnalysisAccessImpl access) {
AnalysisMetaAccess metaAccess = access.getMetaAccess();
AnalysisType type = metaAccess.lookupJavaType(Boolean.class);
JVMCIRuntimeJNIAccess.register(type);
JVMCIRuntimeJNIAccess.register(JVMCIReflectionUtil.getDeclaredMethod(metaAccess, type, "getBoolean", String.class));
}

/**
Expand All @@ -69,14 +74,14 @@ private static void configureJNI() {
* {@code sun.rmi.server.UnicastRef#getRefClass(ObjectOutput)}.</li>
* </ul>
*/
private static void configureReflection(BeforeAnalysisAccess access) {
RuntimeReflection.register(access.findClassByName("com.sun.jndi.url.rmi.rmiURLContextFactory"));
RuntimeReflection.register(access.findClassByName("sun.rmi.server.UnicastRef"));
private static void configureReflection(BeforeAnalysisAccessImpl access) {
JVMCIRuntimeReflection.register(access.findTypeByName("com.sun.jndi.url.rmi.rmiURLContextFactory"));
JVMCIRuntimeReflection.register(access.findTypeByName("sun.rmi.server.UnicastRef"));

RuntimeReflection.register(access.findClassByName("com.sun.jmx.remote.protocol.rmi.ClientProvider"));
RuntimeReflection.register(access.findClassByName("com.sun.jndi.url.rmi.rmiURLContextFactory").getConstructors());
RuntimeReflection.register(access.findClassByName("sun.rmi.server.UnicastRef").getConstructors());
RuntimeReflection.register(access.findClassByName("sun.rmi.server.UnicastRef2").getConstructors());
RuntimeReflection.register(access.findClassByName("com.sun.jmx.remote.protocol.rmi.ClientProvider").getConstructors());
JVMCIRuntimeReflection.register(access.findTypeByName("com.sun.jmx.remote.protocol.rmi.ClientProvider"));
JVMCIRuntimeReflection.register(JVMCIReflectionUtil.getConstructors(access.findTypeByName("com.sun.jndi.url.rmi.rmiURLContextFactory")));
JVMCIRuntimeReflection.register(JVMCIReflectionUtil.getConstructors(access.findTypeByName("sun.rmi.server.UnicastRef")));
JVMCIRuntimeReflection.register(JVMCIReflectionUtil.getConstructors(access.findTypeByName("sun.rmi.server.UnicastRef2")));
JVMCIRuntimeReflection.register(JVMCIReflectionUtil.getConstructors(access.findTypeByName("com.sun.jmx.remote.protocol.rmi.ClientProvider")));
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -30,15 +30,20 @@

import org.graalvm.nativeimage.ImageSingletons;
import org.graalvm.nativeimage.dynamicaccess.AccessCondition;
import org.graalvm.nativeimage.hosted.RuntimeJNIAccess;
import org.graalvm.nativeimage.hosted.RuntimeReflection;
import org.graalvm.nativeimage.hosted.RuntimeSerialization;

import com.oracle.graal.pointsto.meta.AnalysisMetaAccess;
import com.oracle.svm.core.VMInspectionOptions;
import com.oracle.svm.core.feature.AutomaticallyRegisteredFeature;
import com.oracle.svm.core.feature.InternalFeature;
import com.oracle.svm.hosted.FeatureImpl.BeforeAnalysisAccessImpl;
import com.oracle.svm.hosted.dynamicaccess.JVMCIRuntimeJNIAccess;
import com.oracle.svm.hosted.dynamicaccess.JVMCIRuntimeReflection;
import com.oracle.svm.hosted.reflect.proxy.ProxyRegistry;
import com.oracle.svm.util.ReflectionUtil;
import com.oracle.svm.util.JVMCIReflectionUtil;

import jdk.vm.ci.meta.ResolvedJavaMethod;
import jdk.vm.ci.meta.ResolvedJavaType;

@AutomaticallyRegisteredFeature
public class JmxCommonFeature implements InternalFeature {
Expand Down Expand Up @@ -125,10 +130,11 @@ public void afterRegistration(AfterRegistrationAccess access) {

@Override
public void beforeAnalysis(BeforeAnalysisAccess access) {
configureJNI();
configureSerialization(access);
configureReflection(access);
configureProxy(access);
BeforeAnalysisAccessImpl accessImpl = (BeforeAnalysisAccessImpl) access;
configureJNI(accessImpl);
configureSerialization(accessImpl);
configureReflection(accessImpl);
configureProxy(accessImpl);
}

/**
Expand Down Expand Up @@ -156,7 +162,7 @@ public void beforeAnalysis(BeforeAnalysisAccess access) {
* </ul>
* </p>
*/
private static void configureProxy(BeforeAnalysisAccess access) {
private static void configureProxy(BeforeAnalysisAccessImpl access) {
ProxyRegistry proxyRegistry = ImageSingletons.lookup(ProxyRegistry.class);
proxyRegistry.registerProxy(AccessCondition.unconditional(), false, access.findClassByName("com.sun.management.GarbageCollectorMXBean"),
access.findClassByName("javax.management.NotificationEmitter"));
Expand All @@ -182,9 +188,11 @@ private static void configureProxy(BeforeAnalysisAccess access) {
access.findClassByName("javax.management.NotificationEmitter"));
}

private static void configureJNI() {
RuntimeJNIAccess.register(Arrays.class);
RuntimeJNIAccess.register(ReflectionUtil.lookupMethod(Arrays.class, "asList", Object[].class));
private static void configureJNI(BeforeAnalysisAccessImpl access) {
AnalysisMetaAccess metaAccess = access.getMetaAccess();
ResolvedJavaType type = metaAccess.lookupJavaType(Arrays.class);
JVMCIRuntimeJNIAccess.register(type);
JVMCIRuntimeJNIAccess.register(JVMCIReflectionUtil.getDeclaredMethod(metaAccess, type, "asList", Object[].class));
}

/**
Expand All @@ -202,7 +210,7 @@ private static void configureJNI() {
* the remote JMX infrastructure (See {@code sun.management.MappedMXBeanType},
* {@code com.sun.jmx.mbeanserver.MXBeanMapping#makeOpenClass(Type, javax.management.openmbean.OpenType)})
*/
private static void configureSerialization(BeforeAnalysisAccess access) {
private static void configureSerialization(BeforeAnalysisAccessImpl access) {
String[] classes = {
"[B", "com.oracle.svm.core.jdk.UnsupportedFeatureError",
"java.io.IOException", "java.lang.Boolean", "java.lang.ClassCastException", "java.lang.Error",
Expand Down Expand Up @@ -281,7 +289,7 @@ private static void configureSerialization(BeforeAnalysisAccess access) {
* {@code javax.management.remote.rmi.RMIConnectionImpl_Stub}.</li>
* </ul>
*/
private static void configureReflection(BeforeAnalysisAccess access) {
private static void configureReflection(BeforeAnalysisAccessImpl access) {
String[] classes = {
"com.sun.management.internal.OperatingSystemImpl",
"javax.management.remote.rmi.RMIConnectionImpl_Stub",
Expand Down Expand Up @@ -311,13 +319,49 @@ private static void configureReflection(BeforeAnalysisAccess access) {
};

for (String clazz : classes) {
RuntimeReflection.register(access.findClassByName(clazz));
JVMCIRuntimeReflection.register(access.findTypeByName(clazz));
}
for (String clazz : methods) {
RuntimeReflection.register(access.findClassByName(clazz).getMethods());
registerMethods(access.findTypeByName(clazz));
}
for (String clazz : constructors) {
RuntimeReflection.register(access.findClassByName(clazz).getConstructors());
JVMCIRuntimeReflection.register(JVMCIReflectionUtil.getConstructors(access.findTypeByName(clazz)));
}
}

/**
* Registers all public methods from the {@code declaringClass} and its super classes and
* interfaces for runtime reflection.
* <p>
* Note: this code originally used {@link Class#getMethods()}, which has slightly different
* semantics. For methods with the same signature, it only returns the most specific one. This
* code registers all of them. This trades-off registering more methods than really needed for a
* much simpler algorithm. Should at some point {@link JVMCIReflectionUtil} or
* {@link ResolvedJavaType} get an implementation that behaves as {@link Class#getMethods()}, we
* might want to use it.
*/
private static void registerMethods(ResolvedJavaType declaringClass) {
if ("java.lang.Object".equals(declaringClass.toClassName())) {
/*
* Don't register java.lang.Object methods since those are not reflectively needed by
* JMX. This a deviation from Class#getMethods().
*/
return;
}
// Start by fetching public declared methods...
for (ResolvedJavaMethod m : declaringClass.getDeclaredMethods(false)) {
if (m.isPublic()) {
JVMCIRuntimeReflection.register(m);
}
}
// ...then recur over superclass methods...
ResolvedJavaType sc = declaringClass.getSuperclass();
if (sc != null) {
registerMethods(sc);
}
// ...and finally over direct superinterfaces.
for (ResolvedJavaType intf : declaringClass.getInterfaces()) {
registerMethods(intf);
}
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -35,7 +35,6 @@

import org.graalvm.nativeimage.ImageSingletons;
import org.graalvm.nativeimage.dynamicaccess.AccessCondition;
import org.graalvm.nativeimage.hosted.RuntimeReflection;

import com.oracle.svm.configure.ResourcesRegistry;
import com.oracle.svm.core.VMInspectionOptions;
Expand All @@ -46,8 +45,12 @@
import com.oracle.svm.core.jdk.RuntimeSupport;
import com.oracle.svm.core.jdk.management.ManagementAgentStartupHook;
import com.oracle.svm.core.jdk.management.ManagementSupport;
import com.oracle.svm.hosted.reflect.proxy.ProxyRegistry;
import com.oracle.svm.hosted.FeatureImpl.BeforeAnalysisAccessImpl;
import com.oracle.svm.hosted.dynamicaccess.JVMCIRuntimeReflection;
import com.oracle.svm.hosted.reflect.proxy.ProxyRegistry;
import com.oracle.svm.util.JVMCIReflectionUtil;

import jdk.vm.ci.meta.ResolvedJavaType;

@AutomaticallyRegisteredFeature
public class JmxServerFeature implements InternalFeature {
Expand All @@ -71,7 +74,7 @@ private static void handleNativeLibraries(BeforeAnalysisAccess access) {
public void beforeAnalysis(BeforeAnalysisAccess access) {
handleNativeLibraries(access);
registerJMXAgentResources();
configureReflection(access);
configureReflection((BeforeAnalysisAccessImpl) access);
configureProxy(access);
RuntimeSupport.getRuntimeSupport().addStartupHook(new ManagementAgentStartupHook());
}
Expand Down Expand Up @@ -107,20 +110,19 @@ private static void configureProxy(BeforeAnalysisAccess access) {
* </li>
* </ul>
*/
private static void configureReflection(BeforeAnalysisAccess access) {
private static void configureReflection(BeforeAnalysisAccessImpl access) {
Set<PlatformManagedObject> platformManagedObjects = ManagementSupport.getSingleton().getPlatformManagedObjects();
for (PlatformManagedObject p : platformManagedObjects) {
// The platformManagedObjects list contains some PlatformManagedObjectSupplier objects
// that are meant to help initialize some MXBeans at runtime. Skip them here.
if (p instanceof ManagementSupport.PlatformManagedObjectSupplier) {
continue;
}
Class<?> clazz = p.getClass();
RuntimeReflection.register(clazz);
JVMCIRuntimeReflection.register(access.getMetaAccess().lookupJavaType(p.getClass()));
}

Class<?> serviceProviderClass = access.findClassByName("com.sun.jmx.remote.protocol.rmi.ServerProvider");
RuntimeReflection.register(serviceProviderClass);
RuntimeReflection.register(serviceProviderClass.getConstructors());
ResolvedJavaType serviceProviderClass = access.findTypeByName("com.sun.jmx.remote.protocol.rmi.ServerProvider");
JVMCIRuntimeReflection.register(serviceProviderClass);
JVMCIRuntimeReflection.register(JVMCIReflectionUtil.getConstructors(serviceProviderClass));
}
}
Loading