From d902012835916179e0bb86890e7898cc30aef70a Mon Sep 17 00:00:00 2001 From: Lee Hinman Date: Thu, 16 Jul 2015 12:43:30 -0600 Subject: [PATCH] Consistently name Groovy scripts with the same content When adding a script to the Groovy classloader, the script name is used as the class identifier in the classloader. This means that in order not to break JVM Classloader convention, that script must always be available by that name. As a result, modifying a script with the same content over and over causes it to be loaded with a different name (due to the incrementing integer). This is particularly bad when something like chef or puppet replaces the on-disk script file with the same content over and over every time a machine is converged. This change makes the script name the SHA1 hash of the script itself, meaning that replacing a script with the same text will use the same script name. Resolves #12212 --- .../script/groovy/GroovyScriptEngineService.java | 10 +++------- 1 file changed, 3 insertions(+), 7 deletions(-) diff --git a/core/src/main/java/org/elasticsearch/script/groovy/GroovyScriptEngineService.java b/core/src/main/java/org/elasticsearch/script/groovy/GroovyScriptEngineService.java index 683ffc58f0f..17c4284f714 100644 --- a/core/src/main/java/org/elasticsearch/script/groovy/GroovyScriptEngineService.java +++ b/core/src/main/java/org/elasticsearch/script/groovy/GroovyScriptEngineService.java @@ -19,6 +19,8 @@ package org.elasticsearch.script.groovy; +import com.google.common.base.Charsets; +import com.google.common.hash.Hashing; import groovy.lang.Binding; import groovy.lang.GroovyClassLoader; import groovy.lang.Script; @@ -49,7 +51,6 @@ import java.io.IOException; import java.math.BigDecimal; import java.util.HashMap; import java.util.Map; -import java.util.concurrent.atomic.AtomicLong; /** * Provides the infrastructure for Groovy as a scripting language for Elasticsearch @@ -57,7 +58,6 @@ import java.util.concurrent.atomic.AtomicLong; public class GroovyScriptEngineService extends AbstractComponent implements ScriptEngineService { public static final String NAME = "groovy"; - private final AtomicLong counter = new AtomicLong(); private final GroovyClassLoader loader; @Inject @@ -111,7 +111,7 @@ public class GroovyScriptEngineService extends AbstractComponent implements Scri @Override public Object compile(String script) { try { - return loader.parseClass(script, generateScriptName()); + return loader.parseClass(script, Hashing.sha1().hashString(script, Charsets.UTF_8).toString()); } catch (Throwable e) { if (logger.isTraceEnabled()) { logger.trace("exception compiling Groovy script:", e); @@ -190,10 +190,6 @@ public class GroovyScriptEngineService extends AbstractComponent implements Scri return value; } - private String generateScriptName() { - return "Script" + counter.incrementAndGet() + ".groovy"; - } - public static final class GroovyScript implements ExecutableScript, LeafSearchScript { private final CompiledScript compiledScript;