/** * Only matches the {@link Object#toString()} method, also if it was overridden. * * @param <T> The type of the matched object. * @return A matcher that only matches the {@link Object#toString()} method. */ public static <T extends MethodDescription> ElementMatcher.Junction<T> isHashCode() { return named("hashCode").and(takesArguments(0)).and(returns(int.class)); }
/** * Matches any Java bean getter method. * * @param <T> The type of the matched object. * @return A matcher that matches any getter method. */ public static <T extends MethodDescription> ElementMatcher.Junction<T> isGetter() { return takesArguments(0).and(not(returns(TypeDescription.VOID))).and(nameStartsWith("get").or(nameStartsWith("is").and(returnsGeneric(anyOf(boolean.class, Boolean.class))))); }
/** * {@inheritDoc} */ public ElementMatcher<? super MethodDescription> resolve(TypeDescription typeDescription) { // Casting is required by JDK 6. return (ElementMatcher<? super MethodDescription>) isVirtual().and(not(isFinal())) .and(isVisibleTo(typeDescription)) .and(not(ignoredMethods.resolve(typeDescription))) .or(isDeclaredBy(typeDescription)); } }
private static ElementMatcher<MethodDescription> isGroovyMethod() { return isDeclaredBy(named("groovy.lang.GroovyObjectSupport")); }
/** * Matches a {@link ByteCodeElement} for being declared by a given {@link TypeDescription}. This matcher matches * a declared element's raw declaring type. * * @param type The type that is expected to declare the matched byte code element. * @param <T> The type of the matched object. * @return A matcher for byte code elements being declared by the given {@code type}. */ public static <T extends ByteCodeElement> ElementMatcher.Junction<T> isDeclaredBy(TypeDescription type) { return isDeclaredBy(is(type)); }
/** * {@inheritDoc} */ @SuppressWarnings("unchecked") public ElementMatcher<? super MethodDescription> resolve(TypeDescription typeDescription) { // Casting is required by some Java 6 compilers. return (ElementMatcher<? super MethodDescription>) (inverted ? not(isDeclaredBy(typeDescription)) : isDeclaredBy(typeDescription)); } }
@Override public <T> T newProxy(Class<T> interfaceType, Object handler) { Class<? extends T> cls = new ByteBuddy() .subclass(interfaceType) .method(ElementMatchers.isDeclaredBy(interfaceType)) .intercept(MethodDelegation.to(handler, "handler")) .make() .load(interfaceType.getClassLoader(), ClassLoadingStrategy.Default.INJECTION) .getLoaded(); try { return cls.newInstance(); } catch (Throwable t) { ThrowUtil.throwException(t); } return null; // never get here } });
Class<? extends T> proxied = builder.method(ElementMatchers.isDeclaredBy( Introspectior.getTypeDescription(RLiveObject.class)) .and(ElementMatchers.isGetter().or(ElementMatchers.isSetter()) .or(ElementMatchers.named("isPhantom")) .or(ElementMatchers.named("delete")))) .intercept(MethodDelegation.withDefaultConfiguration() .withBinders(FieldProxy.Binder .install(LiveObjectInterceptor.Getter.class, .implement(RLiveObject.class) .method(ElementMatchers.isAnnotatedWith(RFieldAccessor.class) .and(ElementMatchers.named("get") .or(ElementMatchers.named("set")))) .intercept(MethodDelegation.to(FieldAccessorInterceptor.class)) .method(ElementMatchers.isDeclaredBy(RObject.class) .or(ElementMatchers.isDeclaredBy(RObjectAsync.class))) .intercept(MethodDelegation.to(RObjectInterceptor.class)) .implement(RObject.class) .method(ElementMatchers.isDeclaredBy(RExpirable.class) .or(ElementMatchers.isDeclaredBy(RExpirableAsync.class))) .method(ElementMatchers.isDeclaredBy(Map.class) .or(ElementMatchers.isDeclaredBy(ConcurrentMap.class)) .or(ElementMatchers.isDeclaredBy(RMapAsync.class)) .or(ElementMatchers.isDeclaredBy(RMap.class))) .method(ElementMatchers.not(ElementMatchers.isDeclaredBy(Object.class))
private static Object crateForParameters(Class<?> effectiveTargetClass, Set<Class<?>> interfacesToImplement, ClassLoader classLoader, Class<?> interceptorClass) { List<Type> interfacesToImplementAsList = new ArrayList<Type>(interfacesToImplement); Class<?> proxyType = new ByteBuddy() .subclass(effectiveTargetClass) .implement(interfacesToImplementAsList) .method(not(isFinalizer())) .intercept(MethodDelegation.to(interceptorClass)) .make() .load(classLoader) .getLoaded(); return instantiate(proxyType); }
public Factory run() { try { return new Factory.ForJava9CapableVm(new ByteBuddy() .with(TypeValidation.DISABLED) .subclass(ExecutingTransformer.class) .name(ExecutingTransformer.class.getName() + "$ByteBuddy$ModuleSupport") .method(named("transform").and(takesArgument(0, JavaType.MODULE.load()))) .intercept(MethodCall.invoke(ExecutingTransformer.class.getDeclaredMethod("transform", Object.class, ClassLoader.class, ProtectionDomain.class, byte[].class)).onSuper().withAllArguments()) .make() .load(ExecutingTransformer.class.getClassLoader(), ClassLoadingStrategy.Default.WRAPPER_PERSISTENT.with(ExecutingTransformer.class.getProtectionDomain()))
/** * {@inheritDoc} */ public DynamicType make(String auxiliaryTypeName, ClassFileVersion classFileVersion, MethodAccessorFactory methodAccessorFactory) { LinkedHashMap<String, TypeDescription> parameterFields = extractFields(sourceMethod); DynamicType.Builder<?> builder = new ByteBuddy(classFileVersion) .with(TypeValidation.DISABLED) .subclass(forwardingType, ConstructorStrategy.Default.NO_CONSTRUCTORS) .name(auxiliaryTypeName) .modifiers(DEFAULT_TYPE_MODIFIER) .implement(serializableProxy ? new Class<?>[]{Serializable.class} : new Class<?>[0]) .method(ElementMatchers.<MethodDescription>isAbstract().and(isDeclaredBy(forwardingType))) .intercept(new MethodCall(sourceMethod, assigner)) .defineConstructor().withParameters(parameterFields.values()) .intercept(ConstructorCall.INSTANCE); for (Map.Entry<String, TypeDescription> field : parameterFields.entrySet()) { builder = builder.defineField(field.getKey(), field.getValue(), Visibility.PRIVATE); } return builder.make(); }
public InlineBytecodeGenerator(Instrumentation instrumentation, WeakConcurrentMap<Object, MockMethodInterceptor> mocks) { preload(); this.instrumentation = instrumentation; byteBuddy = new ByteBuddy() .with(TypeValidation.DISABLED) .with(Implementation.Context.Disabled.Factory.INSTANCE) .with(MethodGraph.Compiler.ForDeclaredMethods.INSTANCE); mocked = new WeakConcurrentSet<Class<?>>(WeakConcurrentSet.Cleaner.INLINE); String identifier = RandomString.make(); subclassEngine = new TypeCachingBytecodeGenerator(new SubclassBytecodeGenerator(withDefaultConfiguration() .withBinders(of(MockMethodAdvice.Identifier.class, identifier)) .to(MockMethodAdvice.ForReadObject.class), isAbstract().or(isNative()).or(isToString())), false); mockTransformer = new AsmVisitorWrapper.ForDeclaredMethods() .method(isVirtual() .and(not(isBridge().or(isHashCode()).or(isEquals()).or(isDefaultFinalizer()))) .and(not(isDeclaredBy(nameStartsWith("java.")).<MethodDescription>and(isPackagePrivate()))), Advice.withCustomMapping() .bind(MockMethodAdvice.Identifier.class, identifier) .to(MockMethodAdvice.class)) .method(isHashCode(), Advice.withCustomMapping() .bind(MockMethodAdvice.Identifier.class, identifier) .to(MockMethodAdvice.ForHashCode.class)) .method(isEquals(), Advice.withCustomMapping() .bind(MockMethodAdvice.Identifier.class, identifier)
/** * {@inheritDoc} */ public DynamicType make(String auxiliaryTypeName, ClassFileVersion classFileVersion, MethodAccessorFactory methodAccessorFactory) { return new ByteBuddy(classFileVersion) .with(TypeValidation.DISABLED) .ignore(ignoreFinalizer ? isFinalizer() : ElementMatchers.<MethodDescription>none()) .subclass(proxiedType) .name(auxiliaryTypeName) .modifiers(DEFAULT_TYPE_MODIFIER) .implement(serializableProxy ? new Class<?>[]{Serializable.class} : new Class<?>[0]) .method(any()).intercept(new MethodCall(methodAccessorFactory)) .defineMethod(REFLECTION_METHOD, TargetType.class, Ownership.STATIC).intercept(SilentConstruction.INSTANCE) .make(); }
String name = String.format("%s$%s$%d", typeName, "SpockMock", randomNumber); ClassLoadingStrategy<ClassLoader> strategy = determineBestClassLoadingStrategy(targetClass); return new ByteBuddy() .with(TypeValidation.DISABLED) // https://github.com/spockframework/spock/issues/776 .ignore(none()) .subclass(type) .name(name) .implement(additionalInterfaces) .implement(ISpockMockObject.class) .method(any()) .intercept(MethodDelegation.withDefaultConfiguration() .withBinders(Morph.Binder.install(ByteBuddyInvoker.class)) .to(ByteBuddyInterceptorAdapter.class)) .transform(Transformer.ForMethod.withModifiers(SynchronizationState.PLAIN, Visibility.PUBLIC)) // Overridden methods should be public and non-synchronized. .implement(ByteBuddyInterceptorAdapter.InterceptorAccess.class) .intercept(FieldAccessor.ofField("$spock_interceptor")) .defineField("$spock_interceptor", IProxyBasedMockInterceptor.class, Visibility.PRIVATE) .make() .load(classLoader, strategy)
/** * Creates a matcher where only overridable or declared methods are matched unless those are ignored. Methods that * are declared by the target type are only matched if they are not ignored. Declared methods that are not found on the * target type are always matched. * * @param ignoredMethods A method matcher that matches any ignored method. * @param originalType The original type of the instrumentation before adding any user methods. * @return A latent method matcher that identifies any method to instrument for a rebasement or redefinition. */ protected static LatentMatcher<MethodDescription> of(LatentMatcher<? super MethodDescription> ignoredMethods, TypeDescription originalType) { ElementMatcher.Junction<MethodDescription> predefinedMethodSignatures = none(); for (MethodDescription methodDescription : originalType.getDeclaredMethods()) { ElementMatcher.Junction<MethodDescription> signature = methodDescription.isConstructor() ? isConstructor() : ElementMatchers.<MethodDescription>named(methodDescription.getName()); signature = signature.and(returns(methodDescription.getReturnType().asErasure())); signature = signature.and(takesArguments(methodDescription.getParameters().asTypeList().asErasures())); predefinedMethodSignatures = predefinedMethodSignatures.or(signature); } return new InliningImplementationMatcher(ignoredMethods, predefinedMethodSignatures); }
public static <E> E createInstance(Class<E> entityClass) { Class<? extends E> loaded = new ByteBuddy() .subclass( entityClass ) .method( ElementMatchers.named( "toString" ) ) .intercept( FixedValue.value( "transformed" ) ) .make() // we use our internal helper to get a class loading strategy suitable for the JDK used .load( entityClass.getClassLoader(), resolveClassLoadingStrategy( entityClass ) ) .getLoaded(); try { return loaded.newInstance(); } catch (Exception e) { throw new RuntimeException( "Unable to create new instance of " + entityClass.getSimpleName(), e ); } }
@Override public boolean matches(MethodDescription targetMethod) { TypeDescription superClass = targetMethod.getDeclaringType().asErasure(); do { superClass = superClass.getSuperClass().asErasure(); if (declaresMethod(named(targetMethod.getName()) .and(returns(targetMethod.getReturnType().asErasure())) .and(takesArguments(targetMethod.getParameters().asTypeList().asErasures())) .and(extraMethodMatcher)) .matches(superClass)) { return true; } } while (superClassMatcher.matches(superClass)); return false; } }
/** * {@inheritDoc} */ public Compiled compile(TypeDescription instrumentedType) { MethodList<?> targets = new MethodList.Explicit<MethodDescription>(CompoundList.<MethodDescription>of( instrumentedType.getDeclaredMethods().filter(isStatic().or(isPrivate())), methodGraphCompiler.compile(instrumentedType).listNodes().asMethodList()) ).filter(named(name).and(takesArguments(0)).and(not(returns(isPrimitive().or(isArray()))))); if (targets.size() != 1) { throw new IllegalStateException(instrumentedType + " does not define method without arguments with name " + name + ": " + targets); } else if (!targets.getOnly().getReturnType().asErasure().isVisibleTo(instrumentedType)) { throw new IllegalStateException(targets.getOnly() + " is not visible to " + instrumentedType); } else { MethodList<?> candidates = methodGraphCompiler.compile(targets.getOnly().getReturnType(), instrumentedType) .listNodes() .asMethodList() .filter(matcher); List<MethodDelegationBinder.Record> records = new ArrayList<MethodDelegationBinder.Record>(candidates.size()); MethodDelegationBinder methodDelegationBinder = TargetMethodAnnotationDrivenBinder.of(parameterBinders); for (MethodDescription candidate : candidates) { records.add(methodDelegationBinder.compile(candidate)); } return new Compiled.ForMethodReturn(targets.get(0), records); } }
@Override public boolean matches(TypeDescription targetInterface) { if (ElementMatchers.declaresMethod(named(targetMethod.getName()) .and(returns(targetMethod.getReturnType().asErasure())) .and(takesArguments(targetMethod.getParameters().asTypeList().asErasures()))) .matches(targetInterface)) { return true; } else { for (TypeDescription typeDescription : targetInterface.getInterfaces().asErasures()) { if (matches(typeDescription)) { return true; } } } return false; } }
TypeDescription instrumentedType = instrumentedMethod.getDeclaringType().asErasure(); MethodDescription enumConstructor = instrumentedType.getDeclaredMethods() .filter(isConstructor().and(takesArguments(String.class, int.class))) .getOnly(); int ordinal = 0; List<FieldDescription> enumerationFields = new ArrayList<FieldDescription>(values.size()); for (String value : values) { FieldDescription fieldDescription = instrumentedType.getDeclaredFields().filter(named(value)).getOnly(); stackManipulation = new StackManipulation.Compound(stackManipulation, TypeCreation.of(instrumentedType), ArrayFactory.forType(instrumentedType.asGenericType()).withValues(fieldGetters), FieldAccess.forField(instrumentedType.getDeclaredFields().filter(named(ENUM_VALUES)).getOnly()).write() ); return new Size(stackManipulation.apply(methodVisitor, implementationContext).getMaximalSize(), instrumentedMethod.getStackSize());