square / retrofit

A type-safe HTTP client for Android and the JVM
https://square.github.io/retrofit/
Apache License 2.0
43.07k stars 7.31k forks source link

Using Retrofit in Google App Engine #1149

Closed Udinic closed 8 years ago

Udinic commented 9 years ago

I used Retrofit 1.9 on a GAE app I have, in order to make network calls to other services. I used the default client (not UrlFetchClient) and everything worked fine.

After upgrading to Retrofit 2, I made all the necessary changes and now I get this error when trying to make a network call:

java.lang.NoClassDefFoundError: java.net.ProxySelector is a restricted class. Please see the Google App Engine developer's guide for more details. at com.google.appengine.tools.development.agent.runtime.Runtime.reject(Runtime.java:52) at com.squareup.okhttp.OkHttpClient.copyWithDefaults(OkHttpClient.java:614) at com.squareup.okhttp.Call.(Call.java:48) at com.squareup.okhttp.OkHttpClient.newCall(OkHttpClient.java:595) at retrofit.OkHttpCall.createRawCall(OkHttpCall.java:120) at retrofit.OkHttpCall.execute(OkHttpCall.java:110)

I assume that's because OkHttp is the default client (Similar problem in 1.9: http://stackoverflow.com/questions/30912029/using-okhttp-client-via-okclient-on-google-app-engine-throws-a-java-lang-noclas).

Since GAE was supported in older version, will it continue to be supported in Retrofit 2 ? Is there some configuration I need to do to get it to work?

JakeWharton commented 9 years ago

There are no plans to support AppEngine in version 2. This isn't so much as an explicit thing, as it is implicit with our choice to couple the library to OkHttp.

Retrofit 1 existed in a time where there wasn't an HTTP client that met the needs of this library directly, and since Android support was of particular importance, we chose to make it pluggable with an abstraction. We paid a cost for this in the public API, the allocation overhead, and rigidity of execution mechanisms (clients were forced to be synchronous).

Over the years that Retrofit 1 existed, OkHttp grew up. We pushed what we learned from Retrofit and from clients and APIs all over into OkHttp and it became clean and highly robust. The extra abstraction of Retrofit 1 to support multiple clients seemed very old and outdated.

So with v2 we made hard choice to couple ourselves directly to OkHttp knowing that it would cause a small subset of people pain, but have large gains for the majority of its users. AppEngine seems like it's going to be one of those side-effect casualties.

Udinic commented 9 years ago

Got it, thanks for the explanation.

On Wed, Sep 30, 2015, 9:49 PM Jake Wharton notifications@github.com wrote:

There are no plans to support AppEngine in version 2. This isn't so much as an explicit thing, as it is implicit with our choice to couple the library to OkHttp.

Retrofit 1 existed in a time where there wasn't an HTTP client that met the needs of this library directly, and since Android support was of particular importance, we chose to make it pluggable with an abstraction. We paid a cost for this in the public API, the allocation overhead, and rigidity of execution mechanisms (clients were forced to be synchronous).

Over the years that Retrofit 1 existed, OkHttp grew up. We pushed what we learned from Retrofit and from clients and APIs all over into OkHttp and it became clean and highly robust. The extra abstraction of Retrofit 1 to support multiple clients seemed very old and outdated.

So with v2 we made hard choice to couple ourselves directly to OkHttp knowing that it would cause a small subset of people pain, but have large gains for the majority of its users. AppEngine seems like it's going to be one of those side-effect casualties.

— Reply to this email directly or view it on GitHub https://github.com/square/retrofit/issues/1149#issuecomment-144592695.


Udi Cohen http://www.udinic.com

JakeWharton commented 9 years ago

Is there something specific in 2.x that you are unable to do with 1.9.x for your usage on AppEngine? Retrofit 1.9.0 isn't going anywhere, so you don't really have to upgrade.

Udinic commented 9 years ago

Kind of.

I remember having some problems using UrlFetcherClient with retrofit 1.9. I wanted to set the request timeout manually, but something didn't work well. I eventually decided to do that later, as I had more urgent matters.

With 2.x coming out, I thought I'll give it another shot, maybe it'll work out of the box. The outcome was definitely the opposite of what I was hoping for.

I'll go back to 1.9 and try to make it work. I hope I won't need to switch to a different library (or use UrlFetcher directly).

On Thu, Oct 1, 2015, 10:39 PM Jake Wharton notifications@github.com wrote:

Is there something specific in 2.x that you are unable to do with 1.9.x for your usage on AppEngine? Retrofit 1.9.0 isn't going anywhere, so you don't really have to upgrade.

— Reply to this email directly or view it on GitHub https://github.com/square/retrofit/issues/1149#issuecomment-144901810.


Udi Cohen http://www.udinic.com

chirstius commented 8 years ago

Is this decision still "final"? Will there simply be no workaround for running under AppEngine?

I'm seeing a slightly different error, but I suspect it's related: java.lang.NoClassDefFoundError: Could not initialize class com.google.apphosting.runtime.security.shared.stub.java.net.ProxySelector at com.squareup.okhttp.OkHttpClient.copyWithDefaults(OkHttpClient.java:614) at com.squareup.okhttp.Call.(Call.java:48) at com.squareup.okhttp.OkHttpClient.newCall(OkHttpClient.java:595) at retrofit.OkHttpCall.createRawCall(OkHttpCall.java:120) at retrofit.OkHttpCall.execute(OkHttpCall.java:110)

So the official stance is that the only way to support AppEngine is to stay on 1.9?

JakeWharton commented 8 years ago

We have no plans to abstract or switch from using OkHttp as the underlying HTTP client. So as long as OkHttp remains incompatible with AppEngine then Retrofit will be as well.

chirstius commented 8 years ago

Ok, thank you Jake, is it worth asking if OkHttp will ever become compatible with GAE? That seems like the better/right question here, and I can take it over there if that makes more sense.

swankjesse commented 8 years ago

@RexRemus that sounds like something you should ask the GAE maintainers.

chirstius commented 8 years ago

@JakeWharton I see you referenced this issue as being "indirectly addressed" by the changes in #1394 - Can you give an example of how to use the call factory with a GAE compatible HttpClient? How would one get Retrofit to use Google's HttpClient for example? Is a wrapper required? If this is documented somewhere a pointer to that would be sufficient. Thanks!

JakeWharton commented 8 years ago

You have to implement OkHttp's Call.Factory type which is just a function from Request to Call, and return an implementation of Call which wrapped whatever underlying HTTP client you wanted to use. As far as I know there aren't any other examples of alternate Call.Factory / Call implementations.

On Thu, Feb 18, 2016 at 5:30 PM Chuck notifications@github.com wrote:

@JakeWharton https://github.com/JakeWharton I see you referenced this issue as being "indirectly addressed" by the changes in #1394 https://github.com/square/retrofit/pull/1394 - Can you give an example of how to use the call factory with a GAE compatible HttpClient? How would one get Retrofit to use Google's HttpClient for example? Is a wrapper required? If this is documented somewhere a pointer to that would be sufficient. Thanks!

— Reply to this email directly or view it on GitHub https://github.com/square/retrofit/issues/1149#issuecomment-185954250.

chirstius commented 8 years ago

Ok, I'll see if I can muddle through getting that done with a GAE compatible library (probably Google's first) as I find myself once again wanting to use GAE but also wanting to access external services via Retrofit. If you provide a Factory implementation do you still need okhttp/okio as deps?

JakeWharton commented 8 years ago

Yes. Call (and .Factory), Request, Response, and Headers are all model types provided by OkHttp and Request and Response use Okio types.

On Thu, Feb 18, 2016 at 5:48 PM Chuck notifications@github.com wrote:

Ok, I'll see if I can muddle through getting that done with a GAE compatible library (probably Google's first) as I find myself once again wanting to use GAE but also wanting to access external services via Retrofit. If you provide a Factory implementation do you still need okhttp/okio as deps?

— Reply to this email directly or view it on GitHub https://github.com/square/retrofit/issues/1149#issuecomment-185966617.