我有以下Groovy类:

enum Protocol {
    File,
    Ftp,
    Sftp,
    Http,
    Https
}

@Canonical
abstract class Endpoint {
    String name
    Protocol protocol
}

@Canonical
@TupleConstructor(includeFields=true, includeSuperFields=true)
class LocalEndpoint extends Endpoint {
}

class MyAppModule extends AbstractModule {
    @Override
    protected void configure() {
        // Lots of stuff...
    }

  // Lots of other custom providers

  @Provides
    Endpoint providesEndpoint() {
        new LocalEndpoint('fileystem', Protocol.File)
    }
}


不必担心为什么我为Endpoint使用自定义提供程序,而不仅仅是:

bind(Endpoint).toInstance(new LocalEndpoint('fileystem', Protocol.File))


我99.999%的人认为这不在此问题之内,并且以这种方式进行编码,因为完整(非常大)的代码是如何连接的。

我的问题是,Guice和/或Groovy无法找到采用LocalEndpointString参数的Protocol构造函数:

1) Error in custom provider, groovy.lang.GroovyRuntimeException: Could not find matching constructor for: com.example.myapp.model.LocalEndpoint(java.lang.String, com.example.myapp.model.Protocol)
  at com.example.myapp.inject.MyAppModule.providesEndpoint(MyAppModule.groovy:130)
  while locating com.example.myapp.model.Endpoint
    for parameter 2 at com.example.myapp.inject.MyAppModule.providesConfig(MyAppModule.groovy:98)
  at com.example.myapp.inject.MyAppModule.providesConfig(MyAppModule.groovy:98)
  while locating com.example.myapp.config.MyAppConfig


然后,它吐出一个大堆栈跟踪,并列出以下原因:

Caused by: groovy.lang.GroovyRuntimeException: Could not find matching constructor for: com.example.myapp.model.LocalEndpoint(java.lang.String, com.example.myapp.model.Protocol)
        at groovy.lang.MetaClassImpl.invokeConstructor(MetaClassImpl.java:1731)
        at groovy.lang.MetaClassImpl.invokeConstructor(MetaClassImpl.java:1534)


希望通过修改Endpoint和/或LocalEndpoint可以对此进行调整,也许我需要将一些特殊参数传递到@Canonical / @TupleConstructor批注中。有任何想法吗?

最佳答案

我认为您需要在includeSuperProperties批注中添加TupleConstructor,这似乎可以解决它,即使是单独解决:

@TupleConstructor(includeSuperProperties=true)

因此,整个过程将是:

@Canonical
abstract class Endpoint {
    String name
    Protocol protocol
}

@Canonical // You may not need this anymore
@TupleConstructor(includeSuperProperties=true)
class LocalEndpoint extends Endpoint {
}

09-07 16:41