You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

如何通过JNI从Java调用Go函数?及Go实现类JNA跨语言调用方案

Alright, let's tackle both of your questions about connecting Java and Go—this is a super common use case, so I’ll walk you through each step clearly.

问题1:如何通过JNI从Java调用Go函数

JNI (Java Native Interface) lets Java talk to native code, and since Go can compile to C-compatible shared libraries via cgo, we can use that as a bridge. Here's how to make it work:

Step 1: Write your Go code with cgo exports

First, you need to mark your Go functions for export to C using the //export comment, and include the mandatory import "C" line (it has to be on its own line, no other imports grouped with it). Here's your example code, with a tiny addition (an empty main function, since we’re compiling a library but Go requires a main package):

package main

import "fmt"
import "C"

//export Add
func Add(x, y int) int {
	fmt.Printf("Go says: adding %v and %v\n", x, y)
	return x + y
}

// Empty main function required for main package (won't execute when built as a library)
func main() {}

Step 2: Compile Go to a C shared library

Run this command to build a shared library that C (and JNI) can use. The exact output extension depends on your OS:

  • Linux/macOS: libadd.so (macOS might use .dylib instead)
  • Windows: add.dll

Command:

go build -buildmode=c-shared -o libadd.so add.go

This generates two files: libadd.so (the shared library) and libadd.h (a C header with the exported function signatures).

Step 3: Write your Java JNI code

Create a Java class that declares the native method and loads the shared library:

public class GoJNI {
    // Load the compiled Go shared library
    static {
        System.loadLibrary("add"); // Omit prefix/suffix like lib/.so/.dll
    }

    // Declare the native method that maps to our Go Add function
    private native int add(int x, int y);

    public static void main(String[] args) {
        GoJNI app = new GoJNI();
        int result = app.add(3, 5);
        System.out.println("Java says: result is " + result);
    }
}

Step 4: Generate JNI header & write a C bridge

JNI requires a C function with a specific signature to connect Java's native method to the Go function. First, compile your Java file and generate the header:

# Compile Java class
javac GoJNI.java

# Generate JNI header
javah -jni GoJNI

This creates a GoJNI.h file with a function signature like Java_GoJNI_add. Now write a C bridge file (go_jni_bridge.c) to link this JNI function to our Go Add:

#include "GoJNI.h"
#include "libadd.h" // Include the header generated by Go

JNIEXPORT jint JNICALL Java_GoJNI_add(JNIEnv *env, jobject obj, jint x, jint y) {
    // Call the exported Go function, converting types as needed
    return (jint)Add((int)x, (int)y);
}

Step 5: Compile the C bridge & run

Compile the C bridge into a shared library, linking it with the Go library. On Linux, that looks like:

gcc -shared -fpic -I${JAVA_HOME}/include -I${JAVA_HOME}/include/linux go_jni_bridge.c -L. -ladd -o libgojni.so

Finally, run your Java program, specifying the library path:

java -Djava.library.path=. GoJNI

You should see output from both Go and Java!


问题2:用Go实现类似JNA的跨语言调用

JNA (Java Native Access) skips the C bridge entirely—you just declare a Java interface that maps to the native library's functions. This is way simpler for most cases. Here's how to do it with Go:

Step 1: Reuse your Go code & compile to shared library

Use the same Go code from Question 1, and compile it to a shared library with the same command:

go build -buildmode=c-shared -o libadd.so add.go

Step 2: Set up JNA in your Java project

First, get the JNA libraries—you can add them via Maven:

<dependency>
    <groupId>net.java.dev.jna</groupId>
    <artifactId>jna</artifactId>
    <version>5.13.0</version>
</dependency>

Or download the JARs directly and add them to your classpath.

Step 3: Write the Java JNA code

Create an interface that extends Library and declares the Go function, then use it in your main class:

import com.sun.jna.Library;
import com.sun.jna.Native;

// Interface mapping to the Go shared library
public interface GoAddLibrary extends Library {
    // Load the shared library (again, omit prefix/suffix)
    GoAddLibrary INSTANCE = (GoAddLibrary) Native.load("add", GoAddLibrary.class);

    // Declare the function—name and types must match the exported Go function
    int Add(int x, int y);
}

public class GoJNA {
    public static void main(String[] args) {
        int result = GoAddLibrary.INSTANCE.Add(3, 5);
        System.out.println("Java says: result is " + result);
    }
}

Step 4: Run the Java program

Make sure the JNA JARs and your Go shared library are in the right places, then run:

java -cp .:jna.jar GoJNA

That's it—no C code needed!

Quick note on JNI vs JNA

  • JNI: More work (requires a C bridge), but slightly better performance. Great for high-throughput scenarios.
  • JNA: No C code, faster to implement. Performance is good enough for most applications.

内容的提问来源于stack exchange,提问作者dmotta

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.05.25 08:18:51