Dependency conflict errors when using Agones SDK in runtime module

I’ve had a working plugin with nakama-2.7.0 for a few months now, however I recently added some functionality to it and in doing so, I added the dependency for some Agones libs. This caused Nakama to be unable to load the plugin due to “different versions of …” errors. Since my Nakam was out of date, and things were broken anyway, I decided to take this opportunity to upgrade to Nakama 2.9.0 and upgrade my plugin to use nakama-common-1.3.0 at the same time
The upgrade was simple enough, however when I try to run Nakama with my plugin, I still get weird dependency conflict errors. What’s more, is the dependencies in question aren’t even in the go.mod/go.sum files of either my plugin or Nakama.
So Im at a loss right now as to how to proceed.
One approach is to create a separate service that uses the agones api and simply call it via HTTP from nakama plugin
I did this with another layer that also caused (different kinds of) issues, however I’d rather not have to do this every time I want to add functionality to Nakma

For some reason the error messages were being interpreted as links so I am unable to post them here as I am a new user. As such, I have created this pastebin link with the errors.

It should also be noted that I am building my plugin in a docker container with the exact same base image as Nakama-2.9.0 so I know that the same go version is being used.

It should also be noted that while I am absolutely still interested in the what the cause of the error is, I have already converted the relevant code to a speparate microservice that the Nakama runtime plugin simply calls out to via HTTP, so this isn’t an absolute blocker for me anymore.

Hi @jonbonazza. Thanks for the post on the forums to describe this use case. The error you posted can happen with Go-based Nakama projects so I thought it would be valuable to others to explain in detail.

“Could not open Go module”,“path”:“/nakama/data/modules/roa-nakama.so”,“error”:“plugin.Open("/nakama/data/modules/roa-nakama"): plugin was built with a different version of package The Go Programming Language

The specific package named (i.e. “The Go Programming Language”) that cannot be loaded changes sometimes based on the dependencies in your plugin project code but the root cause is all for the same reason. When a project is built with Go as a plugin a copy of the Go runtime is bundled with the shared object; it’s covered in detail here.

The result is that Nakama’s copy of the Go runtime and the Go runtime bundled with the shared object of your plugin code must be an exact match with its list of dependencies (cached in the binaries via Go mod). This should be straightfoward to match dependencies but becomes trickier because Go mod dependency management uses minimal version selection. This means that it’s difficult to pin transitive dependencies to specific versions. This makes it hard to achieve an exact match of the deps tree.

We have found a useful workaround to pin a transitive dependency without a problem when the code is compiled. I’ve put together my example code.

The go.mod file looks like:

module github.com/heroiclabs/agones_nakama

go 1.13

require (
	agones.dev/agones v1.2.0
	github.com/grpc-ecosystem/grpc-gateway v1.11.1
	github.com/heroiclabs/nakama-common v1.3.0
	golang.org/x/net v0.0.0-20190827160401-ba9fcec4b297
	golang.org/x/text v0.3.2
)

The main file for the plugin code looks like:

package main

import (
	agones "agones.dev/agones/sdks/go"
	"context"
	"database/sql"
	"github.com/heroiclabs/nakama-common/runtime"

	// NOTE: Do not remove. These are required to pin as direct dependencies with Go modules.
	_ "golang.org/x/net/idna"
	_ "golang.org/x/text/transform"
	_ "github.com/grpc-ecosystem/grpc-gateway/utilities"
)

func InitModule(ctx context.Context, logger runtime.Logger, db *sql.DB, nk runtime.NakamaModule, initializer runtime.Initializer) error {
	_, err := agones.NewSDK()
	if err != nil {
		return err
	}
	return nil
}

I should note that I don’t know much about the Agones Go SDK so my code is just an example to check it all compiles and runs fine.

I can add more details if it’d help but let me know if this resolves the build issue with your code.

1 Like