6

バックグラウンド

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 を使用しています。

編集

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()
4

1 に答える 1

6

交換

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-extensionString クラスで以下の拡張メソッドを使用します。

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 に追加して置き換える必要があります。したがって、toBooleanString クラスで使用できるようにします。

チャレンジが受け入れられ、実行されました。あなたは私に御馳走を借りています。(ギフトカードも可)。;)

于 2013-10-24T15:16:51.407 に答える