2010-12-05 23 views
2

J'essaie d'utiliser des scripts groovy dans mon application. Le problème est que GroovyScriptEngine # run compile toujours le script, même s'il a été compilé lors d'exécutions précédentes et n'a pas changé depuis. Même si je définis un dossier de sortie physique pour enregistrer les résultats de la compilation dans la configuration.Meilleure façon d'utiliser des scripts groovy dans une application

Quelle est la meilleure façon de contourner ce problème? L'optimum pour moi est que je peux envoyer le script avec un dossier contenant des résultats précompilés et qu'aucune compilation n'est faite (sauf si le script est bien sûr modifié)

Répondre

1

La solution (bidouille) je enfin était de diffuser à la variable scriptCache en utilisant xstream et de le lire en arrière et le mettre dans l'objet

0

Vous ne savez pas si cela vous aide, mais vous pouvez modifier GroovyScriptEngine's comportement à l'aide de CompilerConfiguration (voir GroovyScriptEngine setConfig). Il y a une option CompilerConfiguration. setRecompileGroovySource, qui peut être utilisé pour définir si les sources seront rechargées et recompilées si elles changent. Vous pouvez en savoir plus sur CompilerConfiguration here (page 282).

+0

Je ne sais pas ce que ce drapeau fait, mais le problème est que GroovyScriptEngine # isSourceNewer utilise un objet ScriptCacheEntry. Comme son nom l'indique, il provient d'un cache (une carte). Cette carte est vide lorsque GroovyScriptEngine est créé. Aucun moyen d'entrée isSourceNewer renvoie true, déclenchant la compilation – IttayD

2

Grails 1.3.5 utilise Groovy 1.7.5. Dans cette version Groovy, GroovyScriptEngine.run(..) appelle les méthodes suivantes: createScript(String, Binding) ->loadScriptByName(String) ->isSourceNewer(ScriptCacheEntry).

isSourceNewer(ScriptCacheEntry) est défini comme (malheureusement, je ne l'ai pas trouvé un fichier source correspondant sur le web):

protected boolean isSourceNewer(ScriptCacheEntry entry) 
    throws ResourceException { 
    // ... 

    for (String scriptName : entry.dependencies) { 
     // ... 
     return true; // without any further condition! 
    } 

    return false; 
} 

qui implémente la logique « si un script (queer) a des dépendances, il est plus récent que le script mis en cache (et doit être recompilé) ". Ce n'est pas ce que le code est censé faire; c'est supposé décider par l'heure de la modification.

En newer versions of GroovyScriptEngine, this has been corrected (il y a eu des changements massifs avons à la logique), mais pour l'instant, vous aurez besoin de sous-classe GroovyScriptEngine et écraser isSourceNewer(ScriptCacheEntry) pour fixer vous-même la logique.


Edit: Le bug a été reported et fixed Groovy 1.7.6. - Essayez donc d'utiliser Groovy 1.7.6 dans votre dossier Grails lib.

+0

Bon à savoir, mais ce n'est pas mon problème. Mon problème est la condition 'if (entry == null) return true;' au début de isSourceNewer. Ce qui signifie qu'un nouveau GroovyScriptEngine compilera toujours le script, même s'il a été compilé précédemment et n'a pas changé depuis – IttayD