mirror of
https://gitee.com/BDWare/cm
synced 2025-01-10 09:54:03 +00:00
add remote debug
This commit is contained in:
parent
ca9c51e1bc
commit
8ce956a5c7
@ -24,6 +24,7 @@ import org.bdware.sc.util.JsonUtil;
|
|||||||
import java.io.File;
|
import java.io.File;
|
||||||
import java.io.InputStream;
|
import java.io.InputStream;
|
||||||
import java.io.PrintStream;
|
import java.io.PrintStream;
|
||||||
|
import java.lang.reflect.Constructor;
|
||||||
import java.lang.reflect.Field;
|
import java.lang.reflect.Field;
|
||||||
import java.util.*;
|
import java.util.*;
|
||||||
|
|
||||||
@ -31,7 +32,6 @@ public class ContractClient {
|
|||||||
private static final Logger LOGGER = LogManager.getLogger(ContractClient.class);
|
private static final Logger LOGGER = LogManager.getLogger(ContractClient.class);
|
||||||
public static String cmi = "";
|
public static String cmi = "";
|
||||||
public ContractMeta contractMeta;
|
public ContractMeta contractMeta;
|
||||||
public boolean isDebug;
|
|
||||||
transient SocketGet get;
|
transient SocketGet get;
|
||||||
int port;
|
int port;
|
||||||
String pid;
|
String pid;
|
||||||
@ -196,7 +196,6 @@ public class ContractClient {
|
|||||||
contractMeta.thisPermission = get.syncGet("", "showPermission", "");
|
contractMeta.thisPermission = get.syncGet("", "showPermission", "");
|
||||||
// LOGGER.info("initProps ---- position-----8");
|
// LOGGER.info("initProps ---- position-----8");
|
||||||
isRunning = true;
|
isRunning = true;
|
||||||
contractMeta.isDebug = Boolean.parseBoolean(get.syncGet("", "getDebug", ""));
|
|
||||||
// LOGGER.info("initProps ---- position-----9");
|
// LOGGER.info("initProps ---- position-----9");
|
||||||
get.syncGet("", "registerMangerPort", ContractManager.cPort.getCMPort() + "");
|
get.syncGet("", "registerMangerPort", ContractManager.cPort.getCMPort() + "");
|
||||||
contractMeta.contract =
|
contractMeta.contract =
|
||||||
@ -221,11 +220,9 @@ public class ContractClient {
|
|||||||
public String startProcess(PrintStream ps) throws Exception {
|
public String startProcess(PrintStream ps) throws Exception {
|
||||||
isRunning = false;
|
isRunning = false;
|
||||||
port = -1;
|
port = -1;
|
||||||
|
|
||||||
String darg = "-Djava.library.path=";
|
String darg = "-Djava.library.path=";
|
||||||
String classpath;
|
String classpath;
|
||||||
File jniPath;
|
File jniPath;
|
||||||
|
|
||||||
if (ContractManager.yjsPath == null) {
|
if (ContractManager.yjsPath == null) {
|
||||||
jniPath = new File("./jni/");
|
jniPath = new File("./jni/");
|
||||||
classpath = System.getProperty("java.class.path");
|
classpath = System.getProperty("java.class.path");
|
||||||
@ -233,7 +230,6 @@ public class ContractClient {
|
|||||||
classpath = ContractManager.yjsPath;
|
classpath = ContractManager.yjsPath;
|
||||||
jniPath = new File(classpath).getParentFile();
|
jniPath = new File(classpath).getParentFile();
|
||||||
}
|
}
|
||||||
|
|
||||||
String osJni = ((HardwareInfo.type == OSType.linux) ? "/jni/linux" : "/jni/mac");
|
String osJni = ((HardwareInfo.type == OSType.linux) ? "/jni/linux" : "/jni/mac");
|
||||||
darg += jniPath.getAbsolutePath() + osJni;
|
darg += jniPath.getAbsolutePath() + osJni;
|
||||||
if (!new File(classpath).exists()) {
|
if (!new File(classpath).exists()) {
|
||||||
@ -249,39 +245,63 @@ public class ContractClient {
|
|||||||
new JsonPrimitive("incorrect path: yjs.jar, missing libs"));
|
new JsonPrimitive("incorrect path: yjs.jar, missing libs"));
|
||||||
return JsonUtil.toJson(r);
|
return JsonUtil.toJson(r);
|
||||||
}
|
}
|
||||||
// ProcessBuilder builder =
|
int startPort = ContractManager.cPort.getPortAndInc();
|
||||||
|
List<String> pbParameters = new ArrayList<>();
|
||||||
|
pbParameters.add("java");
|
||||||
|
pbParameters.add("-Dfile.encoding=UTF-8");
|
||||||
|
pbParameters.add(darg);
|
||||||
|
if (contractMeta.contract.getRemoteDebugPort() != 0) {
|
||||||
|
pbParameters.add(String.format("-agentlib:jdwp=transport=dt_socket,address=%d,server=y,suspend=n", contractMeta.contract.getRemoteDebugPort()));
|
||||||
|
}
|
||||||
|
if (contractMeta.contract.isDebug()) {
|
||||||
|
pbParameters.add("-Dlog4j.configurationFile=./log4j2.debug.properties");
|
||||||
|
} else {
|
||||||
|
pbParameters.add("-Dlog4j.configurationFile=./log4j2.properties");
|
||||||
|
}
|
||||||
|
pbParameters.add("-jar");
|
||||||
|
pbParameters.add(classpath);
|
||||||
|
pbParameters.add("-port=" + startPort);
|
||||||
|
pbParameters.add("-cmi=" + cmi);
|
||||||
|
if (contractMeta.contract.isDebug())
|
||||||
|
pbParameters.add("-debug");
|
||||||
|
ProcessBuilder builder;
|
||||||
|
String[] result = new String[pbParameters.size()];
|
||||||
|
pbParameters.toArray(result);
|
||||||
|
Constructor<ProcessBuilder> pbc = ProcessBuilder.class.getDeclaredConstructor(String[].class);
|
||||||
|
builder = pbc.newInstance(new Object[]{result});
|
||||||
|
|
||||||
|
// if (remoteDebug.length() == 0)
|
||||||
|
// builder =
|
||||||
// new ProcessBuilder(
|
// new ProcessBuilder(
|
||||||
// "java",
|
// "java",
|
||||||
// "-Dfile.encoding=UTF-8",
|
// "-Dfile.encoding=UTF-8",
|
||||||
// darg,
|
// darg,
|
||||||
// "-cp",
|
// "-jar",
|
||||||
// jniPath.getAbsolutePath() + "/libs/*:" + classpath,
|
// classpath,
|
||||||
// "org.bdware.sc.ContractProcess",
|
// "-port=" + startPort,
|
||||||
// "-port=" + cPort.getPort());
|
// "-cmi=" + cmi, // cmi 区分不同CM的cp
|
||||||
int startPort = ContractManager.cPort.getPortAndInc();
|
// (isDebug ? "-debug" : ""));
|
||||||
//(isDebug ? "-Dlog4j.configurationFile=./log4j2.debug.properties" : ""),
|
// else
|
||||||
ProcessBuilder builder =
|
// builder =
|
||||||
new ProcessBuilder(
|
//
|
||||||
"java",
|
// new ProcessBuilder(
|
||||||
"-Dfile.encoding=UTF-8",
|
// "java",
|
||||||
darg,
|
// "-Dfile.encoding=UTF-8",
|
||||||
"-jar",
|
// darg, remoteDebug,
|
||||||
classpath,
|
// "-jar",
|
||||||
"-port=" + startPort,
|
// classpath,
|
||||||
"-cmi=" + cmi, // cmi 区分不同CM的cp
|
// "-port=" + startPort,
|
||||||
(isDebug ? "-debug" : ""));
|
// "-cmi=" + cmi, // cmi 区分不同CM的cp
|
||||||
|
// (isDebug ? "-debug" : ""));
|
||||||
|
|
||||||
File directory = new File("./");
|
File directory = new File("./");
|
||||||
LOGGER.debug("[CMD] path: " + directory.getAbsolutePath());
|
LOGGER.debug("[CMD] path: " + directory.getAbsolutePath());
|
||||||
LOGGER.debug(JsonUtil.toPrettyJson(builder.command()));
|
LOGGER.debug(JsonUtil.toPrettyJson(builder.command()));
|
||||||
|
|
||||||
Map<String, String> map = builder.environment();
|
Map<String, String> map = builder.environment();
|
||||||
map.put("java.library.path", jniPath.getAbsolutePath() + osJni);
|
map.put("java.library.path", jniPath.getAbsolutePath() + osJni);
|
||||||
builder.directory(directory);
|
builder.directory(directory);
|
||||||
LOGGER.debug("start process:");
|
LOGGER.debug("start process:");
|
||||||
|
|
||||||
|
|
||||||
process = builder.start();
|
process = builder.start();
|
||||||
|
|
||||||
this.pid = getPid(process);
|
this.pid = getPid(process);
|
||||||
LOGGER.info("[CP PPID] " + pid);
|
LOGGER.info("[CP PPID] " + pid);
|
||||||
PrintStream printStream = new PrintStream(process.getOutputStream());
|
PrintStream printStream = new PrintStream(process.getOutputStream());
|
||||||
@ -318,7 +338,7 @@ public class ContractClient {
|
|||||||
ContractManager.cPort.updateDb(port, true);
|
ContractManager.cPort.updateDb(port, true);
|
||||||
get = new SocketGet("127.0.0.1", port);
|
get = new SocketGet("127.0.0.1", port);
|
||||||
get.syncGet("", "setDBInfo", ContractManager.dbPath);
|
get.syncGet("", "setDBInfo", ContractManager.dbPath);
|
||||||
if (isDebug || get != null) {
|
if (contractMeta.contract.isDebug() || get != null) {
|
||||||
String tagA = (ps == System.out ? "[Contract_" + port + "_out] " : "");
|
String tagA = (ps == System.out ? "[Contract_" + port + "_out] " : "");
|
||||||
String tagB = (ps == System.out ? "[Contract_" + port + "_err] " : "");
|
String tagB = (ps == System.out ? "[Contract_" + port + "_err] " : "");
|
||||||
outputTracer.track(process, sc, tagA, ps);
|
outputTracer.track(process, sc, tagA, ps);
|
||||||
@ -335,9 +355,11 @@ public class ContractClient {
|
|||||||
if (multiContractMeta != null && multiContractMeta.getMembers() != null) {
|
if (multiContractMeta != null && multiContractMeta.getMembers() != null) {
|
||||||
String setMemberResult = get.syncGet(
|
String setMemberResult = get.syncGet(
|
||||||
"", "setMembers", JsonUtil.toJson(multiContractMeta.getMembers()));
|
"", "setMembers", JsonUtil.toJson(multiContractMeta.getMembers()));
|
||||||
LOGGER.debug("setMember:" + setMemberResult);
|
LOGGER.info("setMember:" + setMemberResult);
|
||||||
|
} else {
|
||||||
|
LOGGER.info("setMember ignore, meta:" + (multiContractMeta == null) + (multiContractMeta == null ? "NULL" : " members:" + multiContractMeta.getMembers()));
|
||||||
}
|
}
|
||||||
|
|
||||||
if (isBundlePath(contractMeta.contract.getScriptStr())) {
|
if (isBundlePath(contractMeta.contract.getScriptStr())) {
|
||||||
status =
|
status =
|
||||||
get.syncGet(
|
get.syncGet(
|
||||||
@ -450,10 +472,6 @@ public class ContractClient {
|
|||||||
return contractMeta.logDetail.get(action);
|
return contractMeta.logDetail.get(action);
|
||||||
}
|
}
|
||||||
|
|
||||||
public boolean isDebug() {
|
|
||||||
return contractMeta.isDebug;
|
|
||||||
}
|
|
||||||
|
|
||||||
public long getTimes() {
|
public long getTimes() {
|
||||||
return times;
|
return times;
|
||||||
}
|
}
|
||||||
|
@ -465,14 +465,6 @@ public class ContractManager {
|
|||||||
return statusRecorder.getContractClient(meta.id);
|
return statusRecorder.getContractClient(meta.id);
|
||||||
}
|
}
|
||||||
|
|
||||||
public String startContractAndRedirectWithDebug(Contract c) {
|
|
||||||
return startContractAndRedirect(c, System.out, null, true);
|
|
||||||
}
|
|
||||||
|
|
||||||
public String startContractAndRedirect(Contract c, PrintStream ps) {
|
|
||||||
return startContractAndRedirect(c, ps, null, false);
|
|
||||||
}
|
|
||||||
|
|
||||||
public String getContractStateful(String contractID) {
|
public String getContractStateful(String contractID) {
|
||||||
ContractClient cc = getClient(contractID);
|
ContractClient cc = getClient(contractID);
|
||||||
if (null == cc) {
|
if (null == cc) {
|
||||||
@ -793,7 +785,7 @@ public class ContractManager {
|
|||||||
addLocalContractLog(action, meta.contract.getID(), meta.name, meta.contract.getOwner());
|
addLocalContractLog(action, meta.contract.getID(), meta.name, meta.contract.getOwner());
|
||||||
}
|
}
|
||||||
|
|
||||||
public String startContractAndRedirect(Contract c, PrintStream ps, String alias, boolean isDebug) {
|
public String startContractAndRedirect(Contract c, PrintStream ps, String alias) {
|
||||||
long freeMemory = getFreeMemory();
|
long freeMemory = getFreeMemory();
|
||||||
if (statusRecorder.runningProcess.size() > 5 && (freeMemory < memoryLimit)) {
|
if (statusRecorder.runningProcess.size() > 5 && (freeMemory < memoryLimit)) {
|
||||||
statusRecorder.hangLeastUsedContractProcess();
|
statusRecorder.hangLeastUsedContractProcess();
|
||||||
@ -821,51 +813,12 @@ public class ContractManager {
|
|||||||
if (null == c.getOwner()) {
|
if (null == c.getOwner()) {
|
||||||
c.setOwner(c.getPublicKey());
|
c.setOwner(c.getPublicKey());
|
||||||
}
|
}
|
||||||
|
|
||||||
LOGGER.debug("contract pubKey: " + c.getPublicKey());
|
LOGGER.debug("contract pubKey: " + c.getPublicKey());
|
||||||
|
|
||||||
// 合约启动时读取Manifest文件设置合约DOI
|
// 合约启动时读取Manifest文件设置合约DOI
|
||||||
setContractDOI(c);
|
setContractDOI(c);
|
||||||
setContractStateful(c);
|
setContractStateful(c);
|
||||||
|
|
||||||
// if (c.getDoipFlag()) {
|
|
||||||
// // 合约部署时,更新合约HandleRecord
|
|
||||||
// long tmpStart = System.currentTimeMillis();
|
|
||||||
// try {
|
|
||||||
// if (c.getDOI() == null || c.getDOI().equals("")) {
|
|
||||||
// updateContractHandleRecord( // 创建DO
|
|
||||||
// c,
|
|
||||||
// new ResultCallback() {
|
|
||||||
// @Override
|
|
||||||
// public void onResult(String str) {
|
|
||||||
// c.setDOI(str);
|
|
||||||
// // c.setID(str);
|
|
||||||
// LOGGER.debug("contract DOI: " + c.getDOI());
|
|
||||||
// }
|
|
||||||
// });
|
|
||||||
// } else {
|
|
||||||
// if (findConflictOfDOI(c.getDOI())) {
|
|
||||||
// r = new ContractResult(Status.Error, "Duplicate contract
|
|
||||||
// DOI.");
|
|
||||||
// return JsonUtil.toJson(r);
|
|
||||||
// }
|
|
||||||
// }
|
|
||||||
// } catch (Exception e) {
|
|
||||||
// ByteArrayOutputStream bo = new ByteArrayOutputStream();
|
|
||||||
// e.printStackTrace(new PrintStream(bo));
|
|
||||||
// c.setDOI("registerFailed");
|
|
||||||
// }
|
|
||||||
// LOGGER.info("DOIP executeTime: " + (System.currentTimeMillis() -
|
|
||||||
// tmpStart));
|
|
||||||
// } else c.setDOI("registerDisabled");
|
|
||||||
|
|
||||||
// if (contracts.containsKey(c.getID())) {
|
|
||||||
// r = new ContractResult(Status.Error, "contract existed");
|
|
||||||
// return JsonUtil.toJson(r);
|
|
||||||
// }
|
|
||||||
|
|
||||||
ContractClient client = new ContractClient(c);
|
ContractClient client = new ContractClient(c);
|
||||||
client.isDebug = isDebug;
|
|
||||||
String ret;
|
String ret;
|
||||||
String conflictCheck;
|
String conflictCheck;
|
||||||
addLocalContractLog("startContract", c.getID(), client.contractMeta.name, c.getOwner());
|
addLocalContractLog("startContract", c.getID(), client.contractMeta.name, c.getOwner());
|
||||||
@ -1054,7 +1007,7 @@ public class ContractManager {
|
|||||||
}
|
}
|
||||||
|
|
||||||
public String startContract(Contract c) {
|
public String startContract(Contract c) {
|
||||||
return startContractAndRedirect(c, System.out);
|
return startContractAndRedirect(c, System.out, null);
|
||||||
}
|
}
|
||||||
|
|
||||||
public String queryDEPort(String contractID) {
|
public String queryDEPort(String contractID) {
|
||||||
@ -1309,7 +1262,7 @@ public class ContractManager {
|
|||||||
rcb.onResult(JsonUtil.parseObjectAsJsonObject(cr));
|
rcb.onResult(JsonUtil.parseObjectAsJsonObject(cr));
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
} else if (null != request.getPublicKey() && !request.verifySignature()) {
|
} else if (null != request.getPublicKey() && request.getPublicKey().length() > 30 && !request.verifySignature()) {
|
||||||
request.setPublicKey(null);
|
request.setPublicKey(null);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -1673,6 +1626,7 @@ public class ContractManager {
|
|||||||
boolean isNodeManager = checkNodeManager(owner);
|
boolean isNodeManager = checkNodeManager(owner);
|
||||||
List<ContractInfo> ret = new ArrayList<>();
|
List<ContractInfo> ret = new ArrayList<>();
|
||||||
for (ContractMeta client : statusRecorder.getStatus().values()) {
|
for (ContractMeta client : statusRecorder.getStatus().values()) {
|
||||||
|
if (client.contract == null) continue;
|
||||||
if (!client.contract.getOwner().equals(owner) && !isNodeManager) {
|
if (!client.contract.getOwner().equals(owner) && !isNodeManager) {
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
@ -1805,7 +1759,7 @@ public class ContractManager {
|
|||||||
public String resetDebugFlag(String contractName, boolean isDebug) {
|
public String resetDebugFlag(String contractName, boolean isDebug) {
|
||||||
ContractClient client = getByName(contractName);
|
ContractClient client = getByName(contractName);
|
||||||
String result = client.get.syncGet("", "changeDebugFlag", String.valueOf(isDebug));
|
String result = client.get.syncGet("", "changeDebugFlag", String.valueOf(isDebug));
|
||||||
client.contractMeta.isDebug = isDebug;
|
client.contractMeta.contract.setDebug(isDebug);
|
||||||
return result;
|
return result;
|
||||||
}
|
}
|
||||||
/*
|
/*
|
||||||
|
@ -1,5 +1,7 @@
|
|||||||
package org.bdware.sc;
|
package org.bdware.sc;
|
||||||
|
|
||||||
|
import org.apache.logging.log4j.LogManager;
|
||||||
|
import org.apache.logging.log4j.Logger;
|
||||||
import org.bdware.sc.bean.Contract;
|
import org.bdware.sc.bean.Contract;
|
||||||
import org.bdware.sc.bean.FunctionDesp;
|
import org.bdware.sc.bean.FunctionDesp;
|
||||||
import org.bdware.sc.bean.IDSerializable;
|
import org.bdware.sc.bean.IDSerializable;
|
||||||
@ -20,7 +22,6 @@ public class ContractMeta implements IDSerializable {
|
|||||||
ContractStatusEnum status;
|
ContractStatusEnum status;
|
||||||
String name;
|
String name;
|
||||||
String id;
|
String id;
|
||||||
boolean isDebug;
|
|
||||||
Map<String, REvent.REventSemantics> declaredEvents;
|
Map<String, REvent.REventSemantics> declaredEvents;
|
||||||
List<FunctionDesp> exportedFunctions;
|
List<FunctionDesp> exportedFunctions;
|
||||||
Map<String, String> logDetail;
|
Map<String, String> logDetail;
|
||||||
@ -96,7 +97,7 @@ public class ContractMeta implements IDSerializable {
|
|||||||
// public setMask(){}
|
// public setMask(){}
|
||||||
|
|
||||||
public boolean getIsDebug() {
|
public boolean getIsDebug() {
|
||||||
return isDebug;
|
return contract.isDebug();
|
||||||
}
|
}
|
||||||
|
|
||||||
public FunctionDesp getExportedFunction(String action) {
|
public FunctionDesp getExportedFunction(String action) {
|
||||||
@ -124,9 +125,10 @@ public class ContractMeta implements IDSerializable {
|
|||||||
contract = c;
|
contract = c;
|
||||||
id = c.getID();
|
id = c.getID();
|
||||||
status = ContractStatusEnum.HANGED;
|
status = ContractStatusEnum.HANGED;
|
||||||
isDebug = false;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static Logger LOGGER = LogManager.getLogger(ContractMeta.class);
|
||||||
|
|
||||||
public void setContractExecutor(ContractExecutor executor) {
|
public void setContractExecutor(ContractExecutor executor) {
|
||||||
this.contractExecutor = executor;
|
this.contractExecutor = executor;
|
||||||
}
|
}
|
||||||
|
@ -95,7 +95,7 @@ public class ContractStatusRecorder extends StatusRecorder<ContractMeta> {
|
|||||||
}
|
}
|
||||||
|
|
||||||
private static String resumeStartContract(Contract contract) {
|
private static String resumeStartContract(Contract contract) {
|
||||||
return ContractManager.instance.startContractAndRedirect(contract, null);
|
return ContractManager.instance.startContractAndRedirect(contract, null, null);
|
||||||
}
|
}
|
||||||
|
|
||||||
public boolean hasPID(int pid) {
|
public boolean hasPID(int pid) {
|
||||||
|
@ -31,12 +31,17 @@ public class MultiContractRecorder extends StatusRecorder<MultiContractMeta> {
|
|||||||
public MultiContractMeta getMultiContractMeta(String idOrNameOrDOI) {
|
public MultiContractMeta getMultiContractMeta(String idOrNameOrDOI) {
|
||||||
if (idOrNameOrDOI == null) return null;
|
if (idOrNameOrDOI == null) return null;
|
||||||
ContractMeta meta = ContractManager.instance.statusRecorder.getContractMeta(idOrNameOrDOI);
|
ContractMeta meta = ContractManager.instance.statusRecorder.getContractMeta(idOrNameOrDOI);
|
||||||
|
return getMultiContractMeta(meta);
|
||||||
|
}
|
||||||
|
|
||||||
|
public MultiContractMeta getMultiContractMeta(ContractMeta meta) {
|
||||||
if (meta == null) return null;
|
if (meta == null) return null;
|
||||||
return getStatus().get(meta.id);
|
return getStatus().get(meta.id);
|
||||||
}
|
}
|
||||||
|
|
||||||
public MultiContractMeta createIfNotExist(String contractID) {
|
public MultiContractMeta createIfNotExist(String contractID) {
|
||||||
MultiContractMeta ret = getMultiContractMeta(contractID);
|
ContractMeta meta = ContractManager.instance.statusRecorder.createIfNotExist(contractID);
|
||||||
|
MultiContractMeta ret = getMultiContractMeta(meta);
|
||||||
if (null == ret) {
|
if (null == ret) {
|
||||||
LOGGER.info("requests don't contain contract " + contractID);
|
LOGGER.info("requests don't contain contract " + contractID);
|
||||||
ret = new MultiContractMeta(contractID);
|
ret = new MultiContractMeta(contractID);
|
||||||
|
@ -164,10 +164,6 @@ public class MultiContractMeta implements IDSerializable {
|
|||||||
}
|
}
|
||||||
return sb.toString();
|
return sb.toString();
|
||||||
}
|
}
|
||||||
public void setMembers(String[] m) {
|
|
||||||
members = m;
|
|
||||||
}
|
|
||||||
|
|
||||||
public void setMembers(JsonArray members) {
|
public void setMembers(JsonArray members) {
|
||||||
String[] copied = new String[members.size()];
|
String[] copied = new String[members.size()];
|
||||||
for (int i = 0; i < members.size(); i++) {
|
for (int i = 0; i < members.size(); i++) {
|
||||||
|
20
src/test/java/org/bdware/sc/test/ReflectionTest.java
Normal file
20
src/test/java/org/bdware/sc/test/ReflectionTest.java
Normal file
@ -0,0 +1,20 @@
|
|||||||
|
package org.bdware.sc.test;
|
||||||
|
|
||||||
|
import com.google.gson.Gson;
|
||||||
|
|
||||||
|
import java.lang.reflect.Method;
|
||||||
|
|
||||||
|
public class ReflectionTest {
|
||||||
|
public static class Test {
|
||||||
|
public static void go(String... args) {
|
||||||
|
System.out.println(new Gson().toJson(args));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
@org.junit.Test
|
||||||
|
public void go() throws Exception {
|
||||||
|
Method m = Test.class.getDeclaredMethod("go",String[].class);
|
||||||
|
String[] abc = new String[]{"ab", "cd"};
|
||||||
|
m.invoke(null, new Object[]{abc});
|
||||||
|
}
|
||||||
|
}
|
Loading…
Reference in New Issue
Block a user