brooklyn-dev mailing list archives

Site index · List index
Message view « Date » · « Thread »
Top « Date » · « Thread »
From "ASF GitHub Bot (JIRA)" <j...@apache.org>
Subject [jira] [Commented] (BROOKLYN-513) yaml location for azurecompute-arm templateOptions.ipOptions fails
Date Fri, 02 Jun 2017 10:04:04 GMT

    [ https://issues.apache.org/jira/browse/BROOKLYN-513?page=com.atlassian.jira.plugin.system.issuetabpanels:comment-tabpanel&focusedCommentId=16034425#comment-16034425
] 

ASF GitHub Bot commented on BROOKLYN-513:
-----------------------------------------

Github user neykov commented on a diff in the pull request:

    https://github.com/apache/brooklyn-server/pull/714#discussion_r119822500
  
    --- Diff: utils/common/src/main/java/org/apache/brooklyn/util/javalang/MethodAccessibleReflections.java
---
    @@ -0,0 +1,142 @@
    +/*
    + * Licensed to the Apache Software Foundation (ASF) under one
    + * or more contributor license agreements.  See the NOTICE file
    + * distributed with this work for additional information
    + * regarding copyright ownership.  The ASF licenses this file
    + * to you under the Apache License, Version 2.0 (the
    + * "License"); you may not use this file except in compliance
    + * with the License.  You may obtain a copy of the License at
    + *
    + *     http://www.apache.org/licenses/LICENSE-2.0
    + *
    + * Unless required by applicable law or agreed to in writing,
    + * software distributed under the License is distributed on an
    + * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
    + * KIND, either express or implied.  See the License for the
    + * specific language governing permissions and limitations
    + * under the License.
    + */
    +package org.apache.brooklyn.util.javalang;
    +
    +import java.lang.reflect.Method;
    +import java.lang.reflect.Modifier;
    +import java.util.Set;
    +
    +import org.apache.brooklyn.util.guava.Maybe;
    +import org.slf4j.Logger;
    +import org.slf4j.LoggerFactory;
    +
    +import com.google.common.collect.Sets;
    +
    +/**
    + * Use {@link Reflections} methods to access this. The methods are declared here (to
this 
    + * package-private class) so we can avoid having an ever-growing single Reflections class!
    + */
    +class MethodAccessibleReflections {
    +
    +    private static final Logger LOG = LoggerFactory.getLogger(MethodAccessibleReflections.class);
    +    
    +    /**
    +     * Contains method.toString() representations for methods we have logged about failing
to
    +     * set accessible (or to find an alternative accessible version). Use this to ensure
we 
    +     * log.warn just once per method, rather than risk flooding our log.
    +     */
    +    private static final Set<String> SET_ACCESSIBLE_FAILED_LOGGED_METHODS = Sets.newConcurrentHashSet();
    +    
    +    /**
    +     * Contains method.toString() representations for methods we have logged about having
set
    +     * accessible. Having to setAccessible is discouraged, so want a single log.warn
once per
    +     * method.
    +     */
    +    private static final Set<String> SET_ACCESSIBLE_SUCCEEDED_LOGGED_METHODS =
Sets.newConcurrentHashSet();
    +    
    +    static boolean trySetAccessible(Method method) {
    +        try {
    +            method.setAccessible(true);
    +            if (SET_ACCESSIBLE_SUCCEEDED_LOGGED_METHODS.add(method.toString())) {
    +                LOG.warn("Discouraged use of setAccessible, called for method " + method);
    +            } else {
    +                if (LOG.isTraceEnabled()) LOG.trace("Discouraged use of setAccessible,
called for method " + method);
    +            }
    +            return true;
    +            
    +        } catch (SecurityException e) {
    +            boolean added = SET_ACCESSIBLE_FAILED_LOGGED_METHODS.add(method.toString());
    +            if (added) {
    +                LOG.warn("Problem setting accessible for method " + method, e);
    +            } else {
    +                if (LOG.isTraceEnabled()) LOG.trace("Problem setting accessible for method
" + method, e);
    +            }
    +            return false;
    +        }
    +    }
    +
    +    /**
    +     * @see {@link Reflections#findAccessibleMethod(Method)}
    +     */
    +    static Method findAccessibleMethod(Method method) {
    +        if (!Modifier.isPublic(method.getModifiers())) {
    +            trySetAccessible(method);
    +            return method;
    +        }
    +        boolean declaringClassPublic = Modifier.isPublic(method.getDeclaringClass().getModifiers());
    +        if (!declaringClassPublic) {
    +            // reflectively calling a public method on a private class can fail, unless
we first set it
    +            // call setAccessible. But first see if there is a public method on a public
super-type
    +            // that we can call instead!
    +            Maybe<Method> publicMethod = tryFindPublicEquivalent(method);
    +            if (publicMethod.isPresent()) {
    +                LOG.debug("Switched method for publicly accessible equivalent: method={};
origMethod={}", publicMethod.get(), method);
    +                return publicMethod.get();
    +            } else {
    +                trySetAccessible(method);
    +                return method;
    +            }
    +        }
    +        
    +        return method;
    +    }
    +    
    +    private static Maybe<Method> tryFindPublicEquivalent(Method method) {
    +        if (Modifier.isStatic(method.getModifiers())) {
    +            return Maybe.absent();
    +        }
    +        
    +        Class<?> clazz = method.getDeclaringClass();
    +        
    +        for (Class<?> interf : clazz.getInterfaces()) {
    +            Maybe<Method> altMethod = tryFindPublicMethod(interf, method.getName(),
method.getParameterTypes());
    +            if (altMethod.isPresent()) {
    +                return altMethod;
    +            }
    +        }
    +        
    +        Class<?> superClazz = clazz.getSuperclass();
    +        while (superClazz != null) {
    +            Maybe<Method> altMethod = tryFindPublicMethod(superClazz, method.getName(),
method.getParameterTypes());
    +            if (altMethod.isPresent()) {
    +                return altMethod;
    +            }
    +            superClazz = superClazz.getSuperclass();
    +        }
    +        
    +        return Maybe.absent();
    +    }
    +
    +    private static Maybe<Method> tryFindPublicMethod(Class<?> clazz, String
methodName, Class<?>... parameterTypes) {
    +        if (!Modifier.isPublic(clazz.getModifiers())) {
    +            return Maybe.absent();
    +        }
    +        
    +        try {
    +            Method altMethod = clazz.getMethod(methodName, parameterTypes);
    +            if (Modifier.isPublic(altMethod.getModifiers()) && !Modifier.isStatic(altMethod.getModifiers()))
{
    +                return Maybe.of(altMethod);
    --- End diff --
    
    Somehow missed that, it's all good then.


> yaml location for azurecompute-arm templateOptions.ipOptions fails
> ------------------------------------------------------------------
>
>                 Key: BROOKLYN-513
>                 URL: https://issues.apache.org/jira/browse/BROOKLYN-513
>             Project: Brooklyn
>          Issue Type: Bug
>    Affects Versions: 0.11.0
>            Reporter: Aled Sage
>
> When attempting to use the very latest jclouds 2.1.0-SNAPSHOT azurecompute-arm with the
location yaml below, it fails to convert this to an {{IpOptions}} instance.
> {noformat}
> templateOptions:
>   ipOptions:
>   - subnet: manual-subnet-ambari
> {noformat}
> This is because of how jclouds declares its builder. The {{IpOptions.builder()}} method
returns an instance of {{AutoValue_IpOptions.Builder}}, but that class is package-private
[1]. Therefore reflectively trying to call {{builder.subnet("manual-subnet-ambari")}} is failing
because the method is not accessible.
> [1] https://github.com/jclouds/jclouds-labs/blob/master/azurecompute-arm/src/main/java/org/jclouds/azurecompute/arm/compute/options/IpOptions.java#L60



--
This message was sent by Atlassian JIRA
(v6.3.15#6346)

Mime
View raw message