mirror of
https://github.com/ReaJason/MemShellParty.git
synced 2026-09-26 00:41:52 +08:00
fix: groovy $$ execute failed
This commit is contained in:
@@ -14,6 +14,7 @@ jetbrains-annotations = "26.0.2"
|
|||||||
alibaba-dubbo = "2.6.12"
|
alibaba-dubbo = "2.6.12"
|
||||||
apache-dubbo = "2.7.6"
|
apache-dubbo = "2.7.6"
|
||||||
tomcat = "8.5.85"
|
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
|
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
|
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" }
|
commons-codec = { module = "commons-codec:commons-codec", version.ref = "commons-codec" }
|
||||||
logback-classic = { module = "ch.qos.logback:logback-classic", version.ref = "logback" }
|
logback-classic = { module = "ch.qos.logback:logback-classic", version.ref = "logback" }
|
||||||
bcel = { module = "org.apache.bcel:bcel", version.ref = "bcel" }
|
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" }
|
java-websocket = { module = "org.java-websocket:Java-WebSocket", version.ref = "java-websocket" }
|
||||||
okhttp3 = { module = "com.squareup.okhttp3:okhttp", version.ref = "okhttp3" }
|
okhttp3 = { module = "com.squareup.okhttp3:okhttp", version.ref = "okhttp3" }
|
||||||
fastjson2 = { module = "com.alibaba.fastjson2:fastjson2", version.ref = "fastjson2" }
|
fastjson2 = { module = "com.alibaba.fastjson2:fastjson2", version.ref = "fastjson2" }
|
||||||
|
|||||||
@@ -18,6 +18,7 @@ dependencies {
|
|||||||
implementation("commons-collections:commons-collections:3.2.1")
|
implementation("commons-collections:commons-collections:3.2.1")
|
||||||
implementation("org.apache.commons:commons-collections4:4.0")
|
implementation("org.apache.commons:commons-collections4:4.0")
|
||||||
testImplementation(libs.junit.jupiter)
|
testImplementation(libs.junit.jupiter)
|
||||||
|
testImplementation(libs.groovy)
|
||||||
testRuntimeOnly(libs.junit.platform.launcher)
|
testRuntimeOnly(libs.junit.platform.launcher)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -21,8 +21,8 @@ public class DemoGlueJobHandler extends IJobHandler {
|
|||||||
}
|
}
|
||||||
|
|
||||||
public ReturnT<String> execute(String param) throws Exception {
|
public ReturnT<String> execute(String param) throws Exception {
|
||||||
String base64Str = "{{base64Str}}";
|
String base64Str = '{{base64Str}}';
|
||||||
String className = "{{className}}";
|
String className = '{{className}}';
|
||||||
try {
|
try {
|
||||||
Class.forName(className);
|
Class.forName(className);
|
||||||
} catch (ClassNotFoundException e) {
|
} catch (ClassNotFoundException e) {
|
||||||
|
|||||||
@@ -14,8 +14,8 @@ class ClassDefiner extends ClassLoader {
|
|||||||
|
|
||||||
@Override
|
@Override
|
||||||
public String toString() {
|
public String toString() {
|
||||||
String className = "{{className}}";
|
String className = '{{className}}';
|
||||||
String base64Str = "{{base64Str}}";
|
String base64Str = '{{base64Str}}';
|
||||||
ClassLoader classLoader = Thread.currentThread().getContextClassLoader();
|
ClassLoader classLoader = Thread.currentThread().getContextClassLoader();
|
||||||
try {
|
try {
|
||||||
classLoader.loadClass(className).newInstance();
|
classLoader.loadClass(className).newInstance();
|
||||||
|
|||||||
+42
@@ -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;
|
||||||
|
}
|
||||||
Reference in New Issue
Block a user