From 1ae3e9aac20873056eec210530205a342f436ef1 Mon Sep 17 00:00:00 2001 From: Paul King Date: Mon, 4 Nov 2024 15:25:39 +1000 Subject: [PATCH] GROOVY-11459: configurable hashing algorithm (port for 4_0_X) --- .../java/groovy/lang/GroovyClassLoader.java | 42 ++++++++++++------- 1 file changed, 27 insertions(+), 15 deletions(-) diff --git a/src/main/java/groovy/lang/GroovyClassLoader.java b/src/main/java/groovy/lang/GroovyClassLoader.java index 397eafd9e7f..64a4b335712 100644 --- a/src/main/java/groovy/lang/GroovyClassLoader.java +++ b/src/main/java/groovy/lang/GroovyClassLoader.java @@ -106,6 +106,7 @@ public class GroovyClassLoader extends URLClassLoader { private String sourceEncoding; private Boolean recompile; private static final AtomicInteger scriptNameCounter = new AtomicInteger(1_000_000); // 1,000,000 avoids conflicts with names from the GroovyShell + private static final String HASH_ALGORITHM = System.getProperty("groovy.cache.hashing.algorithm", "md5"); static { registerAsParallelCapable(); @@ -274,11 +275,7 @@ private GroovyCodeSource createCodeSource(PrivilegedAction act * @return the main class defined in the given script */ public Class parseClass(String text) throws CompilationFailedException { - try { - return parseClass(text, "Script_" + EncodingGroovyMethods.md5(text) + ".groovy"); - } catch (NoSuchAlgorithmException e) { - throw new GroovyBugError("Failed to generate md5", e); // should never happen - } + return parseClass(text, "Script_" + genEncodingString(text) + ".groovy"); } public synchronized String generateScriptName() { @@ -314,11 +311,7 @@ public Class parseClass(final GroovyCodeSource codeSource, boolean shouldCacheSo // and avoid occupying Permanent Area/Metaspace repeatedly String cacheKey = genSourceCacheKey(codeSource); - return sourceCache.getAndPut( - cacheKey, - key -> doParseClass(codeSource), - shouldCacheSource - ); + return sourceCache.getAndPut(cacheKey, key -> doParseClass(codeSource), shouldCacheSource); } private String genSourceCacheKey(GroovyCodeSource codeSource) { @@ -342,11 +335,7 @@ private String genSourceCacheKey(GroovyCodeSource codeSource) { strToDigest.append("name:").append(codeSource.getName()); } - try { - return EncodingGroovyMethods.md5(strToDigest); - } catch (NoSuchAlgorithmException e) { - throw new GroovyRuntimeException(e); // should never reach here! - } + return genEncodingString(strToDigest); } private Class doParseClass(GroovyCodeSource codeSource) { @@ -1233,4 +1222,27 @@ public void call(final SourceUnit source, final GeneratorContext context, final } } } + + /** + * Generates an encoded string based on the specified characters and the defined encoding algorithm. + * Supported algorithms currently are "md5" and sha256". + * An exception is throw for an unknown algorithm or if the JVM doesn't support the algorithm. + * + * @param chars The characters to encode. + * @return The encoded string. + */ + public String genEncodingString(CharSequence chars) { + try { + switch(HASH_ALGORITHM) { + case "md5": + return EncodingGroovyMethods.md5(chars); + case "sha256": + return EncodingGroovyMethods.sha256(chars); + default: + throw new IllegalStateException("Unknown hash algorithm"); + } + } catch (NoSuchAlgorithmException e) { + throw new GroovyRuntimeException(e); + } + } }