ClassNotFoundException for com.squareup.okhttp.internal.fram



我正在为一个使用Reactive编程和Reform的类编写单元测试用例。我得到以下异常:

com.locationlabs.finder.android.core.manager.AuthManagerTest > logout_ok STANDARD_ERROR
    Jan 07, 2016 11:28:06 PM com.squareup.okhttp.mockwebserver.MockWebServer$3 execute
    INFO: MockWebServer[51867] starting to accept connections
    Jan 07, 2016 11:28:07 PM com.squareup.okhttp.mockwebserver.MockWebServer$3 execute
    WARNING: MockWebServer[51867] failed unexpectedly
    java.lang.NoClassDefFoundError: com/squareup/okhttp/internal/framed/IncomingStreamHandler
        at com.squareup.okhttp.mockwebserver.MockWebServer.serveConnection(MockWebServer.java:414)
        at com.squareup.okhttp.mockwebserver.MockWebServer.access$800(MockWebServer.java:93)
        at com.squareup.okhttp.mockwebserver.MockWebServer$3.acceptConnections(MockWebServer.java:389)
        at com.squareup.okhttp.mockwebserver.MockWebServer$3.execute(MockWebServer.java:356)
        at com.squareup.okhttp.internal.NamedRunnable.run(NamedRunnable.java:33)
        at java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1145)
        at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:615)
        at java.lang.Thread.run(Thread.java:745)
    Caused by: java.lang.ClassNotFoundException: com.squareup.okhttp.internal.framed.IncomingStreamHandler
        at java.net.URLClassLoader$1.run(URLClassLoader.java:366)
        at java.net.URLClassLoader$1.run(URLClassLoader.java:355)
        at java.security.AccessController.doPrivileged(Native Method)
        at java.net.URLClassLoader.findClass(URLClassLoader.java:354)
        at java.lang.ClassLoader.loadClass(ClassLoader.java:425)
        at sun.misc.Launcher$AppClassLoader.loadClass(Launcher.java:308)
        at java.lang.ClassLoader.loadClass(ClassLoader.java:358)
        ... 8 more

这是我的改装课和经理课。

import java.util.Map;
import retrofit.http.Body;
import retrofit.http.Headers;
import retrofit.http.POST;
import rx.Observable;
public interface AuthService {
   @POST("auth/endAuthSession")
   @Headers({"Content-Type: application/json"})
   Observable<Void> logout();
}
public class AuthManager {
   private AuthService authService;
    public AuthManager(AuthService authService) {
      this.authService = authService;
   }
import java.util.HashMap;
import java.util.Locale;
import java.util.Map;
import rx.Observable;
import rx.functions.Func1;
public Observable<Void> logout() {
    return authService.logout()
            .map(new Func1<Void, Void>() {
               @Override
               public Void call(Void nothing) {
                  JsonUtil.token = null;
                  return null;
               }
            });
   }
}

下面是我的单元测试用例:

import com.ll.core.manager.AuthManager;
import com.ll.core.service.AuthService;
import retrofit.GsonConverterFactory;
import rx.Subscriber;
import rx.observers.TestSubscriber;
import junit.framework.Assert;
import com.google.gson.Gson;
import com.squareup.okhttp.mockwebserver.MockResponse;
import com.squareup.okhttp.mockwebserver.MockWebServer;
import com.squareup.okhttp.OkHttpClient;
import org.junit.Before;
import org.junit.Test;
import retrofit.JacksonConverterFactory;
import retrofit.Retrofit;
import retrofit.RxJavaCallAdapterFactory;
import java.io.IOException;
import java.lang.Override;
import java.lang.Throwable;
import java.lang.Void;
import java.net.HttpURLConnection;

/**
 * Unit test case for AuthManager.
 */
public class AuthManagerTest {
    private AuthService authService;
    private MockWebServer server;
    private Gson gson;
    @Before
    public void setup() throws IOException {
        server = new MockWebServer();
        server.start();
        Retrofit retrofit = new Retrofit
                .Builder()
                .baseUrl(server.url("/"))
                .addConverterFactory(JacksonConverterFactory.create())
                .addCallAdapterFactory(RxJavaCallAdapterFactory.create())
                .client(new OkHttpClient())
                .build();
        authService = retrofit.create(AuthService.class);
    }
    @Test
    public void logout_ok(){
        //Setup resonse.
        MockResponse response = new MockResponse()
                .setResponseCode(HttpURLConnection.HTTP_OK);
        server.enqueue(response);
        AuthManager authManager = new AuthManager(authService);
        TestSubscriber sub = new TestSubscriber();
        authManager.logout().subscribe(sub);
        sub.assertCompleted();
    }
}

最初谷歌搜索表明应该包括okio库。即使包括了"okio,library",我仍然会遇到同样的异常。这是我的成绩单档案。

dependencies {
   compile group: 'com.google.android.gms', name: 'play-services-analytics', version: '8.4.0'
   // HTTP libs
   compile 'com.squareup.retrofit:retrofit:2.0.0-beta2'
   compile 'com.squareup.okhttp:okhttp:2.7.1'
   compile 'com.squareup.okhttp:logging-interceptor:2.6.0'
   // Reactive libs
   compile 'io.reactivex:rxandroid:1.1.0'
   compile 'io.reactivex:rxjava:1.1.0'
   compile 'com.squareup.retrofit:adapter-rxjava:2.0.0-beta2'
   // JSON libs
   compile 'com.fasterxml.jackson.core:jackson-databind:2.7.0-rc2'
   compile 'com.fasterxml.jackson.core:jackson-core:2.7.0-rc2'
   compile 'com.squareup.retrofit:converter-jackson:2.0.0-beta2'
   // DI libs
   compile group: 'com.google.dagger', name: 'dagger', version: '2.0.2'
   apt group: 'com.google.dagger', name: 'dagger-compiler', version: '2.0.2'
   provided 'org.glassfish:javax.annotation:10.0-b28'
   // DB lib
   compile 'io.realm:realm-android:0.87.1'
   // Unit testing dependencies
   testCompile 'junit:junit:4.12'
   testCompile 'com.squareup.okio:okio:1.6.0'
   testCompile 'com.squareup.okhttp:mockwebserver:2.5.0'
   testCompile 'com.squareup.retrofit:retrofit-mock:2.0.0-beta2'
   testCompile 'com.squareup.retrofit:converter-gson:2.0.0-beta2'
}

EDIT1

当我运行以下命令时:

jar -tvf ~/.gradle/caches/modules-2/files-2.1/com.squareup.okhttp/okhttp/2.5.0/4de2b4ed3445c37ec1720a7d214712e845a24636/okhttp-2.5.0.jar

我确实看到了罐子里的班级。

  995 Tue Aug 25 21:12:54 PDT 2015 com/squareup/okhttp/internal/framed/IncomingStreamHandler$1.class
   593 Tue Aug 25 21:12:54 PDT 2015 com/squareup/okhttp/internal/framed/IncomingStreamHandler.class

我仍然不明白为什么单元测试不能找到这个类,即使它在jar文件中。看起来这是Jar的问题。

编辑2:这确实是Jar地狱的问题。如果你注意到上面的渐变文件,我对okhttp使用2.7.1版本,但对mockwebser使用2.5.0版本。当我使用2.7.1版本的mockwebserver时,这个问题已经解决了。

使用proguard模糊代码时,需要添加异常以避免proguard中的类、方法或字段。由于反思,你们的大多数图书馆都处于危险地带。您需要为每个使用例如RXJava、Dagger、Reform和GSON的库找到特定的proguard配置。

另一种解决方案是忘记proguard或像避免整个改装包一样安全。

相关内容

最新更新