31

I've set up a very simple project to test the integration of Robolectric + Data Binding + Retrolambda. When I run the test suit, I get the following message:

Error:(30, 30) Gradle: error: cannot access AndroidHttpClient
class file for android.net.http.AndroidHttpClient not found

This is pretty odd since I don't use AndroidHttpClient anywhere.


The error occurs here, on the "activity" line:

@Before
public void setup() {
    activity = Robolectric.setupActivity(MainActivity.class); // Error on this line
    textView = (TextView) shadowOf(activity).findViewById(R.id.textView);
    button = (Button) activity.findViewById(R.id.button);
    editText = (EditText) activity.findViewById(R.id.editText);
}

The program never uses AndroidHttpClient. In fact, this is the entire program:

@Override
protected void onCreate(Bundle savedInstanceState) {
    super.onCreate(savedInstanceState);

    final ActivityMainBinding binding = DataBindingUtil.setContentView(this, R.layout.activity_main);

    binding.setUser(new User());
    binding.button.setOnClickListener((v) -> {
        binding.textView.setText(String.format("Hello, %s!", binding.editText.getText()));
        binding.editText.setText("");
    });
}

Ideas as to what's wrong?

Technocrat
  • 381
  • 1
  • 3
  • 6
  • 3
    `AndroidHttpClient` was removed from the SDK in API Level 23, so if your `compileSdkVersion` is 23 or higher, that would explain why the class isn't found. As to why Robolectric is trying to access that class, that I can't say. – CommonsWare Sep 24 '15 at 11:07
  • That fixed it! I was running the tests with: "@Config(constants = BuildConfig.class, sdk = 21)". Thanks! – Technocrat Sep 24 '15 at 11:19
  • Write an answer so everyone will benefit – Eugen Martynov Sep 24 '15 at 16:59

5 Answers5

48

AndroidHttpClient was removed from the SDK in v23 of the build tools.

As Robolectric is running against earlier versions, it expects it to be there, which is why you're seeing this error.

For now, you can add it back in:

android {
    useLibrary 'org.apache.http.legacy'
}

As detailed here.

There is a GitHub ticket open for Robolectric to fix this. You can follow the thread/ticket here.

Update:

As some people have correctly pointed out, a better way of doing this would be to create a class android.net.http.AndroidHttpClient in your test resources. This would be a preferred method because you're only modifying the test sources, not the production code, in order to accommodate the tests.

Ben Pearson
  • 7,532
  • 4
  • 30
  • 50
  • 6
    Please don't do that. By adding obsolete library, you're bloating your app with code which is used only for testing. – Dmitry Zaytsev Oct 06 '15 at 09:38
  • Error:Execution failed for task ':app:transformClassesWithJarMergingForDebug'. > com.android.build.api.transform.TransformException: java.util.zip.ZipException: duplicate entry: org/apache/http/ConnectionClosedException.class – Iman Marashi Nov 25 '16 at 08:04
  • @DmitryZaytsev good point. As the answer was receiving quite a lot of attention, I've updated it. – Ben Pearson May 28 '18 at 10:10
17

I've just added fake class android.net.http.AndroidHttpClient in my test sources. And it solved the issue for now. Waiting for Robolectric to be updated

Eugen Martynov
  • 19,888
  • 10
  • 61
  • 114
  • 1
    This solved it for me with the minimum level of impact. The use of `useLibrary` results in extra items being bundled into your main app whereas adding this class under `src/test/java` has no impact on the main app. – Craig Russell Oct 30 '15 at 07:59
6

Apparent problem and solution:

AndroidHttpClient was removed from the SDK in API Level 23, while Robolectric was set to run tests with SDK 21:

AndroidHttpClient was removed from the SDK in API Level 23
Technocrat
  • 381
  • 1
  • 3
  • 6
  • I'm running into the same problem, what was the actual solution? For me compiling with API Level 22 probably isn't an answer. – David Berry Sep 28 '15 at 21:30
  • As I recall, the AndroidHttpClient issue was caused by a discrepancy between the sdk version set for robolectric (21) and the compileSdkVersion (23). However, I wrote the project to evaluate the data binding library and ended up concluding there were still too many issues. – Technocrat Sep 29 '15 at 07:48
5

I was able to solve this problem by creating a new class called AndroidHttpClient within a new package android.net.http. After that I had to annotate my Unit Test class with @Config(constants = BuildConfig.class, sdks = 21) which will run the tests against an emulated version of API 21 which is the last version of Android Robolectric supports currently.

There is currently an issue opened here, so once they release version 3.1 everything should be fine and you won't have to use this workaround.

CodyEngel
  • 1,501
  • 14
  • 22
5

If target SDK is 28 or greater then according to this, we have to put following line in AndroidManifest.xml

<uses-library android:name="org.apache.http.legacy" android:required="false"/>
Naveed Ali
  • 2,609
  • 1
  • 22
  • 37
  • 1
    Thanks Naveed! Been fighting with this for a few hours. Edit: (My error was Caused by: java.lang.ClassNotFoundException: android.net.http.AndroidHttpClient to hopefully point some extra folks to this page via crawlers since the full trace is not in the question.) – Dean Solecki Feb 16 '22 at 17:33