Java 프로젝트를 컴파일하여 생성 된 클래스 파일 목록을 입력으로 받아들이고 이러한 클래스와 관련된 테스트 케이스를 실행하는 플러그인을 작성했습니다. 클래스 로더를 사용하여 클래스를로드하고 JUnitCore()를 사용하여 테스트 케이스를 실행합니다. 아래의 코드는 잘 작동하며 입력 클래스에 대해 실행될 때 아무런 문제가 없습니다.ClassLoader가 이전 버전의 클래스를로드합니다. - Java
Class<?> clazz = Class.forName(className);
Request request = Request.aClass(clazz);
Result result = new JUnitCore().run(request);
그러나 내 프로그램에서 위의 코드는 유사한 클래스에 대해 수천 번 실행해야합니다. 단순함을 위해서 우리는 단 하나의 클래스 만 가지고 있다고 가정합니다. 클래스가 컴파일 된 후 컴파일러 에러 이없는 경우 플러그인의 bin 디렉토리로 복사 된 후 내 프로그램이 호출되고 모든 테스트 케이스를 통과하는지 확인합니다 .
다음 반복에서는 원래 소스 코드가 자동으로 변경된 다음 컴파일되고 컴파일러 오류가없는 경우 테스트 케이스가 다시 복사됩니다. 이 프로세스는 원하는 결과를 얻기 위해 수천 번 실행될 수 있습니다. [경우에 따라서는 몇 시간]
그러나 클래스 로더는 컴파일러 클래스의 첫 번째 버전을 사용하고 다음 반복에서는 새 버전을로드하지 않고 이전 버전을 계속 사용합니다. 나는 각 추가에서 Thread.sleep (1000)을 copy 명령 앞에 추가하면 올바른 버전을 찾을 수 있음을 발견했다.
첫째, 내가 왜하지 복사 후 사본 및 전에 일시 정지 이 필요하십니까? 아마도 파일이 클래스 로더가로드하기 전에 파일을 복사하는 동안 finalize되지 않았을 것이라고 예상하고, 클래스 로더는 이전 버전을 사용합니다. 그러나 복사 전에 일시 중지를 추가하면 제대로 작동하고 복사 후 일시 중지를 추가하면 이전 버전이 사용됩니다.
둘째, 내 프로그램에서 수면을 사용하는 것은 좋지 않습니다. 가장 좋은 경우에 내 플러그인은 원하는 결과를 찾기 위해 몇 시간 동안 작동 할 수 있으며 각 반복에서 수면을 추가하려면 결과를 얻는 데 며칠이 걸릴 수 있습니다. 따라서 나는 수면이없는 해결책을 선호합니다. Thread.sleep없이 위의 문제를 어떻게 복사 할 수 있는지 알고 있다면 알려주십시오.
ClassLoader는 실제로 클래스의 "previos"버전을 사용하지 않으며 처음로드 될 때 클래스의 첫 번째 버전을 사용합니다. 클래스가로드 된 경우 새 클래스로 대체되지 않습니다. 새 버전을로드하려면 약간의 마법을 써야합니다. 그리고 그런 질문은 벌써 물었다. 검색을 사용하라. –
[클래스 새로 고침을위한 새 ClassLoader 만들기] 가능한 복제본 (http://stackoverflow.com/questions/9819318/create-new-classloader-to-reload-class) – Joe
수면을 추가하면 올바른 버전이 사용됩니다. – user3601784