Skip to content

Commit

Permalink
Degrade gracefully on Java 19+ (#145)
Browse files Browse the repository at this point in the history
  • Loading branch information
basil authored Jun 27, 2023
1 parent 11c1d71 commit d62e819
Show file tree
Hide file tree
Showing 2 changed files with 45 additions and 42 deletions.
82 changes: 41 additions & 41 deletions src/main/java/org/kohsuke/file_leak_detector/AgentMain.java
Original file line number Diff line number Diff line change
Expand Up @@ -132,7 +132,6 @@ public void run() {
FileInputStream.class,
FileOutputStream.class,
RandomAccessFile.class,
Class.forName("java.net.PlainSocketImpl"),
ZipFile.class,
AbstractSelectableChannel.class,
AbstractInterruptibleChannel.class,
Expand All @@ -142,6 +141,7 @@ public void run() {

addIfFound(classes, "sun.nio.ch.SocketChannelImpl");
addIfFound(classes, "java.net.AbstractPlainSocketImpl");
addIfFound(classes, "java.net.PlainSocketImpl");
addIfFound(classes, "sun.nio.fs.UnixDirectoryStream");
addIfFound(classes, "sun.nio.fs.UnixSecureDirectoryStream");
addIfFound(classes, "sun.nio.fs.WindowsDirectoryStream");
Expand Down Expand Up @@ -301,59 +301,59 @@ static List<ClassTransformSpec> createSpec() {
new ClassTransformSpec(
"sun/nio/fs/WindowsDirectoryStream", new CloseInterceptor("close")));
}
Collections.addAll(
spec,
/*
* Detect selectors, which may open native pipes and anonymous inodes for event polling.
*/
new ClassTransformSpec(AbstractSelector.class,
new ConstructorInterceptor("(Ljava/nio/channels/spi/SelectorProvider;)V", "openSelector"),
new CloseInterceptor("close")),
/*
* Detect selectors, which may open native pipes and anonymous inodes for event polling.
*/
spec.add(new ClassTransformSpec(
AbstractSelector.class,
new ConstructorInterceptor("(Ljava/nio/channels/spi/SelectorProvider;)V", "openSelector"),
new CloseInterceptor("close")));
/*
* java.net.Socket/ServerSocket uses SocketImpl, and this is where FileDescriptors are actually managed.
*
* SocketInputStream/SocketOutputStream does not maintain a separate FileDescriptor. They just all piggy back on
* the same SocketImpl instance.
*/
if (Runtime.version().feature() < 19) {
spec.add(new ClassTransformSpec(
"java/net/PlainSocketImpl",
// this is where a new file descriptor is allocated.
// it'll occupy a socket even before it gets connected
new OpenSocketInterceptor("create", "(Z)V"),

/*
java.net.Socket/ServerSocket uses SocketImpl, and this is where FileDescriptors
are actually managed.
// When a socket is accepted, it goes to "accept(SocketImpl s)"
// where 's' is the new socket and 'this' is the server socket
new AcceptInterceptor("accept", "(Ljava/net/SocketImpl;)V"),

SocketInputStream/SocketOutputStream does not maintain a separate FileDescriptor.
They just all piggy back on the same SocketImpl instance.
*/
new ClassTransformSpec("java/net/PlainSocketImpl",
// file descriptor actually get closed in socketClose()
// socketPreClose() appears to do something similar, but if you read the source code
// of the native socketClose0() method, then you see that it actually doesn't close
// a file descriptor.
new CloseInterceptor("socketClose")));
// Later versions of the JDK abstracted out the parts of PlainSocketImpl above into a super class
spec.add(new ClassTransformSpec(
"java/net/AbstractPlainSocketImpl",
// this is where a new file descriptor is allocated.
// it'll occupy a socket even before it gets connected
new OpenSocketInterceptor("create", "(Z)V"),

// When a socket is accepted, it goes to "accept(SocketImpl s)"
// where 's' is the new socket and 'this' is the server socket
new AcceptInterceptor("accept","(Ljava/net/SocketImpl;)V"),
new AcceptInterceptor("accept", "(Ljava/net/SocketImpl;)V"),

// file descriptor actually get closed in socketClose()
// socketPreClose() appears to do something similar, but if you read the source code
// of the native socketClose0() method, then you see that it actually doesn't close
// a file descriptor.
new CloseInterceptor("socketClose")
),
// Later versions of the JDK abstracted out the parts of PlainSocketImpl above into a super class
new ClassTransformSpec("java/net/AbstractPlainSocketImpl",
// this is where a new file descriptor is allocated.
// it'll occupy a socket even before it gets connected
new OpenSocketInterceptor("create", "(Z)V"),

// When a socket is accepted, it goes to "accept(SocketImpl s)"
// where 's' is the new socket and 'this' is the server socket
new AcceptInterceptor("accept","(Ljava/net/SocketImpl;)V"),

// file descriptor actually get closed in socketClose()
// socketPreClose() appears to do something similar, but if you read the source code
// of the native socketClose0() method, then you see that it actually doesn't close
// a file descriptor.
new CloseInterceptor("socketClose")
),
new ClassTransformSpec("sun/nio/ch/SocketChannelImpl",
new OpenSocketInterceptor("<init>", "(Ljava/nio/channels/spi/SelectorProvider;Ljava/io/FileDescriptor;Ljava/net/InetSocketAddress;)V"),
new OpenSocketInterceptor("<init>", "(Ljava/nio/channels/spi/SelectorProvider;)V"),
new CloseInterceptor("kill")
)
);
new CloseInterceptor("socketClose")));
}
spec.add(new ClassTransformSpec(
"sun/nio/ch/SocketChannelImpl",
new OpenSocketInterceptor(
"<init>",
"(Ljava/nio/channels/spi/SelectorProvider;Ljava/io/FileDescriptor;Ljava/net/InetSocketAddress;)V"),
new OpenSocketInterceptor("<init>", "(Ljava/nio/channels/spi/SelectorProvider;)V"),
new CloseInterceptor("kill")));
return spec;
}

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -60,9 +60,12 @@ public void testPreMain() throws Exception {

// the following are not available in all JVMs
seenClasses.remove("sun/nio/ch/SocketChannelImpl");
seenClasses.remove("java/net/AbstractPlainSocketImpl");
seenClasses.remove("sun/nio/fs/UnixDirectoryStream");
seenClasses.remove("sun/nio/fs/UnixSecureDirectoryStream");
if (Runtime.version().feature() >= 19) {
seenClasses.remove("java/net/AbstractPlainSocketImpl");
seenClasses.remove("java/net/PlainSocketImpl");
}

assertTrue(
"Had classes in the spec which were not instrumented: " + seenClasses,
Expand Down

0 comments on commit d62e819

Please sign in to comment.