Search code examples
kotlingenericsguice

Cannot inject List<String> for class extending Java Class


Getting below error while trying to Inject List of String into a class constructor. I am extending AbstractDelegator java class as CancelDelegator. AbstractDelegator is referenced from a dependency jar so I can't change that.

No implementation for java.util.List<java.lang.String> annotated with @com.google.inject.name.Named(value=CANCEL_TASKS) was bound.
while locating java.util.List<java.lang.String> annotated with @com.google.inject.name.Named(value=CANCEL_TASKS)
for parameter 1 at com.cancel.core.delegator.CancelDelegator.<init>(CancelDelegator.kt:18). 
at com.cancel.core.config.CancelModule.configure(CancelModule.kt:45)

Following are the classes:

AbstractDelegator.java ( from dependency jar)

public abstract class AbstractDelegator<T extends Request, R extends Response> implements Delegator<T, R> {
    protected final Logger logger = LoggerFactory.getLogger(this.getClass());
    protected Processor<T, R> processor;
    protected List<String> taskSequence;

    protected AbstractDelegator(Processor<T, R> processor, List<String> taskSequence) {
        this.processor = processor;
        this.taskSequence = taskSequence;
    }
 }

CancelDelegator.kt

@Singleton
class CancelDelegator @Inject constructor(
  @Named(CancelConstant.CANCEL_PROCESSOR) processor: Processor<Request?, Response?>?,
  @Named(CancelConstant.CANCEL_TASKS) taskSequence: List<String?>?
) : AbstractDelegator<Request?, Response?>(processor, taskSequence)

GuiceModule.kt

bind<Delegator<Request?, Response?>?>(object : TypeLiteral<Delegator<Request?, Response?>?>() {})
      .annotatedWith(Names.named(CancelConstant.CANCEL_DELEGATOR))
      .to(CancelDelegator::class.java)

bind<List<String?>?>(object : TypeLiteral<List<String?>?>() {})
  .annotatedWith(Names.named(CancelConstant.CANCEL_TASKS))
  .toInstance(Arrays.asList(CancelConstant.CANCEL_PENALTY_TASK))

Its only the List that Guice is not able to inject. Other injections are working fine. I have tried changing List<String?>? to List<String?> and List but nothing seems to work.


Solution

  • Like explained in this GitHub issue,

    var setA: Set<Runnable>
    var setB: MutableSet<Runnable>
    

    is equivalent to the following in Java:

    Set<? extends Runnable> setA;
    Set<Runnable> setB;
    

    You can fix it with the @JvmSuppressWildcards annotation. Something like the following:

    bind(object : TypeLiteral<List<@JvmSuppressWildcards String>>() {})
        .annotatedWith(Names.named(CancelConstant.CANCEL_DELEGATOR))
        .toInstance(listOf("hello", "goodbye"))