Retrofit 2 HTTP method annotation is required (e.g., @GET, @POST, etc.)

12,544

Solution 1

Issue

You're using beta2 versions of retrofit plugins which depend on beta2 version of retrofit which still lives in com.squreup.retrofit package.

compile 'com.squareup.retrofit:adapter-rxjava:2.0.0-beta2'
compile 'com.squareup.retrofit:converter-gson:2.0.0-beta2'

Then you're importing beta3 version of retrofit itself which lives in retrofit2 package. Basically it can be used alongside beta2 version.

compile 'com.squareup.retrofit2:retrofit:2.0.0-beta3'

You're not really using beta3 at all, because it's incompatible with beta2 plugins and you'd get compile time errors. Check your imports to verify.

What happened is (most likely) you use everything from com.square.retrofit package except for the @GET class which is from retrofit2 package. Despite their identical name these classes are not the same.

Solution

Move to beta4 and retrofit2 package. Fix your imports. Profit.

compile 'com.squareup.retrofit2:retrofit:2.0.0-beta4'
compile 'com.squareup.retrofit2:adapter-rxjava:2.0.0-beta4'
compile 'com.squareup.retrofit2:converter-gson:2.0.0-beta4'

Solution 2

Using the wrong "@GET"

This may help someone coming from retrofit1, I was getting this same error and the fix was simple. In my interface I was unaware that I was using @GET from retrofit.http and not @GET from retrofit2.http, changing the annotation from retrofit.http to retrofit2.http was all I needed to do.

enter image description here

Solution 3

It look like you are using proguard and it is stripping annotations. To get saved from it add this lines to your proguard-rules.pro

-keepattributes *Annotation*
-keep class retrofit.** { *; }
-keepclasseswithmembers class * {
@retrofit.http.* <methods>; }
-keepattributes Signature

if not using proguard make sure that you havn't written something in your app build.gradle something like this

buildTypes {
    release {
        minifyEnabled true
        proguardFiles getDefaultProguardFile('proguard-android-optimize.txt'), 'proguard-rules.pro'
    }
}

Note: Android does not come normally with many of the javax.annotation library by default.

if it is not so then try adding this in your gradle dependency (build.gradle)

provided 'org.glassfish:javax.annotation:10.0-b28'
Share:
12,544
DreamBigAlvin
Author by

DreamBigAlvin

I'm android enthusiast and I love researching new trends and technology. I continuously evaluate new coding styles in development to create efficient design and maintainable applications. Exploring RFID/NFC Development and Paperless transaction Mobility. My knowledge, skill, being a critical thinker and eagerness to learn new things sets as an Innovative Software Developer. Being a software developer, we must have a continuous learning process because Innovation never stops. I can do work Individually but I love to work with a team.

Updated on June 07, 2022

Comments

  • DreamBigAlvin
    DreamBigAlvin almost 2 years

    What's wrong with my Retrofit configuration? I'm having this error when I'm adding Basic Authentication with my OkHttpClient but when I used the default client without Interceptor it's working. Or is there something wrong with my Gradle Dependencies..?

    E/AndroidRuntime﹕ FATAL EXCEPTION: main
            java.lang.IllegalArgumentException
        : HTTP method annotation is required (e.g., @GET, @POST, etc.).
                for method APIService.getRegAccrDetails
                        at retrofit.Utils.methodError(Utils.java:177)
                        at retrofit.Utils.methodError(Utils.java:167)
                        at retrofit.RequestFactoryParser.parseMethodAnnotations(RequestFactoryParser.java:135)
                        at retrofit.RequestFactoryParser.parse(RequestFactoryParser.java:59)
                        at retrofit.MethodHandler.create(MethodHandler.java:30)
                        at retrofit.Retrofit.loadMethodHandler(Retrofit.java:151)
                        at retrofit.Retrofit$1.invoke(Retrofit.java:132)
                        at $Proxy0.getRegAccrDetails(Native Method)
                        at alvin.test.myapplication.MainActivity.liferayAccess(MainActivity.java:136)
                        at alvin.test.myapplication.MainActivity.access$000(MainActivity.java:28)
                        at alvin.test.myapplication.MainActivity$1.onClick(MainActivity.java:49)
                        at android.view.View.performClick(View.java:3511)
                        at android.view.View$PerformClick.run(View.java:14105)
                        at android.os.Handler.handleCallback(Handler.java:605)
                        at android.os.Handler.dispatchMessage(Handler.java:92)
                        at android.os.Looper.loop(Looper.java:137)
                        at android.app.ActivityThread.main(ActivityThread.java:4424)
                        at java.lang.reflect.Method.invokeNative(Native Method)
                        at java.lang.reflect.Method.invoke(Method.java:511)
                        at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:784)
                        at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:551)
                        at dalvik.system.NativeStart.main(Native Method)
    

    Here is my API Service to be called

      @GET("Triu-services-portlet.regaccrdetails/get-all-reg-accr-details-by-num-branch-code/num/{num}/branch-code/{branch-code}")
        public Observable<List<RegAccrDetails>> getRegAccrDetails(@Path("num") String num, @Path("branch-code")String branchCode);
    

    My OkHttpClient Interceptor

    private static OkHttpClient createOkHttpClient() {
       String username = "[email protected]";
       String password = "TEST";
       String credentials = username + ":" + password;
       final String basic =
               "Basic " + Base64.encodeToString(credentials.getBytes(), Base64.DEFAULT);//no_wrap
    
    
    
        OkHttpClient client = new OkHttpClient();
        client.interceptors().add(new Interceptor() {
            @Override
            public Response intercept(Chain chain) throws IOException {
                Response response = chain.proceed(chain.request());
    
                Request original = chain.request();
    
                // Customize the request
                Request request = original.newBuilder()
                        .header("Authorization", basic)
                        .header("Accept", "application/json")
                        //.header("Authorization", "auth-token")//add token for service A4oslsSXZxfbLdk
                        .method(original.method(), original.body())
                        .build();
    
                response = chain.proceed(request);
    
                // Customize or return the response
                return response;
            }
        });
    
       return client;
    }
    

    Here is my Call for my API

    private void liferayAccess(){
        Log.d("liferayAccess", "Entered");
        APIService service =  ServiceGenerator.createService(APIService.class);
        Observable<List<RegAccrDetails>> liferayResponse = service.getRegAccrDetails("004589209", "001");
    
        liferayResponse.subscribeOn(Schedulers.newThread()).map(listResponse -> "response index 0 " + listResponse.get(0).getRegNum())
                .subscribe( response-> Log.d("Liferay Num", response),
                            error -> Log.d("Error", error.toString())
                        );
    }
    

    Here is my Gradle Dependencies

     compile fileTree(dir: 'libs', include: ['*.jar'])
    compile 'com.android.support:appcompat-v7:23.1.1'
    
    compile 'io.reactivex:rxjava:1.0.16'
    compile 'io.reactivex:rxandroid:1.1.0'
    compile 'com.squareup.retrofit:adapter-rxjava:2.0.0-beta2'
    compile 'com.squareup.retrofit:converter-gson:2.0.0-beta2'
    
    //compile 'com.squareup.retrofit:converter-simplexml:2.0.0-beta2'
    /*compile 'com.squareup.okhttp:okhttp:2.2.0'*/
    compile ('com.squareup.retrofit2:retrofit:2.0.0-beta3') {//com.squareup.retrofit2:retrofit:2.0.0-beta3
        // exclude Retrofit’s OkHttp peer-dependency module and define your own module import
        //exclude module: 'okhttp'
    }
    compile 'com.squareup.okhttp3:okhttp:3.0.0'
    compile 'com.squareup.okhttp3:logging-interceptor:3.0.1'
    

    Here is my App Gradle File

    apply plugin: 'com.android.application'
    apply plugin: 'me.tatarka.retrolambda'
    android {
        compileSdkVersion 23
        buildToolsVersion "23.0.2"
    
        compileOptions {
            sourceCompatibility JavaVersion.VERSION_1_8
            targetCompatibility JavaVersion.VERSION_1_8
        }
        packagingOptions {
            exclude 'META-INF/LICENSE'
            exclude 'META-INF/NOTICE'
        }
    
    
    
    
        defaultConfig {
            applicationId "alvin.test.myapplication"
            minSdkVersion 15
            targetSdkVersion 23
            versionCode 1
            versionName "1.0"
        }
        buildTypes {
            release {
                minifyEnabled false
                proguardFiles getDefaultProguardFile('proguard-android.txt'), 'proguard-rules.pro'
            }
        }
    }
    
    dependencies {
        compile fileTree(dir: 'libs', include: ['*.jar'])
        compile 'com.android.support:appcompat-v7:23.1.1'
    
        compile 'io.reactivex:rxjava:1.0.16'
        compile 'io.reactivex:rxandroid:1.1.0'
        compile 'com.squareup.retrofit:adapter-rxjava:2.0.0-beta2'
        compile 'com.squareup.retrofit:converter-gson:2.0.0-beta2'
    
        //compile 'com.squareup.retrofit:converter-simplexml:2.0.0-beta2'
        /*compile 'com.squareup.okhttp:okhttp:2.2.0'*/
        compile ('com.squareup.retrofit2:retrofit:2.0.0-beta3') {//com.squareup.retrofit2:retrofit:2.0.0-beta3
            // exclude Retrofit’s OkHttp peer-dependency module and define your own module import
            //exclude module: 'okhttp'
        }
        compile 'com.squareup.okhttp3:okhttp:3.0.0'
        compile 'com.squareup.okhttp3:logging-interceptor:3.0.1'
    
        //compile 'com.squareup.retrofit:retrofit:2.0.0-beta2'
        compile 'com.google.android.gms:play-services-gcm:7.3.0'
        compile 'com.google.android.gms:play-services:7.8.0'
    }
    retrolambda {
        jdk "C:\\Program Files\\Java\\jdk1.8.0_20"
    }
    

    My Proguard. I also tried add and remove it but same error log happen

    -keepattributes *Annotation*
    -keep class retrofit.** { *; }
    -keepclasseswithmembers class * {
    @retrofit.http.* <methods>; }
    -keepattributes Signature
    
    
    -keep class com.google.gson.** { *; }
    -keep class com.google.inject.** { *; }
    -keep class org.apache.http.** { *; }
    -keep class org.apache.james.mime4j.** { *; }
    -keep class javax.inject.** { *; }
    -keep class retrofit.** { *; }
    
  • DreamBigAlvin
    DreamBigAlvin over 8 years
    I'm not using proguard and i'm having the error an i also tried to add that but then.. same thing happened..
  • Harsh Sharma
    Harsh Sharma over 8 years
    @DreamBigAlvin have you checked your build.gradle file
  • DreamBigAlvin
    DreamBigAlvin over 8 years
    my minifyEnabled is false so it will not using the proguard.. i also tried implementing it using proguard but same thing happened i added those proguard rules and it's same error logs..
  • Harsh Sharma
    Harsh Sharma over 8 years
    @DreamBigAlvin have you tried adding the dependency mentioned in my answer
  • Ninja
    Ninja over 7 years
    I meet the same issue.After include your magic code ,it works! It is strange the official website does not offer this
  • Kishan Solanki
    Kishan Solanki over 2 years
    also for other method types like POST etc, Field and FormUrlEncoded are also needs to be the type of retrofit2.http.