ProxyInvocationHandler implements InvocationHandler, Serializable { @Override public Object invoke(Object proxy, Method method, Object[] args) { if (args == null && "toString".equals(method.getName())) { return toString(); } else if (args != null && args.length == 1 && "equals".equals(method.getName())) { return equals(args[0]); } else if (args == null && "hashCode".equals(method.getName())) { return hashCode(); } else if (args == null && "outputRuntimeOptions".equals(method.getName())) { return outputRuntimeOptions((PipelineOptions) proxy); } else if (args != null && "as".equals(method.getName()) && args[0] instanceof Class) { @SuppressWarnings("unchecked") Class<? extends PipelineOptions> clazz = (Class<? extends PipelineOptions>) args[0]; return as(clazz); } else if (args != null && "populateDisplayData".equals(method.getName()) && args[0] instanceof DisplayData.Builder) { @SuppressWarnings("unchecked") DisplayData.Builder builder = (DisplayData.Builder) args[0]; builder.delegate(new PipelineOptionsDisplayData()); return Void.TYPE; } String methodName = method.getName(); synchronized (this) { if (gettersToPropertyNames.containsKey(methodName)) { String propertyName = gettersToPropertyNames.get(methodName); if (!options.containsKey(propertyName)) { Object value = jsonOptions.containsKey(propertyName) ? getValueFromJson(propertyName, method) : getDefault((PipelineOptions) proxy, method); options.put(propertyName, BoundValue.fromDefault(value)); } return options.get(propertyName).getValue(); } else if (settersToPropertyNames.containsKey(methodName)) { options.put(settersToPropertyNames.get(methodName), BoundValue.fromExplicitOption(args[0])); return Void.TYPE; } } throw new RuntimeException( "Unknown method [" + method + "] invoked with args [" + Arrays.toString(args) + "]."); } ProxyInvocationHandler(Map<String, Object> options); private  ProxyInvocationHandler(
      Map<String, BoundValue> options, Map<String, JsonNode> jsonOptions); @Override Object invoke(Object proxy, Method method, Object[] args); String getOptionName(Method method); @Override boolean equals(@Nullable Object obj); @Override int hashCode(); Map<String, Map<String, Object>> outputRuntimeOptions(PipelineOptions options); @Override synchronized String toString();  }
@Test public void testInvokeWithUnknownMethod() throws Exception { expectedException.expect(RuntimeException.class); expectedException.expectMessage( "Unknown method [public abstract void " + "org.apache.beam.sdk.options.ProxyInvocationHandlerTest$UnknownMethod.unknownMethod()] " + "invoked with args [null]."); ProxyInvocationHandler handler = new ProxyInvocationHandler(Maps.newHashMap()); handler.invoke(handler, UnknownMethod.class.getMethod("unknownMethod"), null); }