Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

java.lang.NoSuchMethodError org.apache.http.client.utils.URLEncodedUtils.encPath

I'm trying to make a GET request in Android using Apache HTTP Client library but I'm getting the following stacktrace back when I try to make a request.

06-17 16:19:58.891  10605-10605/com.myapp.test.android E/SELinux﹕ selinux_android_seapp_context_reload: seapp_contexts file is loaded from /data/security/spota/seapp_contexts
06-17 16:19:58.891  10605-10605/com.myapp.test.android D/dalvikvm﹕ Late-enabling CheckJNI
06-17 16:19:59.001  10605-10605/com.myapp.test.android I/dalvikvm﹕ Could not find method org.apache.http.client.utils.URLEncodedUtils.encPath, referenced from method org.apache.http.client.utils.URIBuilder.encodePath
06-17 16:19:59.001  10605-10605/com.myapp.test.android W/dalvikvm﹕ VFY: unable to resolve static method 2455: Lorg/apache/http/client/utils/URLEncodedUtils;.encPath (Ljava/lang/String;Ljava/nio/charset/Charset;)Ljava/lang/String;
06-17 16:19:59.001  10605-10605/com.myapp.test.android D/dalvikvm﹕ VFY: replacing opcode 0x71 at 0x0002
06-17 16:19:59.001  10605-10605/com.myapp.test.android I/dalvikvm﹕ Could not find method org.apache.http.client.utils.URLEncodedUtils.encUric, referenced from method org.apache.http.client.utils.URIBuilder.encodeUric
06-17 16:19:59.001  10605-10605/com.myapp.test.android W/dalvikvm﹕ VFY: unable to resolve static method 2456: Lorg/apache/http/client/utils/URLEncodedUtils;.encUric (Ljava/lang/String;Ljava/nio/charset/Charset;)Ljava/lang/String;
06-17 16:19:59.001  10605-10605/com.myapp.test.android D/dalvikvm﹕ VFY: replacing opcode 0x71 at 0x0002
06-17 16:19:59.001  10605-10605/com.myapp.test.android I/dalvikvm﹕ Could not find method org.apache.http.client.utils.URLEncodedUtils.format, referenced from method org.apache.http.client.utils.URIBuilder.encodeUrlForm
06-17 16:19:59.001  10605-10605/com.myapp.test.android W/dalvikvm﹕ VFY: unable to resolve static method 2461: Lorg/apache/http/client/utils/URLEncodedUtils;.format (Ljava/lang/Iterable;Ljava/nio/charset/Charset;)Ljava/lang/String;
06-17 16:19:59.001  10605-10605/com.myapp.test.android D/dalvikvm﹕ VFY: replacing opcode 0x71 at 0x0002
06-17 16:19:59.001  10605-10605/com.myapp.test.android I/dalvikvm﹕ Could not find method org.apache.http.client.utils.URLEncodedUtils.encUserInfo, referenced from method org.apache.http.client.utils.URIBuilder.encodeUserInfo
06-17 16:19:59.001  10605-10605/com.myapp.test.android W/dalvikvm﹕ VFY: unable to resolve static method 2457: Lorg/apache/http/client/utils/URLEncodedUtils;.encUserInfo (Ljava/lang/String;Ljava/nio/charset/Charset;)Ljava/lang/String;
06-17 16:19:59.001  10605-10605/com.myapp.test.android D/dalvikvm﹕ VFY: replacing opcode 0x71 at 0x0002
06-17 16:19:59.001  10605-10605/com.myapp.test.android I/dalvikvm﹕ Could not find method org.apache.http.client.utils.URLEncodedUtils.parse, referenced from method org.apache.http.client.utils.URIBuilder.parseQuery
06-17 16:19:59.001  10605-10605/com.myapp.test.android W/dalvikvm﹕ VFY: unable to resolve static method 2465: Lorg/apache/http/client/utils/URLEncodedUtils;.parse (Ljava/lang/String;Ljava/nio/charset/Charset;)Ljava/util/List;
06-17 16:19:59.001  10605-10605/com.myapp.test.android D/dalvikvm﹕ VFY: replacing opcode 0x71 at 0x0008
06-17 16:19:59.001  10605-10605/com.myapp.test.android W/dalvikvm﹕ Exception Ljava/lang/NoSuchMethodError; thrown while initializing Lcom/myapp/test/android/IHeart;
06-17 16:19:59.001  10605-10605/com.myapp.test.android D/AndroidRuntime﹕ Shutting down VM
06-17 16:19:59.001  10605-10605/com.myapp.test.android W/dalvikvm﹕ threadid=1: thread exiting with uncaught exception (group=0x41849898)
06-17 16:19:59.001  10605-10605/com.myapp.test.android E/AndroidRuntime﹕ FATAL EXCEPTION: main
    java.lang.NoSuchMethodError: org.apache.http.client.utils.URLEncodedUtils.encPath
            at org.apache.http.client.utils.URIBuilder.encodePath(URIBuilder.java:175)
            at org.apache.http.client.utils.URIBuilder.buildString(URIBuilder.java:136)
            at org.apache.http.client.utils.URIBuilder.build(URIBuilder.java:104)
            at com.myapp.test.android.IHeart.makeGetRequest(IHeart.java:129)
            at com.myapp.test.android.IHeart.getMarketId(IHeart.java:119)
            at com.myapp.test.android.IHeart.setMarketId(IHeart.java:70)
            at com.myapp.test.android.IHeart.initializeIHeart(IHeart.java:60)
            at com.myapp.test.android.IHeart.<init>(IHeart.java:50)
            at com.myapp.test.android.IHeart.<clinit>(IHeart.java:35)
            at com.myapp.test.android.MainActivity.onCreate(MainActivity.java:21)
            at android.app.Activity.performCreate(Activity.java:5369)
            at android.app.Instrumentation.callActivityOnCreate(Instrumentation.java:1104)
            at android.app.ActivityThread.performLaunchActivity(ActivityThread.java:2257)
            at android.app.ActivityThread.handleLaunchActivity(ActivityThread.java:2348)
            at android.app.ActivityThread.access$700(ActivityThread.java:159)
            at android.app.ActivityThread$H.handleMessage(ActivityThread.java:1316)
            at android.os.Handler.dispatchMessage(Handler.java:99)
            at android.os.Looper.loop(Looper.java:137)
            at android.app.ActivityThread.main(ActivityThread.java:5414)
            at java.lang.reflect.Method.invokeNative(Native Method)
            at java.lang.reflect.Method.invoke(Method.java:525)
            at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:1187)
            at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:1003)
            at dalvik.system.NativeStart.main(Native Method)

So it looks like the app crashes when it tries to create a URI object in my code. In particular, when it tries to parse the .setPath(path) piece of code.

// Make the GET request and get the response JSON.
return makeGetRequest(
        SCHEME,
        HOST,
        PATH_MARKET,
        params
);
...
private JSONObject makeGetRequest(String scheme, String host, String path, List<NameValuePair> params) {
        try {
            URI uri = new URIBuilder()
                    .setScheme(scheme)
                    .setHost(host)
                    .setPath(path)  // <-- Where the crash is happening!
                    .setParameters(params)
                    .build();

Here's what my code looks like.

MainActivity.java

public class MainActivity extends Activity {

@Override
public void onCreate(Bundle savedInstanceState) {
    super.onCreate(savedInstanceState);
    setContentView(R.layout.activity_main);

    IHeart.getInstance();
}

@Override
public boolean onCreateOptionsMenu(Menu menu) {
    // Inflate the menu; this adds items to the action bar if it is present.
    getMenuInflater().inflate(com.myapp.test.android.R.menu.main, menu);
    return true;
}

}

IHeart.java

import org.apache.http.HttpEntity;
import org.apache.http.NameValuePair;
import org.apache.http.client.methods.CloseableHttpResponse;
import org.apache.http.client.methods.HttpGet;
import org.apache.http.client.utils.URIBuilder;
import org.apache.http.impl.client.CloseableHttpClient;
import org.apache.http.impl.client.HttpClients;
import org.apache.http.message.BasicNameValuePair;
import org.apache.http.util.EntityUtils;
import org.json.JSONArray;
import org.json.JSONException;
import org.json.JSONObject;
import android.os.AsyncTask;
import android.util.Log;
import java.io.IOException;
import java.net.URI;
import java.net.URISyntaxException;
import java.util.ArrayList;
import java.util.List;
import java.util.concurrent.ExecutionException;

public class IHeart {

    private static final String TAG = IHeart.class.getSimpleName();
    private static IHeart instance = new IHeart();

    private static final String SCHEME = "https";
    private static final String HOST = "api2.iheart.com";
    private static final String PATH_MARKET = "/api/v2/content/markets";

    private long mMarketId;

    public static IHeart getInstance() {
        return instance;
    }

    private IHeart() {
        initializeIHeart();
    }

    private void initializeIHeart() {
        setMarketId();
    }

    private void setMarketId() {
        try {
            JSONObject response = getMarketId("40.7127837", "-74.005941");

            if (response != null) {

                final String KEY_HITS = "hits";
                final String KEY_MARKET_ID = "marketId";

                if (response.isNull(KEY_HITS)) {
                    Log.e(TAG, KEY_HITS + " key doesn't exist in response JSON.");
                } else {
                    JSONArray hitsArray = response.getJSONArray(KEY_HITS);

                    if (hitsArray == null || hitsArray.length() == 0 || hitsArray.isNull(0)) {
                        Log.d(TAG, "Hits array is null/empty.");
                    } else {
                        JSONObject firstHitsObject = hitsArray.getJSONObject(0);

                        if (firstHitsObject == null || firstHitsObject.isNull(KEY_MARKET_ID)) {
                            Log.d(TAG, "Market ID value is null/empty/missing in JSON.");
                        } else {
                            mMarketId = firstHitsObject.getInt(KEY_MARKET_ID);
                            Log.d(TAG, "Market ID = " + mMarketId);
                        }

                    }
                }

            } else {
                Log.e(TAG, "Response JSON was null.");
            }

        } catch (JSONException e) {
            e.printStackTrace();
        }
    }

    private JSONObject getMarketId(String latitude, String longitude) throws JSONException {

        // Define the params
        ArrayList<NameValuePair> params = new ArrayList<NameValuePair>();
        params.add(new BasicNameValuePair("limit", "10"));
        params.add(new BasicNameValuePair("lat", latitude));
        params.add(new BasicNameValuePair("lng", longitude));

        // Make the GET request and get the response JSON.
        return makeGetRequest(
                SCHEME,
                HOST,
                PATH_MARKET,
                params
        );
    }

    private JSONObject makeGetRequest(String scheme, String host, String path, List<NameValuePair> params) {
        try {
            URI uri = new URIBuilder()
                    .setScheme(scheme)
                    .setHost(host)
                    .setPath(path)
                    .setParameters(params)
                    .build();

            Log.d(TAG, "URI = " + uri);

            // Make asyn REST call and return resulting in JSON.
            return new getRequestTask().execute(uri).get();

        } catch (URISyntaxException e) {
            e.printStackTrace();
        } catch (InterruptedException e) {
            e.printStackTrace();
        } catch (ExecutionException e) {
            e.printStackTrace();
        }

        return null;
    }

    private class getRequestTask extends AsyncTask<URI, Void, JSONObject> {

        @Override
        protected JSONObject doInBackground(URI... params) {
            for (URI uri : params) {
                try {
                    CloseableHttpClient httpClient = HttpClients.createDefault();
                    HttpGet httpGet = new HttpGet(uri);

                    CloseableHttpResponse response = httpClient.execute(httpGet);

                    // Read the response
                    HttpEntity httpEntity = response.getEntity();

                    // Create and return JSONObject
                    if (httpEntity != null) {
                        String json = EntityUtils.toString(httpEntity);
                        return new JSONObject(json);
                    }
                } catch (IOException e) {
                    e.printStackTrace();
                } catch (JSONException e) {
                    e.printStackTrace();
                }
            }

            return null;
        }
    }
}

I've create another project, but this time as a Java application, and was able to execute this code just fine. In particular, the Java application didn't crash when it hit the following bit of code like it did in the Android app.

// Make the GET request and get the response JSON.
return makeGetRequest(
        SCHEME,
        HOST,
        PATH_MARKET,
        params
);

I'm also getting no compilation errors when I build by Android project. I'm actually able to run the app but it crashes right away.

Any pointers would be much appreciated.

If it helps, here's my Maven dependency for the Apache HTTP Client:

pom.xml

<dependency>
    <groupId>org.apache.httpcomponents</groupId>
    <artifactId>httpclient</artifactId>
    <version>4.3.4</version>
</dependency>
like image 518
FilmiHero Avatar asked Jun 17 '14 23:06

FilmiHero


2 Answers

Android include outdated Apache HttpClient implementation in their SDK which make it conflict if you add newer Apache Http Client

You should use the HttpClient for Android instead

Google Android 1.0 was released with a pre-BETA snapshot of Apache HttpClient. To coincide with the first Android release Apache HttpClient 4.0 APIs had to be frozen prematurely, while many of interfaces and internal structures were still not fully worked out. [...] Apache HttpClient 4.3 port for Android is intended to remedy the situation by providing official releases compatible with Google Android.

Use this gradle dependency configuration:

dependencies {
    /* ... */
    compile 'org.apache.httpcomponents:httpclient-android:4.3.3'
}

I'm not a maven user, but maven configuration should be something like this

<dependency>
    <groupId>org.apache.httpcomponents</groupId>
    <artifactId>httpclient-android</artifactId>
    <version>4.3.3</version>
</dependency>

You really want to use 4.3.3 since android port of 4.3.4 is not available yet.

To call a HTTP method, slightly change your code (notice HttpGetHC4)

CloseableHttpClient httpClient = HttpClients.createDefault();
HttpGetHC4 httpGet = new HttpGetHC4(url);
CloseableHttpResponse response = httpClient.execute(httpGet);

It use different implementation of URIBuilder so client code need not changed.

like image 192
hanung Avatar answered Oct 15 '22 02:10

hanung


For java, just change the order of http library to the most top position.

like image 24
魏經軒 Avatar answered Oct 15 '22 02:10

魏經軒