基于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 权限