0

Before java 17, we could get the FD on a datagram socket like below trick with reflection, in order to set a socket option for SO_PORTREUSE using a kernel API. But the implementation changed in latest java and the field is now called delegate, and the setAccessible API will not work with it due to a java.lang.reflect.InaccessibleObjectException.

Has anyone found an alternative way to get this from the datagram socket?

    private int getFD(DatagramSocket ds) throws Exception {
        Field dsImpl = DatagramSocket.class.getDeclaredField("impl");
        dsImpl.setAccessible(true);

        Field fd = DatagramSocketImpl.class.getDeclaredField("fd");
        fd.setAccessible(true);

        FileDescriptor fdi = (FileDescriptor) fd.get(dsImpl.get(ds));

        Field fdVal = FileDescriptor.class.getDeclaredField("fd");
        fdVal.setAccessible(true);

        return fdVal.getInt(fdi);
    }
1

1 Answer 1

-2

It appears that using the opens JVM flags we can get this work with java 17 again.

--add-opens=java.base/java.io=ALL-UNNAMED 
--add-opens=java.base/java.net=ALL-UNNAMED 
--add-opens=java.base/sun.nio.ch=ALL-UNNAMED 
--add-opens java.base/java.lang=ALL-UNNAMED 
--add-opens java.base/java.util=ALL-UNNAMED
Sign up to request clarification or add additional context in comments.

1 Comment

Private fields are private for a reason. They are implementation details. Any future release of Java is free to change or remove them. Java has warned people for many years not to rely on such internals.

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.