Default methods not allowed in PipelineOptions

Open Beginner friendly
#19,930 0 comments 0 reactions 0 assignees View on GitHub

Nobody has claimed this yet.

Assessment

Difficulty
2/5
Estimated time
1-3 hours
Newbie friendliness
68/100
Issue type
Bug
Clarity
Clearly specified
Activity status
Stale
Tech stack
java
Domain
api, backend

Research direction

Start in org.apache.beam.sdk.options.PipelineOptionsFactory.java, especially validateMethodsAreEitherBeanMethodOrKnownMethod and the predicates used to identify unknown methods. Reproduce the reported default-method case, then verify that default methods are accepted while non-bean, non-static, non-synthetic, and non-known methods still fail validation.

Written by the indexing model from the issue text.

Description

beam-model bug P3

If I create a class that extends PipelineOptions and contains a default method, the PipelineOptionsFactory will throw an exception because all non-static, non-synthetic and non-known methods need to have a getter and a setter.

For example, these PipelineOptions


public interface MyOptions extends PipelineOptions {
  void setValue(String s);
  String getValue();


  default List<String> getValues() {
     return Arrays.asList(getValue().split(","));
   }
}

will throw an exception in org.apache.beam.sdk.options.PipelineOptionsFactory.java:


private static void validateMethodsAreEitherBeanMethodOrKnownMethod(
    Class<? extends PipelineOptions>
iface,
    Class<? extends PipelineOptions> klass,
    List<PropertyDescriptor> descriptors) {

...
//
Verify that no additional methods are on an interface that aren't a bean property.
// Because methods
can have multiple declarations, we do a name-based comparison
// here to prevent false positives.
SortedSet<Method>
unknownMethods = new TreeSet<>(MethodComparator.INSTANCE);
unknownMethods.addAll(
    Sets.filter(

       Sets.difference(Sets.newHashSet(iface.getMethods()), knownMethods),
        Predicates.and(

           NOT_SYNTHETIC_PREDICATE,
            input -> !knownMethodsNames.contains(input.getName()),

           NOT_STATIC_PREDICATE)));
checkArgument(
    unknownMethods.isEmpty(),
    "Methods %s
on [%s] do not conform to being bean properties.",
    FluentIterable.from(unknownMethods).transform(ReflectHelpers.METHOD_FORMATTER),

   iface.getName());
}

Having a NOT_DEFAULT_PREDICATE in addition to the other predicates would allow 


private static final Predicate<Method> NOT_DEFAULT_PREDICATE = input -> !input.isDefault();

Seems like it would do the trick.

Imported from Jira BEAM-8669. Original Jira may contain additional context.
Reported by: chrisstockton.

Dominant language
Java
Stars
8.7k
Forks
4.7k
Avg merge
2d 6h
Merged PRs (30d)
194

Contributor guide

Open the contributing guide

First steps

  1. Read the whole issue, then the project's contributing guide.
  2. Comment on the issue to say you are picking it up — it saves two people doing the same work.
  3. Fork the repository and make your change on a branch.
  4. Open a pull request that references the issue number.

More from apache/beam

All issues in apache/beam

Similar issues

More Java issues

Get new issues in your inbox

A short digest of beginner-friendly GitHub issues.