2013-07-17 3 views
4

사용자가 코드를 변경 한 코드가 런타임에 JavaCompiler에 의해 다시 컴파일되고 변경된 코드를 실행하기 위해 다시로드해야하는 프로젝트와 같은 IDE에서 작업하고 있습니다. 리플렉션을 사용하고 있지만이 문제는 ClassLoader에서 한 번로드 한 클래스입니다. 아래 코드를 다시 실행하면 변경되지 않습니다. 정적 인 상태로 유지되지만 전체 응용 프로그램을 종료하고 다시 시작하면 다시 컴파일 된 코드의 변경 사항을 볼 수 있습니다.Java 반영, 런타임에 변경 및 재 컴파일 된 클래스를 다시로드하는 방법?

import java.io.File; 
    import java.net.URL; 
    import java.net.URLClassLoader; 

    class MyClass{ 
     public String myMethod() { 
      return "a message"; 
     } 
    } 

    public class Main { 
     public static void main(String[] argv) throws Exception { 
     URL[] urls = null; 
     File dir = new File(System.getProperty("user.dir") + File.separator + "dir"   +  File.separator); 
     URL url = dir.toURI().toURL(); 
     urls = new URL[] { url }; 
     ClassLoader cl = new URLClassLoader(urls); 
     Class cls = cl.loadClass("MyClass"); 
     MyClass myObj = (MyClass) cls.newInstance(); 

     } 

있지만 작동하지 : 내가 찾은 솔루션의

Class<?> clazz = Class.forName("Projects.Demo."+classname); 
    Constructor<?> ctor = clazz.getConstructor(App.class, Ctrl.class); 
    Object object = ctor.newInstance(new Object[] { app , ctrl}); 

하나는 java2s.com "동적으로 수정 된 클래스를 다시로드"로 제목이되는 것입니다 : 아래는 내가 사용하고 내 코드입니다 변경된 클래스는이 코드에 의해 다시로드되지 않으므로 나를 위해.

다른 옵션을 사용할 수있는 경우 도와 주시거나 제안 해주십시오.

+0

클래스가 새 ClassLoader를 만들고 새 ClassLoader로 클래스를로드하는 데 필요한 클래스를 다시로드하기 위해 클래스가 ClassLoader에 속합니다. 나는 당신이 당신이 그것을 다시로드 할 수 없을 메인 프로그램 classLoader에 의해로드되고있는 재로드하고 싶은 클래스를로드했다고 생각합니다. ClassLoader는 친 클래스 로더의 클래스를 상속합니다. – BevynQ

+0

그 방법에 대한 제안을 해주실 수 있나요? 힌트 나 튜토리얼로 도움이 될 수 있습니다. –

답변

3

좋아, 이건 내가해야 할 일이다.

Myclass가 표준 클래스 경로에 있으면 작동하지 않을 수 있으므로주의하십시오.

package nz.test.loader; 

public interface Executer { 

    public void execute(); 

} 


package nz.test.loader; 

import javax.tools.*; 
import java.io.File; 
import java.io.IOException; 
import java.io.PrintWriter; 
import java.io.StringWriter; 
import java.net.URI; 
import java.net.URL; 
import java.net.URLClassLoader; 
import java.util.*; 

public class LoadClass { 

    public static void main(String[] argv) throws Exception { 

     URL[] urls = null; 

     File dir = new File(System.getProperty("user.dir") + File.separator + "out/dir" + File.separator); 
     File classFile = new File(dir,"nz/co.test/loader/MyClass.class"); 
     long lastModified = classFile.lastModified(); 
     URL url = dir.toURI().toURL(); 
     urls = new URL[] { url }; 
     ClassLoader cl = new URLClassLoader(urls); 
     compileClass("first class", dir.getAbsolutePath()); 

     Class cls = cl.loadClass("nz.test.loader.MyClass"); 
     Executer myObj = (Executer) cls.newInstance(); 

     myObj.execute(); 
     compileClass("another class", dir.getAbsolutePath()); 
     cl = new URLClassLoader(urls); 

     cls = cl.loadClass("nz.test.loader.MyClass"); 
     myObj = (Executer) cls.newInstance(); 

     myObj.execute(); 

    } 

    public static void compileClass(String message, String destination) throws IOException { 
     JavaCompiler compiler = ToolProvider.getSystemJavaCompiler(); 
     DiagnosticCollector<JavaFileObject> diagnostics = new DiagnosticCollector<JavaFileObject>(); 

     StringWriter writer = new StringWriter(); 
     PrintWriter out = new PrintWriter(writer); 
     out.println("package nz.test.loader;"); 
     out.println("public class MyClass implements Executer{"); 
     out.println(" public void execute() {"); 
     out.println(" System.out.println(\""+message+"\");"); 
     out.println(" }"); 
     out.println("}"); 
     out.close(); 
     JavaFileObject file = new JavaSourceFromString("nz.test.loader.MyClass", writer.toString()); 

     Iterable<? extends JavaFileObject> compilationUnits = Arrays.asList(file); 

     List<String> optionList = new ArrayList<String>(); 

     JavaFileManager fileManager = compiler.getStandardFileManager(diagnostics, null,null); 
     List<String> params = new ArrayList(); 
     params.add(destination); 
     fileManager.handleOption("-d",params.iterator()); 
     JavaCompiler.CompilationTask task = compiler.getTask(null, fileManager, diagnostics, optionList, null, compilationUnits); 

     boolean success = task.call(); 
     for (Diagnostic diagnostic : diagnostics.getDiagnostics()) { 
      System.out.println(diagnostic.getCode()); 
      System.out.println(diagnostic.getKind()); 
      System.out.println(diagnostic.getPosition()); 
      System.out.println(diagnostic.getStartPosition()); 
      System.out.println(diagnostic.getEndPosition()); 
      System.out.println(diagnostic.getSource()); 
      System.out.println(diagnostic.getMessage(null)); 

     } 
     System.out.println("Success: " + success); 

    } 

} 

class JavaSourceFromString extends SimpleJavaFileObject { 
    final String code; 

    JavaSourceFromString(String name, String code) { 
     super(URI.create("string:///" + name.replace('.', '/') + Kind.SOURCE.extension),Kind.SOURCE); 
     this.code = code; 
    } 

    @Override 
    public CharSequence getCharContent(boolean ignoreEncodingErrors) { 
     return code; 
    } 
}