Plugin was built with a different version of package

Hey guys, I’ve been racking my brain trying to fix this error. As soon as I added https://github.com/awa/go-iap to verify receipts, I’m getting this “plugin was built with a different version of package golang.org/x/net/context/ctxhttp” error
I’ve tried to add
replace golang.org/x/net => golang.org/x/net v0.0.0-20200226121028-0de0cce0169b
to go.mod, matching the same version on Nakama, but it’s still failing

@hasbean I’ve solved this particular error many times before and had planned to describe how best to achieve what you want but I had no problem when I loaded the plugin with your dependency. I’ll describe what I’ve done.

$> go version
go version go1.14 linux/amd64
$> env GO111MODULE=on go get "github.com/awa/go-iap"
$> env GO111MODULE=on go mod vendor
$> env GO111MODULE=on go build --trimpath --mod=vendor --buildmode=plugin -o ./backend.so
...

This is the code I added to InitModule just to check the import (I’ve never used that library before):

client := appstore.New()
logger.Info("%+v", client)

I used Go 1.14 and Nakama 2.11.0 release. Hope this helps.

The error seems to come when I use the Google Play version.

try this one

	jsonKey, err := ioutil.ReadFile("jsonKey.json")
	if err != nil {
		log.Fatal(err)
	}

	client := playstore.New(jsonKey)

@hasbean I had to use code which looks like:

client, _ := playstore.New([]byte(""))
logger.Info("%+v", client)

I ignored the second error argument because I want to check the plugin compiles and loads rather than write well structured code and I received this error from the plugin loader:

plugin.Open("/nakama/data/modules/backend"): plugin was built with a different version of package golang.org/x/net/context/ctxhttp

I’ll write up my usual notes on how to solve it for you now :slight_smile:

@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.

Couldn’t get it to work up until I realized I forgot the “vendor” command.

Much appreciated! I have to figure out a way to smooth out upgrades between versions now, but it works!

1 Like

Hello,
Sadly i still get an error " plugin was built with a different version of package golang.org/x/net/context/ctxhttp", how can i solve this dependency?

@naskha01 What version of the game server do you use? What steps have you tried so far? What does your go.mod file look like? Which dependencies did you pin as shown above?

As you can guess just “i still get an error” really doesn’t help the community to help you.