2

I've 2 interfaces and 2 implementations like below.

  • KafkaConsumerExecutor (Interface)
  • DefaultExecutor (Implementation of 1)
  • ConsumerRecordsProcessor (Interface)
  • LastOnlyRecordsProcessor (Impl of 3.)

--

public interface KafkaConsumerExecutor {
        void start();
        void stop();
}

public class DefaultExecutor<MESSAGE_TYPE> implements KafkaConsumerExecutor {
    private final ConsumerRecordsProcessor<MESSAGE_TYPE> consumerRecordsProcessor;

@Override
public void start(){}
    //processStuff
}

@Override
public void stop(){}
    //kill
}

public interface ConsumerRecordsProcessor<MESSAGE_TYPE> {

    void process(Iterable<ConsumerRecord<String, MESSAGE_TYPE>> consumerRecords);
}

--

public class LastOnlyRecordsProcessor<MESSAGE_TYPE extends Serializable> implements ConsumerRecordsProcessor<MESSAGE_TYPE> {
    public void process(Iterable<ConsumerRecord<String, MESSAGE_TYPE>> consumerRecords){
     // process stuff.
    }
}

Finally, I have the class where I call start the executor.

@Inject
public KafkaListenerManagerImpl(ConsumerExecutor consumerExecutor) {
    this.consumerExecutor= consumerExecutor;
}

And my problem is, I cannot bind my generic implementation DefaultExecutor<String> to ConsumerExecutor

The ways I tried is;

1.

bind(new TypeLiteral<DefaultExecutor<String>>() {}).to(new TypeLiteral<ConsumerExecutor>(){});
bind(LastOnlyRecordsProcessor.class).to(new TypeLiteral<ConsumerRecordsProcessor<Request>>() {});

This one fails with Caused by: java.lang.IllegalArgumentException: argument type mismatch

2.

bind(DefaultExecutor.class).to(new TypeLiteral<ConsumerExecutor>() {});
bind(LastOnlyRecordsProcessor.class).to(new TypeLiteral<ConsumerRecordsProcessor<String>>() {});

This one looks better , but then It can't find the perspective however then I don't have the binding for Processor.

UnsatisfiedDependencyException: There was no object available for injection at SystemInjecteeImpl(requiredType=ConsumerRecordsProcessor<MESSAGE_TYPE>,parent=DefaultExecutor,qualifiers={},position=1,optional=false,self=false,unqualified=null,1237264838)
  1.   bind(DefaultExecutor.class).to(new TypeLiteral<ConsumerExecutor>() {});
      bind(new TypeLiteral<LastOnlyRecordsProcessor<String>>() {}).to(new TypeLiteral<ConsumerRecordsProcessor<String>>() {});
    

Again the same;

Caused by: org.glassfish.hk2.api.UnsatisfiedDependencyException: There was no object available for injection at SystemInjecteeImpl(requiredType=ConsumerRecordsProcessor<MESSAGE_TYPE>,parent=DefaultExecutor,qualifiers={},position=1,optional=false,self=false,unqualified=null,202064342)

Question in a nutshell is that,

  1. I want to bind the DefaultExecutor to ConsumerExecutor.
  2. LastRecordsOnlyProcessor to ConsumerRecordsProcessor

I don't have much hope, but do you guys see where am I doing wrong?

Thanks in advance.

Bleach
  • 309
  • 3
  • 18

1 Answers1

-1

This may be the issue.

 public class Main {
    public static void main(String[] args) {
        Injector injector = Guice.createInjector(new MyModule());
        KafkaListenerManagerImpl kafkaListenerManager = injector.getInstance(KafkaListenerManagerImpl.class);
    }
}
class MyModule extends AbstractModule {
    @Override
    protected void configure() {
        bind(new TypeLiteral<ConsumerExecutor<String>>(){}).to(DefaultExecutor.class);
        bind(new TypeLiteral<ConsumerRecordsProcessor<String>>(){}).to(LastOnlyRecordsProcessor.class);
    }
}

In this example, the MyModule class binds the DefaultExecutor<String> implementation to the ConsumerExecutor interface, and the LastOnlyRecordsProcessor implementation to the ConsumerRecordsProcessor interface.

Change;

bind(new TypeLiteral<ConsumerExecutor<String>>(){}).to(DefaultExecutor.class);

to;

bind(ConsumerExecutor.class).to(DefaultExecutor.class);

and

bind(new TypeLiteral<ConsumerRecordsProcessor<String>>(){}).to(LastOnlyRecordsProcessor.class);

to;

bind(ConsumerRecordsProcessor.class).to(LastOnlyRecordsProcessor.class);

You have to make sure that you have imported the correct dependencies and classes.

Also, in KafkaListenerManagerImpl class, you should be injecting the ConsumerExecutor<String> instead of ConsumerExecutor:

@Inject
public KafkaListenerManagerImpl(ConsumerExecutor<String> consumerExecutor) {
    this.consumerExecutor= consumerExecutor;
}

Hope that helped.

Zac1
  • 208
  • 7
  • 34