heroiclabs / nakama-java

Java client for the Nakama and Satori servers.
https://heroiclabs.com/docs/android-java-client-guide/
Apache License 2.0
31 stars 16 forks source link

2.0.5-snapshot getting runtime error: cannot find a NameResolver #38

Closed vladp closed 4 years ago

vladp commented 4 years ago

Hello, I am using this java-client from a non-android backend java app (regular backend app with JDK 11). Initially, I used released 2.0.4 java client.

Now I am troubleshooting some intermittent 'socket may not be closed issues' under high load with DefaultClient, and decided to upgrade to master (2.0.5-shapsot) of the nakama-java client, noticing that it was recently updated for gradle 6.5.1

I create a new jar (using bash gradlew shadow) from source, but when running my up during DefaultClient construction, I now get a runtime error:

Caused by: java.lang.IllegalArgumentException: cannot find a NameResolver for 127.0.0.1:7349 (Illegal character in scheme name at index 0: 127.0.0.1:7349) It is happening in DefaultClient constructor on builder.build() line (last line in below snippet)

       ManagedChannelBuilder builder = OkHttpChannelBuilder.forAddress(host, port).userAgent("nakama-java-client");
...
            this.managedChannel = builder.build();

I am not that familiar with grpc, but searching for it best I came up is this reference to the issue https://stackoverflow.com/questions/62875526/grpc-java-cannot-find-a-nameresolver-when-using-in-osgi-bundle

I had tried upgrading to latest grpc packages (1.31.0 rather than what's in current build.gradle which is 1.21.0). I also upgraded to latest shadow Jar plugin (6.0.0) None of that help.

At this point I am not sure if the problem is with my environment and when I used 2.0.4 version of the client, I simply was lucky. Or, there is something wrong with my build of 2.0.5-snapshot. Or, it is because I am not using Android java, and regular java might not be supported by design.

Logging this in case others might experience similar problem. Will post here if I find a resolution.

mofirouz commented 4 years ago

Thanks for reporting this. I will also test separately as well.

The immediate thought that comes to mind is that somewhere during the Shadowing of the dependencies, we don’t process gRPC manifest information correctly.

Could you please:

  1. Try your test again with a regular jar or fatjar (not shadowed), and report again.
  2. Clarify what you mean by “ 'socket may not be closed issues' under high load” - how are you creating a socket connection? And what does high load mean?
  3. How is the Java client used(e.g on Android on device or emulator etc) and where is the Nakama server?
vladp commented 4 years ago

@mofirouz Thank you very much for the follow up.

WRT 1. It worked without the shadow Jar plugin. I had some suspicion about it as well, and looked at Shadow jar's issue list, and submitted a follow up comment on a similar report, prior to reporting this. See https://github.com/johnrengelman/shadow/issues/556 This is also why I tried latest shadowJar, but it did not work. But anyway, your suspicion is right on point. After following your advice and trying regular jar, I was able to get it to work. The regular jar is small (under 2mb, while the shadow jar with all the dependencies was about 10mb). So I had to add all the transient dependencies for nakama-java client into my project. Below is the snippet of code, I added to my build.gradle (in case this is of value)

        implementation files   ('libs/nakama-java-2.0.5-SNAPSHOT.jar') //my own build
        // add all the nakama-client needed dependencies
        def grpcVersion="1.21.0"
        implementation "io.grpc:grpc-protobuf-lite:${grpcVersion}"
        //grpc start
        //For Android client, use grpc-okhttp instead of grpc-netty-shaded and grpc-protobuf-lite instead of grpc-protobuf
        implementation ("io.grpc:grpc-okhttp:${grpcVersion}") {
            exclude group: 'com.squareup.okio', module:'okio'
        }
        implementation 'com.google.protobuf:protobuf-lite:3.0.1'
        implementation ('com.google.api.grpc:googleapis-common-protos:0.0.3') {
            exclude group: 'io.grpc', module:'grpc-protobuf'
        }

        // Nakama-client assumes android, but even with that assumption it seems to work
        //so I am not including netty and protobuf below
        // implementation "io.grpc:grpc-netty-shaded:${grpcVersion}"
        //implementation "io.grpc:grpc-protobuf:${grpcVersion}"
        implementation "io.grpc:grpc-stub:${grpcVersion}"
        compileOnly 'org.apache.tomcat:annotations-api:6.0.53' // necessary for Java 9+ as per grpc readme.
        // grpc end
       //nakama-java end

WRT 2.

Clarify what you mean by “ 'socket may not be closed issues' under high load”...

I did not mean to report this as an issue with Nakama client. It was something that I just mentioned for the context, of even I was trying to upgraded from 2.0.4 to build my own client jar. I will report a separate issue, if I think it is worth your time to know/look at it or of interest to others Right now it is just many be my learnings artifact, and without running latest client, I did not even want bother you with this. Sorry about that. (and I am also learning at the same time, and my use case is outside of how you would expect folks using nakama).

Just for additional info, you are interested. I do _clnt = new DefaultClient ... where I connect with the 'custom' Id method. I create, in testing, many of those, (as I mentioned I am connecting to nakama from my java backend program, not from end-user clients). Then, I periodically poll Nakama server for active matches. If Nakama says 'no active match' for a given match Id, I go to the DefaultClient instance that related to that match, and do _client.disconnect(); _client=null Underneath, Default client calls managedChannel.shutdown(). So I thought it was the correct way to shutdown (and there are no other methods exposed on the DefaultClient besides that, at least in my understanding).

WRT 3. How is the Java client used(e.g on Android on device or emulator etc) and where is the Nakama server?

The client is used from backend REST server. Running on linux. Nakama server is on the same dev machine (this is far from any production-like env)


Again thank you for your help. I can continue using my own build of latest nakama-client jar without shadow plugin. So this issue can be closed for my needs(or up to you).

mofirouz commented 4 years ago

Thanks for the extra info - it's very helpful.

We'll look into what's needed to configure the Shadowing and Jar merging properly. Maybe this is something we should consider: https://imperceptiblethoughts.com/shadow/configuration/merging/#merging-service-descriptor-files

I'll leave this issue open as I think it's important to tackle and correct.

vladp commented 4 years ago

Thank you,

wanted to mention one more difficulty that I ran with when deploying the fat/shadow Jar.

Perhaps others will not run into it, so just meant to mention as FYI.

My project is using retrofit2 and underneath, therefore, okhttp and the optional okhttp-logging interceptor. The retrofit2 is latest up-to-date version, and that underneath relies on okhttp 3.14.9. Which also means, that okhttp-logging interceptor has to be 3.14.9 or else there are run-time errors...

After I incorporated nakama-jar into my backend server, suddenly my previously working client REST calls that had nothing to do with Nakama (that my server issues via retrofit2), stopped working.

Started receiving weired runtime error, that some method is not available for okhttp Logging interceptor when receiving a response after the REST call (these were also 3rd party services, that are difficult to test independently). Nothing to do with Nakama.

So I troubleshooted this down to the following: nakama-jar uses pretty conservative (or old) version of okhttp 3.11 Okhttp had a change, after 3.11 where API methods were added, the logging interceptor relied on that.

I had try a number of 'hope-it-works' methods with gradle, to force my project to use okhttp-3.14.9 -- rather than 3.11 but for a reason, that I do not understand, it did not work, and I was still getting this runtime time error in the logging interceptor. Eventually I disabled logging interceptor through out the project, and just moved on.

Additional difficulty for me was, is that gradle does not seem to have all of hit conflict resolution config machinery applied in the same way for maven dependencies vs custom jars.

Now, since I have the ability, to build slim nakama-jar client. I upgraded nakama's okhttp to 3.14.9 enabled back my logging interceptor, and that part started working again. So I back using logging inteceptor with the custom slim nakama-java client.

Reason I am mentioning this, is that perhaps, it is worth considering publishing your JAR through maven, as others might run into dependencies issues with commonly used things like retrofit2 (very widely used in android too), and using gradle's custom conflict resolution trickery -- may be difficult.

mofirouz commented 4 years ago

Thanks a lot for this :)

Completely agreed that the OkHttp library we use is very old, and we're going towards upgrading the deps - having said that we are considering OkHttp 4.x - this would be done inline with the shadowing of deps so hopefully won't cause you issues with retrofit2.

We also would like to turn the GitHub repo into a Maven repo because the process involved with Maven Central submissions is quite antiquated and painful. Let me know what you think of this.

vladp commented 4 years ago

would like to turn the GitHub repo into a Maven repo because the process involved with Maven Central submissions

I am not very familiar with this (never used a dependency that was setup like that). But if the dependency still accessible from Gradle, then it is ok.

May be you can also investigate jitpack.io -- they say, they are free for open source and have what seems to be very easy integration with a github project (especially when the artifact is a single jar).

https://jitpack.io/docs/BUILDING/ I just check in my projects I already have jitpack hosted oss dependencies.

lugehorsam commented 4 years ago

@vladp are you using SSL/TLS?

vladp commented 4 years ago

@lugehorsam no, not using SSL/TLS between my backend and nakama.

Having said that, I did not see any particular limitation in nakama-client (I use http rpc via retrofit2 to call up my lua functions, with 'unwrap=true' query key) that would prevent me from using https in the future, If I needed to.

lugehorsam commented 4 years ago

Thanks @vladp. I wanted to update you that I am able to reproduce this locally now inside a test project, so that gets me quite a way there. Will keep you posted :)

lugehorsam commented 4 years ago

@vladp https://github.com/heroiclabs/nakama-java/pull/39 should resolve the issue. Thanks again for the bug report.