Search in sources :

Example 1 with DuringAnalysisAccess

use of org.graalvm.nativeimage.Feature.DuringAnalysisAccess in project graal by oracle.

the class ReflectionDataBuilder method duringAnalysis.

protected void duringAnalysis(DuringAnalysisAccess a) {
    DuringAnalysisAccessImpl access = (DuringAnalysisAccessImpl) a;
    if (!modified) {
        return;
    }
    modified = false;
    access.requireAnalysisIteration();
    Method reflectionDataMethod = findMethod(Class.class, "reflectionData");
    Class<?> originalReflectionDataClass = access.getImageClassLoader().findClassByName("java.lang.Class$ReflectionData");
    Field declaredFieldsField = findField(originalReflectionDataClass, "declaredFields");
    Field publicFieldsField = findField(originalReflectionDataClass, "publicFields");
    Field declaredMethodsField = findField(originalReflectionDataClass, "declaredMethods");
    Field publicMethodsField = findField(originalReflectionDataClass, "publicMethods");
    Field declaredConstructorsField = findField(originalReflectionDataClass, "declaredConstructors");
    Field publicConstructorsField = findField(originalReflectionDataClass, "publicConstructors");
    Field declaredPublicFieldsField = findField(originalReflectionDataClass, "declaredPublicFields");
    Field declaredPublicMethodsField = findField(originalReflectionDataClass, "declaredPublicMethods");
    Field[] emptyFields = new Field[0];
    Method[] emptyMethods = new Method[0];
    Constructor<?>[] emptyConstructors = new Constructor<?>[0];
    Set<Class<?>> allClasses = new HashSet<>(reflectionClasses);
    reflectionMethods.stream().map(method -> method.getDeclaringClass()).forEach(clazz -> allClasses.add(clazz));
    reflectionFields.stream().map(field -> field.getDeclaringClass()).forEach(clazz -> allClasses.add(clazz));
    /*
         * We need to find all classes that have an enclosingMethod or enclosingConstructor.
         * Unfortunately, there is no reverse lookup (ask a Method or Constructor about the classes
         * they contain), so we need to iterate through all types that have been loaded so far.
         * Accessing the original java.lang.Class for a ResolvedJavaType is not 100% reliable,
         * especially in the case of class and method substitutions. But it is the best we can do
         * here, and we assume that user code that requires reflection support is not using
         * substitutions.
         */
    for (AnalysisType aType : access.getUniverse().getTypes()) {
        Class<?> originalClass = aType.getJavaClass();
        if (originalClass != null && enclosingMethodOrConstructor(originalClass) != null) {
            /*
                 * We haven an enclosing method or constructor for this class, so we add the class
                 * to the set of processed classes so that the ReflectionData is initialized below.
                 */
            allClasses.add(originalClass);
        }
    }
    for (Class<?> clazz : allClasses) {
        DynamicHub hub = access.getHostVM().dynamicHub(access.getMetaAccess().lookupJavaType(clazz));
        if (reflectionClasses.contains(clazz)) {
            ClassForNameSupport.registerClass(clazz);
        }
        /*
             * Ensure all internal fields of the original Class.ReflectionData object are
             * initialized. Calling the public methods triggers lazy initialization of the fields.
             */
        clazz.getDeclaredFields();
        clazz.getFields();
        clazz.getDeclaredMethods();
        clazz.getMethods();
        clazz.getDeclaredConstructors();
        clazz.getConstructors();
        try {
            Object originalReflectionData = reflectionDataMethod.invoke(clazz);
            hub.setReflectionData(new DynamicHub.ReflectionData(filter(declaredFieldsField.get(originalReflectionData), reflectionFields, emptyFields), filter(publicFieldsField.get(originalReflectionData), reflectionFields, emptyFields), filter(declaredMethodsField.get(originalReflectionData), reflectionMethods, emptyMethods), filter(publicMethodsField.get(originalReflectionData), reflectionMethods, emptyMethods), filter(declaredConstructorsField.get(originalReflectionData), reflectionMethods, emptyConstructors), filter(publicConstructorsField.get(originalReflectionData), reflectionMethods, emptyConstructors), nullaryConstructor(declaredConstructorsField.get(originalReflectionData), reflectionMethods), filter(declaredPublicFieldsField.get(originalReflectionData), reflectionFields, emptyFields), filter(declaredPublicMethodsField.get(originalReflectionData), reflectionMethods, emptyMethods), enclosingMethodOrConstructor(clazz)));
        } catch (IllegalAccessException | IllegalArgumentException | InvocationTargetException ex) {
            throw VMError.shouldNotReachHere(ex);
        }
    }
}
Also used : Arrays(java.util.Arrays) AccessibleObject(java.lang.reflect.AccessibleObject) DuringAnalysisAccess(org.graalvm.nativeimage.Feature.DuringAnalysisAccess) ConcurrentHashMap(java.util.concurrent.ConcurrentHashMap) Set(java.util.Set) DynamicHub(com.oracle.svm.core.hub.DynamicHub) DuringAnalysisAccessImpl(com.oracle.svm.hosted.FeatureImpl.DuringAnalysisAccessImpl) Field(java.lang.reflect.Field) Constructor(java.lang.reflect.Constructor) InvocationTargetException(java.lang.reflect.InvocationTargetException) ArrayList(java.util.ArrayList) AnalysisType(com.oracle.graal.pointsto.meta.AnalysisType) VMError(com.oracle.svm.core.util.VMError) HashSet(java.util.HashSet) List(java.util.List) UserError(com.oracle.svm.core.util.UserError) Executable(java.lang.reflect.Executable) ClassForNameSupport(com.oracle.svm.core.hub.ClassForNameSupport) Method(java.lang.reflect.Method) Collections(java.util.Collections) RuntimeReflectionSupport(com.oracle.svm.core.RuntimeReflection.RuntimeReflectionSupport) AnalysisType(com.oracle.graal.pointsto.meta.AnalysisType) Constructor(java.lang.reflect.Constructor) Method(java.lang.reflect.Method) InvocationTargetException(java.lang.reflect.InvocationTargetException) Field(java.lang.reflect.Field) DynamicHub(com.oracle.svm.core.hub.DynamicHub) DuringAnalysisAccessImpl(com.oracle.svm.hosted.FeatureImpl.DuringAnalysisAccessImpl) AccessibleObject(java.lang.reflect.AccessibleObject) HashSet(java.util.HashSet)

Aggregations

AnalysisType (com.oracle.graal.pointsto.meta.AnalysisType)1 RuntimeReflectionSupport (com.oracle.svm.core.RuntimeReflection.RuntimeReflectionSupport)1 ClassForNameSupport (com.oracle.svm.core.hub.ClassForNameSupport)1 DynamicHub (com.oracle.svm.core.hub.DynamicHub)1 UserError (com.oracle.svm.core.util.UserError)1 VMError (com.oracle.svm.core.util.VMError)1 DuringAnalysisAccessImpl (com.oracle.svm.hosted.FeatureImpl.DuringAnalysisAccessImpl)1 AccessibleObject (java.lang.reflect.AccessibleObject)1 Constructor (java.lang.reflect.Constructor)1 Executable (java.lang.reflect.Executable)1 Field (java.lang.reflect.Field)1 InvocationTargetException (java.lang.reflect.InvocationTargetException)1 Method (java.lang.reflect.Method)1 ArrayList (java.util.ArrayList)1 Arrays (java.util.Arrays)1 Collections (java.util.Collections)1 HashSet (java.util.HashSet)1 List (java.util.List)1 Set (java.util.Set)1 ConcurrentHashMap (java.util.concurrent.ConcurrentHashMap)1