DreamBigAlvin DreamBigAlvin - 4 months ago 47
Android Question

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

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 = "test@liferay.com";
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.** { *; }

Answer

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'