#java #spring #exception
#java #spring #исключение
Вопрос:
Я пытаюсь загрузить postgresql
информацию о таблице моей базы данных, не используя традиционный шаблон spring mvc, но также использую java compiler
функцию для создания класса во внутреннем каталоге проекта и перезагрузки всего проекта, чтобы система могла распознать новый класс и метод
Когда я использую простой вычислительный класс в этом механизме, он работает (только для тестирования)
Но когда я альтернативно использую метод, который я настроил для загрузки БД (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)
Конечно, я ищу эту ситуацию с ошибкой
- В состоянии компиляции система может прочитать ваш метод, но когда она пытается прочитать метод, он не работает
- Параметр может быть причиной этой проблемы
В случае 1. Я физически разделяю функции, которые создают функцию и запускают функцию в контроллере.
В случае 2. Метод, который обозначает Test, имеет тот же параметр (список), что и MemberServiceImpl.getMemberList
пожалуйста, не спрашивайте меня, почему вы делаете глупости. Вот почему я здесь.
Мне жаль, что мой английский плохой
Пожалуйста, помогите
Дополнительная информация о классах, которую я сделал
Контроллер
/**
* 클래스 파일 생성
* @return 디렉토리 값 반환
* @throws Exception 예외 처리
*/
@PostMapping("/xlsxDir")
@ResponseBody
public String xlsxDir () throws Exception{
RuleCompiler test = new RuleCompiler();
System.out.println("button clicked");
// report 패키지의 TestRuleCompiler 클래스를 호출하는 테스트 소스
String str ="ttTestRuleCompiler testRuleCompiler = new TestRuleCompiler();n"
"ttint result = testRuleCompiler.Test(list);n"
"ttreturn resu<n";
// jsonLogs 읽어오는 소스
// String str ="ttList<Metadata> jsonLogs = postgreService.getMetadata();nttSystem.out.println(jsonLogs.get(0));nttSystem.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";
}
класс 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 resu<
}
public List<Member> getMemberList() {
List<Member> list = memberDao.getMemberList();
return list;
}
}
компилятор правил класса
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>) resu<
}
}
тест класса
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 resu<
}
public List<Member> getMemberList() {
TestRuleCompiler testRuleCompiler = new TestRuleCompiler();
List<Member> result = testRuleCompiler.getMemberList();
return resu<
}
}
Ответ №1:
Что ж, если вы пропустите проверки во время компиляции и повторно реализуете wheel, вы столкнетесь с проблемами, которых у вас не было бы в противном случае.
Ваш код
Method objMethod = obj.getClass().getMethod("getMemberList", arguments);
Object result = objMethod.invoke(obj, memberService);
вызывается getMemberList
тип obj
, который имеет тип Test
, но public List<Member> getMemberList()
метод Test
не имеет параметров, поэтому, вероятно, вам не следует передавать memberService
в качестве параметра, который, кстати, также упоминается в exception ( 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);
Комментарии:
1. Спасибо, но я попробовал ваше решение и перезапустил проект, все равно получаю ту же ошибку; (
2. Итак, вы вызываете
obj.getClass().getMethod
безarguments
, но все равно получаете сообщение об ошибке, что метод с параметрами не найден?3. на самом деле я действительно не знаю, что это проблема с параметрами? или проблема с аннотациями и компонентами? но, согласно истории журнала, система продолжает говорить, что не может найти метод
4. Что вы не понимаете в «методе тестирования public List<Member> getMemberList() не имеет параметров, поэтому, вероятно, вам не следует передавать MemberService в качестве параметра»? В вашем коде буквально говорится: «Дайте мне метод getMemberList с параметром типа MemberService», а Java говорит: «В Test нет такого метода», что, очевидно, верно.
5. Мой коллега и я решаем эту проблему, используя параметры класса, чтобы система могла считывать имена методов thx для ответа на мой вопрос