net.bytebuddy.implementation.StubMethod Java Examples
The following examples show how to use
net.bytebuddy.implementation.StubMethod.
You can vote up the ones you like or vote down the ones you don't like,
and go to the original project or source file by following the links above each example. You may check out the related API usage on the sidebar.
Example #1
Source File: AbstractDynamicTypeBuilderForInliningTest.java From byte-buddy with Apache License 2.0 | 6 votes |
@Test @JavaVersionRule.Enforce(8) public void testParameterMetaDataRetention() throws Exception { Class<?> dynamicType = create(Class.forName(PARAMETER_NAME_CLASS)) .method(named(FOO)).intercept(StubMethod.INSTANCE) .make() .load(new URLClassLoader(new URL[0], null), ClassLoadingStrategy.Default.WRAPPER) .getLoaded(); Class<?> executable = Class.forName("java.lang.reflect.Executable"); Method getParameters = executable.getDeclaredMethod("getParameters"); Class<?> parameter = Class.forName("java.lang.reflect.Parameter"); Method getName = parameter.getDeclaredMethod("getName"); Method getModifiers = parameter.getDeclaredMethod("getModifiers"); Method first = dynamicType.getDeclaredMethod("foo", String.class, long.class, int.class); Object[] methodParameter = (Object[]) getParameters.invoke(first); assertThat(getName.invoke(methodParameter[0]), is((Object) "first")); assertThat(getName.invoke(methodParameter[1]), is((Object) "second")); assertThat(getName.invoke(methodParameter[2]), is((Object) "third")); assertThat(getModifiers.invoke(methodParameter[0]), is((Object) Opcodes.ACC_FINAL)); assertThat(getModifiers.invoke(methodParameter[1]), is((Object) 0)); assertThat(getModifiers.invoke(methodParameter[2]), is((Object) 0)); }
Example #2
Source File: AbstractDynamicTypeBuilderForInliningTest.java From byte-buddy with Apache License 2.0 | 6 votes |
@Test public void testDisabledAnnotationRetention() throws Exception { Class<?> type = createDisabledRetention(Annotated.class) .field(ElementMatchers.any()).annotateField(new Annotation[0]) .method(ElementMatchers.any()).intercept(StubMethod.INSTANCE) .make() .load(new ByteArrayClassLoader(ClassLoadingStrategy.BOOTSTRAP_LOADER, ClassFileLocator.ForClassLoader.readToNames(SampleAnnotation.class)), ClassLoadingStrategy.Default.WRAPPER) .getLoaded(); @SuppressWarnings("unchecked") Class<? extends Annotation> sampleAnnotation = (Class<? extends Annotation>) type.getClassLoader().loadClass(SampleAnnotation.class.getName()); assertThat(type.isAnnotationPresent(sampleAnnotation), is(true)); assertThat(type.getDeclaredField(FOO).isAnnotationPresent(sampleAnnotation), is(false)); assertThat(type.getDeclaredMethod(FOO, Void.class).isAnnotationPresent(sampleAnnotation), is(false)); assertThat(type.getDeclaredMethod(FOO, Void.class).getParameterAnnotations()[0].length, is(0)); }
Example #3
Source File: AbstractDynamicTypeBuilderForInliningTest.java From byte-buddy with Apache License 2.0 | 6 votes |
@Test public void testEnabledAnnotationRetention() throws Exception { Class<?> type = create(Annotated.class) .field(ElementMatchers.any()).annotateField(new Annotation[0]) .method(ElementMatchers.any()).intercept(StubMethod.INSTANCE) .make() .load(new ByteArrayClassLoader(ClassLoadingStrategy.BOOTSTRAP_LOADER, ClassFileLocator.ForClassLoader.readToNames(SampleAnnotation.class)), ClassLoadingStrategy.Default.WRAPPER) .getLoaded(); @SuppressWarnings("unchecked") Class<? extends Annotation> sampleAnnotation = (Class<? extends Annotation>) type.getClassLoader().loadClass(SampleAnnotation.class.getName()); assertThat(type.isAnnotationPresent(sampleAnnotation), is(true)); assertThat(type.getDeclaredField(FOO).isAnnotationPresent(sampleAnnotation), is(true)); assertThat(type.getDeclaredMethod(FOO, Void.class).isAnnotationPresent(sampleAnnotation), is(true)); assertThat(type.getDeclaredMethod(FOO, Void.class).getParameterAnnotations()[0].length, is(1)); assertThat(type.getDeclaredMethod(FOO, Void.class).getParameterAnnotations()[0][0].annotationType(), is((Object) sampleAnnotation)); }
Example #4
Source File: TypeWriterDefaultTest.java From byte-buddy with Apache License 2.0 | 5 votes |
@Test @JavaVersionRule.Enforce(8) public void testStaticMethodOnAnnotationAssertionJava8() throws Exception { new ByteBuddy() .makeInterface() .defineMethod(FOO, String.class, Visibility.PUBLIC, Ownership.STATIC) .intercept(StubMethod.INSTANCE) .make(); }
Example #5
Source File: ClassByImplementationBenchmark.java From byte-buddy with Apache License 2.0 | 5 votes |
/** * Performs a benchmark of an interface implementation using Byte Buddy. This benchmark uses a type pool to compare against * usage of the reflection API. * * @return The created instance, in order to avoid JIT removal. * @throws java.lang.Exception If the reflective invocation causes an exception. */ @Benchmark public ExampleInterface benchmarkByteBuddyWithTypePool() throws Exception { return (ExampleInterface) new ByteBuddy() .with(TypeValidation.DISABLED) .ignore(none()) .subclass(baseClassDescription) .method(isDeclaredBy(baseClassDescription)).intercept(StubMethod.INSTANCE) .make() .load(newClassLoader(), ClassLoadingStrategy.Default.INJECTION) .getLoaded() .getDeclaredConstructor() .newInstance(); }
Example #6
Source File: ClassByImplementationBenchmark.java From byte-buddy with Apache License 2.0 | 5 votes |
/** * Performs a benchmark of an interface implementation using Byte Buddy. * * @return The created instance, in order to avoid JIT removal. * @throws java.lang.Exception If the reflective invocation causes an exception. */ @Benchmark public ExampleInterface benchmarkByteBuddy() throws Exception { return new ByteBuddy() .with(TypeValidation.DISABLED) .ignore(none()) .subclass(baseClass) .method(isDeclaredBy(baseClass)).intercept(StubMethod.INSTANCE) .make() .load(newClassLoader(), ClassLoadingStrategy.Default.INJECTION) .getLoaded() .getDeclaredConstructor() .newInstance(); }
Example #7
Source File: TypeWriterDefaultTest.java From byte-buddy with Apache License 2.0 | 5 votes |
@Test public void testTypeInitializerOnRebasedInterfaceWithInitializer() throws Exception { assertThat(new ByteBuddy() .makeInterface() .initializer(new ByteCodeAppender.Simple()) .invokable(isTypeInitializer()) .intercept(StubMethod.INSTANCE) .make(), notNullValue(DynamicType.class)); }
Example #8
Source File: TypeWriterDefaultTest.java From byte-buddy with Apache License 2.0 | 5 votes |
@Test public void testTypeInitializerOnRebasedInterfaceWithFrameExpansion() throws Exception { assertThat(new ByteBuddy() .makeInterface() .visit(new AsmVisitorWrapper.ForDeclaredMethods().readerFlags(ClassReader.EXPAND_FRAMES)) .invokable(isTypeInitializer()) .intercept(StubMethod.INSTANCE) .make(), notNullValue(DynamicType.class)); }
Example #9
Source File: TypeWriterDefaultTest.java From byte-buddy with Apache License 2.0 | 5 votes |
@Test public void testTypeInitializerOnRebasedInterfaceWithFrameComputation() throws Exception { assertThat(new ByteBuddy() .makeInterface() .visit(new AsmVisitorWrapper.ForDeclaredMethods().writerFlags(ClassWriter.COMPUTE_FRAMES)) .invokable(isTypeInitializer()) .intercept(StubMethod.INSTANCE) .make(), notNullValue(DynamicType.class)); }
Example #10
Source File: TypeWriterDefaultTest.java From byte-buddy with Apache License 2.0 | 5 votes |
@Test public void testTypeInitializerOnRebasedLegacyInterface() throws Exception { assertThat(new ByteBuddy() .rebase(Class.forName(LEGACY_INTERFACE)) .invokable(isTypeInitializer()) .intercept(StubMethod.INSTANCE) .make(), notNullValue(DynamicType.class)); }
Example #11
Source File: TypeWriterDefaultTest.java From byte-buddy with Apache License 2.0 | 5 votes |
@Test @JavaVersionRule.Enforce(8) public void testTypeInitializerOnRebasedModernInterface() throws Exception { assertThat(new ByteBuddy() .rebase(Class.forName(JAVA_8_INTERFACE)) .invokable(isTypeInitializer()) .intercept(StubMethod.INSTANCE) .make(), notNullValue(DynamicType.class)); }
Example #12
Source File: TypeWriterDefaultTest.java From byte-buddy with Apache License 2.0 | 5 votes |
@Test public void testTypeInitializerOnAnnotation() throws Exception { assertThat(new ByteBuddy() .makeAnnotation() .invokable(isTypeInitializer()) .intercept(StubMethod.INSTANCE) .make() .load(ClassLoadingStrategy.BOOTSTRAP_LOADER, ClassLoadingStrategy.Default.WRAPPER) .getLoaded(), notNullValue(Class.class)); }
Example #13
Source File: TypeWriterDefaultTest.java From byte-buddy with Apache License 2.0 | 5 votes |
@Test public void testTypeInitializerOnInterface() throws Exception { assertThat(new ByteBuddy() .makeInterface() .invokable(isTypeInitializer()) .intercept(StubMethod.INSTANCE) .make() .load(ClassLoadingStrategy.BOOTSTRAP_LOADER, ClassLoadingStrategy.Default.WRAPPER) .getLoaded(), notNullValue(Class.class)); }
Example #14
Source File: TypeWriterDefaultTest.java From byte-buddy with Apache License 2.0 | 5 votes |
@Test(expected = IllegalStateException.class) public void testAnnotationOnMethodPreJava5TypeAssertion() throws Exception { new ByteBuddy(ClassFileVersion.JAVA_V4) .subclass(Object.class) .defineMethod(FOO, void.class) .intercept(StubMethod.INSTANCE) .annotateMethod(AnnotationDescription.Builder.ofType(Foo.class).build()) .make(); }
Example #15
Source File: TypeWriterDefaultTest.java From byte-buddy with Apache License 2.0 | 5 votes |
@Test @JavaVersionRule.Enforce(8) public void testStaticMethodOnInterfaceAssertionJava8() throws Exception { new ByteBuddy() .makeAnnotation() .defineMethod(FOO, String.class, Visibility.PUBLIC, Ownership.STATIC) .intercept(StubMethod.INSTANCE) .make(); }
Example #16
Source File: TypeWriterDefaultTest.java From byte-buddy with Apache License 2.0 | 5 votes |
@Test(expected = IllegalStateException.class) public void testStaticMethodOnAnnotationAssertion() throws Exception { new ByteBuddy(ClassFileVersion.JAVA_V6) .makeAnnotation() .defineMethod(FOO, String.class, Visibility.PUBLIC, Ownership.STATIC) .intercept(StubMethod.INSTANCE) .make(); }
Example #17
Source File: SlimePlugin.java From Slime with MIT License | 5 votes |
private void addDataManagerIntercepts() { getLogger().info("Adding ServerNBTManager intercepts"); redefine(ServerNBTManager.class, builder -> builder .method(named("createChunkLoader")) .intercept(Advice.to(DataManagerAdvice.class).wrap(StubMethod.INSTANCE)) .method(named("saveWorldData").and(takesArguments(2))) .intercept(StubMethod.INSTANCE)); }
Example #18
Source File: RebaseDynamicTypeBuilderTest.java From byte-buddy with Apache License 2.0 | 5 votes |
@Test public void testMethodRebase() throws Exception { DynamicType.Unloaded<?> dynamicType = new ByteBuddy() .rebase(Qux.class) .method(named(BAR)).intercept(StubMethod.INSTANCE) .make(); assertThat(dynamicType.getAuxiliaryTypes().size(), is(0)); Class<?> type = dynamicType.load(new URLClassLoader(new URL[0], null), ClassLoadingStrategy.Default.WRAPPER).getLoaded(); assertThat(type.getDeclaredConstructors().length, is(1)); assertThat(type.getDeclaredMethods().length, is(3)); assertThat(type.getDeclaredMethod(FOO).invoke(null), nullValue(Object.class)); assertThat(type.getDeclaredField(FOO).get(null), is((Object) FOO)); assertThat(type.getDeclaredMethod(BAR).invoke(null), nullValue(Object.class)); assertThat(type.getDeclaredField(FOO).get(null), is((Object) FOO)); }
Example #19
Source File: RedefinitionDynamicTypeBuilderTest.java From byte-buddy with Apache License 2.0 | 5 votes |
@Test public void testMethodRebase() throws Exception { DynamicType.Unloaded<?> dynamicType = new ByteBuddy() .redefine(Qux.class) .method(named(BAR)).intercept(StubMethod.INSTANCE) .make(); assertThat(dynamicType.getAuxiliaryTypes().size(), is(0)); Class<?> type = dynamicType.load(new URLClassLoader(new URL[0], null), ClassLoadingStrategy.Default.WRAPPER).getLoaded(); assertThat(type.getDeclaredConstructors().length, is(1)); assertThat(type.getDeclaredMethods().length, is(2)); assertThat(type.getDeclaredMethod(FOO).invoke(null), nullValue(Object.class)); assertThat(type.getDeclaredField(FOO).get(null), is((Object) FOO)); assertThat(type.getDeclaredMethod(BAR).invoke(null), nullValue(Object.class)); assertThat(type.getDeclaredField(FOO).get(null), is((Object) FOO)); }
Example #20
Source File: TypeWriterInitializerRemapperTest.java From byte-buddy with Apache License 2.0 | 5 votes |
@Test public void testInitializerWithDisabledContext() throws Exception { Class<?> type = new ByteBuddy() .with(Implementation.Context.Disabled.Factory.INSTANCE) .redefine(this.type) .invokable(isTypeInitializer()).intercept(StubMethod.INSTANCE) .make() .load(ClassLoadingStrategy.BOOTSTRAP_LOADER, ClassLoadingStrategy.Default.WRAPPER) .getLoaded(); Class.forName(type.getName(), true, type.getClassLoader()); }
Example #21
Source File: TypeWriterInitializerRemapperTest.java From byte-buddy with Apache License 2.0 | 5 votes |
@Test public void testInitializerWithEnabledContext() throws Exception { Class<?> type = new ByteBuddy() .redefine(this.type) .invokable(isTypeInitializer()).intercept(StubMethod.INSTANCE) .make() .load(ClassLoadingStrategy.BOOTSTRAP_LOADER, ClassLoadingStrategy.Default.WRAPPER) .getLoaded(); Class.forName(type.getName(), true, type.getClassLoader()); }
Example #22
Source File: AdviceImplementationTest.java From byte-buddy with Apache License 2.0 | 5 votes |
@Test public void testExplicitWrapMultiple() throws Exception { Class<?> type = new ByteBuddy(ClassFileVersion.of(Baz.class)) .redefine(Baz.class) .method(named(FOO)) .intercept(Advice.to(Baz.class).wrap(Advice.to(Baz.class).wrap(StubMethod.INSTANCE))) .make() .load(ClassLoadingStrategy.BOOTSTRAP_LOADER, ClassLoadingStrategy.Default.WRAPPER) .getLoaded(); Object baz = type.getDeclaredConstructor().newInstance(); assertThat(type.getDeclaredMethod(FOO).invoke(baz), nullValue(Object.class)); assertThat(type.getDeclaredField(FOO).getInt(null), is(2)); }
Example #23
Source File: AdviceImplementationTest.java From byte-buddy with Apache License 2.0 | 5 votes |
@Test public void testExplicitWrap() throws Exception { assertThat(new ByteBuddy(ClassFileVersion.of(Qux.class)) .subclass(Qux.class) .method(named(FOO)) .intercept(Advice.to(Qux.class).wrap(StubMethod.INSTANCE)) .make() .load(Qux.class.getClassLoader(), ClassLoadingStrategy.Default.WRAPPER) .getLoaded() .getDeclaredConstructor() .newInstance() .foo(), is(FOO)); }
Example #24
Source File: AbstractDynamicTypeBuilderForInliningTest.java From byte-buddy with Apache License 2.0 | 4 votes |
@Test public void testGenericType() throws Exception { InjectionClassLoader classLoader = new ByteArrayClassLoader(ClassLoadingStrategy.BOOTSTRAP_LOADER, false, ClassFileLocator.ForClassLoader.readToNames(GenericType.class)); Class<?> dynamicType = create(GenericType.Inner.class) .method(named(FOO)).intercept(StubMethod.INSTANCE) .make() .load(classLoader, InjectionClassLoader.Strategy.INSTANCE) .getLoaded(); assertThat(dynamicType.getTypeParameters().length, is(2)); assertThat(dynamicType.getTypeParameters()[0].getName(), is("T")); assertThat(dynamicType.getTypeParameters()[0].getBounds().length, is(1)); assertThat(dynamicType.getTypeParameters()[0].getBounds()[0], instanceOf(Class.class)); assertThat(dynamicType.getTypeParameters()[0].getBounds()[0], is((Type) String.class)); assertThat(dynamicType.getTypeParameters()[1].getName(), is("S")); assertThat(dynamicType.getTypeParameters()[1].getBounds().length, is(1)); assertThat(dynamicType.getTypeParameters()[1].getBounds()[0], is((Type) dynamicType.getTypeParameters()[0])); assertThat(dynamicType.getGenericSuperclass(), instanceOf(ParameterizedType.class)); assertThat(((ParameterizedType) dynamicType.getGenericSuperclass()).getActualTypeArguments().length, is(1)); assertThat(((ParameterizedType) dynamicType.getGenericSuperclass()).getActualTypeArguments()[0], instanceOf(ParameterizedType.class)); ParameterizedType superClass = (ParameterizedType) ((ParameterizedType) dynamicType.getGenericSuperclass()).getActualTypeArguments()[0]; assertThat(superClass.getActualTypeArguments().length, is(2)); assertThat(superClass.getActualTypeArguments()[0], is((Type) dynamicType.getTypeParameters()[0])); assertThat(superClass.getActualTypeArguments()[1], is((Type) dynamicType.getTypeParameters()[1])); assertThat(superClass.getOwnerType(), instanceOf(ParameterizedType.class)); assertThat(((ParameterizedType) superClass.getOwnerType()).getRawType(), instanceOf(Class.class)); assertThat(((Class<?>) ((ParameterizedType) superClass.getOwnerType()).getRawType()).getName(), is(GenericType.class.getName())); assertThat(((ParameterizedType) superClass.getOwnerType()).getActualTypeArguments().length, is(1)); assertThat(((ParameterizedType) superClass.getOwnerType()).getActualTypeArguments()[0], is((Type) ((Class<?>) ((ParameterizedType) superClass.getOwnerType()).getRawType()).getTypeParameters()[0])); assertThat(dynamicType.getGenericInterfaces().length, is(1)); assertThat(dynamicType.getGenericInterfaces()[0], instanceOf(ParameterizedType.class)); assertThat(((ParameterizedType) dynamicType.getGenericInterfaces()[0]).getActualTypeArguments()[0], instanceOf(ParameterizedType.class)); assertThat(((ParameterizedType) dynamicType.getGenericInterfaces()[0]).getRawType(), is((Type) Callable.class)); assertThat(((ParameterizedType) dynamicType.getGenericInterfaces()[0]).getOwnerType(), nullValue(Type.class)); assertThat(((ParameterizedType) ((ParameterizedType) dynamicType.getGenericInterfaces()[0]).getActualTypeArguments()[0]) .getActualTypeArguments().length, is(2)); ParameterizedType interfaceType = (ParameterizedType) ((ParameterizedType) dynamicType.getGenericInterfaces()[0]).getActualTypeArguments()[0]; assertThat(interfaceType.getRawType(), is((Type) Map.class)); assertThat(interfaceType.getActualTypeArguments().length, is(2)); assertThat(interfaceType.getActualTypeArguments()[0], instanceOf(WildcardType.class)); assertThat(((WildcardType) interfaceType.getActualTypeArguments()[0]).getUpperBounds().length, is(1)); assertThat(((WildcardType) interfaceType.getActualTypeArguments()[0]).getUpperBounds()[0], is((Type) Object.class)); assertThat(((WildcardType) interfaceType.getActualTypeArguments()[0]).getLowerBounds().length, is(1)); assertThat(((WildcardType) interfaceType.getActualTypeArguments()[0]).getLowerBounds()[0], is((Type) String.class)); assertThat(interfaceType.getActualTypeArguments()[1], instanceOf(WildcardType.class)); assertThat(((WildcardType) interfaceType.getActualTypeArguments()[1]).getUpperBounds().length, is(1)); assertThat(((WildcardType) interfaceType.getActualTypeArguments()[1]).getUpperBounds()[0], is((Type) String.class)); assertThat(((WildcardType) interfaceType.getActualTypeArguments()[1]).getLowerBounds().length, is(0)); Method foo = dynamicType.getDeclaredMethod(FOO, String.class); assertThat(foo.getGenericReturnType(), instanceOf(ParameterizedType.class)); assertThat(((ParameterizedType) foo.getGenericReturnType()).getActualTypeArguments().length, is(1)); assertThat(((ParameterizedType) foo.getGenericReturnType()).getActualTypeArguments()[0], instanceOf(GenericArrayType.class)); assertThat(((GenericArrayType) ((ParameterizedType) foo.getGenericReturnType()).getActualTypeArguments()[0]).getGenericComponentType(), is((Type) dynamicType.getTypeParameters()[0])); assertThat(foo.getTypeParameters().length, is(2)); assertThat(foo.getTypeParameters()[0].getName(), is("V")); assertThat(foo.getTypeParameters()[0].getBounds().length, is(1)); assertThat(foo.getTypeParameters()[0].getBounds()[0], is((Type) dynamicType.getTypeParameters()[0])); assertThat(foo.getTypeParameters()[1].getName(), is("W")); assertThat(foo.getTypeParameters()[1].getBounds().length, is(1)); assertThat(foo.getTypeParameters()[1].getBounds()[0], is((Type) Exception.class)); assertThat(foo.getGenericParameterTypes().length, is(1)); assertThat(foo.getGenericParameterTypes()[0], is((Type) foo.getTypeParameters()[0])); assertThat(foo.getGenericExceptionTypes().length, is(1)); assertThat(foo.getGenericExceptionTypes()[0], is((Type) foo.getTypeParameters()[1])); Method call = dynamicType.getDeclaredMethod("call"); assertThat(call.getGenericReturnType(), is((Type) interfaceType)); }
Example #25
Source File: PersistentAttributeTransformer.java From lams with GNU General Public License v2.0 | 4 votes |
DynamicType.Builder<?> applyTo(DynamicType.Builder<?> builder, boolean accessor) { boolean compositeOwner = false; builder = builder.visit( new AsmVisitorWrapper.ForDeclaredMethods().method( not( nameStartsWith( "$$_hibernate_" ) ), this ) ); for ( FieldDescription enhancedField : enhancedFields ) { builder = builder .defineMethod( EnhancerConstants.PERSISTENT_FIELD_READER_PREFIX + enhancedField.getName(), enhancedField.getType().asErasure(), Visibility.PUBLIC ) .intercept( accessor ? FieldAccessor.ofField( enhancedField.getName() ).in( enhancedField.getDeclaringType().asErasure() ) : fieldReader( enhancedField ) ) .defineMethod( EnhancerConstants.PERSISTENT_FIELD_WRITER_PREFIX + enhancedField.getName(), TypeDescription.VOID, Visibility.PUBLIC ) .withParameters( enhancedField.getType().asErasure() ) .intercept( accessor ? FieldAccessor.ofField( enhancedField.getName() ).in( enhancedField.getDeclaringType().asErasure() ) : fieldWriter( enhancedField ) ); if ( !compositeOwner && !accessor && EnhancerImpl.isAnnotationPresent( enhancedField, Embedded.class ) && enhancementContext.isCompositeClass( enhancedField.getType().asErasure() ) && enhancementContext.doDirtyCheckingInline( managedCtClass ) ) { compositeOwner = true; } } if ( compositeOwner ) { builder = builder.implement( CompositeOwner.class ); if ( enhancementContext.isCompositeClass( managedCtClass ) ) { builder = builder.defineMethod( EnhancerConstants.TRACKER_CHANGER_NAME, void.class, Visibility.PUBLIC ) .withParameters( String.class ) .intercept( Advice.to( CodeTemplates.CompositeOwnerDirtyCheckingHandler.class ).wrap( StubMethod.INSTANCE ) ); } } if ( enhancementContext.doExtendedEnhancement( managedCtClass ) ) { builder = applyExtended( builder ); } return builder; }