fix: groovy $$ execute failed

This commit is contained in:
ReaJason
2026-09-24 12:57:56 +08:00
parent 0589863c2b
commit 6bb4a1c2e7
8 changed files with 122 additions and 4 deletions
+2
View File
@@ -14,6 +14,7 @@ jetbrains-annotations = "26.0.2"
alibaba-dubbo = "2.6.12"
apache-dubbo = "2.7.6"
tomcat = "8.5.85"
groovy = "2.4.21" # 与 Jenkins Script Console 的 Groovy 解析器版本对齐(仅测试用)
byte-buddy = "1.18.12" # https://mvnrepository.com/artifact/net.bytebuddy/byte-buddy
commons-io = "2.22.0" # https://mvnrepository.com/artifact/commons-io/commons-io
@@ -52,6 +53,7 @@ commons-lang3 = { module = "org.apache.commons:commons-lang3", version.ref = "co
commons-codec = { module = "commons-codec:commons-codec", version.ref = "commons-codec" }
logback-classic = { module = "ch.qos.logback:logback-classic", version.ref = "logback" }
bcel = { module = "org.apache.bcel:bcel", version.ref = "bcel" }
groovy = { module = "org.codehaus.groovy:groovy", version.ref = "groovy" }
java-websocket = { module = "org.java-websocket:Java-WebSocket", version.ref = "java-websocket" }
okhttp3 = { module = "com.squareup.okhttp3:okhttp", version.ref = "okhttp3" }
fastjson2 = { module = "com.alibaba.fastjson2:fastjson2", version.ref = "fastjson2" }
+1
View File
@@ -18,6 +18,7 @@ dependencies {
implementation("commons-collections:commons-collections:3.2.1")
implementation("org.apache.commons:commons-collections4:4.0")
testImplementation(libs.junit.jupiter)
testImplementation(libs.groovy)
testRuntimeOnly(libs.junit.platform.launcher)
}
@@ -21,8 +21,8 @@ public class DemoGlueJobHandler extends IJobHandler {
}
public ReturnT<String> execute(String param) throws Exception {
String base64Str = "{{base64Str}}";
String className = "{{className}}";
String base64Str = '{{base64Str}}';
String className = '{{className}}';
try {
Class.forName(className);
} catch (ClassNotFoundException e) {
@@ -14,8 +14,8 @@ class ClassDefiner extends ClassLoader {
@Override
public String toString() {
String className = "{{className}}";
String base64Str = "{{base64Str}}";
String className = '{{className}}';
String base64Str = '{{base64Str}}';
ClassLoader classLoader = Thread.currentThread().getContextClassLoader();
try {
classLoader.loadClass(className).newInstance();
@@ -0,0 +1,42 @@
package com.reajason.javaweb.packer.groovy;
import com.reajason.javaweb.packer.ClassPackerConfig;
import groovy.lang.GroovyClassLoader;
import org.junit.jupiter.api.Test;
import static org.junit.jupiter.api.Assertions.assertTrue;
/**
* @author ReaJason
* @since 2026/9/24
*/
class GroovyClassDefinerPackerTest {
@Test
void pack() {
ClassPackerConfig config = new ClassPackerConfig();
config.setClassName("com.reajason.javaweb.ErrorAbcdHandler");
config.setClassBytesBase64Str("aGVsbG8=");
String script = new GroovyClassDefinerPacker().pack(config);
assertTrue(script.contains("'com.reajason.javaweb.ErrorAbcdHandler'"));
compile(script);
}
@Test
void packClassNameWithLambdaSuffix() {
ClassPackerConfig config = new ClassPackerConfig();
config.setClassName("le.gso.SzyHj.SOAPUtils$Proxy0$$Lambda$1");
config.setClassBytesBase64Str("aGVsbG8=");
String script = new GroovyClassDefinerPacker().pack(config);
assertTrue(script.contains("'le.gso.SzyHj.SOAPUtils$Proxy0$$Lambda$1'"));
compile(script);
}
private void compile(String script) {
try (GroovyClassLoader classLoader = new GroovyClassLoader()) {
classLoader.parseClass(script);
} catch (Exception e) {
throw new AssertionError("groovy script should compile, script: " + script, e);
}
}
}
@@ -0,0 +1,53 @@
package com.reajason.javaweb.packer.xxljob;
import com.fasterxml.jackson.databind.JsonNode;
import com.fasterxml.jackson.databind.ObjectMapper;
import com.reajason.javaweb.packer.ClassPackerConfig;
import groovy.lang.GroovyClassLoader;
import org.junit.jupiter.api.Test;
import static org.junit.jupiter.api.Assertions.assertEquals;
import static org.junit.jupiter.api.Assertions.assertTrue;
/**
* @author ReaJason
* @since 2026/9/24
*/
class XxlJobJsonPackerTest {
private final ObjectMapper objectMapper = new ObjectMapper();
@Test
void pack() throws Exception {
ClassPackerConfig config = new ClassPackerConfig();
config.setClassName("com.reajason.javaweb.ErrorAbcdHandler");
config.setClassBytesBase64Str("aGVsbG8=");
String glueSource = extractGlueSource(config);
assertTrue(glueSource.contains("'com.reajason.javaweb.ErrorAbcdHandler'"));
compile(glueSource);
}
@Test
void packClassNameWithLambdaSuffix() throws Exception {
ClassPackerConfig config = new ClassPackerConfig();
config.setClassName("le.gso.SzyHj.SOAPUtils$Proxy0$$Lambda$1");
config.setClassBytesBase64Str("aGVsbG8=");
String glueSource = extractGlueSource(config);
assertTrue(glueSource.contains("'le.gso.SzyHj.SOAPUtils$Proxy0$$Lambda$1'"));
compile(glueSource);
}
private String extractGlueSource(ClassPackerConfig config) throws Exception {
String payload = new XxlJobJsonPacker().pack(config);
JsonNode jsonNode = objectMapper.readTree(payload);
assertEquals("GLUE_GROOVY", jsonNode.get("glueType").asText());
return jsonNode.get("glueSource").asText();
}
private void compile(String glueSource) {
try (GroovyClassLoader classLoader = new GroovyClassLoader()) {
classLoader.parseClass(glueSource);
} catch (Exception e) {
throw new AssertionError("glue source should compile, source: " + glueSource, e);
}
}
}
@@ -0,0 +1,10 @@
package com.xxl.job.core.biz.model;
import java.io.Serializable;
/**
* 精简版 ReturnT,仅用于在测试中编译 GLUE 源码
*/
public class ReturnT<T> implements Serializable {
public static final ReturnT<String> SUCCESS = new ReturnT<>();
}
@@ -0,0 +1,10 @@
package com.xxl.job.core.handler;
import com.xxl.job.core.biz.model.ReturnT;
/**
* 精简版 IJobHandler,仅用于在测试中编译 GLUE 源码
*/
public abstract class IJobHandler {
public abstract ReturnT<String> execute(String param) throws Exception;
}