通过 Google App Engine 上的 OKClient 使用 OkHttp 客户端会引发“java.lang.NoClassDefFoundError: java.net.ProxySelector";是受限类错误 [英] Using OkHttp client via OKClient on Google App Engine throws a "java.lang.NoClassDefFoundError: java.net.ProxySelector" is a restricted class error

查看:101
本文介绍了通过 Google App Engine 上的 OKClient 使用 OkHttp 客户端会引发“java.lang.NoClassDefFoundError: java.net.ProxySelector";是受限类错误的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我正在尝试在 Google 应用引擎 (1.9.22) 上使用 OKHTTP(版本 2.4.0)和改造(1.9.0).

I am trying to use OKHTTP (version 2.4.0) along retrofit (1.9.0) on google app engine (1.9.22).

这是我如何使用它:

    OkHttpClient okHttpClient = new OkHttpClient();
    okHttpClient.setConnectTimeout(COMPOSER_MODULE_CONNECTION_TIMEOUT,  TimeUnit.SECONDS);
    okHttpClient.setReadTimeout(COMPOSER_MODULE_SOCKET_TIMEOUT, TimeUnit.SECONDS);

    RestAdapter restAdapter = new RestAdapter.Builder()
                .setLogLevel(RestAdapter.LogLevel.FULL)
                .setConverter(new JacksonConverter())
                .setEndpoint(ENDPOINT_PATH)
                .setClient(new OkClient(okHttpClient))
                .build();

这会引发以下错误:

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.apphosting.runtime.security.shared.stub.java.net.ProxySelector.<clinit>(ProxySelector.java)
at com.squareup.okhttp.OkHttpClient.copyWithDefaults(OkHttpClient.java:614)
at com.squareup.okhttp.Call.<init>(Call.java:50)
at com.squareup.okhttp.OkHttpClient.newCall(OkHttpClient.java:595)
at retrofit.client.OkClient.execute(OkClient.java:53)

我从错误中得知java.net.ProxySelector"未列入可在 google appengine 上使用的白名单.

I gather from the error that "java.net.ProxySelector" is not white-listed for use on google appengine.

问题 1)是否可以在谷歌应用引擎(1.9.22)上使用 OKHTTP(版本 2.4.0)和改造(1.9.0)?即,是否有解决此错误的方法

Question 1) Is it possible to use OKHTTP (version 2.4.0) along retrofit (1.9.0) on google app engine (1.9.22)? i.e, is there a work around for this error

如果没有,问题2)有没有其他办法:

if not, Question 2) Are there any other way to:

(a) use async HTTP calls with google appengine (with URLFetchService, for instance) ?

(b) set connection and socket timeouts for the client used from (a) ?

我通过搜索发现的链接:(1) 客户端的Retrofit超时配置(2) Google App Engine URL Fetch Java API

The links i have come across via search: (1) Retrofit timeout configuration for clients (2) Google App Engine URL Fetch Java API

推荐答案

你可以使用 HttpUrlConnection 和 Retrofit2 在 Google APP Engine 中使用

You can use HttpUrlConnection with Retrofit2 to use it in Google APP Engine

import java.io.IOException;
import java.net.HttpURLConnection;
import java.net.URL;

import javax.servlet.http.HttpServletResponse;

import okhttp3.Call;
import okhttp3.Callback;
import okhttp3.Headers;
import okhttp3.MediaType;
import okhttp3.Protocol;
import okhttp3.Request;
import okhttp3.Response;
import okhttp3.ResponseBody;
import okio.BufferedSink;
import okio.BufferedSource;
import okio.Okio;


public class RetrofitCall implements Call {
Request request;

RetrofitCall(Request request) {
    this.request = request;
}

@Override
public Request request() {
    return request;
}

@Override
public Response execute() throws IOException {
    URL url = request.url().url();
final HttpURLConnection connection = (HttpURLConnection) url.openConnection();
    connection.setUseCaches(false);
    connection.setDoOutput(true);
    connection.setRequestMethod(request.method());

    Headers headers = request.headers();
    if (headers != null) {
        for (int i = 0; i < headers.size(); i++) {
            String name = headers.name(i);
            connection.setRequestProperty(name, headers.get(name));
        }
    }

    if (request.body() != null) {
        BufferedSink outbuf;
        outbuf = Okio.buffer(Okio.sink(connection.getOutputStream()));
        request.body().writeTo(outbuf);
        outbuf.close();
    }

    connection.connect();

    final BufferedSource source = Okio.buffer(Okio.source(connection.getInputStream()));
    if (connection.getResponseCode() != HttpServletResponse.SC_OK) {
        throw new IOException("Fail to call " + " :: " + source.readUtf8());
    }
    Response response = new Response.Builder()
            .code(connection.getResponseCode())
            .message(connection.getResponseMessage())
            .request(request)
            .protocol(Protocol.HTTP_1_1)
            .body(new ResponseBody() {
                @Override
                public MediaType contentType() {
                    return MediaType.parse(connection.getContentType());
                }

                @Override
                public long contentLength() {
                    return connection.getContentLengthLong();
                }

                @Override
                public BufferedSource source() {
                    return source;
                }
            })
            .build();
    return response;
}

@Override
public void enqueue(Callback responseCallback) {

}

@Override
public void cancel() {

}

@Override
public boolean isExecuted() {
    return false;
}

@Override
public boolean isCanceled() {
    return false;
}

public static class Factory implements Call.Factory {
    @Override
    public Call newCall(Request request) {
        return new RetrofitCall(request);
    }
}

}

这篇关于通过 Google App Engine 上的 OKClient 使用 OkHttp 客户端会引发“java.lang.NoClassDefFoundError: java.net.ProxySelector";是受限类错误的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
相关文章
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆