This is an automated email from the ASF dual-hosted git repository.

vladimirsitnikov pushed a commit to branch master
in repository https://gitbox.apache.org/repos/asf/jmeter.git

commit 368401df7948044be6d31c18ad620dba4df9518c
Author: Vladimir Sitnikov <[email protected]>
AuthorDate: Fri Nov 7 13:15:30 2025 +0300

    chore: remove uses of commons-codec. Java 17 has both Base64 and HexFormat
---
 bin/testfiles/TCP_TESTS.jmx                        | 20 ++++++++--------
 src/components/build.gradle.kts                    |  1 -
 src/core/build.gradle.kts                          |  3 ---
 .../org/apache/jmeter/util/JSR223TestElement.java  | 14 ++++++++---
 .../org/apache/jmeter/util/ScriptCacheKey.java     | 22 ++++++++++--------
 .../jmeter/util/keystore/JmeterKeyStore.java       |  4 ++--
 src/dist/build.gradle.kts                          |  4 ++++
 src/functions/build.gradle.kts                     |  1 -
 .../jmeter/functions/DigestEncodeFunction.java     | 27 ++++++++--------------
 .../java/org/apache/jorphan/util/JOrphanUtils.java | 26 +++++----------------
 .../jmeter/protocol/http/proxy/ProxyControl.java   | 10 ++++----
 11 files changed, 60 insertions(+), 72 deletions(-)

diff --git a/bin/testfiles/TCP_TESTS.jmx b/bin/testfiles/TCP_TESTS.jmx
index 1bfd6e85cd..d646bef3a0 100644
--- a/bin/testfiles/TCP_TESTS.jmx
+++ b/bin/testfiles/TCP_TESTS.jmx
@@ -74,7 +74,7 @@ import org.apache.mina.transport.socket.nio.NioSocketAcceptor;
 class TimeServerHandler extends IoHandlerAdapter
 {
        private static final String EOL = &quot;\n&quot;;
-    Logger log = LoggerFactory.getLogger(TimeServerHandler.class);     
+    Logger log = LoggerFactory.getLogger(TimeServerHandler.class);
     public void exceptionCaught( IoSession session, Throwable cause ) throws 
Exception
     {
           log.error(&quot;Exception occured&quot;, cause);
@@ -85,7 +85,7 @@ class TimeServerHandler extends IoHandlerAdapter
     {
         String str = message.trim().toString();
         log.info(&quot;Received {}&quot;, str);
-        
+
         String[] words = str.split(&quot; &quot;);
         if(words[0].equalsIgnoreCase(&quot;quit&quot;) ) {
             session.close();
@@ -269,10 +269,10 @@ 
vars.put(&quot;CR&quot;,URLDecoder.decode(&quot;%0A&quot;, &quot;ASCII&quot;));
             <stringProp 
name="cacheKey">e7ac0019-16aa-40b4-b30f-e254c0a75f27</stringProp>
             <stringProp name="filename"></stringProp>
             <stringProp name="parameters"></stringProp>
-            <stringProp name="script">import 
org.apache.commons.codec.binary.Hex;
-Hex hex = new Hex();
-OUT.println(new String(hex.decode(prev.getResponseData())));
-vars.put(&quot;result_decoded&quot;, new 
String(hex.decode(prev.getResponseData())));</stringProp>
+            <stringProp name="script">import java.util.HexFormat;
+String decoded = new 
String(HexFormat.of().parseHex(prev.getResponseDataAsString()));
+OUT.println(decoded);
+vars.put(&quot;result_decoded&quot;, decoded);</stringProp>
             <stringProp name="scriptLanguage">groovy</stringProp>
           </JSR223PostProcessor>
           <hashTree/>
@@ -500,10 +500,10 @@ if (oldResponseMessage != null &amp;&amp; 
oldResponseMessage.contains(&quot;java
             <stringProp 
name="cacheKey">e7ac0019-16aa-40b4-b30f-e254c0a75f27</stringProp>
             <stringProp name="filename"></stringProp>
             <stringProp name="parameters"></stringProp>
-            <stringProp name="script">import 
org.apache.commons.codec.binary.Hex;
-Hex hex = new Hex();
-OUT.println(new String(hex.decode(prev.getResponseData())));
-vars.put(&quot;result_decoded&quot;, new 
String(hex.decode(prev.getResponseData())));</stringProp>
+            <stringProp name="script">import java.util.HexFormat;
+String decoded = new 
String(HexFormat.of().parseHex(prev.getResponseDataAsString()));
+OUT.println(decoded);
+vars.put(&quot;result_decoded&quot;, decoded);</stringProp>
             <stringProp name="scriptLanguage">groovy</stringProp>
           </JSR223PostProcessor>
           <hashTree/>
diff --git a/src/components/build.gradle.kts b/src/components/build.gradle.kts
index 111475b090..f485e2bc69 100644
--- a/src/components/build.gradle.kts
+++ b/src/components/build.gradle.kts
@@ -51,7 +51,6 @@ dependencies {
     implementation("net.minidev:json-smart")
     implementation("net.minidev:accessors-smart")
     implementation("org.apache.commons:commons-pool2")
-    implementation("commons-codec:commons-codec")
     implementation("org.ow2.asm:asm")
     implementation("org.jodd:jodd-log") {
         exclude("ch.qos.logback")
diff --git a/src/core/build.gradle.kts b/src/core/build.gradle.kts
index de661927bd..ab84960a6a 100644
--- a/src/core/build.gradle.kts
+++ b/src/core/build.gradle.kts
@@ -91,9 +91,6 @@ dependencies {
     implementation("com.github.weisj:darklaf-property-loader")
     implementation("com.github.weisj:darklaf-extensions-rsyntaxarea")
     implementation("com.miglayout:miglayout-swing")
-    implementation("commons-codec:commons-codec") {
-        because("DigestUtils")
-    }
     implementation("org.apache-extras.beanshell:bsh:2.0b6") {
         because("Direct dependency required from BeanShellInterpreter")
     }
diff --git 
a/src/core/src/main/java/org/apache/jmeter/util/JSR223TestElement.java 
b/src/core/src/main/java/org/apache/jmeter/util/JSR223TestElement.java
index 5b042f33b6..f6fe6716ab 100644
--- a/src/core/src/main/java/org/apache/jmeter/util/JSR223TestElement.java
+++ b/src/core/src/main/java/org/apache/jmeter/util/JSR223TestElement.java
@@ -21,7 +21,10 @@ import java.io.BufferedReader;
 import java.io.File;
 import java.io.IOException;
 import java.io.Serializable;
+import java.nio.charset.StandardCharsets;
 import java.nio.file.Files;
+import java.security.MessageDigest;
+import java.security.NoSuchAlgorithmException;
 import java.util.Properties;
 import java.util.function.Function;
 
@@ -32,7 +35,6 @@ import javax.script.ScriptEngine;
 import javax.script.ScriptEngineManager;
 import javax.script.ScriptException;
 
-import org.apache.commons.codec.digest.DigestUtils;
 import org.apache.jmeter.samplers.SampleResult;
 import org.apache.jmeter.samplers.Sampler;
 import org.apache.jmeter.testelement.TestStateListener;
@@ -306,8 +308,14 @@ public abstract class JSR223TestElement extends 
ScriptingTestElement
      */
     private void computeScriptMD5(String script) {
         // compute the md5 of the script if needed
-        if(scriptMd5 == null) {
-            scriptMd5 = ScriptCacheKey.ofString(DigestUtils.md5Hex(script));
+        if (scriptMd5 == null) {
+            try {
+                MessageDigest md = MessageDigest.getInstance("MD5");
+                md.update(script.getBytes(StandardCharsets.UTF_8));
+                scriptMd5 = ScriptCacheKey.ofDigest(md.digest());
+            } catch (NoSuchAlgorithmException e) {
+                throw new RuntimeException("MessageDigest.getInstance(MD5) was 
not found", e);
+            }
         }
     }
 
diff --git a/src/core/src/main/java/org/apache/jmeter/util/ScriptCacheKey.java 
b/src/core/src/main/java/org/apache/jmeter/util/ScriptCacheKey.java
index 6b7ea21c97..c006adf5bc 100644
--- a/src/core/src/main/java/org/apache/jmeter/util/ScriptCacheKey.java
+++ b/src/core/src/main/java/org/apache/jmeter/util/ScriptCacheKey.java
@@ -17,6 +17,8 @@
 
 package org.apache.jmeter.util;
 
+import java.util.Arrays;
+import java.util.HexFormat;
 import java.util.Objects;
 
 interface ScriptCacheKey {
@@ -25,8 +27,8 @@ interface ScriptCacheKey {
      * @param key cache key
      * @return cache key
      */
-    static ScriptCacheKey ofString(String key) {
-        return new StringScriptCacheKey(key);
+    static ScriptCacheKey ofDigest(byte[] key) {
+        return new DigestScriptCacheKey(key);
     }
 
     /**
@@ -40,11 +42,11 @@ interface ScriptCacheKey {
         return new FileScriptCacheKey(language, absolutePath, lastModified);
     }
 
-    final class StringScriptCacheKey implements ScriptCacheKey {
-        final String contents;
+    final class DigestScriptCacheKey implements ScriptCacheKey {
+        final byte[] digest;
 
-        StringScriptCacheKey(String contents) {
-            this.contents = contents;
+        DigestScriptCacheKey(byte[] digest) {
+            this.digest = digest;
         }
 
         @Override
@@ -55,19 +57,19 @@ interface ScriptCacheKey {
             if (o == null || getClass() != o.getClass()) {
                 return false;
             }
-            StringScriptCacheKey that = (StringScriptCacheKey) o;
-            return Objects.equals(contents, that.contents);
+            DigestScriptCacheKey that = (DigestScriptCacheKey) o;
+            return Arrays.equals(digest, that.digest);
         }
 
         @Override
         public int hashCode() {
-            return contents.hashCode();
+            return Arrays.hashCode(digest);
         }
 
         @Override
         public String toString() {
             return "StringScriptCacheKey{" +
-                    "contents='" + contents + '\'' +
+                    "contents='" + HexFormat.of().formatHex(digest) + '\'' +
                     '}';
         }
     }
diff --git 
a/src/core/src/main/java/org/apache/jmeter/util/keystore/JmeterKeyStore.java 
b/src/core/src/main/java/org/apache/jmeter/util/keystore/JmeterKeyStore.java
index 40eaf0d17a..2f0b69c01c 100644
--- a/src/core/src/main/java/org/apache/jmeter/util/keystore/JmeterKeyStore.java
+++ b/src/core/src/main/java/org/apache/jmeter/util/keystore/JmeterKeyStore.java
@@ -34,12 +34,12 @@ import java.util.Arrays;
 import java.util.Collection;
 import java.util.Enumeration;
 import java.util.HashMap;
+import java.util.HexFormat;
 import java.util.List;
 import java.util.Map;
 import java.util.Objects;
 import java.util.stream.Collectors;
 
-import org.apache.commons.codec.binary.Hex;
 import org.apache.jmeter.threads.JMeterContextService;
 import org.apache.jorphan.util.StringUtilities;
 import org.slf4j.Logger;
@@ -242,7 +242,7 @@ public final class JmeterKeyStore {
         if (data instanceof String s) {
             return s;
         }
-        return Hex.encodeHexString((byte[]) data);
+        return HexFormat.of().formatHex((byte[]) data);
     }
 
     private static String sanGeneralNameIndexToName(Integer index) {
diff --git a/src/dist/build.gradle.kts b/src/dist/build.gradle.kts
index 44bfe693e4..26661caa01 100644
--- a/src/dist/build.gradle.kts
+++ b/src/dist/build.gradle.kts
@@ -89,6 +89,10 @@ dependencies {
         api(project(p))
     }
 
+    runtimeOnly("commons-codec:commons-codec") {
+        because("commons-codec was a dependency in previous JMeter versions, 
so we keep it for compatibility")
+    }
+
     binLicense(project(":src:licenses", "binLicense"))
     srcLicense(project(":src:licenses", "srcLicense"))
     generatorJar(project(":src:generator", "archives"))
diff --git a/src/functions/build.gradle.kts b/src/functions/build.gradle.kts
index b948246962..773eb6b7df 100644
--- a/src/functions/build.gradle.kts
+++ b/src/functions/build.gradle.kts
@@ -24,7 +24,6 @@ dependencies {
     testImplementation(testFixtures(projects.src.core))
 
     implementation("org.mozilla:rhino")
-    implementation("commons-codec:commons-codec")
     implementation("org.apache.commons:commons-jexl")
     implementation("org.apache.commons:commons-jexl3")
     implementation("commons-io:commons-io") {
diff --git 
a/src/functions/src/main/java/org/apache/jmeter/functions/DigestEncodeFunction.java
 
b/src/functions/src/main/java/org/apache/jmeter/functions/DigestEncodeFunction.java
index b7325ad23a..0d215dc2bd 100644
--- 
a/src/functions/src/main/java/org/apache/jmeter/functions/DigestEncodeFunction.java
+++ 
b/src/functions/src/main/java/org/apache/jmeter/functions/DigestEncodeFunction.java
@@ -22,10 +22,9 @@ import java.security.MessageDigest;
 import java.security.NoSuchAlgorithmException;
 import java.util.ArrayList;
 import java.util.Collection;
+import java.util.HexFormat;
 import java.util.List;
-import java.util.Locale;
 
-import org.apache.commons.codec.binary.Hex;
 import org.apache.jmeter.engine.util.CompoundVariable;
 import org.apache.jmeter.samplers.SampleResult;
 import org.apache.jmeter.samplers.Sampler;
@@ -85,7 +84,14 @@ public class DigestEncodeFunction extends AbstractFunction {
                 md.update(salt.getBytes(StandardCharsets.UTF_8));
             }
             byte[] bytes = md.digest();
-            encodedString = uppercase(Hex.encodeHexString(bytes), values, 3);
+            HexFormat hexFormat = HexFormat.of();
+            if (values.length > 3) {
+                String shouldUpperCase = values[3].execute();
+                if (Boolean.parseBoolean(shouldUpperCase)) {
+                    hexFormat = hexFormat.withUpperCase();
+                }
+            }
+            encodedString = hexFormat.formatHex(bytes);
             addVariableValue(encodedString, values, 4);
         } catch (NoSuchAlgorithmException e) {
             log.error("Error calling {} function with value {}, digest 
algorithm {}, salt {}, ", KEY, stringToEncode,
@@ -94,21 +100,6 @@ public class DigestEncodeFunction extends AbstractFunction {
         return encodedString;
     }
 
-    /**
-     * Upper case value if optional parameter value is true
-     *
-     * @param encodedString
-     * @param index
-     * @return
-     */
-    private static String uppercase(String encodedString, CompoundVariable[] 
values, int index) {
-        String shouldUpperCase = values.length > index ? 
values[index].execute() : null;
-        if (Boolean.parseBoolean(shouldUpperCase)) {
-            return encodedString.toUpperCase(Locale.ROOT);
-        }
-        return encodedString;
-    }
-
     @Override
     public void setParameters(Collection<CompoundVariable> parameters) throws 
InvalidVariableException {
         checkParameterCount(parameters, MIN_PARAMETER_COUNT, 
MAX_PARAMETER_COUNT);
diff --git 
a/src/jorphan/src/main/java/org/apache/jorphan/util/JOrphanUtils.java 
b/src/jorphan/src/main/java/org/apache/jorphan/util/JOrphanUtils.java
index 1ca523bc6e..794f8406a7 100644
--- a/src/jorphan/src/main/java/org/apache/jorphan/util/JOrphanUtils.java
+++ b/src/jorphan/src/main/java/org/apache/jorphan/util/JOrphanUtils.java
@@ -27,6 +27,7 @@ import java.net.ServerSocket;
 import java.net.Socket;
 import java.security.SecureRandom;
 import java.util.ArrayList;
+import java.util.HexFormat;
 import java.util.List;
 import java.util.Map;
 import java.util.StringTokenizer;
@@ -403,15 +404,7 @@ public final class JOrphanUtils {
      * @return hex representation of binary input
      */
     public static String baToHexString(byte[] ba) {
-        StringBuilder sb = new StringBuilder(ba.length * 2);
-        for (byte b : ba) {
-            int j = b & 0xff;
-            if (j < 16) {
-                sb.append('0'); // $NON-NLS-1$ add zero padding
-            }
-            sb.append(Integer.toHexString(j));
-        }
-        return sb.toString();
+        return baToHexString(ba, '\0');
     }
 
     /**
@@ -422,18 +415,11 @@ public final class JOrphanUtils {
      * @return hex representation of binary input
      */
     public static String baToHexString(byte[] ba, char separator) {
-        StringBuilder sb = new StringBuilder(ba.length * 2);
-        for (int i = 0; i < ba.length; i++) {
-            if (i > 0 && separator != 0) {
-                sb.append(separator);
-            }
-            int j = ba[i] & 0xff;
-            if (j < 16) {
-                sb.append('0'); // $NON-NLS-1$ add zero padding
-            }
-            sb.append(Integer.toHexString(j));
+        HexFormat format = HexFormat.of();
+        if (separator != 0) {
+            format = format.withDelimiter(Character.toString(separator));
         }
-        return sb.toString();
+        return format.formatHex(ba);
     }
 
     /**
diff --git 
a/src/protocol/http/src/main/java/org/apache/jmeter/protocol/http/proxy/ProxyControl.java
 
b/src/protocol/http/src/main/java/org/apache/jmeter/protocol/http/proxy/ProxyControl.java
index b7b29c1708..826549a979 100644
--- 
a/src/protocol/http/src/main/java/org/apache/jmeter/protocol/http/proxy/ProxyControl.java
+++ 
b/src/protocol/http/src/main/java/org/apache/jmeter/protocol/http/proxy/ProxyControl.java
@@ -27,6 +27,7 @@ import java.io.Serializable;
 import java.nio.charset.StandardCharsets;
 import java.security.GeneralSecurityException;
 import java.security.KeyStore;
+import java.security.MessageDigest;
 import java.security.UnrecoverableKeyException;
 import java.security.cert.CertificateExpiredException;
 import java.security.cert.CertificateNotYetValidException;
@@ -34,6 +35,7 @@ import java.security.cert.X509Certificate;
 import java.util.ArrayDeque;
 import java.util.ArrayList;
 import java.util.Arrays;
+import java.util.Base64;
 import java.util.Collection;
 import java.util.Date;
 import java.util.Deque;
@@ -49,8 +51,6 @@ import java.util.prefs.Preferences;
 import java.util.regex.PatternSyntaxException;
 import java.util.stream.Collectors;
 
-import org.apache.commons.codec.binary.Base64;
-import org.apache.commons.codec.digest.DigestUtils;
 import org.apache.jmeter.assertions.Assertion;
 import org.apache.jmeter.assertions.ResponseAssertion;
 import org.apache.jmeter.assertions.gui.AssertionGui;
@@ -720,7 +720,7 @@ public class ProxyControl extends GenericController 
implements NonTestElement {
                             
authorization.setURL(computeAuthUrl(result.getUrlAsString()));
                             authorization.setMechanism(mechanism);
                             if(BASIC_AUTH.equals(authType)) {
-                                String authCred = new 
String(Base64.decodeBase64(authCredentialsBase64), StandardCharsets.UTF_8);
+                                String authCred = new 
String(Base64.getDecoder().decode(authCredentialsBase64), 
StandardCharsets.UTF_8);
                                 String[] loginPassword = authCred.split(":"); 
//$NON-NLS-1$
                                 if(loginPassword.length == 2) {
                                     authorization.setUser(loginPassword[0]);
@@ -785,10 +785,12 @@ public class ProxyControl extends GenericController 
implements NonTestElement {
                 if (caCert == null) {
                     return new String[]{"Could not find certificate"};
                 }
+                MessageDigest md = MessageDigest.getInstance("SHA-1");
+                md.update(caCert.getEncoded());
                 return new String[]
                         {
                         caCert.getSubjectX500Principal().toString(),
-                        "Fingerprint(SHA1): " + 
JOrphanUtils.baToHexString(DigestUtils.sha1(caCert.getEncoded()), ' '),
+                        "Fingerprint(SHA1): " + 
JOrphanUtils.baToHexString(md.digest(), ' '),
                         "Created: "+ caCert.getNotBefore().toString()
                         };
             } catch (GeneralSecurityException e) {

Reply via email to