You are viewing a plain text version of this content. The canonical link for it is here.
Posted to dev@reef.apache.org by Sharath Malladi <sh...@microsoft.com.INVALID> on 2018/06/18 22:57:04 UTC

Tang "ambiguous subplan" exception when using Lists

Hi,

If I have a class that has multiple injectors (one of which injects a list), then I get an InjectionException about an "Ambiguous subplan".
As you can see from the exception below, it assumes that I attempted to bind to an empty list, which I did not .. so there should be no ambiguity.

Is there a work around for this issue.

Thanks,
Sharath.

For example, here is the class with two injectors:


class TcpPortProvider {
  protected final List<String> list;
  protected final String s;

  @Inject
  TcpPortProvider(@Parameter(TcpPortList.class) final List<String> tcpPortList) {
    System.out.println("tcpPortList constructor");
    this.list = tcpPortList;
    this.s = "";
  }


  @Inject
  TcpPortProvider(@Parameter(TcpPortListString.class) final String s) {
    System.out.println("TcpPortListString constructor");
    this.s = s;
    this.list = null;
  }

  @NamedParameter
  static class TcpPortList implements Name<List<String>> {
  }

  @NamedParameter
  static class TcpPortListString implements Name<String> {
  }
}


And here is the code to instantiate using injection where I only supplied argument for the injector that uses the string.


final JavaConfigurationBuilder cb = tang.newConfigurationBuilder();
cb.bindNamedParameter(TcpProvider.TcpPortListString.class, "this is a string");
tang.newInjector(cb.build()).getInstance(TcpPortProvider.class);



And here is the exception (note how it indicates that I also bound to an empty list):

org.apache.reef.tang.exceptions.InjectionException: Cannot inject org.apache.reef.tang.TcpPortProvider Ambiguous subplan org.apache.reef.tang.TcpPortProvider
  new TcpPortProvider(String TcpPortListString = this is a string)
  new TcpPortProvider(list {
 } )
]

                at org.apache.reef.tang.implementation.java.InjectorImpl.injectFromPlan(InjectorImpl.java:600)
                at org.apache.reef.tang.implementation.java.InjectorImpl.getInstance(InjectorImpl.java:515)
                at org.apache.reef.tang.implementation.java.InjectorImpl.getInstance(InjectorImpl.java:533)
                at org.apache.reef.tang.TestTang.testTcpProvider(TestTang.java:452)
                at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
                at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:62)
                at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)
                at java.lang.reflect.Method.invoke(Method.java:498)
                at org.junit.runners.model.FrameworkMethod$1.runReflectiveCall(FrameworkMethod.java:47)
                at org.junit.internal.runners.model.ReflectiveCallable.run(ReflectiveCallable.java:12)
                at org.junit.runners.model.FrameworkMethod.invokeExplosively(FrameworkMethod.java:44)
                at org.junit.internal.runners.statements.InvokeMethod.evaluate(InvokeMethod.java:17)
                at org.junit.internal.runners.statements.RunBefores.evaluate(RunBefores.java:26)
                at org.junit.rules.ExpectedException$ExpectedExceptionStatement.evaluate(ExpectedException.java:168)
                at org.junit.rules.RunRules.evaluate(RunRules.java:20)
                at org.junit.runners.ParentRunner.runLeaf(ParentRunner.java:271)
                at org.junit.runners.BlockJUnit4ClassRunner.runChild(BlockJUnit4ClassRunner.java:70)
                at org.junit.runners.BlockJUnit4ClassRunner.runChild(BlockJUnit4ClassRunner.java:50)
                at org.junit.runners.ParentRunner$3.run(ParentRunner.java:238)
                at org.junit.runners.ParentRunner$1.schedule(ParentRunner.java:63)
                at org.junit.runners.ParentRunner.runChildren(ParentRunner.java:236)
                at org.junit.runners.ParentRunner.access$000(ParentRunner.java:53)
                at org.junit.runners.ParentRunner$2.evaluate(ParentRunner.java:229)
                at org.junit.runners.ParentRunner.run(ParentRunner.java:309)
                at org.junit.runner.JUnitCore.run(JUnitCore.java:160)
                at com.intellij.junit4.JUnit4IdeaTestRunner.startRunnerWithArgs(JUnit4IdeaTestRunner.java:68)
                at com.intellij.rt.execution.junit.IdeaTestRunner$Repeater.startRunnerWithArgs(IdeaTestRunner.java:47)
                at com.intellij.rt.execution.junit.JUnitStarter.prepareStreamsAndStart(JUnitStarter.java:242)
                at com.intellij.rt.execution.junit.JUnitStarter.main(JUnitStarter.java:70)


Process finished with exit code -1



Re: Tang "ambiguous subplan" exception when using Lists

Posted by Sharath Malladi <sh...@microsoft.com.INVALID>.
Ah ok. So my suggestion is a breaking change to REEF. I will defer this to the REEF gurus to comment on.

-Sharath Malladi.
________________________________
From: Gyewon Lee <st...@gmail.com>
Sent: Wednesday, June 27, 2018 12:50:27 AM
To: dev@reef.apache.org
Subject: Re: Tang "ambiguous subplan" exception when using Lists

Hi, Sharath.

Yes, your understanding is right and your suggestion seems better to me.
Actually, current named parameter annotation has similar arguments named
"default_values" that can bind multiple elements to set/list named
parameters.
I think we can make use of existing "default_values" and just change its
semantics so that the named parameters with no defined default_values will
be bound to "null" (which means not bound in Tang InjectionPlan) instead of
an empty list.

For example,

@NamedParameter(doc = "Class A")
public class A implements Name<List<String>> {
}

currently "A" has default value of empty list, but after the patch its
default value will be null. We can set the default value of this named
parameter to an empty list by

@NamedParameter(doc = "Class A", default_values = {})
public class A implements Name<List<String>> {
}

The only problem is that it will make some legacy code outside REEF
repository not work, which is why I suggested adding new arguments. But if
we can afford this change, I prefer this way to adding new parameters,
which will definitely increase complexity.

Best regards,
Gyewon

2018-06-27 15:10 GMT+09:00 Sharath Malladi <sh...@microsoft.com.invalid>:

> Gyewon,
>
> If I understand correctly:
>
> [NamedParameter(default_empty_list=“true/false”)]
> List<int> myList;
>
> Would mean that if I don’t supply a binding, myList has no binding when
> the flag is false. And if the flag is set to true and I don’t provide a
> binding, then it binds to an empty list (as is the behavior now).
>
> I prefer that we rather achieve this by the following as it is more
> straightforward to follow:
> [NamedParameter(default={})] // the equivalent of default_empty_list set
> to true - bind to empty list.
> [NamedParameter] // the equivalent of default_empty_list set to false -
> don’t bind.
>
> We could achieve this by replacing all existing occurrences to set the
> default of {} and then make this change.
>
> I am not the expert; so please push back if you feel so.
>
> Thanks,
> -Sharath Malladi.
> ________________________________
> From: Gyewon Lee <st...@gmail.com>
> Sent: Tuesday, June 26, 2018 10:43 PM
> To: dev@reef.apache.org
> Subject: Re: Tang "ambiguous subplan" exception when using Lists
>
> Hi, all.
>
> I found out that many codes in REEF are already implemented based on the
> assumption that empty list will be bound, even though there are no default
> values specified for named parameters. For this reason, fixing this issue
> causes InjectionExceptions in some REEF tests.
>
> IMHO, whether empty List(or Set) would be bound or not as default value
> must be explicitly exposed when defining named parameters. My initial plan
> is adding additional boolean arguments on "NamedParameter" annotation, such
> as "default_empty_list" and "default_empty_set".
>
> How do you think about it? I'd like to hear your opinion.
>
> Best regards,
> Gyewon
>
> 2018-06-22 10:08 GMT+09:00 Gyewon Lee <st...@gmail.com>:
>
> > I have an created an issue on this bug.
> >
> > https://na01.safelinks.protection.outlook.com/?url=
> https%3A%2F%2Fissues.apache.org%2Fjira%2Fbrowse%2FREEF-
> 2040&amp;data=02%7C01%7Csharathm%40microsoft.com%
> 7C781d76bc3cd14bf0adf908d5dbf0f1ba%7C72f988bf86f141af91ab2d7cd011
> db47%7C1%7C0%7C636656750250177387&amp;sdata=3VkTXjvVeJqnlye2jlQuY2md2b2mw3
> yyZXBtCapRsj0%3D&amp;reserved=0
> >
> > Best regards,
> > Gyewon
> >
> > 2018-06-22 9:49 GMT+09:00 Gyewon Lee <st...@gmail.com>:
> >
> >> Hi, Sharath. Sorry for my late response.
> >>
> >> I have looked at Tang code and found out that for Set and List named
> >> parameters, the default value could be set to empty set or empty list
> even
> >> though there are no bound default values. I'm not sure on the reason,
> >> though.
> >>
> >> I will open an issue in JIRA and send a PR soon.
> >>
> >> Best regards,
> >> Gyewon.
> >>
> >> 2018-06-22 2:20 GMT+09:00 Sharath Malladi <sharathm@microsoft.com.
> invalid
> >> >:
> >>
> >>> Hi Gyewon,
> >>>
> >>> Did you get time to investigate this. Could you share your findings.
> >>>
> >>> Thanks,
> >>> Sharath.
> >>>
> >>> -----Original Message-----
> >>> From: Gyewon Lee <st...@gmail.com>
> >>> Sent: Monday, June 18, 2018 6:02 PM
> >>> To: dev@reef.apache.org
> >>> Subject: Re: Tang "ambiguous subplan" exception when using Lists
> >>>
> >>> Hi, Sharath.
> >>>
> >>> As you say, it seems you haven't bound anything for "TcpPortList". I
> >>> will look into the Tang code and get back to you after I find the
> cause.
> >>>
> >>> Best regards,
> >>> Gyewon
> >>>
> >>> 2018-06-19 7:57 GMT+09:00 Sharath Malladi
> <sharathm@microsoft.com.invali
> >>> d>:
> >>>
> >>> > Hi,
> >>> >
> >>> > If I have a class that has multiple injectors (one of which injects a
> >>> > list), then I get an InjectionException about an "Ambiguous subplan".
> >>> > As you can see from the exception below, it assumes that I attempted
> >>> > to bind to an empty list, which I did not .. so there should be no
> >>> ambiguity.
> >>> >
> >>> > Is there a work around for this issue.
> >>> >
> >>> > Thanks,
> >>> > Sharath.
> >>> >
> >>> > For example, here is the class with two injectors:
> >>> >
> >>> >
> >>> > class TcpPortProvider {
> >>> > protected final List<String> list;
> >>> > protected final String s;
> >>> >
> >>> > @Inject
> >>> > TcpPortProvider(@Parameter(TcpPortList.class) final List<String>
> >>> > tcpPortList) {
> >>> > System.out.println("tcpPortList constructor");
> >>> > this.list = tcpPortList;
> >>> > this.s = "";
> >>> > }
> >>> >
> >>> >
> >>> > @Inject
> >>> > TcpPortProvider(@Parameter(TcpPortListString.class) final String s)
> >>> {
> >>> > System.out.println("TcpPortListString constructor");
> >>> > this.s = s;
> >>> > this.list = null;
> >>> > }
> >>> >
> >>> > @NamedParameter
> >>> > static class TcpPortList implements Name<List<String>> {
> >>> > }
> >>> >
> >>> > @NamedParameter
> >>> > static class TcpPortListString implements Name<String> {
> >>> > }
> >>> > }
> >>> >
> >>> >
> >>> > And here is the code to instantiate using injection where I only
> >>> > supplied argument for the injector that uses the string.
> >>> >
> >>> >
> >>> > final JavaConfigurationBuilder cb = tang.newConfigurationBuilder();
> >>> > cb.bindNamedParameter(TcpProvider.TcpPortListString.class, "this is
> a
> >>> > string");
> >>> > tang.newInjector(cb.build()).getInstance(TcpPortProvider.class);
> >>> >
> >>> >
> >>> >
> >>> > And here is the exception (note how it indicates that I also bound to
> >>> > an empty list):
> >>> >
> >>> > org.apache.reef.tang.exceptions.InjectionException: Cannot inject
> >>> > org.apache.reef.tang.TcpPortProvider Ambiguous subplan
> >>> > org.apache.reef.tang.TcpPortProvider
> >>> > new TcpPortProvider(String TcpPortListString = this is a string)
> >>> > new TcpPortProvider(list {
> >>> > } )
> >>> > ]
> >>> >
> >>> > at org.apache.reef.tang.implementation.java.
> >>> > InjectorImpl.injectFromPlan(InjectorImpl.java:600)
> >>> > at org.apache.reef.tang.implementation.java.
> >>> > InjectorImpl.getInstance(InjectorImpl.java:515)
> >>> > at org.apache.reef.tang.implementation.java.
> >>> > InjectorImpl.getInstance(InjectorImpl.java:533)
> >>> > at org.apache.reef.tang.TestTang.
> >>> > testTcpProvider(TestTang.java:452)
> >>> > at sun.reflect.NativeMethodAccessorImpl.invoke0(Native
> >>> > Method)
> >>> > at sun.reflect.NativeMethodAccessorImpl.invoke(
> >>> > NativeMethodAccessorImpl.java:62)
> >>> > at sun.reflect.DelegatingMethodAccessorImpl.invoke(
> >>> > DelegatingMethodAccessorImpl.java:43)
> >>> > at java.lang.reflect.Method.invoke(Method.java:498)
> >>> > at org.junit.runners.model.FrameworkMethod$1.
> >>> > runReflectiveCall(FrameworkMethod.java:47)
> >>> > at org.junit.internal.runners.
> >>> > model.ReflectiveCallable.run(ReflectiveCallable.java:12)
> >>> > at org.junit.runners.model.FrameworkMethod.
> >>> > invokeExplosively(FrameworkMethod.java:44)
> >>> > at org.junit.internal.runners.statements.InvokeMethod.
> >>> > evaluate(InvokeMethod.java:17)
> >>> > at org.junit.internal.runners.statements.RunBefores.
> >>> > evaluate(RunBefores.java:26)
> >>> > at org.junit.rules.ExpectedException$
> >>> > ExpectedExceptionStatement.evaluate(ExpectedException.java:168)
> >>> > at org.junit.rules.RunRules.evaluate(RunRules.java:20)
> >>> > at org.junit.runners.ParentRunner.runLeaf(
> >>> > ParentRunner.java:271)
> >>> > at org.junit.runners.BlockJUnit4ClassRunner.runChild(
> >>> > BlockJUnit4ClassRunner.java:70)
> >>> > at org.junit.runners.BlockJUnit4ClassRunner.runChild(
> >>> > BlockJUnit4ClassRunner.java:50)
> >>> > at org.junit.runners.ParentRunner$3.run(
> >>> > ParentRunner.java:238)
> >>> > at org.junit.runners.ParentRunner$1.schedule(
> >>> > ParentRunner.java:63)
> >>> > at org.junit.runners.ParentRunner.runChildren(
> >>> > ParentRunner.java:236)
> >>> > at org.junit.runners.ParentRunner.access$000(
> >>> > ParentRunner.java:53)
> >>> > at org.junit.runners.ParentRunner$2.evaluate(
> >>> > ParentRunner.java:229)
> >>> > at org.junit.runners.ParentRunner.run(ParentRunner.
> >>> > java:309)
> >>> > at org.junit.runner.JUnitCore.run(JUnitCore.java:160)
> >>> > at com.intellij.junit4.JUnit4IdeaTestRunner.
> >>> > startRunnerWithArgs(JUnit4IdeaTestRunner.java:68)
> >>> > at com.intellij.rt.execution.
> >>> > junit.IdeaTestRunner$Repeater.startRunnerWithArgs(IdeaTestRu
> >>> nner.java:47)
> >>> > at com.intellij.rt.execution.junit.JUnitStarter.
> >>> > prepareStreamsAndStart(JUnitStarter.java:242)
> >>> > at com.intellij.rt.execution.junit.JUnitStarter.main(
> >>> > JUnitStarter.java:70)
> >>> >
> >>> >
> >>> > Process finished with exit code -1
> >>> >
> >>> >
> >>> >
> >>>
> >>
> >>
> >
>

Re: Tang "ambiguous subplan" exception when using Lists

Posted by Gyewon Lee <st...@gmail.com>.
Hi, Sharath.

Yes, your understanding is right and your suggestion seems better to me.
Actually, current named parameter annotation has similar arguments named
"default_values" that can bind multiple elements to set/list named
parameters.
I think we can make use of existing "default_values" and just change its
semantics so that the named parameters with no defined default_values will
be bound to "null" (which means not bound in Tang InjectionPlan) instead of
an empty list.

For example,

@NamedParameter(doc = "Class A")
public class A implements Name<List<String>> {
}

currently "A" has default value of empty list, but after the patch its
default value will be null. We can set the default value of this named
parameter to an empty list by

@NamedParameter(doc = "Class A", default_values = {})
public class A implements Name<List<String>> {
}

The only problem is that it will make some legacy code outside REEF
repository not work, which is why I suggested adding new arguments. But if
we can afford this change, I prefer this way to adding new parameters,
which will definitely increase complexity.

Best regards,
Gyewon

2018-06-27 15:10 GMT+09:00 Sharath Malladi <sh...@microsoft.com.invalid>:

> Gyewon,
>
> If I understand correctly:
>
> [NamedParameter(default_empty_list=“true/false”)]
> List<int> myList;
>
> Would mean that if I don’t supply a binding, myList has no binding when
> the flag is false. And if the flag is set to true and I don’t provide a
> binding, then it binds to an empty list (as is the behavior now).
>
> I prefer that we rather achieve this by the following as it is more
> straightforward to follow:
> [NamedParameter(default={})] // the equivalent of default_empty_list set
> to true - bind to empty list.
> [NamedParameter] // the equivalent of default_empty_list set to false -
> don’t bind.
>
> We could achieve this by replacing all existing occurrences to set the
> default of {} and then make this change.
>
> I am not the expert; so please push back if you feel so.
>
> Thanks,
> -Sharath Malladi.
> ________________________________
> From: Gyewon Lee <st...@gmail.com>
> Sent: Tuesday, June 26, 2018 10:43 PM
> To: dev@reef.apache.org
> Subject: Re: Tang "ambiguous subplan" exception when using Lists
>
> Hi, all.
>
> I found out that many codes in REEF are already implemented based on the
> assumption that empty list will be bound, even though there are no default
> values specified for named parameters. For this reason, fixing this issue
> causes InjectionExceptions in some REEF tests.
>
> IMHO, whether empty List(or Set) would be bound or not as default value
> must be explicitly exposed when defining named parameters. My initial plan
> is adding additional boolean arguments on "NamedParameter" annotation, such
> as "default_empty_list" and "default_empty_set".
>
> How do you think about it? I'd like to hear your opinion.
>
> Best regards,
> Gyewon
>
> 2018-06-22 10:08 GMT+09:00 Gyewon Lee <st...@gmail.com>:
>
> > I have an created an issue on this bug.
> >
> > https://na01.safelinks.protection.outlook.com/?url=
> https%3A%2F%2Fissues.apache.org%2Fjira%2Fbrowse%2FREEF-
> 2040&amp;data=02%7C01%7Csharathm%40microsoft.com%
> 7C781d76bc3cd14bf0adf908d5dbf0f1ba%7C72f988bf86f141af91ab2d7cd011
> db47%7C1%7C0%7C636656750250177387&amp;sdata=3VkTXjvVeJqnlye2jlQuY2md2b2mw3
> yyZXBtCapRsj0%3D&amp;reserved=0
> >
> > Best regards,
> > Gyewon
> >
> > 2018-06-22 9:49 GMT+09:00 Gyewon Lee <st...@gmail.com>:
> >
> >> Hi, Sharath. Sorry for my late response.
> >>
> >> I have looked at Tang code and found out that for Set and List named
> >> parameters, the default value could be set to empty set or empty list
> even
> >> though there are no bound default values. I'm not sure on the reason,
> >> though.
> >>
> >> I will open an issue in JIRA and send a PR soon.
> >>
> >> Best regards,
> >> Gyewon.
> >>
> >> 2018-06-22 2:20 GMT+09:00 Sharath Malladi <sharathm@microsoft.com.
> invalid
> >> >:
> >>
> >>> Hi Gyewon,
> >>>
> >>> Did you get time to investigate this. Could you share your findings.
> >>>
> >>> Thanks,
> >>> Sharath.
> >>>
> >>> -----Original Message-----
> >>> From: Gyewon Lee <st...@gmail.com>
> >>> Sent: Monday, June 18, 2018 6:02 PM
> >>> To: dev@reef.apache.org
> >>> Subject: Re: Tang "ambiguous subplan" exception when using Lists
> >>>
> >>> Hi, Sharath.
> >>>
> >>> As you say, it seems you haven't bound anything for "TcpPortList". I
> >>> will look into the Tang code and get back to you after I find the
> cause.
> >>>
> >>> Best regards,
> >>> Gyewon
> >>>
> >>> 2018-06-19 7:57 GMT+09:00 Sharath Malladi
> <sharathm@microsoft.com.invali
> >>> d>:
> >>>
> >>> > Hi,
> >>> >
> >>> > If I have a class that has multiple injectors (one of which injects a
> >>> > list), then I get an InjectionException about an "Ambiguous subplan".
> >>> > As you can see from the exception below, it assumes that I attempted
> >>> > to bind to an empty list, which I did not .. so there should be no
> >>> ambiguity.
> >>> >
> >>> > Is there a work around for this issue.
> >>> >
> >>> > Thanks,
> >>> > Sharath.
> >>> >
> >>> > For example, here is the class with two injectors:
> >>> >
> >>> >
> >>> > class TcpPortProvider {
> >>> > protected final List<String> list;
> >>> > protected final String s;
> >>> >
> >>> > @Inject
> >>> > TcpPortProvider(@Parameter(TcpPortList.class) final List<String>
> >>> > tcpPortList) {
> >>> > System.out.println("tcpPortList constructor");
> >>> > this.list = tcpPortList;
> >>> > this.s = "";
> >>> > }
> >>> >
> >>> >
> >>> > @Inject
> >>> > TcpPortProvider(@Parameter(TcpPortListString.class) final String s)
> >>> {
> >>> > System.out.println("TcpPortListString constructor");
> >>> > this.s = s;
> >>> > this.list = null;
> >>> > }
> >>> >
> >>> > @NamedParameter
> >>> > static class TcpPortList implements Name<List<String>> {
> >>> > }
> >>> >
> >>> > @NamedParameter
> >>> > static class TcpPortListString implements Name<String> {
> >>> > }
> >>> > }
> >>> >
> >>> >
> >>> > And here is the code to instantiate using injection where I only
> >>> > supplied argument for the injector that uses the string.
> >>> >
> >>> >
> >>> > final JavaConfigurationBuilder cb = tang.newConfigurationBuilder();
> >>> > cb.bindNamedParameter(TcpProvider.TcpPortListString.class, "this is
> a
> >>> > string");
> >>> > tang.newInjector(cb.build()).getInstance(TcpPortProvider.class);
> >>> >
> >>> >
> >>> >
> >>> > And here is the exception (note how it indicates that I also bound to
> >>> > an empty list):
> >>> >
> >>> > org.apache.reef.tang.exceptions.InjectionException: Cannot inject
> >>> > org.apache.reef.tang.TcpPortProvider Ambiguous subplan
> >>> > org.apache.reef.tang.TcpPortProvider
> >>> > new TcpPortProvider(String TcpPortListString = this is a string)
> >>> > new TcpPortProvider(list {
> >>> > } )
> >>> > ]
> >>> >
> >>> > at org.apache.reef.tang.implementation.java.
> >>> > InjectorImpl.injectFromPlan(InjectorImpl.java:600)
> >>> > at org.apache.reef.tang.implementation.java.
> >>> > InjectorImpl.getInstance(InjectorImpl.java:515)
> >>> > at org.apache.reef.tang.implementation.java.
> >>> > InjectorImpl.getInstance(InjectorImpl.java:533)
> >>> > at org.apache.reef.tang.TestTang.
> >>> > testTcpProvider(TestTang.java:452)
> >>> > at sun.reflect.NativeMethodAccessorImpl.invoke0(Native
> >>> > Method)
> >>> > at sun.reflect.NativeMethodAccessorImpl.invoke(
> >>> > NativeMethodAccessorImpl.java:62)
> >>> > at sun.reflect.DelegatingMethodAccessorImpl.invoke(
> >>> > DelegatingMethodAccessorImpl.java:43)
> >>> > at java.lang.reflect.Method.invoke(Method.java:498)
> >>> > at org.junit.runners.model.FrameworkMethod$1.
> >>> > runReflectiveCall(FrameworkMethod.java:47)
> >>> > at org.junit.internal.runners.
> >>> > model.ReflectiveCallable.run(ReflectiveCallable.java:12)
> >>> > at org.junit.runners.model.FrameworkMethod.
> >>> > invokeExplosively(FrameworkMethod.java:44)
> >>> > at org.junit.internal.runners.statements.InvokeMethod.
> >>> > evaluate(InvokeMethod.java:17)
> >>> > at org.junit.internal.runners.statements.RunBefores.
> >>> > evaluate(RunBefores.java:26)
> >>> > at org.junit.rules.ExpectedException$
> >>> > ExpectedExceptionStatement.evaluate(ExpectedException.java:168)
> >>> > at org.junit.rules.RunRules.evaluate(RunRules.java:20)
> >>> > at org.junit.runners.ParentRunner.runLeaf(
> >>> > ParentRunner.java:271)
> >>> > at org.junit.runners.BlockJUnit4ClassRunner.runChild(
> >>> > BlockJUnit4ClassRunner.java:70)
> >>> > at org.junit.runners.BlockJUnit4ClassRunner.runChild(
> >>> > BlockJUnit4ClassRunner.java:50)
> >>> > at org.junit.runners.ParentRunner$3.run(
> >>> > ParentRunner.java:238)
> >>> > at org.junit.runners.ParentRunner$1.schedule(
> >>> > ParentRunner.java:63)
> >>> > at org.junit.runners.ParentRunner.runChildren(
> >>> > ParentRunner.java:236)
> >>> > at org.junit.runners.ParentRunner.access$000(
> >>> > ParentRunner.java:53)
> >>> > at org.junit.runners.ParentRunner$2.evaluate(
> >>> > ParentRunner.java:229)
> >>> > at org.junit.runners.ParentRunner.run(ParentRunner.
> >>> > java:309)
> >>> > at org.junit.runner.JUnitCore.run(JUnitCore.java:160)
> >>> > at com.intellij.junit4.JUnit4IdeaTestRunner.
> >>> > startRunnerWithArgs(JUnit4IdeaTestRunner.java:68)
> >>> > at com.intellij.rt.execution.
> >>> > junit.IdeaTestRunner$Repeater.startRunnerWithArgs(IdeaTestRu
> >>> nner.java:47)
> >>> > at com.intellij.rt.execution.junit.JUnitStarter.
> >>> > prepareStreamsAndStart(JUnitStarter.java:242)
> >>> > at com.intellij.rt.execution.junit.JUnitStarter.main(
> >>> > JUnitStarter.java:70)
> >>> >
> >>> >
> >>> > Process finished with exit code -1
> >>> >
> >>> >
> >>> >
> >>>
> >>
> >>
> >
>

Re: Tang "ambiguous subplan" exception when using Lists

Posted by Sharath Malladi <sh...@microsoft.com.INVALID>.
Gyewon,

If I understand correctly:

[NamedParameter(default_empty_list=“true/false”)]
List<int> myList;

Would mean that if I don’t supply a binding, myList has no binding when the flag is false. And if the flag is set to true and I don’t provide a binding, then it binds to an empty list (as is the behavior now).

I prefer that we rather achieve this by the following as it is more straightforward to follow:
[NamedParameter(default={})] // the equivalent of default_empty_list set to true - bind to empty list.
[NamedParameter] // the equivalent of default_empty_list set to false - don’t bind.

We could achieve this by replacing all existing occurrences to set the default of {} and then make this change.

I am not the expert; so please push back if you feel so.

Thanks,
-Sharath Malladi.
________________________________
From: Gyewon Lee <st...@gmail.com>
Sent: Tuesday, June 26, 2018 10:43 PM
To: dev@reef.apache.org
Subject: Re: Tang "ambiguous subplan" exception when using Lists

Hi, all.

I found out that many codes in REEF are already implemented based on the
assumption that empty list will be bound, even though there are no default
values specified for named parameters. For this reason, fixing this issue
causes InjectionExceptions in some REEF tests.

IMHO, whether empty List(or Set) would be bound or not as default value
must be explicitly exposed when defining named parameters. My initial plan
is adding additional boolean arguments on "NamedParameter" annotation, such
as "default_empty_list" and "default_empty_set".

How do you think about it? I'd like to hear your opinion.

Best regards,
Gyewon

2018-06-22 10:08 GMT+09:00 Gyewon Lee <st...@gmail.com>:

> I have an created an issue on this bug.
>
> https://na01.safelinks.protection.outlook.com/?url=https%3A%2F%2Fissues.apache.org%2Fjira%2Fbrowse%2FREEF-2040&amp;data=02%7C01%7Csharathm%40microsoft.com%7C781d76bc3cd14bf0adf908d5dbf0f1ba%7C72f988bf86f141af91ab2d7cd011db47%7C1%7C0%7C636656750250177387&amp;sdata=3VkTXjvVeJqnlye2jlQuY2md2b2mw3yyZXBtCapRsj0%3D&amp;reserved=0
>
> Best regards,
> Gyewon
>
> 2018-06-22 9:49 GMT+09:00 Gyewon Lee <st...@gmail.com>:
>
>> Hi, Sharath. Sorry for my late response.
>>
>> I have looked at Tang code and found out that for Set and List named
>> parameters, the default value could be set to empty set or empty list even
>> though there are no bound default values. I'm not sure on the reason,
>> though.
>>
>> I will open an issue in JIRA and send a PR soon.
>>
>> Best regards,
>> Gyewon.
>>
>> 2018-06-22 2:20 GMT+09:00 Sharath Malladi <sharathm@microsoft.com.invalid
>> >:
>>
>>> Hi Gyewon,
>>>
>>> Did you get time to investigate this. Could you share your findings.
>>>
>>> Thanks,
>>> Sharath.
>>>
>>> -----Original Message-----
>>> From: Gyewon Lee <st...@gmail.com>
>>> Sent: Monday, June 18, 2018 6:02 PM
>>> To: dev@reef.apache.org
>>> Subject: Re: Tang "ambiguous subplan" exception when using Lists
>>>
>>> Hi, Sharath.
>>>
>>> As you say, it seems you haven't bound anything for "TcpPortList". I
>>> will look into the Tang code and get back to you after I find the cause.
>>>
>>> Best regards,
>>> Gyewon
>>>
>>> 2018-06-19 7:57 GMT+09:00 Sharath Malladi <sharathm@microsoft.com.invali
>>> d>:
>>>
>>> > Hi,
>>> >
>>> > If I have a class that has multiple injectors (one of which injects a
>>> > list), then I get an InjectionException about an "Ambiguous subplan".
>>> > As you can see from the exception below, it assumes that I attempted
>>> > to bind to an empty list, which I did not .. so there should be no
>>> ambiguity.
>>> >
>>> > Is there a work around for this issue.
>>> >
>>> > Thanks,
>>> > Sharath.
>>> >
>>> > For example, here is the class with two injectors:
>>> >
>>> >
>>> > class TcpPortProvider {
>>> > protected final List<String> list;
>>> > protected final String s;
>>> >
>>> > @Inject
>>> > TcpPortProvider(@Parameter(TcpPortList.class) final List<String>
>>> > tcpPortList) {
>>> > System.out.println("tcpPortList constructor");
>>> > this.list = tcpPortList;
>>> > this.s = "";
>>> > }
>>> >
>>> >
>>> > @Inject
>>> > TcpPortProvider(@Parameter(TcpPortListString.class) final String s)
>>> {
>>> > System.out.println("TcpPortListString constructor");
>>> > this.s = s;
>>> > this.list = null;
>>> > }
>>> >
>>> > @NamedParameter
>>> > static class TcpPortList implements Name<List<String>> {
>>> > }
>>> >
>>> > @NamedParameter
>>> > static class TcpPortListString implements Name<String> {
>>> > }
>>> > }
>>> >
>>> >
>>> > And here is the code to instantiate using injection where I only
>>> > supplied argument for the injector that uses the string.
>>> >
>>> >
>>> > final JavaConfigurationBuilder cb = tang.newConfigurationBuilder();
>>> > cb.bindNamedParameter(TcpProvider.TcpPortListString.class, "this is a
>>> > string");
>>> > tang.newInjector(cb.build()).getInstance(TcpPortProvider.class);
>>> >
>>> >
>>> >
>>> > And here is the exception (note how it indicates that I also bound to
>>> > an empty list):
>>> >
>>> > org.apache.reef.tang.exceptions.InjectionException: Cannot inject
>>> > org.apache.reef.tang.TcpPortProvider Ambiguous subplan
>>> > org.apache.reef.tang.TcpPortProvider
>>> > new TcpPortProvider(String TcpPortListString = this is a string)
>>> > new TcpPortProvider(list {
>>> > } )
>>> > ]
>>> >
>>> > at org.apache.reef.tang.implementation.java.
>>> > InjectorImpl.injectFromPlan(InjectorImpl.java:600)
>>> > at org.apache.reef.tang.implementation.java.
>>> > InjectorImpl.getInstance(InjectorImpl.java:515)
>>> > at org.apache.reef.tang.implementation.java.
>>> > InjectorImpl.getInstance(InjectorImpl.java:533)
>>> > at org.apache.reef.tang.TestTang.
>>> > testTcpProvider(TestTang.java:452)
>>> > at sun.reflect.NativeMethodAccessorImpl.invoke0(Native
>>> > Method)
>>> > at sun.reflect.NativeMethodAccessorImpl.invoke(
>>> > NativeMethodAccessorImpl.java:62)
>>> > at sun.reflect.DelegatingMethodAccessorImpl.invoke(
>>> > DelegatingMethodAccessorImpl.java:43)
>>> > at java.lang.reflect.Method.invoke(Method.java:498)
>>> > at org.junit.runners.model.FrameworkMethod$1.
>>> > runReflectiveCall(FrameworkMethod.java:47)
>>> > at org.junit.internal.runners.
>>> > model.ReflectiveCallable.run(ReflectiveCallable.java:12)
>>> > at org.junit.runners.model.FrameworkMethod.
>>> > invokeExplosively(FrameworkMethod.java:44)
>>> > at org.junit.internal.runners.statements.InvokeMethod.
>>> > evaluate(InvokeMethod.java:17)
>>> > at org.junit.internal.runners.statements.RunBefores.
>>> > evaluate(RunBefores.java:26)
>>> > at org.junit.rules.ExpectedException$
>>> > ExpectedExceptionStatement.evaluate(ExpectedException.java:168)
>>> > at org.junit.rules.RunRules.evaluate(RunRules.java:20)
>>> > at org.junit.runners.ParentRunner.runLeaf(
>>> > ParentRunner.java:271)
>>> > at org.junit.runners.BlockJUnit4ClassRunner.runChild(
>>> > BlockJUnit4ClassRunner.java:70)
>>> > at org.junit.runners.BlockJUnit4ClassRunner.runChild(
>>> > BlockJUnit4ClassRunner.java:50)
>>> > at org.junit.runners.ParentRunner$3.run(
>>> > ParentRunner.java:238)
>>> > at org.junit.runners.ParentRunner$1.schedule(
>>> > ParentRunner.java:63)
>>> > at org.junit.runners.ParentRunner.runChildren(
>>> > ParentRunner.java:236)
>>> > at org.junit.runners.ParentRunner.access$000(
>>> > ParentRunner.java:53)
>>> > at org.junit.runners.ParentRunner$2.evaluate(
>>> > ParentRunner.java:229)
>>> > at org.junit.runners.ParentRunner.run(ParentRunner.
>>> > java:309)
>>> > at org.junit.runner.JUnitCore.run(JUnitCore.java:160)
>>> > at com.intellij.junit4.JUnit4IdeaTestRunner.
>>> > startRunnerWithArgs(JUnit4IdeaTestRunner.java:68)
>>> > at com.intellij.rt.execution.
>>> > junit.IdeaTestRunner$Repeater.startRunnerWithArgs(IdeaTestRu
>>> nner.java:47)
>>> > at com.intellij.rt.execution.junit.JUnitStarter.
>>> > prepareStreamsAndStart(JUnitStarter.java:242)
>>> > at com.intellij.rt.execution.junit.JUnitStarter.main(
>>> > JUnitStarter.java:70)
>>> >
>>> >
>>> > Process finished with exit code -1
>>> >
>>> >
>>> >
>>>
>>
>>
>

Re: Tang "ambiguous subplan" exception when using Lists

Posted by Gyewon Lee <st...@gmail.com>.
Hi, all.

I found out that many codes in REEF are already implemented based on the
assumption that empty list will be bound, even though there are no default
values specified for named parameters. For this reason, fixing this issue
causes InjectionExceptions in some REEF tests.

IMHO, whether empty List(or Set) would be bound or not as default value
must be explicitly exposed when defining named parameters. My initial plan
is adding additional boolean arguments on "NamedParameter" annotation, such
as "default_empty_list" and "default_empty_set".

How do you think about it? I'd like to hear your opinion.

Best regards,
Gyewon

2018-06-22 10:08 GMT+09:00 Gyewon Lee <st...@gmail.com>:

> I have an created an issue on this bug.
>
> https://issues.apache.org/jira/browse/REEF-2040
>
> Best regards,
> Gyewon
>
> 2018-06-22 9:49 GMT+09:00 Gyewon Lee <st...@gmail.com>:
>
>> Hi, Sharath. Sorry for my late response.
>>
>> I have looked at Tang code and found out that for Set and List named
>> parameters, the default value could be set to empty set or empty list even
>> though there are no bound default values. I'm not sure on the reason,
>> though.
>>
>> I will open an issue in JIRA and send a PR soon.
>>
>> Best regards,
>> Gyewon.
>>
>> 2018-06-22 2:20 GMT+09:00 Sharath Malladi <sharathm@microsoft.com.invalid
>> >:
>>
>>> Hi Gyewon,
>>>
>>> Did you get time to investigate this. Could you share your findings.
>>>
>>> Thanks,
>>> Sharath.
>>>
>>> -----Original Message-----
>>> From: Gyewon Lee <st...@gmail.com>
>>> Sent: Monday, June 18, 2018 6:02 PM
>>> To: dev@reef.apache.org
>>> Subject: Re: Tang "ambiguous subplan" exception when using Lists
>>>
>>> Hi, Sharath.
>>>
>>> As you say, it seems you haven't bound anything for "TcpPortList". I
>>> will look into the Tang code and get back to you after I find the cause.
>>>
>>> Best regards,
>>> Gyewon
>>>
>>> 2018-06-19 7:57 GMT+09:00 Sharath Malladi <sharathm@microsoft.com.invali
>>> d>:
>>>
>>> > Hi,
>>> >
>>> > If I have a class that has multiple injectors (one of which injects a
>>> > list), then I get an InjectionException about an "Ambiguous subplan".
>>> > As you can see from the exception below, it assumes that I attempted
>>> > to bind to an empty list, which I did not .. so there should be no
>>> ambiguity.
>>> >
>>> > Is there a work around for this issue.
>>> >
>>> > Thanks,
>>> > Sharath.
>>> >
>>> > For example, here is the class with two injectors:
>>> >
>>> >
>>> > class TcpPortProvider {
>>> >   protected final List<String> list;
>>> >   protected final String s;
>>> >
>>> >   @Inject
>>> >   TcpPortProvider(@Parameter(TcpPortList.class) final List<String>
>>> > tcpPortList) {
>>> >     System.out.println("tcpPortList constructor");
>>> >     this.list = tcpPortList;
>>> >     this.s = "";
>>> >   }
>>> >
>>> >
>>> >   @Inject
>>> >   TcpPortProvider(@Parameter(TcpPortListString.class) final String s)
>>> {
>>> >     System.out.println("TcpPortListString constructor");
>>> >     this.s = s;
>>> >     this.list = null;
>>> >   }
>>> >
>>> >   @NamedParameter
>>> >   static class TcpPortList implements Name<List<String>> {
>>> >   }
>>> >
>>> >   @NamedParameter
>>> >   static class TcpPortListString implements Name<String> {
>>> >   }
>>> > }
>>> >
>>> >
>>> > And here is the code to instantiate using injection where I only
>>> > supplied argument for the injector that uses the string.
>>> >
>>> >
>>> > final JavaConfigurationBuilder cb = tang.newConfigurationBuilder();
>>> > cb.bindNamedParameter(TcpProvider.TcpPortListString.class, "this is a
>>> > string");
>>> > tang.newInjector(cb.build()).getInstance(TcpPortProvider.class);
>>> >
>>> >
>>> >
>>> > And here is the exception (note how it indicates that I also bound to
>>> > an empty list):
>>> >
>>> > org.apache.reef.tang.exceptions.InjectionException: Cannot inject
>>> > org.apache.reef.tang.TcpPortProvider Ambiguous subplan
>>> > org.apache.reef.tang.TcpPortProvider
>>> >   new TcpPortProvider(String TcpPortListString = this is a string)
>>> >   new TcpPortProvider(list {
>>> >  } )
>>> > ]
>>> >
>>> >                 at org.apache.reef.tang.implementation.java.
>>> > InjectorImpl.injectFromPlan(InjectorImpl.java:600)
>>> >                 at org.apache.reef.tang.implementation.java.
>>> > InjectorImpl.getInstance(InjectorImpl.java:515)
>>> >                 at org.apache.reef.tang.implementation.java.
>>> > InjectorImpl.getInstance(InjectorImpl.java:533)
>>> >                 at org.apache.reef.tang.TestTang.
>>> > testTcpProvider(TestTang.java:452)
>>> >                 at sun.reflect.NativeMethodAccessorImpl.invoke0(Native
>>> > Method)
>>> >                 at sun.reflect.NativeMethodAccessorImpl.invoke(
>>> > NativeMethodAccessorImpl.java:62)
>>> >                 at sun.reflect.DelegatingMethodAccessorImpl.invoke(
>>> > DelegatingMethodAccessorImpl.java:43)
>>> >                 at java.lang.reflect.Method.invoke(Method.java:498)
>>> >                 at org.junit.runners.model.FrameworkMethod$1.
>>> > runReflectiveCall(FrameworkMethod.java:47)
>>> >                 at org.junit.internal.runners.
>>> > model.ReflectiveCallable.run(ReflectiveCallable.java:12)
>>> >                 at org.junit.runners.model.FrameworkMethod.
>>> > invokeExplosively(FrameworkMethod.java:44)
>>> >                 at org.junit.internal.runners.statements.InvokeMethod.
>>> > evaluate(InvokeMethod.java:17)
>>> >                 at org.junit.internal.runners.statements.RunBefores.
>>> > evaluate(RunBefores.java:26)
>>> >                 at org.junit.rules.ExpectedException$
>>> > ExpectedExceptionStatement.evaluate(ExpectedException.java:168)
>>> >                 at org.junit.rules.RunRules.evaluate(RunRules.java:20)
>>> >                 at org.junit.runners.ParentRunner.runLeaf(
>>> > ParentRunner.java:271)
>>> >                 at org.junit.runners.BlockJUnit4ClassRunner.runChild(
>>> > BlockJUnit4ClassRunner.java:70)
>>> >                 at org.junit.runners.BlockJUnit4ClassRunner.runChild(
>>> > BlockJUnit4ClassRunner.java:50)
>>> >                 at org.junit.runners.ParentRunner$3.run(
>>> > ParentRunner.java:238)
>>> >                 at org.junit.runners.ParentRunner$1.schedule(
>>> > ParentRunner.java:63)
>>> >                 at org.junit.runners.ParentRunner.runChildren(
>>> > ParentRunner.java:236)
>>> >                 at org.junit.runners.ParentRunner.access$000(
>>> > ParentRunner.java:53)
>>> >                 at org.junit.runners.ParentRunner$2.evaluate(
>>> > ParentRunner.java:229)
>>> >                 at org.junit.runners.ParentRunner.run(ParentRunner.
>>> > java:309)
>>> >                 at org.junit.runner.JUnitCore.run(JUnitCore.java:160)
>>> >                 at com.intellij.junit4.JUnit4IdeaTestRunner.
>>> > startRunnerWithArgs(JUnit4IdeaTestRunner.java:68)
>>> >                 at com.intellij.rt.execution.
>>> > junit.IdeaTestRunner$Repeater.startRunnerWithArgs(IdeaTestRu
>>> nner.java:47)
>>> >                 at com.intellij.rt.execution.junit.JUnitStarter.
>>> > prepareStreamsAndStart(JUnitStarter.java:242)
>>> >                 at com.intellij.rt.execution.junit.JUnitStarter.main(
>>> > JUnitStarter.java:70)
>>> >
>>> >
>>> > Process finished with exit code -1
>>> >
>>> >
>>> >
>>>
>>
>>
>

Re: Tang "ambiguous subplan" exception when using Lists

Posted by Gyewon Lee <st...@gmail.com>.
I have an created an issue on this bug.

https://issues.apache.org/jira/browse/REEF-2040

Best regards,
Gyewon

2018-06-22 9:49 GMT+09:00 Gyewon Lee <st...@gmail.com>:

> Hi, Sharath. Sorry for my late response.
>
> I have looked at Tang code and found out that for Set and List named
> parameters, the default value could be set to empty set or empty list even
> though there are no bound default values. I'm not sure on the reason,
> though.
>
> I will open an issue in JIRA and send a PR soon.
>
> Best regards,
> Gyewon.
>
> 2018-06-22 2:20 GMT+09:00 Sharath Malladi <sh...@microsoft.com.invalid>
> :
>
>> Hi Gyewon,
>>
>> Did you get time to investigate this. Could you share your findings.
>>
>> Thanks,
>> Sharath.
>>
>> -----Original Message-----
>> From: Gyewon Lee <st...@gmail.com>
>> Sent: Monday, June 18, 2018 6:02 PM
>> To: dev@reef.apache.org
>> Subject: Re: Tang "ambiguous subplan" exception when using Lists
>>
>> Hi, Sharath.
>>
>> As you say, it seems you haven't bound anything for "TcpPortList". I will
>> look into the Tang code and get back to you after I find the cause.
>>
>> Best regards,
>> Gyewon
>>
>> 2018-06-19 7:57 GMT+09:00 Sharath Malladi <sharathm@microsoft.com.invali
>> d>:
>>
>> > Hi,
>> >
>> > If I have a class that has multiple injectors (one of which injects a
>> > list), then I get an InjectionException about an "Ambiguous subplan".
>> > As you can see from the exception below, it assumes that I attempted
>> > to bind to an empty list, which I did not .. so there should be no
>> ambiguity.
>> >
>> > Is there a work around for this issue.
>> >
>> > Thanks,
>> > Sharath.
>> >
>> > For example, here is the class with two injectors:
>> >
>> >
>> > class TcpPortProvider {
>> >   protected final List<String> list;
>> >   protected final String s;
>> >
>> >   @Inject
>> >   TcpPortProvider(@Parameter(TcpPortList.class) final List<String>
>> > tcpPortList) {
>> >     System.out.println("tcpPortList constructor");
>> >     this.list = tcpPortList;
>> >     this.s = "";
>> >   }
>> >
>> >
>> >   @Inject
>> >   TcpPortProvider(@Parameter(TcpPortListString.class) final String s) {
>> >     System.out.println("TcpPortListString constructor");
>> >     this.s = s;
>> >     this.list = null;
>> >   }
>> >
>> >   @NamedParameter
>> >   static class TcpPortList implements Name<List<String>> {
>> >   }
>> >
>> >   @NamedParameter
>> >   static class TcpPortListString implements Name<String> {
>> >   }
>> > }
>> >
>> >
>> > And here is the code to instantiate using injection where I only
>> > supplied argument for the injector that uses the string.
>> >
>> >
>> > final JavaConfigurationBuilder cb = tang.newConfigurationBuilder();
>> > cb.bindNamedParameter(TcpProvider.TcpPortListString.class, "this is a
>> > string");
>> > tang.newInjector(cb.build()).getInstance(TcpPortProvider.class);
>> >
>> >
>> >
>> > And here is the exception (note how it indicates that I also bound to
>> > an empty list):
>> >
>> > org.apache.reef.tang.exceptions.InjectionException: Cannot inject
>> > org.apache.reef.tang.TcpPortProvider Ambiguous subplan
>> > org.apache.reef.tang.TcpPortProvider
>> >   new TcpPortProvider(String TcpPortListString = this is a string)
>> >   new TcpPortProvider(list {
>> >  } )
>> > ]
>> >
>> >                 at org.apache.reef.tang.implementation.java.
>> > InjectorImpl.injectFromPlan(InjectorImpl.java:600)
>> >                 at org.apache.reef.tang.implementation.java.
>> > InjectorImpl.getInstance(InjectorImpl.java:515)
>> >                 at org.apache.reef.tang.implementation.java.
>> > InjectorImpl.getInstance(InjectorImpl.java:533)
>> >                 at org.apache.reef.tang.TestTang.
>> > testTcpProvider(TestTang.java:452)
>> >                 at sun.reflect.NativeMethodAccessorImpl.invoke0(Native
>> > Method)
>> >                 at sun.reflect.NativeMethodAccessorImpl.invoke(
>> > NativeMethodAccessorImpl.java:62)
>> >                 at sun.reflect.DelegatingMethodAccessorImpl.invoke(
>> > DelegatingMethodAccessorImpl.java:43)
>> >                 at java.lang.reflect.Method.invoke(Method.java:498)
>> >                 at org.junit.runners.model.FrameworkMethod$1.
>> > runReflectiveCall(FrameworkMethod.java:47)
>> >                 at org.junit.internal.runners.
>> > model.ReflectiveCallable.run(ReflectiveCallable.java:12)
>> >                 at org.junit.runners.model.FrameworkMethod.
>> > invokeExplosively(FrameworkMethod.java:44)
>> >                 at org.junit.internal.runners.statements.InvokeMethod.
>> > evaluate(InvokeMethod.java:17)
>> >                 at org.junit.internal.runners.statements.RunBefores.
>> > evaluate(RunBefores.java:26)
>> >                 at org.junit.rules.ExpectedException$
>> > ExpectedExceptionStatement.evaluate(ExpectedException.java:168)
>> >                 at org.junit.rules.RunRules.evaluate(RunRules.java:20)
>> >                 at org.junit.runners.ParentRunner.runLeaf(
>> > ParentRunner.java:271)
>> >                 at org.junit.runners.BlockJUnit4ClassRunner.runChild(
>> > BlockJUnit4ClassRunner.java:70)
>> >                 at org.junit.runners.BlockJUnit4ClassRunner.runChild(
>> > BlockJUnit4ClassRunner.java:50)
>> >                 at org.junit.runners.ParentRunner$3.run(
>> > ParentRunner.java:238)
>> >                 at org.junit.runners.ParentRunner$1.schedule(
>> > ParentRunner.java:63)
>> >                 at org.junit.runners.ParentRunner.runChildren(
>> > ParentRunner.java:236)
>> >                 at org.junit.runners.ParentRunner.access$000(
>> > ParentRunner.java:53)
>> >                 at org.junit.runners.ParentRunner$2.evaluate(
>> > ParentRunner.java:229)
>> >                 at org.junit.runners.ParentRunner.run(ParentRunner.
>> > java:309)
>> >                 at org.junit.runner.JUnitCore.run(JUnitCore.java:160)
>> >                 at com.intellij.junit4.JUnit4IdeaTestRunner.
>> > startRunnerWithArgs(JUnit4IdeaTestRunner.java:68)
>> >                 at com.intellij.rt.execution.
>> > junit.IdeaTestRunner$Repeater.startRunnerWithArgs(IdeaTestRu
>> nner.java:47)
>> >                 at com.intellij.rt.execution.junit.JUnitStarter.
>> > prepareStreamsAndStart(JUnitStarter.java:242)
>> >                 at com.intellij.rt.execution.junit.JUnitStarter.main(
>> > JUnitStarter.java:70)
>> >
>> >
>> > Process finished with exit code -1
>> >
>> >
>> >
>>
>
>

Re: Tang "ambiguous subplan" exception when using Lists

Posted by Gyewon Lee <st...@gmail.com>.
Hi, Sharath. Sorry for my late response.

I have looked at Tang code and found out that for Set and List named
parameters, the default value could be set to empty set or empty list even
though there are no bound default values. I'm not sure on the reason,
though.

I will open an issue in JIRA and send a PR soon.

Best regards,
Gyewon.

2018-06-22 2:20 GMT+09:00 Sharath Malladi <sh...@microsoft.com.invalid>:

> Hi Gyewon,
>
> Did you get time to investigate this. Could you share your findings.
>
> Thanks,
> Sharath.
>
> -----Original Message-----
> From: Gyewon Lee <st...@gmail.com>
> Sent: Monday, June 18, 2018 6:02 PM
> To: dev@reef.apache.org
> Subject: Re: Tang "ambiguous subplan" exception when using Lists
>
> Hi, Sharath.
>
> As you say, it seems you haven't bound anything for "TcpPortList". I will
> look into the Tang code and get back to you after I find the cause.
>
> Best regards,
> Gyewon
>
> 2018-06-19 7:57 GMT+09:00 Sharath Malladi <sharathm@microsoft.com.
> invalid>:
>
> > Hi,
> >
> > If I have a class that has multiple injectors (one of which injects a
> > list), then I get an InjectionException about an "Ambiguous subplan".
> > As you can see from the exception below, it assumes that I attempted
> > to bind to an empty list, which I did not .. so there should be no
> ambiguity.
> >
> > Is there a work around for this issue.
> >
> > Thanks,
> > Sharath.
> >
> > For example, here is the class with two injectors:
> >
> >
> > class TcpPortProvider {
> >   protected final List<String> list;
> >   protected final String s;
> >
> >   @Inject
> >   TcpPortProvider(@Parameter(TcpPortList.class) final List<String>
> > tcpPortList) {
> >     System.out.println("tcpPortList constructor");
> >     this.list = tcpPortList;
> >     this.s = "";
> >   }
> >
> >
> >   @Inject
> >   TcpPortProvider(@Parameter(TcpPortListString.class) final String s) {
> >     System.out.println("TcpPortListString constructor");
> >     this.s = s;
> >     this.list = null;
> >   }
> >
> >   @NamedParameter
> >   static class TcpPortList implements Name<List<String>> {
> >   }
> >
> >   @NamedParameter
> >   static class TcpPortListString implements Name<String> {
> >   }
> > }
> >
> >
> > And here is the code to instantiate using injection where I only
> > supplied argument for the injector that uses the string.
> >
> >
> > final JavaConfigurationBuilder cb = tang.newConfigurationBuilder();
> > cb.bindNamedParameter(TcpProvider.TcpPortListString.class, "this is a
> > string");
> > tang.newInjector(cb.build()).getInstance(TcpPortProvider.class);
> >
> >
> >
> > And here is the exception (note how it indicates that I also bound to
> > an empty list):
> >
> > org.apache.reef.tang.exceptions.InjectionException: Cannot inject
> > org.apache.reef.tang.TcpPortProvider Ambiguous subplan
> > org.apache.reef.tang.TcpPortProvider
> >   new TcpPortProvider(String TcpPortListString = this is a string)
> >   new TcpPortProvider(list {
> >  } )
> > ]
> >
> >                 at org.apache.reef.tang.implementation.java.
> > InjectorImpl.injectFromPlan(InjectorImpl.java:600)
> >                 at org.apache.reef.tang.implementation.java.
> > InjectorImpl.getInstance(InjectorImpl.java:515)
> >                 at org.apache.reef.tang.implementation.java.
> > InjectorImpl.getInstance(InjectorImpl.java:533)
> >                 at org.apache.reef.tang.TestTang.
> > testTcpProvider(TestTang.java:452)
> >                 at sun.reflect.NativeMethodAccessorImpl.invoke0(Native
> > Method)
> >                 at sun.reflect.NativeMethodAccessorImpl.invoke(
> > NativeMethodAccessorImpl.java:62)
> >                 at sun.reflect.DelegatingMethodAccessorImpl.invoke(
> > DelegatingMethodAccessorImpl.java:43)
> >                 at java.lang.reflect.Method.invoke(Method.java:498)
> >                 at org.junit.runners.model.FrameworkMethod$1.
> > runReflectiveCall(FrameworkMethod.java:47)
> >                 at org.junit.internal.runners.
> > model.ReflectiveCallable.run(ReflectiveCallable.java:12)
> >                 at org.junit.runners.model.FrameworkMethod.
> > invokeExplosively(FrameworkMethod.java:44)
> >                 at org.junit.internal.runners.statements.InvokeMethod.
> > evaluate(InvokeMethod.java:17)
> >                 at org.junit.internal.runners.statements.RunBefores.
> > evaluate(RunBefores.java:26)
> >                 at org.junit.rules.ExpectedException$
> > ExpectedExceptionStatement.evaluate(ExpectedException.java:168)
> >                 at org.junit.rules.RunRules.evaluate(RunRules.java:20)
> >                 at org.junit.runners.ParentRunner.runLeaf(
> > ParentRunner.java:271)
> >                 at org.junit.runners.BlockJUnit4ClassRunner.runChild(
> > BlockJUnit4ClassRunner.java:70)
> >                 at org.junit.runners.BlockJUnit4ClassRunner.runChild(
> > BlockJUnit4ClassRunner.java:50)
> >                 at org.junit.runners.ParentRunner$3.run(
> > ParentRunner.java:238)
> >                 at org.junit.runners.ParentRunner$1.schedule(
> > ParentRunner.java:63)
> >                 at org.junit.runners.ParentRunner.runChildren(
> > ParentRunner.java:236)
> >                 at org.junit.runners.ParentRunner.access$000(
> > ParentRunner.java:53)
> >                 at org.junit.runners.ParentRunner$2.evaluate(
> > ParentRunner.java:229)
> >                 at org.junit.runners.ParentRunner.run(ParentRunner.
> > java:309)
> >                 at org.junit.runner.JUnitCore.run(JUnitCore.java:160)
> >                 at com.intellij.junit4.JUnit4IdeaTestRunner.
> > startRunnerWithArgs(JUnit4IdeaTestRunner.java:68)
> >                 at com.intellij.rt.execution.
> > junit.IdeaTestRunner$Repeater.startRunnerWithArgs(
> IdeaTestRunner.java:47)
> >                 at com.intellij.rt.execution.junit.JUnitStarter.
> > prepareStreamsAndStart(JUnitStarter.java:242)
> >                 at com.intellij.rt.execution.junit.JUnitStarter.main(
> > JUnitStarter.java:70)
> >
> >
> > Process finished with exit code -1
> >
> >
> >
>

RE: Tang "ambiguous subplan" exception when using Lists

Posted by Sharath Malladi <sh...@microsoft.com.INVALID>.
Hi Gyewon,

Did you get time to investigate this. Could you share your findings.

Thanks,
Sharath.

-----Original Message-----
From: Gyewon Lee <st...@gmail.com> 
Sent: Monday, June 18, 2018 6:02 PM
To: dev@reef.apache.org
Subject: Re: Tang "ambiguous subplan" exception when using Lists

Hi, Sharath.

As you say, it seems you haven't bound anything for "TcpPortList". I will look into the Tang code and get back to you after I find the cause.

Best regards,
Gyewon

2018-06-19 7:57 GMT+09:00 Sharath Malladi <sh...@microsoft.com.invalid>:

> Hi,
>
> If I have a class that has multiple injectors (one of which injects a 
> list), then I get an InjectionException about an "Ambiguous subplan".
> As you can see from the exception below, it assumes that I attempted 
> to bind to an empty list, which I did not .. so there should be no ambiguity.
>
> Is there a work around for this issue.
>
> Thanks,
> Sharath.
>
> For example, here is the class with two injectors:
>
>
> class TcpPortProvider {
>   protected final List<String> list;
>   protected final String s;
>
>   @Inject
>   TcpPortProvider(@Parameter(TcpPortList.class) final List<String>
> tcpPortList) {
>     System.out.println("tcpPortList constructor");
>     this.list = tcpPortList;
>     this.s = "";
>   }
>
>
>   @Inject
>   TcpPortProvider(@Parameter(TcpPortListString.class) final String s) {
>     System.out.println("TcpPortListString constructor");
>     this.s = s;
>     this.list = null;
>   }
>
>   @NamedParameter
>   static class TcpPortList implements Name<List<String>> {
>   }
>
>   @NamedParameter
>   static class TcpPortListString implements Name<String> {
>   }
> }
>
>
> And here is the code to instantiate using injection where I only 
> supplied argument for the injector that uses the string.
>
>
> final JavaConfigurationBuilder cb = tang.newConfigurationBuilder(); 
> cb.bindNamedParameter(TcpProvider.TcpPortListString.class, "this is a 
> string"); 
> tang.newInjector(cb.build()).getInstance(TcpPortProvider.class);
>
>
>
> And here is the exception (note how it indicates that I also bound to 
> an empty list):
>
> org.apache.reef.tang.exceptions.InjectionException: Cannot inject 
> org.apache.reef.tang.TcpPortProvider Ambiguous subplan 
> org.apache.reef.tang.TcpPortProvider
>   new TcpPortProvider(String TcpPortListString = this is a string)
>   new TcpPortProvider(list {
>  } )
> ]
>
>                 at org.apache.reef.tang.implementation.java.
> InjectorImpl.injectFromPlan(InjectorImpl.java:600)
>                 at org.apache.reef.tang.implementation.java.
> InjectorImpl.getInstance(InjectorImpl.java:515)
>                 at org.apache.reef.tang.implementation.java.
> InjectorImpl.getInstance(InjectorImpl.java:533)
>                 at org.apache.reef.tang.TestTang.
> testTcpProvider(TestTang.java:452)
>                 at sun.reflect.NativeMethodAccessorImpl.invoke0(Native
> Method)
>                 at sun.reflect.NativeMethodAccessorImpl.invoke(
> NativeMethodAccessorImpl.java:62)
>                 at sun.reflect.DelegatingMethodAccessorImpl.invoke(
> DelegatingMethodAccessorImpl.java:43)
>                 at java.lang.reflect.Method.invoke(Method.java:498)
>                 at org.junit.runners.model.FrameworkMethod$1.
> runReflectiveCall(FrameworkMethod.java:47)
>                 at org.junit.internal.runners.
> model.ReflectiveCallable.run(ReflectiveCallable.java:12)
>                 at org.junit.runners.model.FrameworkMethod.
> invokeExplosively(FrameworkMethod.java:44)
>                 at org.junit.internal.runners.statements.InvokeMethod.
> evaluate(InvokeMethod.java:17)
>                 at org.junit.internal.runners.statements.RunBefores.
> evaluate(RunBefores.java:26)
>                 at org.junit.rules.ExpectedException$
> ExpectedExceptionStatement.evaluate(ExpectedException.java:168)
>                 at org.junit.rules.RunRules.evaluate(RunRules.java:20)
>                 at org.junit.runners.ParentRunner.runLeaf(
> ParentRunner.java:271)
>                 at org.junit.runners.BlockJUnit4ClassRunner.runChild(
> BlockJUnit4ClassRunner.java:70)
>                 at org.junit.runners.BlockJUnit4ClassRunner.runChild(
> BlockJUnit4ClassRunner.java:50)
>                 at org.junit.runners.ParentRunner$3.run(
> ParentRunner.java:238)
>                 at org.junit.runners.ParentRunner$1.schedule(
> ParentRunner.java:63)
>                 at org.junit.runners.ParentRunner.runChildren(
> ParentRunner.java:236)
>                 at org.junit.runners.ParentRunner.access$000(
> ParentRunner.java:53)
>                 at org.junit.runners.ParentRunner$2.evaluate(
> ParentRunner.java:229)
>                 at org.junit.runners.ParentRunner.run(ParentRunner.
> java:309)
>                 at org.junit.runner.JUnitCore.run(JUnitCore.java:160)
>                 at com.intellij.junit4.JUnit4IdeaTestRunner.
> startRunnerWithArgs(JUnit4IdeaTestRunner.java:68)
>                 at com.intellij.rt.execution.
> junit.IdeaTestRunner$Repeater.startRunnerWithArgs(IdeaTestRunner.java:47)
>                 at com.intellij.rt.execution.junit.JUnitStarter.
> prepareStreamsAndStart(JUnitStarter.java:242)
>                 at com.intellij.rt.execution.junit.JUnitStarter.main(
> JUnitStarter.java:70)
>
>
> Process finished with exit code -1
>
>
>

Re: Tang "ambiguous subplan" exception when using Lists

Posted by Gyewon Lee <st...@gmail.com>.
Hi, Sharath.

As you say, it seems you haven't bound anything for "TcpPortList". I will
look into the Tang code and get back to you after I find the cause.

Best regards,
Gyewon

2018-06-19 7:57 GMT+09:00 Sharath Malladi <sh...@microsoft.com.invalid>:

> Hi,
>
> If I have a class that has multiple injectors (one of which injects a
> list), then I get an InjectionException about an "Ambiguous subplan".
> As you can see from the exception below, it assumes that I attempted to
> bind to an empty list, which I did not .. so there should be no ambiguity.
>
> Is there a work around for this issue.
>
> Thanks,
> Sharath.
>
> For example, here is the class with two injectors:
>
>
> class TcpPortProvider {
>   protected final List<String> list;
>   protected final String s;
>
>   @Inject
>   TcpPortProvider(@Parameter(TcpPortList.class) final List<String>
> tcpPortList) {
>     System.out.println("tcpPortList constructor");
>     this.list = tcpPortList;
>     this.s = "";
>   }
>
>
>   @Inject
>   TcpPortProvider(@Parameter(TcpPortListString.class) final String s) {
>     System.out.println("TcpPortListString constructor");
>     this.s = s;
>     this.list = null;
>   }
>
>   @NamedParameter
>   static class TcpPortList implements Name<List<String>> {
>   }
>
>   @NamedParameter
>   static class TcpPortListString implements Name<String> {
>   }
> }
>
>
> And here is the code to instantiate using injection where I only supplied
> argument for the injector that uses the string.
>
>
> final JavaConfigurationBuilder cb = tang.newConfigurationBuilder();
> cb.bindNamedParameter(TcpProvider.TcpPortListString.class, "this is a
> string");
> tang.newInjector(cb.build()).getInstance(TcpPortProvider.class);
>
>
>
> And here is the exception (note how it indicates that I also bound to an
> empty list):
>
> org.apache.reef.tang.exceptions.InjectionException: Cannot inject
> org.apache.reef.tang.TcpPortProvider Ambiguous subplan
> org.apache.reef.tang.TcpPortProvider
>   new TcpPortProvider(String TcpPortListString = this is a string)
>   new TcpPortProvider(list {
>  } )
> ]
>
>                 at org.apache.reef.tang.implementation.java.
> InjectorImpl.injectFromPlan(InjectorImpl.java:600)
>                 at org.apache.reef.tang.implementation.java.
> InjectorImpl.getInstance(InjectorImpl.java:515)
>                 at org.apache.reef.tang.implementation.java.
> InjectorImpl.getInstance(InjectorImpl.java:533)
>                 at org.apache.reef.tang.TestTang.
> testTcpProvider(TestTang.java:452)
>                 at sun.reflect.NativeMethodAccessorImpl.invoke0(Native
> Method)
>                 at sun.reflect.NativeMethodAccessorImpl.invoke(
> NativeMethodAccessorImpl.java:62)
>                 at sun.reflect.DelegatingMethodAccessorImpl.invoke(
> DelegatingMethodAccessorImpl.java:43)
>                 at java.lang.reflect.Method.invoke(Method.java:498)
>                 at org.junit.runners.model.FrameworkMethod$1.
> runReflectiveCall(FrameworkMethod.java:47)
>                 at org.junit.internal.runners.
> model.ReflectiveCallable.run(ReflectiveCallable.java:12)
>                 at org.junit.runners.model.FrameworkMethod.
> invokeExplosively(FrameworkMethod.java:44)
>                 at org.junit.internal.runners.statements.InvokeMethod.
> evaluate(InvokeMethod.java:17)
>                 at org.junit.internal.runners.statements.RunBefores.
> evaluate(RunBefores.java:26)
>                 at org.junit.rules.ExpectedException$
> ExpectedExceptionStatement.evaluate(ExpectedException.java:168)
>                 at org.junit.rules.RunRules.evaluate(RunRules.java:20)
>                 at org.junit.runners.ParentRunner.runLeaf(
> ParentRunner.java:271)
>                 at org.junit.runners.BlockJUnit4ClassRunner.runChild(
> BlockJUnit4ClassRunner.java:70)
>                 at org.junit.runners.BlockJUnit4ClassRunner.runChild(
> BlockJUnit4ClassRunner.java:50)
>                 at org.junit.runners.ParentRunner$3.run(
> ParentRunner.java:238)
>                 at org.junit.runners.ParentRunner$1.schedule(
> ParentRunner.java:63)
>                 at org.junit.runners.ParentRunner.runChildren(
> ParentRunner.java:236)
>                 at org.junit.runners.ParentRunner.access$000(
> ParentRunner.java:53)
>                 at org.junit.runners.ParentRunner$2.evaluate(
> ParentRunner.java:229)
>                 at org.junit.runners.ParentRunner.run(ParentRunner.
> java:309)
>                 at org.junit.runner.JUnitCore.run(JUnitCore.java:160)
>                 at com.intellij.junit4.JUnit4IdeaTestRunner.
> startRunnerWithArgs(JUnit4IdeaTestRunner.java:68)
>                 at com.intellij.rt.execution.
> junit.IdeaTestRunner$Repeater.startRunnerWithArgs(IdeaTestRunner.java:47)
>                 at com.intellij.rt.execution.junit.JUnitStarter.
> prepareStreamsAndStart(JUnitStarter.java:242)
>                 at com.intellij.rt.execution.junit.JUnitStarter.main(
> JUnitStarter.java:70)
>
>
> Process finished with exit code -1
>
>
>