1

내 목적은 런타임에 클래스 정의에 새로운 속성 + getter setter 메소드를 동적으로 주입하는 것입니다. 현재 새로 생성 된 속성을 사용하여 코드를 다시 생성하여 생성 된 코드를 컴파일하는 메서드가 있습니다.런타임시 동적으로 생성되고 컴파일 된 java .classfile에 의해 런타임에 기존 클래스를 바꿔야 함

처음에는 컴파일 할 때 각 클래스에 대한 템플릿을 갖게됩니다. 프로젝트를 실행하면 템플릿 클래스가 런타임에로드됩니다. 동적으로 자바 코드를 생성하고 컴파일하는 코드를 작성했습니다. 아래 코드를 사용하여 새로 생성 된 클래스를로드 할 때 삽입 된 메소드에 액세스 할 수 없습니다. 나는 기존의 런타임 정의를 덮어 쓸 수 없다고 생각한다. 나는 많은 블로그를 훑어 보았지만 여전히 왜 그런지 이해할 수 없었다. 도와주세요.

DROOLS에서 새로 추가 된 메소드에 액세스 중이며 컴파일하는 동안 문제를 제기 할 수있는 다른 클래스에서는 참조되지 않습니다. 새로운 속성을 가진 룰 엔진의 규칙은 런타임에 업데이트되므로 그에 맞게 코드를 수정해야합니다. 아래는 ClassLoader 코드입니다. 이 코드는 예외를 던지지 않지만 내 목적을 해결하지 못합니다. 코딩이 올바른지 확실하지 않습니다.

+0

이것은 XY 문제처럼 들립니다. 요구 사항을 이해하면 Groovy ExpandoMetaClass가 원하는 것을 수행해야합니다. – chrylis

답변

1

URLClassLoader은 런타임에 새로 생성 된 클래스를로드해야 할 때 유용 할 수 있습니다. 죄송 합니다만 URLCLassLoader을 사용하여 이미로드 된 클래스의 정의를 새로 고침 (즉, 클래스 다시로드) 할 수 없습니다.

아래 코드를 사용하여 새로 생성 된 클래스를로드 할 때 삽입 된 메소드에 액세스 할 수있는 사람이 이 아닙니다. 나는 기존 런타임 정의를 덮어 쓸 수 없다고 생각합니다.

URLClassLoader은 지정된 클래스가 이미로드되어 있는지 확인합니다. 발견되면로드 된 클래스를 가리키는 인스턴스를 반환합니다. 따라서 기존 런타임 정의를 겹쳐 쓸 수는 없습니다.

솔루션 : 자바에서 동적 클래스 다시로드를 지원하는 표준 접근 방식, 하나는이 바이트의 정보를 사용하여 클래스를로드 (자사의 .class 파일) 클래스의 바이트의 정보를 읽어와 사용자 정의 클래스 로더를 작성해야 . 사용자 정의 클래스 로더를 사용하는 동안

기억해야 할 :

  • 쓰레기 수집해야한다 (클래스로드) 클래스 로더 및 클래스의 모든로드 된 인스턴스의 인스턴스를 기존의 클래스를 다시로드합니다.
  • 사용자 정의 ClassLoader는 특정 클래스 (로드/다시로드해야 함) 만로드해야합니다. 다른 모든 클래스 (빌드중인 Java 클래스 또는 다른 패키지의 클래스)로드 요청은 상위 클래스 로더에 위임되어야합니다. 내장 시스템 클래스를로드하려고하면 권한 예외가 발생할 수 있습니다. 클래스를로드 할 때 클래스 로더에 의해 다음

단계는 다음과 같습니다

  1. 확인 클래스가 이미로드 된 경우.
  2. 로드하지 않은 경우 상위 클래스 로더에게 클래스를로드하도록 요청하십시오.
  3. 상위 클래스 로더가 클래스를로드 할 수없는 경우이 클래스 로더에서로드하려고 시도하십시오.

클래스를 다시로드 할 수있는 클래스 로더를 구현할 때이 시퀀스에서 조금 벗어날 필요가 있습니다. 클래스 리로딩 요청을 상위 클래스 로더에 위임해서는 안됩니다.

다음은 Java에서 사용자 정의 클래스 로더를 개발하는 데 도움이되는 샘플 링크입니다.

http://www.javablogging.com/java-classloader-2-write-your-own-classloader/
http://tutorials.jenkov.com/java-reflection/dynamic-class-loading-reloading.html는 귀하의 코멘트 후 편집 :

내가 생각하는 문장의 InputStream 스트림 = getClass() getClassLoader를() 같이 getResourceAsStream (이름).. 예에서 loadClassData 함수가 최신 클래스를 가져 오지 않았습니다. 그것 (클래스의 이전 버전으로 가리키는) 스트림을 얻기 위해 기존 ClassLoader을 사용하고 있기 때문에

자네 말이 맞아

, 그것은 단순히 클래스의 최신 버전을 따기되지 않습니다.

당신은 대신 사용할 수

FileInputStream stream = new FileInputStream("Path to your class file"); 
ByteArrayOutputStream buffer = new ByteArrayOutputStream(); 
int data = stream.read(); 

while(data != -1){ 
    buffer.write(data); 
    data = stream.read(); 
} 

stream.close(); 

byte[] classData = buffer.toByteArray(); 


클래스의 바이트의 정보를 읽고 ClassLoader (사용자 정의 클래스 로더)의 버전을 사용하여로드하려고합니다.

+0

제공된 링크를 살펴 보았는데 개념이 명확합니다. 내 자신의 사용자 정의 클래스 로더를 작성하여 클래스 로딩 시퀀스를 변경해야합니다. 내 요구 사항에 따라 http://www.javablogging.com/java-classloader-2-write-your-own-classloader/와 동일한 코드를 사용했습니다. 그렇더라도 최신 버전의 클래스가로드되지 않습니다. 내 이해하려면 성명을 생각하십시오 InputStream stream = getClass(). getClassLoader(). getResourceAsStream (name); 예제의 loadClassData 함수가 최신 버전의 클래스를 선택하지 않습니다. 내가 뭔가를 놓친다면 나에게 조언해라. – Chandu

+0

@Chandu : 귀하의 의견을 게시 한 후 수정했습니다. 그것을보십시오. 도움이되는지 확인하십시오. –