/** * There are some nasty bugs for introspection with generics. This method addresses those nasty * bugs and tries to find proper methods if available * http://bugs.sun.com/view_bug.do?bug_id=6788525 http://bugs.sun.com/view_bug.do?bug_id=6528714 * * @param descriptor * @return */ private static PropertyDescriptor fixGenericDescriptor( Class<?> clazz, PropertyDescriptor descriptor) { Method readMethod = descriptor.getReadMethod(); Method writeMethod = descriptor.getWriteMethod(); if (readMethod != null && (readMethod.isBridge() || readMethod.isSynthetic())) { String propertyName = descriptor.getName(); // capitalize the first letter of the string; String baseName = Character.toUpperCase(propertyName.charAt(0)) + propertyName.substring(1); String setMethodName = "set" + baseName; String getMethodName = "get" + baseName; Method[] methods = clazz.getMethods(); for (Method method : methods) { if (method.getName().equals(getMethodName) && !method.isBridge() && !method.isSynthetic()) { try { descriptor.setReadMethod(method); } catch (IntrospectionException e) { // move on } } if (method.getName().equals(setMethodName) && !method.isBridge() && !method.isSynthetic()) { try { descriptor.setWriteMethod(method); } catch (IntrospectionException e) { // move on } } } } return descriptor; }
private void initMethodConstraints( Class<?> clazz, AnnotationIgnores annotationIgnores, BeanMetaDataCache beanMetaDataCache) { final Method[] declaredMethods = ReflectionHelper.getDeclaredMethods(clazz); for (Method method : declaredMethods) { // HV-172; ignoring synthetic methods (inserted by the compiler), as they can't have any // constraints // anyway and possibly hide the actual method with the same signature in the built meta model if (Modifier.isStatic(method.getModifiers()) || annotationIgnores.isIgnoreAnnotations(method) || method.isSynthetic()) { continue; } // try to get meta data from cache, otherwise retrieve it from the class MethodMetaData methodMetaData = getFromCache(clazz, method, beanMetaDataCache); if (methodMetaData == null) { methodMetaData = findMethodMetaData(method); } addMethodMetaConstraint(clazz, methodMetaData); } }
public static List<ButtonInfo> computeButtonsForClass(Class<?> someClass, String list) { List<ButtonInfo> buttons = new ArrayList<ButtonInfo>(); for (Method method : someClass.getMethods()) { if (method.isBridge() || method.isSynthetic()) { continue; } Button button = getButtonForMethod(method, list); if (button != null) { ButtonInfo buttonInfo = new ButtonInfo(button, method, someClass); buttons.add(buttonInfo); } } Collections.sort(buttons, new ButtonComparatorByOrder()); // Group together buttons of the same group for (int i = 0; i < buttons.size() - 1; i++) { ButtonInfo info = buttons.get(i); String group = info.getButton().group(); if (!StringUtils.isBlank(group)) { int count = 1; for (int j = i + 1; j < buttons.size(); j++) { ButtonInfo info2 = buttons.get(j); if (info2.getButton().group().equals(group)) { buttons.remove(j); buttons.add(i + count, info2); count++; } } } } return buttons; }
public void testOverrideMethods() throws Exception { HashSet<String> methodsThatShouldNotBeOverridden = new HashSet<String>(); methodsThatShouldNotBeOverridden.add("reopen"); methodsThatShouldNotBeOverridden.add("doOpenIfChanged"); methodsThatShouldNotBeOverridden.add("clone"); boolean fail = false; for (Method m : FilterIndexReader.class.getMethods()) { int mods = m.getModifiers(); if (Modifier.isStatic(mods) || Modifier.isFinal(mods) || m.isSynthetic()) { continue; } Class<?> declaringClass = m.getDeclaringClass(); String name = m.getName(); if (declaringClass != FilterIndexReader.class && declaringClass != Object.class && !methodsThatShouldNotBeOverridden.contains(name)) { System.err.println("method is not overridden by FilterIndexReader: " + name); fail = true; } else if (declaringClass == FilterIndexReader.class && methodsThatShouldNotBeOverridden.contains(name)) { System.err.println("method should not be overridden by FilterIndexReader: " + name); fail = true; } } assertFalse( "FilterIndexReader overrides (or not) some problematic methods; see log above", fail); // some more inner classes: checkOverrideMethods(FilterIndexReader.FilterTermEnum.class); checkOverrideMethods(FilterIndexReader.FilterTermDocs.class); // TODO: FilterTermPositions should extend correctly, this is borken, // but for backwards compatibility we let it be: // checkOverrideMethods(FilterIndexReader.FilterTermPositions.class); }
private void validateNonRuleMethod(Method method, ValidationProblemCollector problems) { if (!Modifier.isPrivate(method.getModifiers()) && !Modifier.isStatic(method.getModifiers()) && !method.isSynthetic() && !ModelSchemaUtils.isObjectMethod(method)) { problems.add(method, "A method that is not annotated as a rule must be private"); } }
private void addBeanMapping( WSDDService service, Class<?> clazz, Collection<Class<?>> mappedClasses) { while (clazz != null) { while (clazz.isArray()) { clazz = clazz.getComponentType(); } if (!needsMapping(clazz)) return; if (mappedClasses.contains(clazz)) return; mappedClasses.add(clazz); for (Method m : clazz.getDeclaredMethods()) { if (!m.isSynthetic() && m.getName().startsWith("get") && m.getParameterTypes().length == 0 && (m.getModifiers() & Modifier.PUBLIC) != 0) { addBeanMapping(service, m.getReturnType(), mappedClasses); } } WSDDBeanMapping m = new WSDDBeanMapping(); m.setLanguageSpecificType(clazz); Package p = clazz.getPackage(); if (p == null) { // arrayちゃんと処理できてる? // System.out.println(clazz); } String packageName = p != null ? p.getName() : ""; String simpleName = clazz.getSimpleName(); boolean qnameSet = false; for (Pair<String, String> n : namespaceMappings) { if (packageName.startsWith(n.getFirst())) { String rest = packageName.substring(n.getFirst().length()).replace('.', '/'); String nsPrefix = n.getSecond(); if (rest.length() > 0) { rest = rest + "/"; if (nsPrefix.endsWith("/") && rest.charAt(0) == '/') { rest = rest.substring(1); } } m.setQName(new QName(n.getSecond() + rest, simpleName)); qnameSet = true; break; } } if (!qnameSet) { m.setQName(new QName("uri:" + packageName + "/", simpleName)); } m.setSerializer(WSDDConstants.BEAN_SERIALIZER_FACTORY); m.setDeserializer(WSDDConstants.BEAN_DESERIALIZER_FACTORY); service.addTypeMapping(m); clazz = clazz.getSuperclass(); } }
public List<ProviderMethod<?>> getProviderMethods(Binder binder) { System.out.println("end"); List<ProviderMethod<?>> result = Lists.newArrayList(); Multimap<Signature, Method> methodsBySignature = HashMultimap.create(); for (Class<?> c = delegate.getClass(); c != Object.class; c = c.getSuperclass()) { for (Method method : c.getDeclaredMethods()) { // private/static methods cannot override or be overridden by other methods, so there is no // point in indexing them. // Skip synthetic methods and bridge methods since java will automatically generate // synthetic overrides in some cases where we don't want to generate an error (e.g. // increasing visibility of a subclass). if (((method.getModifiers() & (Modifier.PRIVATE | Modifier.STATIC)) == 0) && !method.isBridge() && !method.isSynthetic()) { methodsBySignature.put(new Signature(method), method); } Optional<Annotation> annotation = isProvider(binder, method); if (annotation.isPresent()) { result.add(createProviderMethod(binder, method, annotation.get())); } } } // we have found all the providers and now need to identify if any were overridden // In the worst case this will have O(n^2) in the number of @Provides methods, but that is only // assuming that every method is an override, in general it should be very quick. for (ProviderMethod<?> provider : result) { Method method = provider.getMethod(); for (Method matchingSignature : methodsBySignature.get(new Signature(method))) { // matching signature is in the same class or a super class, therefore method cannot be // overridding it. if (matchingSignature.getDeclaringClass().isAssignableFrom(method.getDeclaringClass())) { continue; } // now we know matching signature is in a subtype of method.getDeclaringClass() if (overrides(matchingSignature, method)) { String annotationString = provider.getAnnotation().annotationType() == Provides.class ? "@Provides" : "@" + provider.getAnnotation().annotationType().getCanonicalName(); binder.addError( "Overriding " + annotationString + " methods is not allowed." + "\n\t" + annotationString + " method: %s\n\toverridden by: %s", method, matchingSignature); break; } } } return result; }
/** * Build metadata from annotations on classes and methods * * @return */ public static ResourceClass fromAnnotations(Class<?> clazz) { ResourceClassBuilder builder = resourceClass(clazz); for (Method method : clazz.getMethods()) { if (!method.isSynthetic() && !method.getDeclaringClass().equals(Object.class)) processMethod(builder, clazz, method); } if (!clazz.isInterface()) { processFields(builder, clazz); } processSetters(builder, clazz); return builder.buildClass(); }
protected Method getApplyMethod(Transform t) { Method[] methods = t.getClass().getMethods(); for (Method method : methods) { if (method.getName().equals("apply") && method.getParameterTypes().length == 1 && !method.isSynthetic()) { method.setAccessible(true); return method; } } return null; }
protected boolean _isIncludableMethod(Method m, MethodFilter filter) { if (filter != null && !filter.includeMethod(m)) { return false; } /* 07-Apr-2009, tatu: Looks like generics can introduce hidden * bridge and/or synthetic methods. I don't think we want to * consider those... */ if (m.isSynthetic() || m.isBridge()) { return false; } return true; }
private void checkOverrideMethods(Class<?> clazz) throws Exception { boolean fail = false; for (Method m : clazz.getMethods()) { int mods = m.getModifiers(); if (Modifier.isStatic(mods) || Modifier.isFinal(mods) || m.isSynthetic()) { continue; } Class<?> declaringClass = m.getDeclaringClass(); if (declaringClass != clazz && declaringClass != Object.class) { System.err.println( "method is not overridden by " + clazz.getName() + ": " + m.toGenericString()); fail = true; } } assertFalse(clazz.getName() + " does not override some methods; see log above", fail); }
/** * Checks that the method found through reflection matches the specification from the API xml * file. */ private void checkMethodCompliance() { for (JDiffMethod method : jDiffMethods) { try { // this is because jdiff think a method in an interface is not abstract if (JDiffType.INTERFACE.equals(mClassType)) { method.mModifier |= Modifier.ABSTRACT; } Method m = findMatchingMethod(method); if (m == null) { mResultObserver.notifyFailure( SignatureTestActivity.FAILURE_TYPE.MISSING_METHOD, method.toReadableString(mAbsoluteClassName), "No method with correct signature found:" + method.toSignatureString()); } else { if (m.isVarArgs()) { method.mModifier |= METHOD_MODIFIER_VAR_ARGS; } if (m.isBridge()) { method.mModifier |= METHOD_MODIFIER_BRIDGE; } if (m.isSynthetic()) { method.mModifier |= METHOD_MODIFIER_SYNTHETIC; } // FIXME: A workaround to fix the final mismatch on enumeration if (mClass.isEnum() && method.mName.equals("values")) { return; } if (!areMethodModifiedCompatibile(method, m)) { mResultObserver.notifyFailure( SignatureTestActivity.FAILURE_TYPE.MISMATCH_METHOD, method.toReadableString(mAbsoluteClassName), "Non-compatible method found when looking for " + method.toSignatureString()); } } } catch (Exception e) { SignatureTestLog.e("Got exception when checking method compliance", e); mResultObserver.notifyFailure( SignatureTestActivity.FAILURE_TYPE.CAUGHT_EXCEPTION, method.toReadableString(mAbsoluteClassName), "Exception!"); } } }
@Test public void testGetImplementationReflection() throws Exception { Class updatableResource = BackendDataCenterResource.class.getInterfaces()[0].getInterfaces()[0]; Assert.assertEquals(updatableResource, UpdatableResource.class); Method update = null; for (Method method : updatableResource.getMethods()) { if (method.getName().equals("update")) update = method; } Assert.assertNotNull(update); Method implemented = Types.getImplementingMethod(BackendDataCenterResource.class, update); Method actual = null; for (Method method : BackendDataCenterResource.class.getMethods()) { if (method.getName().equals("update") && !method.isSynthetic()) actual = method; } Assert.assertEquals(implemented, actual); }
private static Method findAnnotatedInterfaceMethod( Class<?> root, Class<?> iface, Method implementation) { for (Method method : iface.getMethods()) { if (method.isSynthetic()) continue; if (!method.getName().equals(implementation.getName())) continue; if (method.getParameterTypes().length != implementation.getParameterTypes().length) continue; Method actual = Types.getImplementingMethod(root, method); if (!actual.equals(implementation)) continue; if (method.isAnnotationPresent(Path.class) || IsHttpMethod.getHttpMethods(method) != null) return method; } for (Class<?> extended : iface.getInterfaces()) { Method m = findAnnotatedInterfaceMethod(root, extended, implementation); if (m != null) return m; } return null; }
private Class<? extends SharedState> findStateType() { try { Class<?> class1 = getClass(); while (class1 != null) { try { Method m = class1.getDeclaredMethod("getState", (Class[]) null); Class<?> type = m.getReturnType(); if (!m.isSynthetic()) { return type.asSubclass(SharedState.class); } } catch (NoSuchMethodException nsme) { } // Try in superclass instead class1 = class1.getSuperclass(); } throw new NoSuchMethodException(getClass().getCanonicalName() + ".getState()"); } catch (Exception e) { throw new RuntimeException("Error finding state type for " + getClass().getName(), e); } }
/** * Returns true if the method is a provider. * * <p>Synthetic bridge methods are excluded. Starting with JDK 8, javac copies annotations onto * bridge methods (which always have erased signatures). */ private Optional<Annotation> isProvider(Binder binder, Method method) { if (method.isBridge() || method.isSynthetic()) { return Optional.absent(); } Annotation annotation = null; for (Class<? extends Annotation> annotationClass : scanner.annotationClasses()) { Annotation foundAnnotation = method.getAnnotation(annotationClass); if (foundAnnotation != null) { if (annotation != null) { binder.addError( "More than one annotation claimed by %s on method %s." + " Methods can only have one annotation claimed per scanner.", scanner, method); return Optional.absent(); } annotation = foundAnnotation; } } return Optional.fromNullable(annotation); }
private Method findMethod(Method[] candidates, String name, Class<?>... parameterTypes) throws NoSuchMethodException { Method firstMatch = null; List<Method> allMatches = null; for (Method m : candidates) { if (name.equals(m.getName()) && R.matchParameterTypes(m, parameterTypes)) { if (firstMatch == null) { firstMatch = m; } else { if (allMatches == null) { allMatches = new ArrayList<Method>(); allMatches.add(firstMatch); } allMatches.add(m); } } } if (firstMatch == null) { throw new NoSuchMethodException( clazz.getName() + "." + name + '(' + parameterTypesToString(parameterTypes) + ')'); } if (allMatches == null) { return firstMatch; } // There are multiple methods with the same name and parameter types. The RI's docs says // pick the method with the most specific return type or pick an arbitrary if there are // no such methods. Dalvik just filters out synthetic methods and then picks an arbitrary // one (if the source language is Java there should only be one non-synthetic match). Method result = null; for (Method m : allMatches) { if (!m.isSynthetic()) { return m; } result = m; } return result; }
private static ImmutableList<Method> getAnnotatedMethodsNotCached(Class<?> clazz) { Set<? extends Class<?>> supertypes = TypeToken.of(clazz).getTypes().rawTypes(); Map<MethodIdentifier, Method> identifiers = Maps.newHashMap(); for (Class<?> supertype : supertypes) { for (Method method : supertype.getDeclaredMethods()) { if (method.isAnnotationPresent(Subscribe.class) && !method.isSynthetic()) { // TODO(user): Should check for a generic parameter type and error out Class<?>[] parameterTypes = method.getParameterTypes(); checkArgument( parameterTypes.length == 1, "Method %s has @Subscribe annotation but has %s parameters." + "Subscriber methods must have exactly 1 parameter.", method, parameterTypes.length); MethodIdentifier ident = new MethodIdentifier(method); if (!identifiers.containsKey(ident)) { identifiers.put(ident, method); } } } } return ImmutableList.copyOf(identifiers.values()); }
static CachedMethod[] getMethods(Kryo kryo, Class type) { CachedMethod[] cachedMethods = methodCache.get(type); if (cachedMethods != null) { return cachedMethods; } ArrayList<Method> allMethods = new ArrayList(); Class nextClass = type; while ((nextClass != null) && (nextClass != Object.class)) { Collections.addAll(allMethods, nextClass.getDeclaredMethods()); nextClass = nextClass.getSuperclass(); } PriorityQueue<Method> methods = new PriorityQueue( Math.max(1, allMethods.size()), new Comparator<Method>() { @Override public int compare(Method o1, Method o2) { // Methods are sorted so they can be represented as an index. int diff = o1.getName().compareTo(o2.getName()); if (diff != 0) { return diff; } Class[] argTypes1 = o1.getParameterTypes(); Class[] argTypes2 = o2.getParameterTypes(); if (argTypes1.length > argTypes2.length) { return 1; } if (argTypes1.length < argTypes2.length) { return -1; } for (int i = 0; i < argTypes1.length; i++) { diff = argTypes1[i].getName().compareTo(argTypes2[i].getName()); if (diff != 0) { return diff; } } throw new RuntimeException("Two methods with same signature!"); // Impossible. } }); for (int i = 0, n = allMethods.size(); i < n; i++) { Method method = allMethods.get(i); int modifiers = method.getModifiers(); if (Modifier.isStatic(modifiers)) { continue; } if (Modifier.isPrivate(modifiers)) { continue; } if (method.isSynthetic()) { continue; } methods.add(method); } int n = methods.size(); cachedMethods = new CachedMethod[n]; for (int i = 0; i < n; i++) { CachedMethod cachedMethod = new CachedMethod(); cachedMethod.method = methods.poll(); // Store the serializer for each final parameter. Class[] parameterTypes = cachedMethod.method.getParameterTypes(); cachedMethod.serializers = new Serializer[parameterTypes.length]; for (int ii = 0, nn = parameterTypes.length; ii < nn; ii++) { if (kryo.isFinal(parameterTypes[ii])) { cachedMethod.serializers[ii] = kryo.getSerializer(parameterTypes[ii]); } } cachedMethods[i] = cachedMethod; } methodCache.put(type, cachedMethods); return cachedMethods; }
public void validate(EjbModule module) { Set<String> applicationExceptions = new HashSet<String>(); for (ApplicationException applicationException : module.getEjbJar().getAssemblyDescriptor().getApplicationException()) { applicationExceptions.add(applicationException.getExceptionClass()); } for (EnterpriseBean bean : module.getEjbJar().getEnterpriseBeans()) { Class<?> ejbClass = null; try { ejbClass = loadClass(bean.getEjbClass()); } catch (OpenEJBException e) { continue; } if (bean instanceof SessionBean) { SessionBean session = (SessionBean) bean; for (AsyncMethod asyncMethod : session.getAsyncMethod()) { Method method = getMethod(ejbClass, asyncMethod); if (method == null) { fail( bean, "asynchronous.missing", asyncMethod.getMethodName(), ejbClass.getName(), getParameters(asyncMethod.getMethodParams())); } else { checkAsynchronousMethod(session, ejbClass, method, applicationExceptions); } } for (String className : session.getAsynchronousClasses()) { try { Class<?> cls = loadClass(className); for (Method method : cls.getDeclaredMethods()) { if (Modifier.isPublic(method.getModifiers()) && !method.isSynthetic()) { checkAsynchronousMethod(session, ejbClass, method, applicationExceptions); } else { // warn(session, "asynchronous.methodignored", ejbClass.getName(), // method.getName()); } } } catch (OpenEJBException e) { // ignore ? } } } else { ClassFinder classFinder = new ClassFinder(ejbClass); for (Method method : classFinder.findAnnotatedMethods(Asynchronous.class)) { ignoredMethodAnnotation( "Asynchronous", bean, bean.getEjbClass(), method.getName(), bean.getClass().getSimpleName()); } if (ejbClass.getAnnotation(Asynchronous.class) != null) { ignoredClassAnnotation( "Asynchronous", bean, bean.getEjbClass(), bean.getClass().getSimpleName()); } } } }
public void configureClassNode(CompileUnit compileUnit, ClassNode classNode) { try { Class clazz = classNode.getTypeClass(); Field[] fields = clazz.getDeclaredFields(); for (Field f : fields) { ClassNode ret = makeClassNode(compileUnit, f.getGenericType(), f.getType()); FieldNode fn = new FieldNode(f.getName(), f.getModifiers(), ret, classNode, null); setAnnotationMetaData(f.getAnnotations(), fn); classNode.addField(fn); } Method[] methods = clazz.getDeclaredMethods(); for (Method m : methods) { ClassNode ret = makeClassNode(compileUnit, m.getGenericReturnType(), m.getReturnType()); Parameter[] params = makeParameters( compileUnit, m.getGenericParameterTypes(), m.getParameterTypes(), m.getParameterAnnotations()); ClassNode[] exceptions = makeClassNodes(compileUnit, m.getGenericExceptionTypes(), m.getExceptionTypes()); MethodNode mn = new MethodNode(m.getName(), m.getModifiers(), ret, params, exceptions, null); mn.setSynthetic(m.isSynthetic()); setMethodDefaultValue(mn, m); setAnnotationMetaData(m.getAnnotations(), mn); mn.setGenericsTypes(configureTypeVariable(m.getTypeParameters())); classNode.addMethod(mn); } Constructor[] constructors = clazz.getDeclaredConstructors(); for (Constructor ctor : constructors) { Parameter[] params = makeParameters( compileUnit, ctor.getGenericParameterTypes(), ctor.getParameterTypes(), ctor.getParameterAnnotations()); ClassNode[] exceptions = makeClassNodes(compileUnit, ctor.getGenericExceptionTypes(), ctor.getExceptionTypes()); classNode.addConstructor(ctor.getModifiers(), params, exceptions, null); } Class sc = clazz.getSuperclass(); if (sc != null) classNode.setUnresolvedSuperClass( makeClassNode(compileUnit, clazz.getGenericSuperclass(), sc)); makeInterfaceTypes(compileUnit, classNode, clazz); setAnnotationMetaData(classNode.getTypeClass().getAnnotations(), classNode); PackageNode packageNode = classNode.getPackage(); if (packageNode != null) { setAnnotationMetaData(classNode.getTypeClass().getPackage().getAnnotations(), packageNode); } } catch (NoClassDefFoundError e) { throw new NoClassDefFoundError( "Unable to load class " + classNode.toString(false) + " due to missing dependency " + e.getMessage()); } catch (MalformedParameterizedTypeException e) { throw new RuntimeException( "Unable to configure class node for class " + classNode.toString(false) + " due to malformed parameterized types", e); } }
@Override public boolean apply(final Method method) { return method.isSynthetic(); }
/** * Returns true if the method is eligible to be injected. This is different than {@link * #isValidMethod}, because ineligibility will not drop a method from being injected if a * superclass was eligible & valid. Bridge & synthetic methods are excluded from eligibility for * two reasons: * * <p>Prior to Java8, javac would generate these methods in subclasses without annotations, which * means this would accidentally stop injecting a method annotated with {@link * javax.inject.Inject}, since the spec says to stop injecting if a subclass isn't annotated with * it. * * <p>Starting at Java8, javac copies the annotations to the generated subclass method, except it * leaves out the generic types. If this considered it a valid injectable method, this would eject * the parent's overridden method that had the proper generic types, and would use invalid * injectable parameters as a result. * * <p>The fix for both is simply to ignore these synthetic bridge methods. */ private static boolean isEligibleForInjection(Method method, boolean statics) { return Modifier.isStatic(method.getModifiers()) == statics && !method.isBridge() && !method.isSynthetic(); }