基于jna 的libeasytier-ffi java 版本

java 的jna 是一个简化jni 开发的包,以下是基于jna开发一个libeasytier-ffi 的java 包

代码结构

  • 如下
├── pom.xml
├── README.md
└── src
    ├── app.yaml
    ├── main
    │   ├── java
    │   │   └── com
    │   │       └── dalong
    │   │           └── easytier
    │   │               └── EasyTierLibrary.java
    │   └── resources
    └── test
        └── java
            └── com
                └── dalong
                    └── Application.java

代码说明

  • pom.xml
<?xml version="1.0" encoding="UTF-8"?>
<project xmlns="http://maven.apache.org/POM/4.0.0"
         xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
         xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
    <modelVersion>4.0.0</modelVersion>

    <groupId>com.dalong</groupId>
    <artifactId>easytier-ffi-java</artifactId>
    <version>1.0-SNAPSHOT</version>

    <properties>
        <maven.compiler.source>11</maven.compiler.source>
        <maven.compiler.target>11</maven.compiler.target>
        <project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
    </properties>

    <dependencies>
        <dependency>
            <groupId>net.java.dev.jna</groupId>
            <artifactId>jna</artifactId>
            <version>5.17.0</version>
        </dependency>
    </dependencies>
    <profiles>
        <profile>
            <id>fatjar</id>
            <build>
                <plugins>
                    <plugin>
                        <groupId>org.apache.maven.plugins</groupId>
                        <artifactId>maven-shade-plugin</artifactId>
                        <version>3.5.1</version>
                        <executions>
                            <execution>
                                <phase>package</phase>
                                <goals>
                                    <goal>shade</goal>
                                </goals>
                                <configuration>
                                    <createDependencyReducedPom>false</createDependencyReducedPom>
                                </configuration>
                            </execution>
                        </executions>
                    </plugin>
                </plugins>
            </build>
        </profile>
    </profiles>
    <distributionManagement>
        <repository>
            <id>github</id>
            <name>GitHub OWNER Apache Maven Packages</name>
            <url>https://maven.pkg.github.com/rongfengliang/easytier-ffi-jna</url>
        </repository>
    </distributionManagement>
</project>
  • 包装代码

EasyTierLibrary.java

package com.dalong.easytier;

import com.sun.jna.*;
import com.sun.jna.ptr.PointerByReference;

import java.util.Arrays;
import java.util.List;

public interface EasyTierLibrary extends Library {

    class KeyValuePair extends Structure {

        public Pointer key;
        public Pointer value;

        @Override
        protected List<String> getFieldOrder() {
            return Arrays.asList("key", "value");
        }
    }
    // 此次基于了属性配置,暂时没有直接打包
    EasyTierLibrary INSTANCE = Native.load(System.getProperty("easytier.library.path", "easytier_ffi"),
            EasyTierLibrary.class);

    void get_error_msg(PointerByReference out);
    void free_string(Pointer s);
    int parse_config(String cfg_str);
    int run_network_instance(String cfg_str);
    int retain_network_instance(PointerByReference inst_names, long length);
    int collect_network_infos(KeyValuePair[] infos, long max_length);

}

使用

  • Application.java

app.yaml 配置

instance_name = "xxxxx"
instance_id = "xxxxx"
dhcp = true
listeners = [
"tcp://0.0.0.0:11010",
"udp://0.0.0.0:11010",
"wg://0.0.0.0:11011",
]
rpc_portal = "0.0.0.0:0"

[network_identity]
network_name = "xxxxx"
network_secret = "xxxxx"

[[peer]]
uri = "tcp://xxx:11010"

[flags]

代码

public class Application {
    public static void main(String[] args) throws IOException {
        EasyTierLibrary library = EasyTierLibrary.INSTANCE;
        var config  = Files.readString(Path.of("app.yaml"));
        var result = library.run_network_instance(config);
        if (result ==0) {
            System.out.println("Network instance started successfully.");
            while (true) {
                try {
                    Thread.sleep(3000);
                    int maxLength = 10;
                    EasyTierLibrary.KeyValuePair[] infos = (EasyTierLibrary.KeyValuePair[])
                            (new EasyTierLibrary.KeyValuePair()).toArray(maxLength);
                    int count = EasyTierLibrary.INSTANCE.collect_network_infos(infos, maxLength);
                    for (int i = 0; i < count; i++) {
                        String key = infos[i].key.getString(0);
                        String value = infos[i].value.getString(0);
                        System.out.println(key + ": " + value);
                    }
                } catch (InterruptedException e) {
                    System.out.println("Application interrupted: " + e.getMessage());
                    break; // Exit the loop if interrupted
                }
            }
        } else {
            System.out.println("Failed to start network instance. Error code: " + result);
            var errorMsg = new PointerByReference();
            library.get_error_msg(errorMsg);
            System.out.println("Error message: " + errorMsg.getValue().getString(0));
        }

    }
}

说明

代码我已经提交github了,同时maven 包也发布到github repo 了,可以直接使用,目前为了方便ffi 库没有直接包含到项目中,需要运行的时候配置,同时对于运行需要root 权限

参考资料

https://github.com/rongfengliang/easytier-ffi-jna

https://github.com/java-native-access/jna

posted on 2025-08-18 08:00  荣锋亮  阅读(16)  评论(0)    收藏  举报

导航