Intercept RandomAccessFile

6 views
Skip to first unread message

Loïc MATHIEU

unread,
Dec 1, 2025, 9:03:42 AMDec 1
to Byte Buddy
Hi,

First of all, thanks for this amazing framework!

I want to intercept calls to the open(String, int) method of the RandomAccessFile.

I use the following code but the calls to the method are not intercepted.
I also tried with an intereceptor but it didn't work.
I tried with a REDEFINITION instead of a RETRANSFORMATION but it's the same result.

public class Main {
    public static void main(String[] args) {
        Instrumentation instrumentation = ByteBuddyAgent.install();
        ClassInjector.UsingUnsafe.Factory factory = ClassInjector.UsingUnsafe.Factory.resolve(instrumentation);

        new AgentBuilder.Default()
                .ignore(ElementMatchers.none())
                .disableClassFormatChanges()
                .with(new AgentBuilder.InjectionStrategy.UsingUnsafe.OfFactory(factory))
                .with(AgentBuilder.RedefinitionStrategy.RETRANSFORMATION)
                .with(new AgentBuilder.Listener.WithTransformationsOnly(AgentBuilder.Listener.StreamWriting.toSystemOut()))
                .with(new AgentBuilder.Listener.WithErrorsOnly(AgentBuilder.Listener.StreamWriting.toSystemError()))
                .with(new AgentBuilder.Listener.Filtering(ElementMatchers.is("java.io.RandomAccessFile"), AgentBuilder.Listener.StreamWriting.toSystemOut()))
                .type(ElementMatchers.is(RandomAccessFile.class))
                .transform((builder, typeDescription, classLoader, javaModule, protectionDomain) -> {
                    return builder.visit(Advice
                            .to(RandomAccessFileAdvice.class)
                            .on(ElementMatchers.isMethod().and(ElementMatchers.named("open")).and(ElementMatchers.takesArguments(String.class, Integer.class)).and(ElementMatchers.returns(void.class)).and(ElementMatchers.isPrivate()))
                    );
                })
                .installOn(instrumentation);

        try {
            var file = Path.of("/tmp/test").toFile();
            file.createNewFile();
            try (var raf = new RandomAccessFile(file, "rw")) {
                raf.write("Hello World".getBytes());
            }
        } catch (IOException e) {
            throw new RuntimeException(e);
        }
    }

    static class RandomAccessFileAdvice {

        @Advice.OnMethodEnter
        public static void onEnter(@Advice.Origin String method, @Advice.Argument(0) String name, @Advice.Argument(1) String mode) {
            System.err.println("Intercepted method: " + method + " with arguments: " + name);
        }

        @Advice.OnMethodExit
        public static void onExit(@Advice.Origin String method) {
            System.err.println("Exiting method: " + method + " with return value: ");
        }
    }
}

Rafael Winterhalter

unread,
Dec 1, 2025, 12:00:13 PMDec 1
to Loïc MATHIEU, Byte Buddy
What does the log say?

--
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.
To view this discussion visit https://groups.google.com/d/msgid/byte-buddy/7faf13fb-abce-4a14-870a-5e7f02c78763n%40googlegroups.com.

Loïc MATHIEU

unread,
Dec 1, 2025, 12:04:00 PMDec 1
to Rafael Winterhalter, Byte Buddy
Everything seems OK but it never intercept the method

[Byte Buddy] DISCOVERY java.io.RandomAccessFile [null, module java.base, Thread[#1,main,5,main], loaded=true]
[Byte Buddy] TRANSFORM java.io.RandomAccessFile [null, module java.base, Thread[#1,main,5,main], loaded=true]
[Byte Buddy] TRANSFORM java.io.RandomAccessFile [null, module java.base, Thread[#1,main,5,main], loaded=true]
[Byte Buddy] COMPLETE java.io.RandomAccessFile [null, module java.base, Thread[#1,main,5,main], loaded=true]

Rafael Winterhalter

unread,
Dec 1, 2025, 1:23:48 PMDec 1
to Loïc MATHIEU, Byte Buddy
Possibly, it is intrinsified by the VM.

You can run with -Dnet.bytebuddy.dump=/some/folder

to output the class files and see if everything is like expected in the resulting class file. If that's the case, the VM is not using the byte code.

Loïc MATHIEU

unread,
Dec 2, 2025, 8:17:38 AMDec 2
to Rafael Winterhalter, Byte Buddy
Hi,
Both are identical, here is the directory listing
-rw-rw-r-- 1 loic loic  790 Dec  2 14:04 'net.bytebuddy.utility.Invoker$Dispatcher.class'
-rw-rw-r-- 1 loic loic  12K Dec  2 14:04  net.bytebuddy.mirror.AccessibleObject-original.1764680699089.class
-rw-rw-r-- 1 loic loic 6.3K Dec  2 14:04  net.bytebuddy.mirror.AccessibleObject.1764680699089.class
-rw-rw-r-- 1 loic loic 1.4K Dec  2 14:04 'java.lang.ClassLoader$ByteBuddyAccessor$V1.1764680699142.class'
-rw-rw-r-- 1 loic loic 2.9K Dec  2 14:04 'net.bytebuddy.agent.builder.AgentBuilder$Default$ExecutingTransformer$ByteBuddy$ModuleSupport.1764680699171.class'
-rw-rw-r-- 1 loic loic  11K Dec  2 14:04  java.io.RandomAccessFile-original.1764680699220.class
-rw-rw-r-- 1 loic loic  11K Dec  2 14:04  java.io.RandomAccessFile.1764680699220.class

The two files java.io.RandomAccessFile-original.1764680699220.class and java.io.RandomAccessFile.1764680699220.class have the same method content for private void open(String name, int mode)

Rafael Winterhalter

unread,
Dec 2, 2025, 10:27:57 AMDec 2
to Loïc MATHIEU, Byte Buddy
I think you need to replace Integer.class with int.class in your matcher. 

Loïc MATHIEU

unread,
Dec 2, 2025, 10:45:18 AMDec 2
to Rafael Winterhalter, Byte Buddy
Oh, that was just that!
I used that before with an interceptor but the interceptor didn't work so I used an Integer.
But with a advice, int.class works and the advice is called.

Thanks a lot! 
Reply all
Reply to author
Forward
0 new messages