public class DynamicCompiler {
public static void main(String[] args) {
String sourceCode =
"public class HelloWorld {" +
" public void sayHello() {" +
" System.out.println(\"Hello, World!\");" + // 누락된 세미콜론 추가
" }" +
"}";
try {
// 컴파일된 클래스를 메모리에 저장하기 위한 임시 경로
File tempDir = new File(System.getProperty("java.io.tmpdir"));
// JavaCompiler API를 사용하여 코드 컴파일
JavaCompiler compiler = ToolProvider.getSystemJavaCompiler();
StandardJavaFileManager fileManager = compiler.getStandardFileManager(null, null, null);
// Java 소스 코드 파일 생성
File sourceFile = new File(tempDir, "HelloWorld.java");
System.out.println(sourceFile);
try (BufferedWriter writer = new BufferedWriter(new FileWriter(sourceFile))) {
writer.write(sourceCode);
}
// 컴파일 옵션 설정
Iterable<? extends JavaFileObject> compilationUnits =
fileManager.getJavaFileObjectsFromFiles(Collections.singletonList(sourceFile));
// DiagnosticCollector를 사용하여 에러 메시지 수집
DiagnosticCollector<JavaFileObject> diagnostics = new DiagnosticCollector<>();
// CompilationTask 생성 시 diagnostics를 전달
JavaCompiler.CompilationTask task = compiler.getTask(
null,
fileManager,
diagnostics, // 에러 메시지 수집기 추가
null,
null,
compilationUnits
);
// 컴파일 수행
boolean success = task.call();
// 컴파일 오류가 발생한 경우, 에러 메시지를 출력
if (!success) {
StringBuilder errorMessages = new StringBuilder();
for (Diagnostic<? extends JavaFileObject> diagnostic : diagnostics.getDiagnostics()) {
errorMessages.append("Error on line " + diagnostic.getLineNumber() + ": " + diagnostic.getMessage(null) + "\n");
}
System.err.println("Compilation failed:\n" + errorMessages.toString());
sourceFile.delete();
return;
}
// 컴파일된 클래스 로드
URLClassLoader classLoader = URLClassLoader.newInstance(new URL[] { tempDir.toURI().toURL() });
Class<?> clazz = classLoader.loadClass("HelloWorld");
// 클래스 인스턴스 생성 및 메소드 호출
Object instance = clazz.getDeclaredConstructor().newInstance();
Method method = clazz.getMethod("sayHello");
PrintStream orign = System.out;
ByteArrayOutputStream baos = new ByteArrayOutputStream();
PrintStream ps = new PrintStream(baos);
System.setOut(ps); // System.out을 새로운 PrintStream으로 변경
// 메소드 호출 (콘솔 출력이 ByteArrayOutputStream으로 캡처됨)
method.invoke(instance);
// 콘솔 출력된 값을 가져오기
String consoleOutput = baos.toString().trim(); // trim()을 사용하여 양쪽 공백 제거
System.setOut(orign);
// 캡처된 콘솔 출력 값 출력
System.out.println("Captured Console Output: " + consoleOutput);
// 임시 파일 정리
sourceFile.delete();
} catch (Exception e) {
e.printStackTrace();
}
}
}
'JAVA > Java Study' 카테고리의 다른 글
[Java] 한글 자소분리 (0) | 2024.11.08 |
---|---|
[Java] Record (0) | 2024.10.30 |
[GIS] 1. Shp 파일 (1) | 2024.09.06 |
[Java] Mvc 패턴 Model1 , Model2 (0) | 2024.06.25 |
[Java] Virtual Thread (0) | 2024.06.05 |