In memory compiler 로 변경, 기동시 스크립트 로딩 추가
This commit is contained in:
@@ -22,11 +22,13 @@ dependencies {
|
|||||||
implementation 'org.springframework.boot:spring-boot-starter-thymeleaf'
|
implementation 'org.springframework.boot:spring-boot-starter-thymeleaf'
|
||||||
implementation 'nz.net.ultraq.thymeleaf:thymeleaf-layout-dialect'
|
implementation 'nz.net.ultraq.thymeleaf:thymeleaf-layout-dialect'
|
||||||
// implementation 'com.github.darrachequesne:spring-data-jpa-datatables:5.1.0'
|
// implementation 'com.github.darrachequesne:spring-data-jpa-datatables:5.1.0'
|
||||||
|
|
||||||
implementation 'org.apache.commons:commons-lang3:3.10'
|
implementation 'org.apache.commons:commons-lang3:3.10'
|
||||||
implementation 'commons-io:commons-io:2.6'
|
implementation 'commons-io:commons-io:2.6'
|
||||||
implementation 'com.jayway.jsonpath:json-path:2.4.0'
|
implementation 'com.jayway.jsonpath:json-path:2.4.0'
|
||||||
implementation 'io.netty:netty-all:4.1.60.Final'
|
implementation 'io.netty:netty-all:4.1.60.Final'
|
||||||
runtimeOnly 'com.h2database:h2'
|
runtimeOnly 'com.h2database:h2'
|
||||||
|
implementation 'org.mdkt.compiler:InMemoryJavaCompiler:1.3.0'
|
||||||
testImplementation 'org.springframework.boot:spring-boot-starter-test'
|
testImplementation 'org.springframework.boot:spring-boot-starter-test'
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -0,0 +1,28 @@
|
|||||||
|
package com.eactive.httpmockserver;
|
||||||
|
|
||||||
|
import com.eactive.httpmockserver.script.ScriptInfoService;
|
||||||
|
import com.eactive.httpmockserver.script.ScriptLoader;
|
||||||
|
import org.slf4j.Logger;
|
||||||
|
import org.slf4j.LoggerFactory;
|
||||||
|
import org.springframework.beans.factory.annotation.Autowired;
|
||||||
|
import org.springframework.stereotype.Component;
|
||||||
|
|
||||||
|
import javax.annotation.PostConstruct;
|
||||||
|
|
||||||
|
@Component
|
||||||
|
public class PostConstructBean {
|
||||||
|
private final Logger logger = LoggerFactory.getLogger(this.getClass());
|
||||||
|
|
||||||
|
@Autowired
|
||||||
|
public ScriptInfoService scriptInfoService;
|
||||||
|
|
||||||
|
@PostConstruct
|
||||||
|
public void init() {
|
||||||
|
logger.info("init scripts");
|
||||||
|
try {
|
||||||
|
ScriptLoader.getInstance().init(scriptInfoService);
|
||||||
|
} catch (Exception e) {
|
||||||
|
logger.error("init scripts failed", e);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -62,7 +62,7 @@ public class ScriptController {
|
|||||||
}
|
}
|
||||||
|
|
||||||
@PostMapping("/manage/saveScriptInfo")
|
@PostMapping("/manage/saveScriptInfo")
|
||||||
public String saveScriptInfo(@Valid ScriptInfo spec, BindingResult result, Model model) throws IOException, ClassNotFoundException {
|
public String saveScriptInfo(@Valid ScriptInfo spec, BindingResult result, Model model) throws Exception {
|
||||||
if (result.hasErrors()) {
|
if (result.hasErrors()) {
|
||||||
return "page/add-edit-script-info";
|
return "page/add-edit-script-info";
|
||||||
}
|
}
|
||||||
@@ -74,7 +74,7 @@ public class ScriptController {
|
|||||||
}
|
}
|
||||||
|
|
||||||
if (BooleanUtils.toBoolean(spec.getUseYn())) {
|
if (BooleanUtils.toBoolean(spec.getUseYn())) {
|
||||||
// 기존설정 useYn=N으로 수정
|
// ±âÁ¸¼³Á¤ useYn=NÀ¸·Î ¼öÁ¤
|
||||||
scriptInfoService.setUnuseOthers(spec.getId());
|
scriptInfoService.setUnuseOthers(spec.getId());
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -9,6 +9,8 @@ import java.util.Optional;
|
|||||||
public interface ScriptInfoService {
|
public interface ScriptInfoService {
|
||||||
public ScriptInfo findActiveScriptInfo();
|
public ScriptInfo findActiveScriptInfo();
|
||||||
|
|
||||||
|
public List<ScriptInfo> findAllScriptInfos();
|
||||||
|
|
||||||
public List<ScriptInfo> findAllScriptInfos(Pageable pageable);
|
public List<ScriptInfo> findAllScriptInfos(Pageable pageable);
|
||||||
|
|
||||||
public List<ScriptInfo> findAllScriptInfos(Example<ScriptInfo> example, Pageable pageable);
|
public List<ScriptInfo> findAllScriptInfos(Example<ScriptInfo> example, Pageable pageable);
|
||||||
|
|||||||
@@ -23,6 +23,11 @@ public class ScriptInfoServiceImpl implements ScriptInfoService {
|
|||||||
return dao.findFirstByUseYn("Y");
|
return dao.findFirstByUseYn("Y");
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public List<ScriptInfo> findAllScriptInfos() {
|
||||||
|
return dao.findAll();
|
||||||
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public List<ScriptInfo> findAllScriptInfos(Pageable pageable) {
|
public List<ScriptInfo> findAllScriptInfos(Pageable pageable) {
|
||||||
Page<ScriptInfo> pagedResult = dao.findAll(pageable);
|
Page<ScriptInfo> pagedResult = dao.findAll(pageable);
|
||||||
|
|||||||
@@ -1,6 +1,8 @@
|
|||||||
package com.eactive.httpmockserver.script;
|
package com.eactive.httpmockserver.script;
|
||||||
|
|
||||||
import org.apache.commons.io.IOUtils;
|
import org.apache.commons.io.IOUtils;
|
||||||
|
import org.mdkt.compiler.InMemoryJavaCompiler;
|
||||||
|
import org.springframework.beans.factory.annotation.Autowired;
|
||||||
|
|
||||||
import javax.tools.JavaCompiler;
|
import javax.tools.JavaCompiler;
|
||||||
import javax.tools.ToolProvider;
|
import javax.tools.ToolProvider;
|
||||||
@@ -12,6 +14,7 @@ import java.lang.reflect.InvocationTargetException;
|
|||||||
import java.net.URL;
|
import java.net.URL;
|
||||||
import java.net.URLClassLoader;
|
import java.net.URLClassLoader;
|
||||||
import java.util.HashMap;
|
import java.util.HashMap;
|
||||||
|
import java.util.List;
|
||||||
import java.util.Map;
|
import java.util.Map;
|
||||||
|
|
||||||
public class ScriptLoader{
|
public class ScriptLoader{
|
||||||
@@ -36,42 +39,29 @@ public class ScriptLoader{
|
|||||||
return newInstance;
|
return newInstance;
|
||||||
}
|
}
|
||||||
|
|
||||||
class DynamicLoader extends ClassLoader{
|
// class DynamicLoader extends ClassLoader{
|
||||||
public Class<Script> loadScript(String fullClassName, byte[] classData){
|
// public Class<Script> loadScript(String fullClassName, byte[] classData){
|
||||||
return (Class<Script>) defineClass(fullClassName,
|
// return (Class<Script>) defineClass(fullClassName,
|
||||||
classData, 0, classData.length);
|
// classData, 0, classData.length);
|
||||||
|
// }
|
||||||
|
// }
|
||||||
|
|
||||||
|
public void init(ScriptInfoService scriptInfoService) throws Exception {
|
||||||
|
List<ScriptInfo> scriptInfoList = scriptInfoService.findAllScriptInfos();
|
||||||
|
for (ScriptInfo info :scriptInfoList) {
|
||||||
|
load(info.getScriptName(), info.getScriptCode());
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
public void load(String scriptName, String scriptCode) throws ClassNotFoundException, IOException {
|
public void load(String scriptName, String scriptCode) throws Exception {
|
||||||
String source = scriptCode;
|
String source = scriptCode;
|
||||||
String fullPath = DYNAMIC_BASE_PATH + "/" + scriptName;
|
|
||||||
String fullPackage = DYNAMIC_BASE_PACKAGE + "." + scriptName;
|
String fullPackage = DYNAMIC_BASE_PACKAGE + "." + scriptName;
|
||||||
|
|
||||||
|
Class<Script> cls = (Class<Script>) InMemoryJavaCompiler.newInstance().compile(fullPackage, source);
|
||||||
|
|
||||||
File packagePath = new File(path + DYNAMIC_BASE_PATH);
|
// Script newInstance = cls.getDeclaredConstructor().newInstance();
|
||||||
if(!packagePath.exists())
|
// String xx = newInstance.postProcess("abc","ddd");
|
||||||
packagePath.mkdirs();
|
// System.out.println(xx);
|
||||||
|
|
||||||
File sourceFile = new File(path + fullPath + ".java");
|
|
||||||
new FileWriter(sourceFile).append(source).close();
|
|
||||||
|
|
||||||
// 만들어진 Java 파일을 컴파일한다.
|
|
||||||
JavaCompiler compiler = ToolProvider.getSystemJavaCompiler();
|
|
||||||
compiler.run(null, System.out, System.out, sourceFile.getPath());
|
|
||||||
|
|
||||||
|
|
||||||
// File classPath = new File(path + DYNAMIC_BASE_PATH);
|
|
||||||
|
|
||||||
// 컴파일된 Class를 Load
|
|
||||||
// URLClassLoader classLoader = URLClassLoader.newInstance(new URL[] {classPath.toURI().toURL()});
|
|
||||||
// Class<Script> cls = (Class<Script>) Class.forName(fullPackage, true, classLoader);
|
|
||||||
// new File(path + DYNAMIC_BASE_PATH + "/" + scriptName +".class").delete();
|
|
||||||
// sourceFile.delete();
|
|
||||||
File classFile = new File(path + DYNAMIC_BASE_PATH + "/" + scriptName +".class");
|
|
||||||
byte[] classData = IOUtils.toByteArray(new FileInputStream(classFile));
|
|
||||||
DynamicLoader dynamicLoader = new DynamicLoader();
|
|
||||||
Class<Script> cls = dynamicLoader.loadScript(fullPackage, classData);
|
|
||||||
this.loadedClass.put(scriptName, cls);
|
this.loadedClass.put(scriptName, cls);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
Reference in New Issue
Block a user