첨부 할 프로그램의 코드는 다음과 같습니다.실행중인 프로세스에 에이전트를 연결할 때 바이트 버디 변압기가 적용되지 않습니다.
public class Foo {
}
public class TestEntry {
public TestEntry() {
}
public static void main(String[] args) throws Exception {
try
{
while(true)
{
System.out.println(new Foo().toString());
Thread.sleep(1000);
}
}
catch(Exception e)
{}
}
}
내가하려고하는 것은 Foo.toString()이 다음 에이전트를 사용하여 'test'를 반환하도록하는 것입니다.
public class InjectionAgent {
public InjectionAgent() {
}
public static void agentmain(String args, Instrumentation inst) throws Exception
{
System.out.println("agentmain Args:" + args);
new AgentBuilder.Default()
.type(ElementMatchers.named("Foo"))
.transform(new AgentBuilder.Transformer() {
@Override
public Builder<?> transform(Builder<?> arg0, TypeDescription arg1,
ClassLoader arg2, JavaModule arg3) {
return arg0.method(ElementMatchers.named("toString"))
.intercept(FixedValue.value("test"));
}
}).installOn(inst);
}
public static void premain(String args, Instrumentation inst) throws Exception
{
System.out.println("premain Args:" + args);
new AgentBuilder.Default()
.type(ElementMatchers.named("Foo"))
.transform(new AgentBuilder.Transformer() {
@Override
public Builder<?> transform(Builder<?> arg0, TypeDescription arg1,
ClassLoader arg2, JavaModule arg3) {
return arg0.method(ElementMatchers.named("toString"))
.intercept(FixedValue.value("test"));
}
}).installOn(inst);
}
}
나는 - javaagent 방법을 사용했을 때 성공했음을 알았지 만, 첨부 방법이 실패한 반면, 여기에는 첨부 코드가 있습니다.
public class Injection {
public Injection() {
}
public static void main(String[] args) throws AttachNotSupportedException, IOException, AgentLoadException, AgentInitializationException, InterruptedException {
VirtualMachine vm = null;
String agentjarpath = args[0];
vm = VirtualMachine.attach(args[1]);
vm.loadAgent(agentjarpath, "This is Args to the Agent.");
vm.detach();
}
}
난 =========== 부착 후 TestEntry의 출력
[Byte Buddy] DISCOVERY Foo [[email protected], null, loaded=true]
[Byte Buddy] TRANSFORM Foo [[email protected], null, loaded=true]
[Byte Buddy] COMPLETE Foo [[email protected], null, loaded=true]
쇼 에이전트에 AgentBuilder.Listener.StreamWriting.toSystemOut()를 추가하려고 ============= 업데이트 ======================== =========== 나는이
public class Foo {
public String Bar()
{
return "Bar";
}
}
처럼 푸에 공개 방법 '바'를 정의하고 난 다음에 Foo.Bar()을 "수정"반환 만들려고 노력했다 방법 :
public static void agentmain(String args, Instrumentation inst) throws Exception
{
System.out.println("agentmain Args:" + args);
premain(args, inst);
new AgentBuilder.Default()
.with(RedefinitionStrategy.RETRANSFORMATION)
.disableClassFormatChanges()
.with(AgentBuilder.Listener.StreamWriting.toSystemOut())
.type(ElementMatchers.named("Foo"))
.transform(new AgentBuilder.Transformer() {
@Override
public Builder<?> transform(Builder<?> arg0, TypeDescription arg1,
ClassLoader arg2, JavaModule arg3) {
return arg0.visit(Advice.to(InjectionTemplate.class).on(ElementMatchers.named("Bar")));
}
})
.installOn(inst);
}
static class InjectionTemplate {
@Advice.OnMethodExit
static void exit(@Advice.Return String self) {
System.out.println(self.toString() + " " + self.getClass().toString());
self = new String("modified");
}
}
하지만 난이 오류가있어 :
java.lang.IllegalStateException: Cannot write to read-only parameter class java.lang.String at 1
어떤 제안?
'Foo'는'toString()'메소드를 가지고 있지 않습니다. 재정의는 메소드 추가를 지원하지 않습니다. 로딩 시간 계측 만 멤버 추가 또는 제거를 지원합니다. – Holger
반환 값 읽기 전용 속성을 false로 설정해야합니다. –
@Rafael 나는 그것이 작동합니다. 한 가지 더 질문합니다. 내 재정의를 제거 할 수 있습니까? 어떤 상황에 대해서는 원래의 상태로 프로그램을 다시 만들고 싶습니다 ... – surlary