title: Guice Inject annotation in scala
body: <p>I'm trying to create a custom elasticsearch plugin using scala by following the following <a href="http://www.citrine.io/blog/2015/2/24/building-a-custom-analyzer-in-lucene-part-two" rel="nofollow noreferrer">tutorial</a> (which is in Java).</p>
  
  <pre><code>public class PlusSignAnalyzerProvider extends
      AbstractIndexAnalyzerProvider {
  
          /* Constructor. Nothing special here. */
          @Inject
          public PlusSignAnalyzerProvider(Index index,
          @IndexSettings Settings indexSettings, Environment env,
          @Assisted String name, @Assisted Settings settings) throws IOException {
                  super(index, indexSettings, name, settings);
          }
  
          /* This function needs to be overridden to return an instance of
           * PlusSignAnalyzer.
           */
          @Override
          public PlusSignAnalyzer get() {
              return this.analyzer;
          }
  
          /* Instance of PlusSignAnalyzer class that is returned by this class. */
          protected PlusSignAnalyzer analyzer = new PlusSignAnalyzer();
  
          /* Name to associate with this class. We will use this in
           * PlusSignBinderProcessor.
           */
          public static final String NAME = "plus_sign";
      }
  </code></pre>
  
  <p>Trying to achieve this in scala I did the following:</p>
  
  <pre><code>@Inject class PlusSignAnalyzerProvider(index: Index,
                                     @IndexSettings indexSettings: Settings,
                                     env: Environment,
                                     @AssistedInject @Assisted name: String,
                                     @AssistedInject @Assisted settings: Settings)
    extends AbstractIndexAnalyzerProvider[PlusSignAnalyzer](index, indexSettings, name, settings) {
  
    val analyzer: PlusSignAnalyzer = new PlusSignAnalyzer()
  
    def NAME = "plus_sign"
  
    override def get(): PlusSignAnalyzer = {
      this.analyzer
    }
  }
  </code></pre>
  
  <p>which at runtime gives me an error:</p>
  
  <pre><code>Exception in thread "main" org.elasticsearch.common.inject.CreationException: Guice creation errors:
  
  1) Could not find a suitable constructor in com.xxxxxx.yyyyyyy.es.plugins.PlusSignAnalyzerProvider. Classes must have either one (and only one) constructor annotated with @Inject or a zero-argument constructor that is not private.
  at com.xxxxxx.yyyyyyy.es.plugins.PlusSignAnalyzerProvider.class(Unknown Source)
  at _unknown_
  
  1 error
      at org.elasticsearch.common.inject.internal.Errors.throwCreationExceptionIfErrorsExist(Errors.java:344)
      at org.elasticsearch.common.inject.InjectorBuilder.initializeStatically(InjectorBuilder.java:151)
      at org.elasticsearch.common.inject.InjectorBuilder.build(InjectorBuilder.java:102)
      at org.elasticsearch.common.inject.Guice.createInjector(Guice.java:93)
      at org.elasticsearch.common.inject.Guice.createInjector(Guice.java:70)
      at org.elasticsearch.common.inject.ModulesBuilder.createInjector(ModulesBuilder.java:59)
      at org.elasticsearch.node.internal.InternalNode.&lt;init&gt;(InternalNode.java:203)
      at org.elasticsearch.node.NodeBuilder.build(NodeBuilder.java:159)
  </code></pre>
  
  <p>[EDITED]: The following also doesn't work:</p>
  
  <pre><code>class PlusSignAnalyzerProvider @Inject() (index: Index,
                                     @IndexSettings indexSettings: Settings,
                                     env: Environment,
                                     @Assisted name: String,
                                     @Assisted settings: Settings)
  extends AbstractIndexAnalyzerProvider[PlusSignAnalyzer](index, indexSettings,   name, settings) {
  
    val analyzer: PlusSignAnalyzer = new PlusSignAnalyzer()
  
    def NAME = "plus_sign"
  
    override def get(): PlusSignAnalyzer = {
      this.analyzer
    }
  }
  </code></pre>
  
  <p>And the error thrown is:</p>
  
  <pre><code>  Exception in thread "main" org.elasticsearch.common.inject.CreationException: Guice creation errors:
  
  1) No implementation for java.lang.String annotated with @org.elasticsearch.common.inject.assistedinject.Assisted(value=) was bound.
    while locating java.lang.String annotated with @org.elasticsearch.common.inject.assistedinject.Assisted(value=)
      for parameter 3 at com.xxxxxx.yyyyyyy.es.plugins.PlusSignAnalyzerProvider.&lt;init&gt;(Unknown Source)
    at _unknown_
  
  2) No implementation for org.elasticsearch.common.settings.Settings annotated with @org.elasticsearch.common.inject.assistedinject.Assisted(value=) was bound.
    while locating org.elasticsearch.common.settings.Settings annotated with @org.elasticsearch.common.inject.assistedinject.Assisted(value=)
      for parameter 4 at com.xxxxxx.yyyyyyy.es.plugins.PlusSignAnalyzerProvider.&lt;init&gt;(Unknown Source)
    at _unknown_
  
  3) No implementation for org.elasticsearch.common.settings.Settings annotated with @org.elasticsearch.index.settings.IndexSettings() was bound.
    while locating org.elasticsearch.common.settings.Settings annotated with @org.elasticsearch.index.settings.IndexSettings()
      for parameter 1 at com.xxxxxx.yyyyyyy.es.plugins.PlusSignAnalyzerProvider.&lt;init&gt;(Unknown Source)
    at _unknown_
  
  4) Could not find a suitable constructor in org.elasticsearch.index.Index. Classes must have either one (and only one) constructor annotated with @Inject or a zero-argument constructor that is not private.
    at org.elasticsearch.index.Index.class(Unknown Source)
    while locating org.elasticsearch.index.Index
      for parameter 0 at com.xxxxxx.yyyyyyy.es.plugins.PlusSignAnalyzerProvider.&lt;init&gt;(Unknown Source)
    at _unknown_
  
  4 errors
      at org.elasticsearch.common.inject.internal.Errors.throwCreationExceptionIfErrorsExist(Errors.java:344)
      at org.elasticsearch.common.inject.InjectorBuilder.initializeStatically(InjectorBuilder.java:151)
      at org.elasticsearch.common.inject.InjectorBuilder.build(InjectorBuilder.java:102)
      at org.elasticsearch.common.inject.Guice.createInjector(Guice.java:93)
      at org.elasticsearch.common.inject.Guice.createInjector(Guice.java:70)
      at org.elasticsearch.common.inject.ModulesBuilder.createInjector(ModulesBuilder.java:59)
      at org.elasticsearch.node.internal.InternalNode.&lt;init&gt;(InternalNode.java:203)
      at org.elasticsearch.node.NodeBuilder.build(NodeBuilder.java:159)
  </code></pre>
  
  <p>On googling I ended up in SO links <a href="https://stackoverflow.com/questions/16316719/guice-assisted-injection-deeper-down-the-dependency-hierarchy">2</a>, <a href="https://stackoverflow.com/questions/23680901/guice-could-not-find-suitable-constructor-when-suitable-constructor-supplied">3</a></p>
  
  <p>But unfortunately, being a newbie I couldn't make out much out of it and rid my error. Can someone point me what needs to be rectified here.</p>
  
  <p>[EDITED:] Including the code for Module Object as well.</p>
  
  <pre><code>import org.elasticsearch.common.inject.AbstractModule
  
  class PlusSignBinderModule extends AbstractModule {
    override def configure(): Unit = {
      bind(classOf[PlusSignAnalyzerProvider]).asEagerSingleton()
    }
  }
  </code></pre>
  
  <p>Code for Plugin:</p>
  
  <pre><code>class MyFirstAnalyzerPlugin extends AbstractPlugin {
    override def description(): String = {
      "Custom elasticsearch analyzer plugin"
    }
  
    override def name(): String = {
      "my-analyzer"
    }
  
    override def modules(): Collection[Class[_ &lt;: Module]] = {
      val modules: Collection[Class[_ &lt;: Module]] = Lists.newArrayList()
      modules.add(classOf[PlusSignBinderModule])
      modules
    }
  }
  </code></pre>