/** @return the {@link DoFnInvoker} for the given {@link DoFn}. */ public <InputT, OutputT> DoFnInvoker<InputT, OutputT> newByteBuddyInvoker( DoFnSignature signature, DoFn<InputT, OutputT> fn) { checkArgument( signature.fnClass().equals(fn.getClass()), "Signature is for class %s, but fn is of class %s", signature.fnClass(), fn.getClass()); try { @SuppressWarnings("unchecked") DoFnInvokerBase<InputT, OutputT, DoFn<InputT, OutputT>> invoker = (DoFnInvokerBase<InputT, OutputT, DoFn<InputT, OutputT>>) getByteBuddyInvokerConstructor(signature).newInstance(fn); for (OnTimerMethod onTimerMethod : signature.onTimerMethods().values()) { invoker.addOnTimerInvoker( onTimerMethod.id(), OnTimerInvokers.forTimer(fn, onTimerMethod.id())); } return invoker; } catch (InstantiationException | IllegalAccessException | IllegalArgumentException | InvocationTargetException | SecurityException e) { throw new RuntimeException("Unable to bind invoker for " + fn.getClass(), e); } }