Go通过调用java的jar包来解决go生态轮子不足的问题
这两天有一个应用需要做一下附近的人,底层想采用lucene的lucene-spatial3d来做LBS,但go语言没有lucene的完整第三方包,轮子不足只能采用go调用java的方式解决。
第一种思路是想采用Netty来建立一个服务,然后go采用网络请求的方式来调用服务接口,但这种方式需要常驻一个服务,虽然资源用不了多少,但也是会一直跑着一个进程,斟酌再三决定放弃这种思路。
第二种思路是go直接调用java写的jar包,用的时候调用执行,用完不会有进程常驻,对服务器资源合理使用更优。下边就简单介绍一下此种方式的操作(具体用Lucene做LBS业务逻辑此文省去,此文重点介绍如何go调用jar包进行交互处理)。
【Java工程】
1、首先创建一个Maven工程,生成的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.yurongbj</groupId>
<artifactId>lucene_lbs</artifactId>
<version>1.0-SNAPSHOT</version>
<name>lucene_lbs</name>
<!-- FIXME change it to the project's website -->
<url>http://www.yurongbj.com</url>
<properties>
<project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
<maven.compiler.source>1.7</maven.compiler.source>
<maven.compiler.target>1.7</maven.compiler.target>
</properties>
<dependencies>
<dependency>
<groupId>cn.hutool</groupId>
<artifactId>hutool-all</artifactId>
<version>5.8.0.M2</version>
</dependency>
<!-- lucene全文搜索引擎 -->
<dependency>
<groupId>org.apache.lucene</groupId>
<artifactId>lucene-core</artifactId>
<version>9.0.0</version>
</dependency>
<dependency>
<groupId>org.apache.lucene</groupId>
<artifactId>lucene-analysis-smartcn</artifactId>
<version>9.0.0</version>
</dependency>
<dependency>
<groupId>org.apache.lucene</groupId>
<artifactId>lucene-queries</artifactId>
<version>9.0.0</version>
</dependency>
<dependency>
<groupId>org.apache.lucene</groupId>
<artifactId>lucene-spatial3d</artifactId>
<version>9.0.0</version>
</dependency>
<dependency>
<groupId>org.apache.lucene</groupId>
<artifactId>lucene-spatial-extras</artifactId>
<version>9.0.0</version>
</dependency>
<dependency>
<groupId>junit</groupId>
<artifactId>junit</artifactId>
<version>4.11</version>
<scope>test</scope>
</dependency>
</dependencies>
<build>
<pluginManagement><!-- lock down plugins versions to avoid using Maven defaults (may be moved to parent pom) -->
<plugins>
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-jar-plugin</artifactId>
<version>3.1.0</version>
<configuration>
<archive>
<manifest>
<addClasspath>true</addClasspath>
<!-- 此处为程序主入口-->
<mainClass>com.yurongbj.App</mainClass>
</manifest>
</archive>
</configuration>
</plugin>
<plugin>
<artifactId>maven-assembly-plugin</artifactId>
<configuration>
<archive>
<manifest>
<mainClass>com.yurongbj.App</mainClass>
</manifest>
</archive>
<descriptorRefs>
<descriptorRef>jar-with-dependencies</descriptorRef>
</descriptorRefs>
</configuration>
</plugin>
<!-- clean lifecycle, see https://maven.apache.org/ref/current/maven-core/lifecycles.html#clean_Lifecycle -->
<plugin>
<artifactId>maven-clean-plugin</artifactId>
<version>3.1.0</version>
</plugin>
<!-- default lifecycle, jar packaging: see https://maven.apache.org/ref/current/maven-core/default-bindings.html#Plugin_bindings_for_jar_packaging -->
<plugin>
<artifactId>maven-resources-plugin</artifactId>
<version>3.0.2</version>
</plugin>
<plugin>
<artifactId>maven-compiler-plugin</artifactId>
<version>3.8.0</version>
</plugin>
<plugin>
<artifactId>maven-surefire-plugin</artifactId>
<version>2.22.1</version>
</plugin>
<plugin>
<artifactId>maven-install-plugin</artifactId>
<version>2.5.2</version>
</plugin>
<plugin>
<artifactId>maven-deploy-plugin</artifactId>
<version>2.8.2</version>
</plugin>
<!-- site lifecycle, see https://maven.apache.org/ref/current/maven-core/lifecycles.html#site_Lifecycle -->
<plugin>
<artifactId>maven-site-plugin</artifactId>
<version>3.7.1</version>
</plugin>
<plugin>
<artifactId>maven-project-info-reports-plugin</artifactId>
<version>3.0.0</version>
</plugin>
</plugins>
</pluginManagement>
</build>
</project>
2、入口文件App.java
package com.yurongbj;
import cn.hutool.core.util.CharsetUtil;
import cn.hutool.core.util.HexUtil;
/**
* 公司:御融(北京)科技有限公司
* 作者:softHardware
* 描述:用于建立附近的人索引和搜索,。
*/
public class App
{
public static void main( String[] args )
{
if(args.length==0){
System.out.println( "error" );
return;
}
if(args.length==1){
//将中文内容转换为16进制字符串,如果不转换直接输出,Go读取的中文解析内容会不正常。
String hex = HexUtil.encodeHexStr("缺少参数,至少2个参数", CharsetUtil.CHARSET_UTF_8);
System.out.println(hex);
return;
}
String arg = args[0];
if(arg.equals("index")){
//获取内容,创建索引
System.out.println( args[1] );
}
if(arg.equals("search")){
//获取内容,搜索附近5KM数据
System.out.println( args[1] );
}
}
}
3、使用带依赖jar包打包命令进行编译打包
命令:mvn assembly:assembly(注意在pom.xml中引入对应的插件maven-assembly-plugin)
4、打包成功后,在工程目录target文件夹下即可看到生成的jar包:lucene_lbs-1.0-SNAPSHOT-jar-with-dependencies.jar,此文件即为下文GO工程中待调用的jar包。

【Go工程】
1、创建Go工程(具体创建方法请自行查阅Go工程创建方法)
2、入口main.go文件调用测试
package main
import (
"encoding/hex"
"fmt"
"os/exec"
"github.com/gogf/gf/v2/os/gctx"
"github.com/gogf/gf/v2/util/gconv"
)
func main() {
//调用刚才打包的jar包,此处故意传入一个参数来验证返回值为“缺少参数,至少2各参数”
cmdJava := exec.Command("java", "-jar", "lucene_lbs-1.0-SNAPSHOT-jar-with-dependencies.jar", "index")
out, err := cmdJava.Output()
if err != nil {
println("java error:", err.Error())
}
hexStr, hexErr := hex.DecodeString(string(out))
if hexErr != nil {
println("java hexErr:", hexErr.Error())
}
println("hexStr:", hexStr)
res := gconv.String(hexStr)
fmt.Printf("call java: %qn", res)
}
3、将生成的lucene_lbs-1.0-SNAPSHOT-jar-with-dependencies.jar文件拷贝到和main.go相同的目录下,执行命令进行测试:
go run main.go
输出如下内容则代表调用成功:
call java: "缺少参数,至少2个参数"