static {
SecurityFixerAgent.initialize();
}
public static void main(String[] args) throws Exception {
System.setSecurityManager(new SecurityManager());
System.out.println("Security manager is set!");
try {
System.setSecurityManager(null);
} catch (SecurityException e) {
System.out.println("Security manager cannot be reset!");
}
}
}
I get that I should be using an AgentBuilder and the premain method so that I can replace the method before it is first loaded, but my example doesn't seem to change anything when run:static AgentBuilder.Identified.Extendable createExtendable(Instrumentation inst) { final File folder = new File("bootstrap"); folder.mkdir(); final ElementMatcher.Junction<NamedElement> systemType = ElementMatchers.is(named("java.lang.System")); final AgentBuilder.Identified identified = new AgentBuilder.Default() .enableBootstrapInjection(folder, inst) .type(systemType); final Implementation definition = MethodDelegation.to(MySystemInterceptor.class); return identified.transform((builder, type) -> builder.method(named("setSecurityManager")) .intercept(definition)); }
It seems like this may be not be possible since it is static, final, and a Java internal class all at the same time. I've looked through the documentation and Stack Overflow, and there is an example of someone overriding System.currentTimeMillis using bootclasspath:But I don't know if instrumentation works along the same lines.
--
You received this message because you are subscribed to the Google Groups "Byte Buddy" group.
To unsubscribe from this group and stop receiving emails from it, send an email to byte-buddy+...@googlegroups.com.
For more options, visit https://groups.google.com/d/optout.
.withRedefinitionStrategy(AgentBuilder.RedefinitionStrategy.REDEFINITION)
.withTypeStrategy(AgentBuilder.TypeStrategy.Default.REDEFINE)
ByteBuddy byteBuddy = new ByteBuddy().with(Implementation.Context.Disabled.Factory.INSTANCE);
agentBuilder.withByteBuddy(byteBuddy)
For "try registering a AgentBuilder.Listener on your agent" I have:
agentBuilder.withListener(new AgentBuilder.Listener.StreamWriting(System.out))
So the final result is:private static AgentBuilder createAgentBuilder(Instrumentation inst) {
final File folder = new File("bootstrap");
folder.mkdir();
final ElementMatcher.Junction<NamedElement> systemType = ElementMatchers.named("java.lang.System");
AgentBuilder.Transformer transformer = (builder, typeDescription) -> {
return builder.method(ElementMatchers.named("setSecurityManager"))
.intercept(MethodDelegation.to(MySystemInterceptor.class));
};
ByteBuddy byteBuddy = new ByteBuddy().with(Implementation.Context.Disabled.Factory.INSTANCE);
final AgentBuilder agentBuilder = new AgentBuilder.Default()
//.enableBootstrapInjection(folder, inst)
.withByteBuddy(byteBuddy)
.withRedefinitionStrategy(AgentBuilder.RedefinitionStrategy.REDEFINITION)
.withTypeStrategy(AgentBuilder.TypeStrategy.Default.REDEFINE)
.withListener(new AgentBuilder.Listener.StreamWriting(System.out))
.type(systemType)
.transform(transformer);
return agentBuilder;
}
No, it is not. Is your interceptor package-private? Seems like the class is not visible.
static void install(String arg, Instrumentation inst) {Then I could point the agent at the bootstrap jar with:
appendInterceptorToBootstrap(arg, inst);
AgentBuilder agentBuilder = createAgentBuilder(inst);
agentBuilder.installOn(inst);
}
private static void appendInterceptorToBootstrap(String arg, Instrumentation inst) {
try {
File file = new File(arg).getCanonicalFile();
if (!file.exists()) {
throw new IllegalStateException(arg + " does not exist");
}
if (!file.isFile()) {
throw new IllegalStateException(arg + " is not a file");
}
if (!file.canRead()) {
throw new IllegalStateException(arg + " cannot be read");
}
JarFile jarFile = new JarFile(file);
inst.appendToBootstrapClassLoaderSearch(jarFile);
} catch (IOException e) {
throw new IllegalStateException(e);
}
}
You are welcome. You choose a very special use case for a first attempt, I am glad you got it working! Cheers, Rafael