Plugin was built with a different version of package

@hasbean Ok I’ve solved it but it did prove to be quite tricky due to the cross-over of dependencies between what’s used in Nakama server and what’s pulled in transitively by the “go-iap” library. First I’ll explain why the plugin loader exposes this error when the shared object is loaded.

Due to this issue with Go plugins they bundle their own copy of the Go runtime inside the shared object. They also store a dependency list to ensure that undefined behaviour cannot occur if the host binary contains a different dependency tree to the plugin code.

If the dependencies between host binary and shared object (plugin) do not match exactly then the plugin loader will throw the error above. The problem next is how to make sure the dependencies can be matched exactly between the two pieces of binary code.

This is where Go makes things difficult because it uses minimal version selection. It’s quite hard to pin transitive dependencies because Go will select the minimal version that it thinks satisfies the dependency tree in just your plugin code project without any way to make it clear that there’s another dependency tree to consider. Fortunately there’s a handy trick although a little unorthodox to solve this problem.

You can use “blank imports” to trick the Go toolchain into considering the transitive dependencies from the server as a direct dependency in your plugin code just to allow you to pin them to the exact versions used in Nakama server.

In your case the “go-iap” has a number of dependencies which transitively overlap with Nakama so the solution needs this added to your imports at the top of your main.go file:

import (
	"context"
	"database/sql"
	"github.com/awa/go-iap/playstore"
	"github.com/heroiclabs/nakama-common/runtime"

	// NOTE: Required to pin transitive dependencies.
	_ "cloud.google.com/go/compute/metadata"
	_ "go.opencensus.io/trace"
	_ "golang.org/x/net/context"
	_ "golang.org/x/oauth2"
	_ "golang.org/x/sys/unix"
	_ "google.golang.org/api/googleapi"
	_ "google.golang.org/genproto/googleapis/rpc/status"
)

You can then update your mod file to track the correct set of transitives:

module github.com/username/somerepo

go 1.14

require (
	cloud.google.com/go v0.45.1
	github.com/awa/go-iap v1.3.0
	github.com/heroiclabs/nakama-common v1.4.0
	go.opencensus.io v0.22.1
	golang.org/x/net v0.0.0-20200226121028-0de0cce0169b
	golang.org/x/oauth2 v0.0.0-20190604053449-0f29369cfe45
	golang.org/x/sys v0.0.0-20200223170610-d5e6a3e2c0ae
	google.golang.org/api v0.10.0
	google.golang.org/genproto v0.0.0-20200226201735-46b91f19d98c
)

To check the exact set of dependencies in Nakama use vendor/modules.txt and the go.mod file. You must use these files on the correct tag that matches the release of Nakama you use and note that dependencies can and will be updated in future with new releases of the server.

Finally use env GO111MODULE=on go mod vendor as usual to vendor the dependencies and the rest of the steps as normal to compile and load your Go code.

2 Likes