Thanks to visit codestin.com
Credit goes to github.com

Skip to content

Not able to intercept java.net.Socket class constructor #1850

@aballa-perforce

Description

@aballa-perforce

@raphw Pleas help.

We’re facing an issue where our code creates a large number of sockets, and once we hit the OS limit for file descriptors, the program shuts down. We increased the limit using ulimit -n 65535, but it still feels like a ticking time bomb.

The codebase is large, and we’re not able to find who is creating the sockets or from where. We use Apache HttpClient and many other third-party libraries, so it’s possible a third-party library is doing this.

lsof -p <OUR_CODE_PID> output
lsof -p <OUR_CODE_PID>

# Thousands of sockets like the following are being created:

java   <OUR_CODE_PID> <user> <FILE_DESCRIPTOR>u  sock(<TYPE_OF_DESCRIPTOR>)  0,9  0t0  <KERNEL_SOCKET_INODE>  protocol: TCP

We tried to gather more information using OS commands, but the OS reports these as UNBOUND/EPHEMERAL and we can’t get any additional details.

We support Java 17, but the current version runs on Java 8.

We attempted to write a java.net.Socket interceptor using byte-buddy-agent-1.10.0.jar and byte-buddy-dep-1.10.0.jar to intercept the java.net.Socket constructor, but it isn’t working.

We tested the same code against a custom class and it works fine.

Our research suggests that java.net.Socket is a bootstrap class, so we need to inject the agent into the bootstrap class loader. We tried that as well, but it’s still not working.

Can someone point us in the right direction?

SocketCreationAgent
import java.io.File;
import java.lang.instrument.Instrumentation;

import net.bytebuddy.agent.builder.AgentBuilder;
import net.bytebuddy.asm.Advice;
import net.bytebuddy.matcher.ElementMatchers;

public class SocketCreationAgent {

    public static void premain(String agentArgs, Instrumentation inst) {
        System.out.println("SocketCreationAgent loaded");

        // WORKS (custom class)
        new AgentBuilder.Default()
            .ignore(ElementMatchers.none())
            .type(ElementMatchers.named("com.soa.socket.interceptor.agent.test.InterceptThisClass"))
            .transform((builder, typeDescription, classLoader, module) -> {
                System.out.println("Transforming class: " + typeDescription.getName());
                return builder.constructor(ElementMatchers.any())
                              .intercept(Advice.to(SocketInterceptorAdvice.class));
            })
            .installOn(inst);

        // DOES NOT WORK (bootstrap class)
        new AgentBuilder.Default()
            .ignore(ElementMatchers.none())
            .type(ElementMatchers.named("java.net.Socket"))
            .transform((builder, typeDescription, classLoader, module) -> {
                System.out.println("Transforming class: " + typeDescription.getName());
                return builder.constructor(ElementMatchers.any())
                              .intercept(Advice.to(SocketInterceptorAdvice.class));
            })
            .installOn(inst);

        // DOES NOT WORK (with bootstrap injection)
        // Path to the agent JAR that includes SocketInterceptorAdvice.class
        File agentJar = new File("socket.interceptor-0.0.1-SNAPSHOT.jar");

        new AgentBuilder.Default()
            .ignore(ElementMatchers.none())
            .enableBootstrapInjection(inst, agentJar) // allow bootstrap class loader to see advice
            .type(ElementMatchers.named("java.net.Socket"))
            .transform((builder, typeDescription, classLoader, module) -> {
                System.out.println("Transforming java.net.Socket");
                return builder.constructor(ElementMatchers.any())
                              .intercept(Advice.to(SocketInterceptorAdvice.class));
            })
            .installOn(inst);
    }
}
SocketInterceptorAdvice
import net.bytebuddy.asm.Advice;

public class SocketInterceptorAdvice {

    @Advice.OnMethodEnter
    public static void onEnter() {
        System.out.println("SocketInterceptorAdvice: constructor called");
        Thread.dumpStack();
    }

    @Advice.OnMethodExit
    public static void onExit() {
        System.out.println("SocketInterceptorAdvice: constructor finished");
    }
}
InterceptThisClass
public class InterceptThisClass {
    public InterceptThisClass() {
        System.out.println("In Test Constructor.");
    }
}
SocketInterceptorTest
import java.io.IOException;
import java.net.Socket;

public class SocketInterceptorTest {

    public static void main(String[] args) throws IOException {
        // Open a few sockets to test interception
        for (int i = 0; i < 3; i++) {
            InterceptThisClass t = new InterceptThisClass();

            Socket socket = new Socket();
            // Socket socket = new Socket("google.com", 80);
        }
    }
}
Running the test
java -javaagent:/<path>/socket.interceptor-0.0.1-SNAPSHOT.jar SocketInterceptorTest
Sample output which works for custom class but not for java.net.Socket
SocketCreationAgent loaded
Transforming class: socket.interceptor.agent.test.InterceptThisClass
SocketInterceptorAdvice: constructor called
java.lang.Exception: Stack trace
	at java.lang.Thread.dumpStack(Thread.java:1336)
	at socket.interceptor.agent.test.InterceptThisClass.<init>(InterceptThisClass.java)
	at socket.interceptor.agent.test.SocketInterceptorTest.main(SocketInterceptorTest.java:11)
In Test Constructor.
SocketInterceptorAdvice: constructor finished
Transforming class: java.net.Socket
Transforming java.net.Socket
SocketInterceptorAdvice: constructor called
java.lang.Exception: Stack trace
	at java.lang.Thread.dumpStack(Thread.java:1336)
	at socket.interceptor.agent.test.InterceptThisClass.<init>(InterceptThisClass.java)
	at socket.interceptor.agent.test.SocketInterceptorTest.main(SocketInterceptorTest.java:11)
In Test Constructor.
SocketInterceptorAdvice: constructor finished
SocketInterceptorAdvice: constructor called
java.lang.Exception: Stack trace
	at java.lang.Thread.dumpStack(Thread.java:1336)
	at socket.interceptor.agent.test.InterceptThisClass.<init>(InterceptThisClass.java)
	at socket.interceptor.agent.test.SocketInterceptorTest.main(SocketInterceptorTest.java:11)
In Test Constructor.
SocketInterceptorAdvice: constructor finished

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions