Как создать ConfigObject, используя только вложенные карты в Grails?

Можно ли реализовать закрывающий конфиг в виде карты карт?

grails {
  acme {
     host = 'localhost'
     poolSettings {
        timeout = 5000
     }
  }
}

Приведенный выше конфиг является соглашением для плагина Grails. Мы осуществляем миграцию, и из-за устаревших ограничений нам необходимо динамически создавать конфигурацию, чтобы исключить влияние на устаревший код.

Я начал с простого конфига:

grails.acme = [host:'localhost']

Это прекрасно работает с плагином при запуске, поэтому я добавил вложенную карту:

grails.acme = [host:'localhost']
def poolProps = //do some work to get pool settings
grails.acme << [poolSettings:poolProps]

При запуске я довольно печатаю grails.acme:

{
    "host": "locahost",
    "poolSettings": {
        "timeout": 5000
    }
}

Это выглядит нормально, но вскоре после плагина acme происходит сбой со следующей ошибкой:

2014-09-27 23: 27: 07,460 [localhost-startStop-1] ERROR context.GrailsContextLoader - Ошибка при инициализации приложения: нет подписи метода: AcmePlugin$_closure2_closure5_closure9 .doCall() применим для типов аргументов: (grails.spring.BeanBuilder) значения: [grails.spring.BeanBuilder@7b067fd7] Возможные решения: doCall(java.lang.Object, java.lang.Object), call(), call([Ljava.lang.Object;), call(java.lang.Object), call(java.lang.Object, java.lang.Object), findAll() Сообщение: нет подписи метода: AcmeGrailsPlugin$_closure2_closure5_closure9.doCall() применимо для типов аргументов: (grails.spring.BeanBuilder) значения: [grails.spring.BeanBuilder@7b067 fd7] Возможные решения: doCall (java.lang.Object, java.lang.Object), call (), call ([Ljava.lang.Object;), call (java.lang)..Object), вызов (java.lang.Object, java.lang.Object)

Я немного озадачен этим, я предполагаю, что это невозможно, и я не уверен, как даже приблизиться к соглашению на основе замыканий динамически.

2 ответа

Решение

Одна проблема с вашим кодом может заключаться в том, что структура узла конфигурации выглядит отлично, но на самом деле это не так. Т.е. что некоторые узлы Map случаи, но не ConfigObject экземпляров.

В большинстве случаев это, вероятно, не будет иметь значения, но в вашем случае кажется, что сторонний плагин дает сбой с некоторым уродливым и непонятным исключением.

Я не могу воссоздать вашу проблему, поэтому не могу с уверенностью сказать, является ли это реальной проблемой, с которой вы столкнулись, или предлагаемое решение решило вашу проблему. Тем не менее, моей первой попыткой было бы исправить типы так, чтобы все узлы в дереве конфигурации имели тип ConfigObject, Что-то вроде этого:

def poolProps = [timeout: 5000] as ConfigObject // convert type to ConfigObject
grails.acme.host = 'localhost'
grails.acme << [ poolSettings : poolProps ]

Обратите внимание, что если создаваемые вами карты (в данном случае poolProps) содержат вложенные элементы карты, вам также придется конвертировать их.

Да это возможно, на самом деле

grails {
   acme {
      host = 'localhost'
      poolSettings {
         timeout = 5000
      }
   }
}

такой же как:

grails.acme.host = 'localhost'
grails.acme.poolSettings.timeout = 5000

замыкания - это просто синтаксический сахар. Вы даже можете комбинировать оба типа:

grails.acme {
   host = 'localhost'
   poolSettings.timeout = 5000
}
Другие вопросы по тегам