Search code examples
javadependency-injectionguiceguice-3

Guice Assisted : No implementation for java.lang.String annotated with @com.google.inject.assistedinject.Assisted(value=prefix) was bound


I've done this a million of times, but right now it's not working and I don't know why !

I've my interface that defines the contract of the Writers like :

public interface Writer {
    
    void exit() throws IOException;

    void write(String row) throws IOException;
}

Concrete implementation :

import com.google.inject.assistedinject.Assisted;
import javax.inject.Inject;


public class TextFileWriter implements Writer {

    //...
    @Inject
    public TextFileWriter(@Assisted("store") String store, @Assisted("prefix") String prefix, @Assisted Line line, @Assisted LocalDate date) throws IOException {
    //...
    }

    //...
}

Now the factory :

public interface WriterFactory {
    
    Writer textWriter(String store, String prefix, Line line, LocalDate date) throws IOException;
}

And finally my config :

@Override
protected void configure() {
    install(new FactoryModuleBuilder()
            .implement(Writer.class, TextFileWriter.class)
            .build(WriterFactory.class)
    );
}

With all of this at the startup it throws an exception that is saying :

  1. No implementation for java.lang.String annotated with @com.google.inject.assistedinject.Assisted(value=prefix) was bound.
    while locating java.lang.String annotated with @com.google.inject.assistedinject.Assisted(value=prefix) for the 2nd parameter of daemons.filerecorder.TextFileWriter.(TextFileWriter.java:38)
    at daemons.filerecorder.WriterFactory.textWriter(WriterFactory.java:1) at com.google.inject.assistedinject.FactoryProvider2.initialize(FactoryProvider2.java:666) at com.google.inject.assistedinject.FactoryModuleBuilder$1.configure(FactoryModuleBuilder.java:335) (via modules: com.google.inject.util.Modules$OverrideModule -> modules.GuiceConfig -> com.google.inject.assistedinject.FactoryModuleBuilder$1)

  2. No implementation for java.lang.String annotated with @com.google.inject.assistedinject.Assisted(value=store) was bound.
    while locating java.lang.String annotated with @com.google.inject.assistedinject.Assisted(value=store) for the 1st parameter of daemons.filerecorder.TextFileWriter.(TextFileWriter.java:38)
    at daemons.filerecorder.WriterFactory.textWriter(WriterFactory.java:1) at com.google.inject.assistedinject.FactoryProvider2.initialize(FactoryProvider2.java:666) at com.google.inject.assistedinject.FactoryModuleBuilder$1.configure(FactoryModuleBuilder.java:335) (via modules: com.google.inject.util.Modules$OverrideModule -> modules.GuiceConfig -> com.google.inject.assistedinject.FactoryModuleBuilder$1)

  3. A binding to java.lang.String annotated with @com.google.inject.assistedinject.Assisted(value=) was already configured at daemons.filerecorder.WriterFactory.textWriter(). at daemons.filerecorder.WriterFactory.textWriter(WriterFactory.java:1)
    at com.google.inject.assistedinject.FactoryProvider2.initialize(FactoryProvider2.java:666) at com.google.inject.assistedinject.FactoryModuleBuilder$1.configure(FactoryModuleBuilder.java:335) (via modules: com.google.inject.util.Modules$OverrideModule -> modules.GuiceConfig -> com.google.inject.assistedinject.FactoryModuleBuilder$1)

Any idea to get this work ?

Thanks in advance.


Solution

  • Add @Assisted to the ambiguous String-typed parameters of the interface

    You're missing the @Assisted parameter on the factory method. So adapt as follow:

    public interface WriterFactory {
      Writer textWriter(@Assisted("store") String store, @Assisted("prefix") String prefix, Line line, LocalDate date) throws IOException;
    }
    

    This is explained in the FactoryModuleBuilder javadoc, section "Making parameter types distinct". It's mandatory because you have two parameters with the same type, String.