1
votes
class ClassA {
    protected ClassA(Injector baseGraph, 
                     BlobStoreContext context,
                     SwiftApi api,
                     @Memoized Supplier<Set<? extends Location>> locations,
                     @Assisted String regionId,PayloadSlicer slicer,
                     @Named(PROPERTY_USER_THREADS) ListeningExecutorService userExecutor) {
     }
}

class ClassB extends ClassA {
    protected ClassB(Injector baseGraph,
                     BlobStoreContext context,
                     SwiftApi api,
                     @Memoized Supplier<Set<? extends Location>> locations,
                     @Assisted String regionId,
                     PayloadSlicer slicer,
                     @Named(PROPERTY_USER_THREADS) ListeningExecutorService userExecutor) {
        super(baseGraph, context, api, locations, regionId, slicer, userExecutor);
    }

}

class C extends AbstractModule {

    protected void configure() {
        bind(classA).to(classB);
    }
}

There some problem in the constructor args while binding.

Error that am getting

Caused by: com.google.inject.CreationException: Guice creation errors:

1) No implementation for java.lang.String annotated with @com.google.inject.assistedinject.Assisted(value=) was bound. while locating java.lang.String annotated with @com.google.inject.assistedinject.Assisted(value=) for parameter 4 at

1
Why do you call constructor of the superclass of ClassB in ClassB's constructor? This is normally not advised. - Grzegorz Górkiewicz

1 Answers

0
votes

@Assisted is used in the context of assisted injection, which is a Guice feature that automatically implements a factory for you that mixes normal constructor parameters with Guice-provided parameter injections. For instance, here:

class ClassB extends ClassA {
    protected ClassB(Injector baseGraph,
                     BlobStoreContext context,
                     SwiftApi api,
                     @Memoized Supplier<Set<? extends Location>> locations,
                     @Assisted String regionId,
                     PayloadSlicer slicer,
                     @Named(PROPERTY_USER_THREADS) ListeningExecutorService userExecutor) {
        super(baseGraph, context, api, locations, regionId, slicer, userExecutor);
    }

}

I would expect to see this interface:

public interface ClassBFactory {
  ClassB create(String regionId);
}

Which you would then bind in your AbstractModule subclass like this:

install(new FactoryModuleBuilder().build(ClassBFactory.class));

Guice can then inspect the ClassBFactory interface, observe the ClassB return value, match the String regionId parameter of create to the @Assisted String regionId parameter of your constructor, and then provide this ClassBFactory instance to your graph. At that point, rather than injecting ClassB, you inject a ClassBFactory and then call classBFactory.create("foo") to create a ClassB with its regionId set to "foo".

However, if you try to inject ClassB rather than ClassBFactory, Guice will not give your @Assisted annotation any special treatment, and will not be able to inject that field. Search your codebase to see if a factory interface exists, and if not, you'll need to create one (or otherwise redesign your constructor).