如何从 JDK(SocketChannelImpl 和 SocketDispatcher)更改 Java 本机代码(C 实现)并重新编译以与 JDK 一起使用?

Lat*_*ter 1 java jvm nio real-time

我需要在 Linux 上运行的 JDK 上找到、重新编译和部署以下本机方法,来自SocketDispatcher.java:(本机方法位于下面代码的底部,因此请向下滚动)

package sun.nio.ch;

import java.io.*;

/**
 * Allows different platforms to call different native methods
 * for read and write operations.
 */

class SocketDispatcher extends NativeDispatcher
{

    static {
        IOUtil.load();
    }

    int read(FileDescriptor fd, long address, int len) throws IOException {
        return read0(fd, address, len);
    }

    long readv(FileDescriptor fd, long address, int len) throws IOException {
        return readv0(fd, address, len);
    }

    int write(FileDescriptor fd, long address, int len) throws IOException {
        return write0(fd, address, len);
    }

    long writev(FileDescriptor fd, long address, int len) throws IOException {
        return writev0(fd, address, len);
    }

    void preClose(FileDescriptor fd) throws IOException {
        preClose0(fd);
    }

    void close(FileDescriptor fd) throws IOException {
        close0(fd);
    }

    //-- Native methods
    static native int read0(FileDescriptor fd, long address, int len)
        throws IOException;

    static native long readv0(FileDescriptor fd, long address, int len)
        throws IOException;

    static native int write0(FileDescriptor fd, long address, int len)
        throws IOException;

    static native long writev0(FileDescriptor fd, long address, int len)
        throws IOException;

    static native void preClose0(FileDescriptor fd) throws IOException;

    static native void close0(FileDescriptor fd) throws IOException;
}
Run Code Online (Sandbox Code Playgroud)

来源:http : //grepcode.com/file_/repository.grepcode.com/java/root/jdk/openjdk/8u40-b25/sun/nio/ch/SocketDispatcher.java/?v= source

所以基本上我想让本地方法write0打印“Hello from native write0!”。

问题:

  • write0Linux的 C/C++ 代码在哪里?

  • 如何write0在 Linux 上重新编译(gcc 命令行?)C/C++ 代码?

  • 如何启动我的 JVM 并让它write0在 Linux 上使用我新编译的本机代码?

apa*_*gin 6

SocketDispatcherLinux 上没有本机实现。它是 Windows 特定的类;在Linux上它只是共享的实现FileDispatcherImpl

FileDispatcherImpl 的原生代码在src/solaris/native/sun/nio/ch/FileDispatcherImpl.c(在 OpenJDKsolaris目录中代表 POSIX 代码,所以 Linux 实现也在那里)。

如果要覆盖本机方法,则必须使用自己的实现创建共享库。本机方法名称遵循JNI 约定,例如本机函数 forFileDispatherImpl.write0应具有以下签名:

JNIEXPORT jint JNICALL
Java_sun_nio_ch_FileDispatcherImpl_write0(JNIEnv *env, jclass clazz,
                              jobject fdo, jlong address, jint len)
Run Code Online (Sandbox Code Playgroud)

一旦您构建了自己的共享库并覆盖了一个或多个函数,请使用 预加载它LD_PRELOAD,JVM 将在来自 JDK 的任何本机代码之前链接您的函数。顺便说一句,JDK 本机FileDispatcherImpl和其他java.nio东西进来了libnio.so