[英]No default constructor found; nested exception is java.lang.NoSuchMethodException with Spring MVC?
[英]Spring Request processing failed; nested exception is java.lang.NoSuchMethodException:
I'm trying to load my postgresql
db's table information not using traditional spring mvc pattern but also use java compiler
function to make class into internal project directory & reload whole project that System can Recognize new class & method
当我在这个机制中使用简单的计算 class 时,它可以工作(仅用于测试)
但是当我交替使用我为加载数据库(DAO,SERVICE)设置的方法时,
系统无法读取我的方法
这是错误代码
12월 02, 2020 3:29:57 오후 org.apache.catalina.core.StandardWrapperValve invoke
심각: 경로 [/inspect]의 컨텍스트 내의 서블릿 [dispatcher]을(를) 위한 Servlet.service() 호출이, 근본 원인(root cause)과 함께, 예외 [Request processing failed; nested exception is java.lang.NoSuchMethodException: kr.com.inspect.rule.Test.getMemberList(kr.com.inspect.service.impl.MemberServiceImpl)]을(를) 발생시켰습니다.
java.lang.NoSuchMethodException: kr.com.inspect.rule.Test.getMemberList(kr.com.inspect.service.impl.MemberServiceImpl)
at java.base/java.lang.Class.getMethod(Class.java:2108)
at kr.com.inspect.rule.RuleCompiler.runObject(RuleCompiler.java:127)
at kr.com.inspect.controller.PostgreController.testRun(PostgreController.java:185)
在编译状态系统可以读取你的方法,但是当它试图读取方法时,它不起作用
参数可以是这个问题的Issue
在情况 1. 我在物理上划分创建 function 并在 controller 中运行 function 的功能。
在情况 2. 代表 Test 的方法具有与 MemberServiceImpl.getMemberList 相同的参数(列表)
请不要问我你为什么做傻事。 这就是我在这里的原因。
很抱歉我的英语很差
我制作的更多课程信息
Controller
/**
* 클래스 파일 생성
* @return 디렉토리 값 반환
* @throws Exception 예외 처리
*/
@PostMapping("/xlsxDir")
@ResponseBody
public String xlsxDir () throws Exception{
RuleCompiler test = new RuleCompiler();
System.out.println("button clicked");
// report 패키지의 TestRuleCompiler 클래스를 호출하는 테스트 소스
String str ="\t\tTestRuleCompiler testRuleCompiler = new TestRuleCompiler();\n" +
"\t\tint result = testRuleCompiler.Test(list);\n" +
"\t\treturn result;\n";
// jsonLogs 읽어오는 소스
// String str ="\t\tList<Metadata> jsonLogs = postgreService.getMetadata();\n\t\tSystem.out.println(jsonLogs.get(0));\n\t\tSystem.out.println(\"success\");";
// java 파일 컴파일 후 class 로드하는 메서드 호출
//Object obj =
test.create(str, memberService);
return "true";
}
/**
* 클래스 파일 실행
* @return 디렉토리 값 반환
* @throws Exception 예외 처리
*/
@PostMapping("/testRun")
@ResponseBody
public String testRun () throws Exception{
RuleCompiler rc = new RuleCompiler();
System.out.println("button clicked");
Test test = new Test();
// Test.class 안의 runMethod 메서드 실행하는 메서드 호출
List<Member> rst = rc.runObject(test, memberService);
System.out.println("result : " + rst);
return "true";
}
class TestRuleCompiler
package kr.com.inspect.report;
import java.util.List;
import kr.com.inspect.dao.MemberDao;
import kr.com.inspect.dto.Member;
public class TestRuleCompiler {
public MemberDao memberDao;
public int Test(int[] list){
int result = 0;
for(int i : list)
result = result + i;
return result;
}
public List<Member> getMemberList() {
List<Member> list = memberDao.getMemberList();
return list;
}
}
class 规则编译器
package kr.com.inspect.rule;
import edu.emory.mathcs.backport.java.util.Arrays;
import kr.com.inspect.dto.Member;
import kr.com.inspect.service.MemberService;
import kr.com.inspect.service.PostgreService;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.stereotype.Component;
import javax.tools.*;
import java.io.File;
import java.io.FileWriter;
import java.lang.reflect.Method;
import java.net.URL;
import java.net.URLClassLoader;
import java.util.ArrayList;
import java.util.List;
@Component
public class RuleCompiler extends Thread {
public static final Logger logger = LoggerFactory.getLogger(RuleCompiler.class);
// 자바파일 생성하고 컴파일후 class 파일 로드해오는 파일 (이 메서드는 잘 작동됩니다.)
public Object create(String body, MemberService memberService)throws Exception{
String path = "/home/namuhwang/Documents/GitHub/spring-db-connect/src/main/java/";
String classPath = "/home/namuhwang/Documents/GitHub/spring-db-connect/target/classes/";
// Source를 만들고 Java파일 생성
File sourceFile = new File(path+"kr/com/inspect/rule/Test.java");
String source = this.getSource(body);
new FileWriter(sourceFile).append(source).close();
// java파일 컴파일 할때 옵션주기
List<String> optionList = new ArrayList<>();
// CLASS PATH 추가
optionList.add("-classpath");
optionList.add(System.getProperty("java.class.path")+":"+classPath);
// optionList.add(System.getProperty("java.class.path"));
// CLASS 파일 저장할 디렉토리
optionList.add("-d");
optionList.add(classPath);
// 만들어진 Java 파일을 컴파일
JavaCompiler compiler = ToolProvider.getSystemJavaCompiler();
List<String> sources = Arrays.asList(new String[] {path+"kr/com/inspect/rule/Test.java"});
DiagnosticCollector<JavaFileObject> diagnostic = new DiagnosticCollector<JavaFileObject>();
StandardJavaFileManager fileManager = compiler.getStandardFileManager(diagnostic, null, null);
Iterable<? extends JavaFileObject> compilationUnit
= fileManager.getJavaFileObjectsFromStrings(sources);
System.out.println("before Compile");
JavaCompiler.CompilationTask task = compiler.getTask(
null,
fileManager,
diagnostic,
optionList,
null,
compilationUnit
);
Boolean success = task.call();
System.out.println("after Compile");
// 기본 comiler run하는 코드 (추후에 삭제 예정)
// compiler.run(null, System.out, System.out, path+"kr/com/inspect/rule/Test.java");
System.out.println("before Load");
// 컴파일된 Class를 Load
URLClassLoader classLoader = URLClassLoader.newInstance(new URL[] {new File(classPath).toURI().toURL()});
// Class<?> cls = Class.forName("kr.com.inspect.rule.Test", true, classLoader);
Class<?> cls = classLoader.loadClass("kr.com.inspect.rule.Test");
System.out.println("after Load");
// Load한 Class의 Instance를 생성
return cls.newInstance();
// return (Object)true;
}
public String getSource(String body) {
StringBuffer sb = new StringBuffer();
// Java Source를 생성한다.
// report 패키지의 TestRuleCompiler 클래스를 호출하는 테스트 소스
sb.append("package kr.com.inspect.rule;\n"+
"import kr.com.inspect.report.TestRuleCompiler;\n"+
"public class Test { \n"+
"public int runMethod(int[] list) {\n")
.append(body)
.append("\t}\n}");
// jsonLog 읽어오는 소스
// sb.append("package kr.com.inspect.rule;\n"+
// "import kr.com.inspect.service.PostgreService;\n" +
// "import kr.com.inspect.dto.Metadata;\n"+
// "import java.util.List;\n"+
// "public class Test { \n"+
// "\tpublic void runMethod(PostgreService postgreService) throws Exception {\n")
// .append(body)
// .append("\t}\n}");
return sb.toString();
}
// Test.class 안의 runMethod 메서드 실행
@SuppressWarnings("unchecked")
public List<Member> runObject(Object obj, MemberService memberService) throws Exception{
//int[] list = {1, 2, 3};
logger.debug("d",obj);
logger.warn("w",obj);
logger.error("e",obj);
logger.info("i",obj);
logger.trace("t",obj);
System.out.println(memberService);
System.out.println(obj);
Class<?> arguments[] = new Class[]{memberService.getClass()}; //postgreService
System.out.println(arguments);
logger.debug("d",obj);
logger.warn("w",obj);
logger.error("e",obj);
logger.info("i",obj);
logger.trace("t",obj);
// Source를 만들때 지정한 Method를 실행
// runMethod 메소드 지정
Method objMethod = obj.getClass().getMethod("getMemberList", arguments);
// 인자로 list를 보냄
Object result = objMethod.invoke(obj, memberService);
// postgreService 가 인자로 보내져야 하는데 보내지질 않음
System.out.println("before Method");
System.out.println(obj);
System.out.println(memberService);
// 문제 부분 (여기서 실행이 멈춤)
logger.debug("d",obj);
logger.warn("w",obj);
logger.error("e",obj);
logger.info("i",obj);
logger.trace("t",obj);
//Method objMethod = obj.getClass().getMethod("runMethod", arguments);
logger.debug("d",obj);
logger.warn("w",obj);
logger.error("e",obj);
logger.info("i",obj);
logger.trace("t",obj);
System.out.println(objMethod);
System.out.println("after Method");
System.out.println(obj);
System.out.println(memberService);
logger.debug("d",obj);
logger.warn("w",obj);
logger.error("e",obj);
logger.info("i",obj);
logger.trace("t",obj);
//Object result = objMethod.invoke(obj, postgreService);
logger.debug("d",obj);
logger.warn("w",obj);
logger.error("e",obj);
logger.info("i",obj);
logger.trace("t",obj);
System.out.println(result);
System.out.println("after invoke");
return (List<Member>) result;
}
}
class 测试
package kr.com.inspect.rule;
import java.util.List;
import org.springframework.beans.factory.annotation.Autowired;
import kr.com.inspect.dto.Member;
import kr.com.inspect.report.TestRuleCompiler;
import kr.com.inspect.service.impl.MemberServiceImpl;
public class Test {
public MemberServiceImpl memberServiceimpl;
public int runMethod01(int[] list) {
TestRuleCompiler testRuleCompiler = new TestRuleCompiler();
int result = testRuleCompiler.Test(list);
return result;
}
public List<Member> getMemberList() {
TestRuleCompiler testRuleCompiler = new TestRuleCompiler();
List<Member> result = testRuleCompiler.getMemberList();
return result;
}
}
好吧,如果您跳过编译时检查并重新实现轮子,您会遇到其他情况下不会遇到的问题。
你的代码
Method objMethod = obj.getClass().getMethod("getMemberList", arguments);
Object result = objMethod.invoke(obj, memberService);
正在调用Test
类型的obj
的getMemberList
但Test
的public List<Member> getMemberList()
方法没有参数,因此您可能不应该将memberService
作为参数传递,顺便提一下,异常中也提到了这一点( java.lang.NoSuchMethodException: kr.com.inspect.rule.Test.getMemberList(kr.com.inspect.service.impl.MemberServiceImpl))
):
Method objMethod = obj.getClass().getMethod("getMemberList");
Object result = objMethod.invoke(obj);
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.