Normalizing JAR Packages
Java package normalization is intended for JAR packages that contain .so files. Store the .so binary files in different paths, and modify and adapt the associated Java files. The generated JAR packages can run on both the Kunpeng and x86 platforms.
Procedure
Java provides the Java Native Interface (JNI) to call native functions. However, the JNI file needs to be compiled separately. That is, use the C code that can be understood by Java to call native functions. The process is complex. A more convenient method is to use the Java Native Access (JNA) framework. It provides a dynamic forwarder to implement data type mapping between Java and C, simplifying the native function call. You only need to place the compiled .so files in the default platform associated path of JNA. The JNA interface can be used to quickly call SO libraries on different platforms, implementing JAR package normalization.
Example:
In the following code example, a JAR package that contains a libcrc32.so dynamic library is compiled for JAR package normalization so that the JAR package can be called and run on both the Kunpeng and x86 platforms.
- Compile and generate Kunpeng and x86 dynamic libraries.
Compile the following crc32-related code segment to generate the libcrc32.so files for the Kunpeng and x86 platforms.
// crc32.cpp #include <stdint.h> extern "C" { #ifdef __x86_64__ uint32_t crc32_u8(uint32_t crc, uint8_t value) { __asm__("crc32b %1, %0" : "+r"(crc) : "rm"(value)); return crc; } #endif #ifdef __aarch64__ uint32_t crc32_u8(uint32_t crc, uint8_t value) { __asm__("crc32cb %w[c], %w[c], %w[v]":[c]"+r"(crc):[v]"r"(value)); return crc; } #endif }Compile the dynamic library:
gcc crc32.cpp -fPIC -shared -o libcrc32.so
For the Kunpeng platform, add the -march=armv8-a+crc compilation option.
- Generate a JAR package using JNA interface functions.Compile the Clibrary.java file using JNA interface functions. (You need to download JNA JAR package in advance. Version 5.1.0 or later is recommended.) JNA searches for the corresponding .so file in the default platform directory. (For example, resources/linux-aarch64 or resources/linux-x86-64. You need to create the directory in the project in advance.) Then, place the compiled .so file in the architecture directory. The content of the Clibrary.java file is as follows:
package org.example; import com.sun.jna.Library; import com.sun.jna.Native; public interface Clibrary extends Library { Clibrary INSTANCE = Native.load("crc32", Clibrary.class); int crc32_u8(int crc, byte value); }
Compress the Clibrary.java file and related .so files into a JAR package. Then, the crc32_u8 function can be called on multiple platforms. The structure of some related files is as follows:
├── java
│ └── org
│ └── example
│ └──Clibrary.java
└── resources
├── linux-aarch64
│ └── libcrc32.so
└── linux-x86-64
└── libcrc32.so