5

I have a Guice module that has a @Provides method that takes 2 parameters and returns the implementation of the interface:

public class **ClientModule** extends **AbstractModule**{

@Override
protected void configure(){

}

@Singleton
@Provides
protected ClientInterfaces provideService(String param1, String param2){
   returns something
 }

}

In my main class that injects the module, how do I pass the params to the @Provides method?

public MainClass{
main(){
Injector injector = Guice.createInjector( new ClientModule());
MainClass mainClass = injector.getInstance(MainClass.class);

}

This throws a Null pointer exception param1

jwesonga
  • 4,249
  • 16
  • 56
  • 83
  • You must declare bindings in your Guice-module to the parameters in the `provideService` method. – eiden Aug 27 '12 at 08:26

2 Answers2

7

You don't call a provides method yourself, it is called by Guice when you first need to access (in this case) your ClientInterfaces Implementation.

I assume, you need configuration parameters to initialize your ClientInterfaces.

So try Binding-Annotation, the simplest is @Named:

configure() {
   bindConstant().annotatedWith(Names.named("hostName")).to("myHost");
   bindConstant().annotatedWith(Names.named("port")).to("8080");
}
@Provides
@Singleton
public MyService provideMyService(@Named("hostName") String host, @Named("port") String port) {
   // init MyService 
   return ....
}

Of course, you normally will read myHost and "8080" from a properties file System.props instead of hard coding constants.

The first time you need to Inject a MyService, Guice will notice that it needs to annotated Strings to fulfill the requirements of the provide method and search for the values bound to the Annotatioon name ...

Hunsu
  • 3,281
  • 7
  • 29
  • 64
Jan Galinski
  • 11,768
  • 8
  • 54
  • 77
  • 1
    I would suggest custom binding annotations in preference to using @Named: http://code.google.com/p/google-guice/wiki/BindingAnnotations. It's more code, but I like the compile-time checking and the fact that any IDE's rename refactoring will work on the custom annotation. – smjZPkYjps Aug 27 '12 at 21:44
  • 1
    Absolutely. But I assumed a beginners level here and didnt want to open another barrel ... – Jan Galinski Aug 28 '12 at 12:11
  • That's sad. There is no reason why Guice couldn't allow an easy interface to pass in custom properties at runtime through Java, rather than forcing clients to pass config parameters through environment variables. There are practical reasons to do so in corporate environments. – html_programmer Oct 31 '22 at 12:19
2

You don't pass parameters to the provider method. Guice needs to be able to create the parameters itself. It doesn't make sense for you to pass the parameters yourself because then there's no need for Guice.

If you want Guice to be able to provide the parameters to provideService, those parameters will either need a binding annotation on each parameter. Since they both have the same type, Guice can't know which String values it knows how to provide should be passed for which parameter.

If you know what to pass for param1 and param2 from your main code path, then move provideService somewhere that it can be called directly. No need for Guice in that situation.

smjZPkYjps
  • 1,168
  • 8
  • 12
  • I find this answer more confusing than helpful. So, everytime I know, what (configuration) parameters a ServiceProvider needs, there is no need for Guice? – Jan Galinski Aug 27 '12 at 20:47
  • You're right. I up-voted your response since mine was hastily put together and is misleading, whereas your code example makes things very clear. – smjZPkYjps Aug 27 '12 at 21:27