I've read Google guice - multibinding + generics + assistedinject but it doesn't seem to answer my specific scenario. Here's what i have:
The interfaces to use with FactoryModuleBuilder
public interface IFilterFactory<T extends IFilter> {
T create(FilterConfig config);
}
public interface IFilterOneFactory extends IFilterFactory<FilterOne> {}
public interface IFilterTwoFactory extends IFilterFactory<FilterTwo> {}
My Guice module:
@Override
protected void configure() {
install(new FactoryModuleBuilder().build(IFilterOneFactory.class));
install(new FactoryModuleBuilder().build(IFilterTwoFactory.class));
Multibinder<IFilterFactory<?>> filterBinder = Multibinder.newSetBinder(binder(), new TypeLiteral<IFilterFactory<?>>() {});
filterBinder.addBinding().to(IFilterOneFactory.class);
filterBinder.addBinding().to(IFilterTwoFactory.class);
}
My main filter that is supposed to combine all other filters:
public class MainFilterFactory {
@Inject
MainFilterFactory(Set<IFilterFactory<?>> factories) {
this.factories = factories;
}
public MainFilter get(String groupKey) {
FilterConfig fc = new FilterConfig(groupKey);
IFilter[] filters = this.factories.stream().map(f -> f.create(fc)).toArray(IFilter[]::new);
return new MainFilter(Arrays.asList(filters));
}
}
That actually doesn't work. And i get the following stacktraces:
[WARNING]
java.lang.reflect.InvocationTargetException
at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:62)
at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)
at java.lang.reflect.Method.invoke(Method.java:497)
at org.codehaus.mojo.exec.ExecJavaMojo$1.run(ExecJavaMojo.java:297)
at java.lang.Thread.run(Thread.java:745)
[WARNING]
com.google.inject.internal.util.$ComputationException: java.lang.ArrayIndexOutOfBoundsException: 19640
at com.google.inject.internal.util.$MapMaker$StrategyImpl.compute(MapMaker.java:553)
at com.google.inject.internal.util.$MapMaker$StrategyImpl.compute(MapMaker.java:419)
at com.google.inject.internal.util.$CustomConcurrentHashMap$ComputingImpl.get(CustomConcurrentHashMap.java:2041)
at com.google.inject.internal.util.$StackTraceElements.forType(StackTraceElements.java:70)
at com.google.inject.internal.Errors.formatSource(Errors.java:687)
at com.google.inject.internal.Errors.format(Errors.java:555)
at com.google.inject.CreationException.getMessage(CreationException.java:48)
at java.lang.Throwable.getLocalizedMessage(Throwable.java:391)
at java.lang.Throwable.toString(Throwable.java:480)
at java.lang.String.valueOf(String.java:2982)
at java.lang.StringBuilder.append(StringBuilder.java:131)
at java.lang.Throwable.printEnclosedStackTrace(Throwable.java:695)
at java.lang.Throwable.printStackTrace(Throwable.java:667)
at java.lang.Throwable.printStackTrace(Throwable.java:643)
at org.apache.maven.cli.PrintStreamLogger.warn(PrintStreamLogger.java:131)
at org.apache.maven.monitor.logging.DefaultLog.warn(DefaultLog.java:93)
at org.codehaus.mojo.exec.ExecJavaMojo$IsolatedThreadGroup.uncaughtException(ExecJavaMojo.java:386)
at org.codehaus.mojo.exec.ExecJavaMojo$1.run(ExecJavaMojo.java:309)
at java.lang.Thread.run(Thread.java:745)
Caused by: java.lang.ArrayIndexOutOfBoundsException: 19640
at com.google.inject.internal.asm.$ClassReader.<init>(Unknown Source)
at com.google.inject.internal.asm.$ClassReader.<init>(Unknown Source)
at com.google.inject.internal.asm.$ClassReader.<init>(Unknown Source)
at com.google.inject.internal.util.$LineNumbers.<init>(LineNumbers.java:62)
at com.google.inject.internal.util.$StackTraceElements$1.apply(StackTraceElements.java:36)
at com.google.inject.internal.util.$StackTraceElements$1.apply(StackTraceElements.java:33)
at com.google.inject.internal.util.$MapMaker$StrategyImpl.compute(MapMaker.java:549)
... 18 more
Am I doing anything wrong here ?
This is actually a Guice compatibility issue between Guice 3.0 and Java 8. See: https://github.com/google/guice/issues/757
I was missing some @Assisted
and @Inject
in the constructors and Guice failed to report the error because some lambdas were used in those classes.
Commenting the lambdas allowed me to see the errors and fix them. I then Uncommented them and everything seems to work as intended.