javadependency-injectionguiceguice-3

Creating an instance using factory with assisted parameters throws exception with Google Guice


I have an interface with two implementations

public interface JobConfiguration {
    void execute();
}

DecryptJobConfiguration:

public class DecryptJobConfiguration implements JobConfiguration {
    @Inject
    public DecryptJobConfiguration(@Assisted("secretKey") String secretKey,
                                   @Assisted("inputImagePath") String inputImagePath,
                                   ImageDecrypter imageDecrypter) {
        // Do stuff
    }

    @Override
    public void execute(){
        // DO stuff
    }
}

EncryptJobConfiguration:

public class EncryptJobConfiguration implements JobConfiguration {
    @Inject
    public EncryptJobConfiguration(@Assisted("inputString") String inputString,
                                   @Assisted("secretKey") String secretKey,
                                   @Assisted("inputImagePath") String inputImagePath,
                                   ImageEncrypter imageEncrypter,
        // Do stuff
    }

    @Override
    public void execute() {
        // Do stuff
    }
}

I have a factory interface:

public interface JobConfigurationFactory {
    @Named("encrypt")
    JobConfiguration createEncrypt(@Assisted("inputString") String inputString,
                                   @Assisted("secretKey") String secretKey,
                                   @Assisted("inputImagePath") String inputImagePath);

    @Named("decrypt")
    JobConfiguration createDecrypt(@Assisted("secretKey") String secretKey,
                                   @Assisted("inputImagePath") String inputImagePath);
}

Which is installed in Google Guice:

install(new FactoryModuleBuilder()
        .implement(JobConfiguration.class, Names.named("encrypt"), EncryptJobConfiguration.class)
        .implement(JobConfiguration.class, Names.named("decrypt"), DecryptJobConfiguration.class)
        .build(JobConfigurationFactory.class));

In another class where I wish to create an instance of EncryptJobConfiguration I inject JobConfigurationFactory:

@Inject
public CommandLineArgumentValidator(JobConfigurationFactory jobConfigurationFactory){
    this.jobConfigurationFactory = jobConfigurationFactory;
}

and later in one of the methods I call createEncrypt:

jobConfigurationFactory.createEncrypt("A", "B", "C");

I would expect this to return me an instance of EncryptJobConfiguration, but it results in this exception:

java.lang.NoSuchMethodError: com.google.common.base.Preconditions.checkState(ZLjava/lang/String;Ljava/lang/Object;)V

at com.google.inject.assistedinject.FactoryProvider2.invoke(FactoryProvider2.java:824) at com.sun.proxy.$Proxy12.createEncrypt(Unknown Source) at com.infojolt.imageencrypt.CommandLineArgumentValidator.validateArguments(CommandLineArgumentValidator.java:29) at com.infojolt.imageencrypt.CommandLineArgumentValidatorTest.validateArgumentsReturnsInputStringWhenAllRequiredFieldsAreSet(CommandLineArgumentValidatorTest.java:55) at java.base/jdk.internal.reflect.NativeMethodAccessorImpl.invoke0(Native Method)

This is my first time using Google Guice and I'm not sure if I am misunderstanding how it should work? How should I create a new instance of EncryptJobConfiguration?


Solution

  • It turns out I missed an important piece of information from the question. I was using Google Guice 4.0. Upgrading to v4.2 resolved the problem without any other code changes.