2017-01-27 18 views
1

현재 내 대학 프로젝트를 진행하고 있습니다. 사용자가 자바 메소드를 텍스트 영역에 입력 할 수있는 응용 프로그램에서 작업합니다. 그런 다음 응용 프로그램은 이러한 메서드를 클래스에 넣고 사용자가 컴파일 단추를 눌렀을 때 컴파일합니다.java : 런타임에 상속 클래스 컴파일

은 지금까지 나는이 방법을 사용 : https://stackoverflow.com/a/2946402

을 그리고 그것은 처음에 나를 위해 일하지만, 그것은 단지 간단한 (독립) 클래스를 컴파일합니다. 런타임에 컴파일해야하는 클래스는 응용 프로그램의 다른 클래스를 확장합니다. 이렇게하면 사용자는 구현 한 수퍼 클래스의 일부 메서드에 액세스해야합니다.

public Class<?> loadClass(String filename) { 
     WorkingDirectory workingDirectory = WorkingDirectory.getInstance(); 
     File directory = workingDirectory.getCompileDirectory(); 
     File javaFile = workingDirectory.createJavaFileFromUserProgram(filename); 
     Class<?> cls = null; 
     try { 

      // Compile source file. 
      JavaCompiler compiler = ToolProvider.getSystemJavaCompiler(); 

      compiler.run(null, null, null, javaFile.getPath()); 

      URLClassLoader classLoader = URLClassLoader.newInstance(new URL[] { directory.toURI().toURL() }); 
      cls = Class.forName(filename, true, classLoader); 
     } catch (Exception e) { 
      e.printStackTrace(); 
     } 
     return cls; 
    } 

이 아무것도를 확장 does'nt 클래스와 잘 작동 : 이 내가 클래스를 컴파일하는 데 사용하는 방법입니다. 확장을 추가하면 다음과 같은 오류 메시지가 나타납니다.

error: cannot find symbol 
    public class UsersClass extends ExistingClass { public void main() { 
            ^
     symbol: class ExistingClass 
    1 error 
    java.lang.ClassNotFoundException: UsersClass 
     at java.net.URLClassLoader.findClass(URLClassLoader.java:381) 
     at java.lang.ClassLoader.loadClass(ClassLoader.java:424) 
     at java.net.FactoryURLClassLoader.loadClass(URLClassLoader.java:814) 
     at java.lang.ClassLoader.loadClass(ClassLoader.java:357) 
     at java.lang.Class.forName0(Native Method) 
     at java.lang.Class.forName(Class.java:348) 
     at utils.SimulatorClassloader.loadClass(SimulatorClassloader.java:51) 
     at simulator.Simulator.lambda$4(Simulator.java:171).... 

누군가 내 메소드에서 추가/변경해야하는 것을 알고 있습니까? 몇 시간 동안 조사를 해봤지만 그 이후로는 진전을 이루지 못했습니다.

+0

가 너무'ExisitingClass'을 창조 하셨 는가? – msagala25

+0

ExistingClass는 해당 응용 프로그램에 이미있는 클래스입니다. 나는 그것을 구현했다. 이 클래스에는 사용자 클래스가 기존 클래스를 확장하기 때문에 사용자가 사용할 수있는 일부 개인 메서드와 일부 공용 메서드가 포함되어 있습니다. UsersClass는 응용 프로그램이 시작될 때 존재하지 않는 클래스입니다. 응용 프로그램은 .java 파일을 생성하고 사용자가 런타임에 컴파일 버튼을 누를 때이를 컴파일합니다. – JWo

+1

당신은'UserClass'가'ExistingClass'을 가져 왔다고 생각하십니까? 아마 그들은 다른 패키지에 있습니다. 확인해 봐. – msagala25

답변

0

실수를 인식하지 못했지만 LKTN.25 힌트를 통해 알게되었습니다.

먼저 : 가져 오기 섹션에서 UsersClass에 오타가 있습니다. 이 실수가 사라진 후에 또 다른 오류가 발생했습니다.

둘째 : 내 기본 클래스에도 기본 생성자와 하위 클래스가 없습니다. 그리고 하위 클래스는 다른 생성자를 덮어 쓰지 않았습니다. 따라서 하위 클래스의 인스턴스를 만들 수 없습니다.

분명히 "누군가 내 메소드에서 추가/변경해야하는 것을 알고 있습니까?" 올바른 질문이 아니 었습니다. 그 실수는 어딘가에 있었다.

업데이트 : 런타임에 인스턴스를 만들 수 없어서 사용자 클래스에 생성자를 삽입해야한다고 생각했습니다. 사용자 클래스에는 생성자가 전혀 필요하지 않습니다 (Java의 경우와 같이). 그것은 슈퍼 클래스에서 가져옵니다.

분명히 다음 스 니펫이 작동하지 않습니다.

Class<?> cls = new SimulatorClassloader().loadClass(this.simulatorGUI.getStageTitle()); 
       try { 
        Method method = cls.getMethod("main"); 
        try { 
         method.invoke(cls.newInstance()); 
        } catch (Exception e1) { 
         // TODO Auto-generated catch block 
         e1.printStackTrace(); 
        } 

하지만 (약간 수정 코드) 실제로 작업을 수행합니다

Class<?> cls = new SimulatorClassloader().loadClass(this.simulatorGUI.getStageTitle()); 
       try { 
        Method method = cls.getMethod("main"); 
        try { 
         Object obj = cls.newInstance(); 
         method.invoke(obj); 
        } catch (Exception e1) { 
         // TODO Auto-generated catch block 
         e1.printStackTrace(); 
        } 
+0

'덮어 쓰기'? * override *를 의미합니까? – EJP

+0

예, 있습니다. 그 죄송합니다. – JWo