如何在Grails中仅使用嵌套地图创建ConfigObject? [英] How to create ConfigObject using only nested maps in Grails?

查看:103
本文介绍了如何在Grails中仅使用嵌套地图创建ConfigObject?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述


$ b

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

上面的配置是针对grails插件的约定。我们正在进行迁移,并且由于传统约束,我们需要动态创建配置以消除对传统代码的影响。



我从一个简单的配置开始:

  grails.acme = [host:'localhost'] 

这个插件在启动时可以正常工作,所以我添加了一个嵌套map:

  grails.acme = [host:'localhost'] 
def poolProps = //做一些工作获取游泳池设置
grails.acme<< [poolSettings:poolProps]

在启动时我漂亮地打印 grails.acme
$ p $ {
host:locahost,
poolSettings :{
timeout:5000
}
}

它看起来很正常,但在acme插件失败后不久出现以下错误:


2014-09-27 23:27:07,460 [localhost -startStop-1]错误
context.GrailsContextLoader - 初始化应用程序时出错:无
方法签名:AcmePlugin $ _closure2_closure5_closure9 .doCall()
适用于参数类型:(grails.spring。 BeanBuilder)values:
[grails.spring.BeanBuilder@7b067fd7]可能的解决方案:
doCall(java.lang.Object,java.lang.Object),call(),
call([ Ljava.lang.Object;),调用(java.lang.Object),
调用(java.lang.Object,java.lang.Object),findAll()消息:无
方法的签名:
AcmeGrailsPlugin $ _closure2_closur可能的解决方案:
doCall(java.lang.String) (Object,java.lang.Object),call(),
call([Ljava.lang.Object;),call(java.lang.Object),
call(java.lang.Object, java.lang.Object)


我对此有点不解,我假设这是不可能的,而我不知道如何动态地接近基于闭包的约定。

解决方案

代码的一个问题可能是配置节点结构看起来完全没问题,但事实上并非如此。即某些节点是 Map 实例,但不是 ConfigObject 实例。



在大多数情况下,这可能无关紧要,但就您的情况而言,第三方插件似乎失败并带有一些难以理解且难以理解的异常。



我无法重现您的问题,因此我无法确定这是您遇到的真正问题,还是建议的解决方案能否解决您的问题。不过,我的第一个尝试是修复类型,使配置树中的所有节点的类型都是 ConfigObject 。像这样:

  def poolProps = [timeout:5000]作为ConfigObject //将类型转换为ConfigObject 
grails。 acme.host ='localhost'
grails.acme<<请注意,如果您创建的地图(本例中为poolProps)包含嵌套地图元素,你将不得不转换这些。

It is possible to implement closure-based config as a map of maps?

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

The above config is convention for a grails plugin. We're doing a migration, and due to legacy constraints, we need to create the config dynamically to eliminate impact to legacy code.

I started with a simple config:

grails.acme = [host:'localhost']

This works fine with the plugin on startup, so I added a nested map:

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

On startup I pretty print grails.acme:

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

It looks normal, but soon after the acme plugin fails with the following error:

2014-09-27 23:27:07,460 [localhost-startStop-1] ERROR context.GrailsContextLoader - Error initializing the application: No signature of method: AcmePlugin$_closure2_closure5_closure9 .doCall() is applicable for argument types: (grails.spring.BeanBuilder) values: [grails.spring.BeanBuilder@7b067fd7] Possible solutions: doCall(java.lang.Object, java.lang.Object), call(), call([Ljava.lang.Object;), call(java.lang.Object), call(java.lang.Object, java.lang.Object), findAll() Message: No signature of method: AcmeGrailsPlugin$_closure2_closure5_closure9.doCall() is applicable for argument types: (grails.spring.BeanBuilder) values: [grails.spring.BeanBuilder@7b067 fd7] Possible solutions: doCall(java.lang.Object, java.lang.Object), call(), call([Ljava.lang.Object;), call(java.lang.Object), call(java.lang.Object, java.lang.Object)

I'm sort of stumped on this, I'm assuming it's not possible, and I'm not sure how to even approach the closure-based convention dynamically.

解决方案

One problem with your code might be that the config node structure looks perfectly all right, but in fact isn't. I.e. that some nodes are Map instances, but not ConfigObject instances.

In most cases this probably won't matter, but in your case it seems that a 3rd party plugin fails with some ugly and incomprehensible exception.

I'm unable to recreate your problem, so I can't say for sure whether this is the real problem that you've encountered, nor whether the suggested solution fix your problem. Nevertheless, my first attempt would be to fix the types so that all nodes in the configuration tree are of type ConfigObject. Something like this:

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

Note that if the maps you create (poolProps in this case) contains nested map elements, you would have to convert those as well.

这篇关于如何在Grails中仅使用嵌套地图创建ConfigObject?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆