0 x00 background

When I was developing on M1 (arm processor), I needed to use Netty, specifically to use its Unix Domain Socket functionality, so it was defined in POM.xml

        <dependency>
            <groupId>io.netty</groupId>
            <artifactId>netty-transport-native-kqueue</artifactId>
            <classifier>osx-x86_64</classifier>
        </dependency>
Copy the code

Netty-transport-native – kqueue-4.1.63.final-osx-x86_64. jar is introduced in the project. The project fails to be started

Caused by: java.lang.IllegalArgumentException: Unsupported channel type: ServerDomainSocketChannel at reactor.netty.resources.DefaultLoopNIO.getChannel(DefaultLoopNIO.java:50) ~ [reactor - netty - core - 1.0.6. Jar: 1.0.6] at reactor.net. Ty resources. LoopResources. OnChannel (LoopResources. Java: 214) ~ [reactor - netty - core - 1.0.6. Jar: 1.0.6]Copy the code

0 x01 analysis

The exception comes from the following code

	public <CHANNEL extends Channel> CHANNEL getChannel(Class<CHANNEL> channelClass) {
		if (channelClass.equals(SocketChannel.class)) {
			return (CHANNEL) new NioSocketChannel();
		}
		if (channelClass.equals(ServerSocketChannel.class)) {
			return (CHANNEL) new NioServerSocketChannel();
		}
		if (channelClass.equals(DatagramChannel.class)) {
			return (CHANNEL) new NioDatagramChannel();
		}
		throw new IllegalArgumentException("Unsupported channel type: " + channelClass.getSimpleName());
	}
Copy the code

This code in DefaultLoopNIO inherits from DefaultLoop, the implementation class of DefaultLoop, and the DefaultLoopKQueue. Netty is supposed to decide which system is using the implementation class of DefaultLoop. For example, MacOS uses DefaultLoopKQueue and Linux uses DefaultLoopEpoll.

I’m using MacOS, so the code should go to DefaultLoopKQueue, not DefaultLoopNIO, and trace back to the source with this problem

The original is netty at the start of the time, undertook the following judgment

// The code is in the PlatformDependent class private static final String NORMALIZED_ARCH = normalizeArch(SystemPropertyUtil.get("os.arch", "")); On arm64, NORMALIZED_ARCH = aarch_64...... public static String normalizedArch() { return NORMALIZED_ARCH; }Copy the code

Through Native# loadNativeLibrary function call PlatformDependent. NormalizedArch () to judge the operating system type

Then from Native#loadNativeLibrary to NativeLibraryLoader#load(), finally concatenate the jnilib name that should be used on macos(arm64) platform, Libnetty_transport_native_kqueue_aarch_64.jnilib, then search for the file in the search file path defined by the project.

Of course I can’t find it because I’m introducing the netty-transport-native kqueue-osx_x86_64 jar, The jnilib file is named libnetty_transport_native_kqueue_x86_64.jnilib

So I thought declaring the correct dependencies in POM.xml was enough

        <dependency>
            <groupId>io.netty</groupId>
            <artifactId>netty-transport-native-kqueue</artifactId>
            <classifier>osx-aarch_64</classifier>
        </dependency>
Copy the code

0 x02 solve

However, the problem is that the Netty-transport-native kqueue-osx_aARCH_64 jar is not available in maven Center release and Snapshot libraries. Unfortunately, I have no choice but to try to compile this JAR myself.

Inspired by the netty-transport-native epoll-4.1.43.final-Linux-aarch_64. jar migration guide (CentOS 7.6), So it was decided to compile netty-transport-native kqueue-osx_aARCH_64 on macOS (ARM64) machines, using the same steps described in this document. Only the command to compile step 2 needs to be replaced with./ MVNW clean install-pl transport-native- epoll-dskiptests =true./ MVNW clean install-pl Transport – native – kqueue – DskipTests = true.

Netty-transport-native kqueue-4.1.63.final-osx-aarch_64. jar netty-transport-native kqueue-4.1.63.final-osx-aarch_64. jar netty-transport-native kqueue-4.1.63.final-osx-aarch_64. jar netty-transport-native kqueue-4.1.63.final-osx-aarch_64. jar The compilation results are as follows

Referring to SpringBoot to import the local JAR package, I chose to place the JAR package in the project directory.

First create directory lib under SRC, Jar and netty-transport-native- kqueue-4.1.63.final-osx-aarch_64. jar and netty-transport-native- kqueue-4.1.63.final. jar Then add the lib folder to the IDEA Libraries

Finally, modify pom.xml

        <dependency>
            <groupId>io.netty</groupId>
            <artifactId>netty-transport-native-kqueue</artifactId>
            <classifier>osx-aarch_64</classifier>
            <version>4.1.63. The Final</version>
        </dependency>
Copy the code

Start-up project, we can start up smoothly.

0 x03 end

Netty-transport-native kqueue-4.1.63.final.jar will be released to Maven Center soon.