Применение расширений Groovy в Grails вызывает исключение MissingMethodException для String # toBoolean ()

Задний план

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)
  }
}

И я добавляю в свой BuildConfig.groovy

compile ('ca.redtoad:groovy-crypto-extensions:0.2') {
  excludes 'groovy-all'
}

Вопрос

Проблема в том, что теперь я не могу использовать метод toBoolean() Groovy String:

groovy.lang.MissingMethodException: нет сигнатуры метода: java.lang.String.toBoolean () не применяется для типов аргументов: () значения: [] Возможные решения: asBoolean (), asBoolean (), toFloat (), toDouble ()

Поскольку Groovy уже зарегистрирован, почему метод отсутствует? Я использую Grails 2.2.4.

ИЗМЕНИТЬ

Протестировано на отличной консоли 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()

person Community    schedule 24.10.2013    source источник
comment
@dmahapatro Вызов тебе, друг мой :-)   -  person    schedule 24.10.2013
comment
Есть ли награда, мой дорогой друг? Шучу ... займусь этим, как только я закончу встречу прямо сейчас. ;)   -  person dmahapatro    schedule 24.10.2013
comment
вопрос имеет право на награду через 2 дня хе-хе   -  person    schedule 24.10.2013


Ответы (1)


Заменять

map.each { CachedClass cls, List<MetaMethod> methods ->
    cls.setNewMopMethods(methods)
}

с участием

map.each { CachedClass cls, List<MetaMethod> methods ->
    //Add new MOP methods instead of set them as new
    cls.addNewMopMethods(methods) 
}

Когда новый мета-метод установлен в 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)
] 

Если для этих методов задан CachedClass, существующие методы стираются. Поэтому его нужно заменить добавлением их в CachedClass. Следовательно, делая toBoolean доступным в классе String.

Вызов принят и выполнен. Ты должен мне угощение. (Возможна и подарочная карта). ;)

person dmahapatro    schedule 24.10.2013
comment
Да, чувак, я тебе должен! Я начал отладку MetaClassRegistryImpl, но мне пришлось покинуть офис, и, вероятно, я потрачу больше времени, чтобы разобраться в этом :-) Спасибо! - person ; 24.10.2013
comment
@ SérgioMichels Не беспокойтесь. Рад, что это было полезно. :) - person dmahapatro; 25.10.2013