내 응용 프로그램을 시작하는 동안 추가 기능으로 일부 코드를 보강하려고합니다. 전체 설정 자체가 잘 작동하지만 javassist가 잘못된 코드를 생성 할 수 있다고 생각하는 지점이 있습니다.
특정 클래스의 특정 메서드에서이 작업을 수행하고 있으며 반환 값이 실제로 StringBuilder
또는 유형 인지 확인하기 전에 확인했습니다 StringBuffer
.
ctMethod.insertAfter("$_.SOME_METHOD(); $_.SOME_FIELD = <...>;");
SOME_METHOD () 및 SOME_FIELD는 모두 및 AbstractStringBuilder
의 수퍼 클래스 인 에서 선언됩니다 . 둘 다 공용으로 정의되며 그 자체는 패키지 전용입니다.StringBuilder
StringBuffer
java.lang.AbstractStringBuilder
작업 자체는 성공했지만이 코드를 실행하면 " java.lang.IllegalAccessError: tried to access class java.lang.AbstractStringBuilder from class <...>
" 오류가 발생 합니다. 인쇄 디버깅을 통해 메서드에 액세스하는 것은 잘 작동하지만 필드에 액세스하면 충돌이 발생한다는 것을 알았습니다.
그래서 생성 된 바이트 코드를 확인했습니다.
...
invokevirtual #41 <java/lang/StringBuilder.SOME_METHOD>
...
getfield #72 <java/lang/AbstractStringBuilder.SOME_FIELD>
...
따라서 메서드에 액세스하려면 StringBuilder
자체적으로 확인되지만 필드의 경우 수정 된 코드의 위치에서 액세스 할 수없는 AbstractStringBuilder로 확인됩니다. Btw, 디 컴파일 된 바이트 코드는 괜찮아 보입니다.
또한 정적 코드에서이 필드에 액세스하고 있으므로이 필드의 바이트 코드를 확인했습니다.
...
getfield #37 <java/lang/StringBuilder.SOME_FIELD>
...
이것은 기본 컴파일러로 컴파일 된 코드이며 참조 용으로 AbstractStringBuilder를 사용하지 않습니다.
그래서 내 질문은 : JVM의 가시성과 상속 개념에 관한 것을 감독 했습니까? 아니면 javassist가 이것을 올바르게 해결하지 못합니까? 내 설명이 이해할 수 있기를 바랍니다. 그렇지 않으면 알려 주시면 개선하도록 노력하겠습니다.
이것은 Javassist의 오류입니다.
필드는 가상이 아닙니다. 다른 클래스의 이름을 지정하면 해당 클래스에서 액세스 할 수 있어야하는 다른 (그림자) 필드에 실제로 액세스 할 수 있습니다.
이 기사는 인터넷에서 수집됩니다. 재 인쇄 할 때 출처를 알려주십시오.
침해가 발생한 경우 연락 주시기 바랍니다[email protected] 삭제
몇 마디 만하겠습니다