Sér*_*els 6 grails groovy grails-2.2
Groovy具有向现有类添加方法的功能,我发现了一些 有趣的类.
然后我发现我需要自定义我的Grails引导程序来加载它们,所以我添加:
def init = { servletContext -> addExtensionModules() }
def addExtensionModules() {
Map<CachedClass, List<MetaMethod>> map = [:]
ClassLoader classLoader = Thread.currentThread().contextClassLoader
try {
Enumeration<URL> resources = classLoader.getResources(MetaClassRegistryImpl.MODULE_META_INF_FILE)
for (URL url in resources) {
if (url.path.contains('groovy-all')) {
// already registered
continue
}
Properties properties = new Properties()
InputStream inStream
try {
inStream = url.openStream()
properties.load(inStream)
GroovySystem.metaClassRegistry.registerExtensionModuleFromProperties(properties,
classLoader, map)
}
catch (IOException e) {
throw new GroovyRuntimeException("Unable to load module META-INF descriptor", e)
} finally {
inStream?.close()
}
}
} catch (IOException ignored) {}
map.each { CachedClass cls, List<MetaMethod> methods ->
cls.setNewMopMethods(methods)
}
}
Run Code Online (Sandbox Code Playgroud)
我添加了BuildConfig.groovy
compile ('ca.redtoad:groovy-crypto-extensions:0.2') {
excludes 'groovy-all'
}
Run Code Online (Sandbox Code Playgroud)
问题是现在我不能使用toBoolean()Groovy String 的方法:
groovy.lang.MissingMethodException:没有方法签名:java.lang.String.toBoolean()适用于参数类型:()values:[]可能的解决方案:asBoolean(),asBoolean(),toFloat(),toDouble()
由于groovy已经注册,为什么缺少这种方法?我正在使用Grails 2.2.4.
编辑
在一个groovy 2.0.8控制台中测试,代码可以工作,所以可能与Grails有关.
@Grab('ca.redtoad:groovy-crypto-extensions:0.2')
@GrabExclude('org.codehaus.groovy:groovy-all')
addExtensionModules() //same method of BootStrap, ommited to make shorter.
def key = "password".toKey()
def ciphertext = "some plaintext".bytes.encrypt(key: key)
def x = new String(ciphertext.decrypt(key: key)).toBoolean()
println "S".toBoolean()
Run Code Online (Sandbox Code Playgroud)
更换
map.each { CachedClass cls, List<MetaMethod> methods ->
cls.setNewMopMethods(methods)
}
Run Code Online (Sandbox Code Playgroud)
同
map.each { CachedClass cls, List<MetaMethod> methods ->
//Add new MOP methods instead of set them as new
cls.addNewMopMethods(methods)
}
Run Code Online (Sandbox Code Playgroud)
当CachedClass在现有扩展/元方法中设置新的元方法时,扩展模块中唯一提供的扩展将覆盖该方法.在这种情况下,groovy-crypto-extension在String类上使用以下扩展方法
class java.lang.String=
[public static javax.crypto.spec.SecretKeySpec ca.redtoad.groovy.extensions.crypto.CryptoExtensionMethods.toKey(java.lang.String),
public static javax.crypto.spec.SecretKeySpec ca.redtoad.groovy.extensions.crypto.CryptoExtensionMethods.toKey(java.lang.String,java.util.Map)
]
Run Code Online (Sandbox Code Playgroud)
如果将这些方法设置为CachedClass,则会清除现有方法.因此必须将它们添加到CachedClass中进行替换.因此,toBoolean在String类上可用.
挑战被接受并执行.你欠我一个款待.(礼品卡也可以接受).;)