Unable to create a call adapter for the sample class. Plain

I am using retrofit 2.0.0-beta1 with SimpleXml. I want to get a simple (XML) resource from a REST service. Marshalling / Unmarshalling a simple object with SimpleXML works great.

When using this code (converted pre 2.0.0 format):

final Retrofit rest = new Retrofit.Builder() .addConverterFactory(SimpleXmlConverterFactory.create()) .baseUrl(endpoint) .build(); SimpleService service = rest.create(SimpleService.class); LOG.info(service.getSimple("572642")); 

Services:

 public interface SimpleService { @GET("/simple/{id}") Simple getSimple(@Path("id") String id); } 

I get this exception:

 Exception in thread "main" java.lang.IllegalArgumentException: Unable to create call adapter for class example.Simple for method SimpleService.getSimple at retrofit.Utils.methodError(Utils.java:201) at retrofit.MethodHandler.createCallAdapter(MethodHandler.java:51) at retrofit.MethodHandler.create(MethodHandler.java:30) at retrofit.Retrofit.loadMethodHandler(Retrofit.java:138) at retrofit.Retrofit$1.invoke(Retrofit.java:127) at com.sun.proxy.$Proxy0.getSimple(Unknown Source) 

What am I missing? I know that return type processing is done using Call . But I want the service to return business objects as a type (and work in synchronization mode).

UPDATE

After adding additional dependencies and .addCallAdapterFactory(RxJavaCallAdapterFactory.create()) , as suggested by different answers, I still get this error:

 Caused by: java.lang.IllegalArgumentException: Could not locate call adapter for class simple.Simple. Tried: * retrofit.RxJavaCallAdapterFactory * retrofit.DefaultCallAdapter$1 
+62
java rest retrofit simple-framework
Aug 28 '15 at 10:37
source share
13 answers

Short answer: return Call<Simple> to your service interface.

It looks like Retrofit 2.0 is trying to find a way to create a proxy object for your service interface. He expects you to write this:

 public interface SimpleService { @GET("/simple/{id}") Call<Simple> getSimple(@Path("id") String id); } 

However, he still wants to play well and be flexible if you do not want to return Call . To support this, it has a CallAdapter concept that needs to know how to adapt Call<Simple> to Simple .

Using RxJavaCallAdapterFactory is only useful if you are trying to return rx.Observable<Simple> .

The simplest solution is to return a Call , as Retrofit expects. You can also write CallAdapter.Factory if you really need it.

+43
Oct 18 '15 at 20:22
source share

add dependencies:

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

create your adapter as follows:

 Retrofit rest = new Retrofit.Builder() .baseUrl(endpoint) .addCallAdapterFactory(RxJavaCallAdapterFactory.create()) .addConverterFactory(SimpleXmlConverterFactory.create()) .build(); 

addCallAdapterFactory () and addConverterFactory () should both be called.

Services:

 public interface SimpleService { @GET("/simple/{id}") Call<Simple> getSimple(@Path("id") String id); } 

Change Simple to Call<Simple> .

+52
Sep 15 '15 at 11:44
source share

With the new modification (2. +) you need to add addCallAdapterFactory, which can be normal or RxJavaCallAdapterFactory (for Observables). I think you can add more than both. It automatically checks which one to use. See a working example below. You can also check this link for more details.

  Retrofit retrofit = new Retrofit.Builder().baseUrl(ApiConfig.BASE_URL) .addConverterFactory(GsonConverterFactory.create()) .addCallAdapterFactory(RxJavaCallAdapterFactory.create()) .build() 
+35
Aug 28 '15 at 17:09
source share

Add the following dependencies for modification 2

  compile 'com.squareup.retrofit2:retrofit:2.1.0' 

for GSON

  compile 'com.squareup.retrofit2:converter-gson:2.1.0' 

for observables

 compile 'com.squareup.retrofit2:adapter-rxjava:2.1.0' 

In your case for XML, you will need to include the following dependencies

  compile 'com.squareup.retrofit2:converter-simplexml:2.1.0' 

Update service call below

 final Retrofit rest = new Retrofit.Builder() .addCallAdapterFactory(RxJavaCallAdapterFactory.create()) .addConverterFactory(SimpleXmlConverterFactory.create()) .baseUrl(endpoint) .build(); SimpleService service = rest.create(SimpleService.class); 
+13
Sep 07 '15 at 18:40
source share

If you want to use retrofit2 , and you do not want to always return retrofit2.Call<T> , you need to create your own CallAdapter.Factory , which returns a simple type, as you expected. A simple code might look like this:

 import retrofit2.Call; import retrofit2.CallAdapter; import retrofit2.Retrofit; import java.lang.annotation.Annotation; import java.lang.reflect.Type; public class SynchronousCallAdapterFactory extends CallAdapter.Factory { public static CallAdapter.Factory create() { return new SynchronousCallAdapterFactory(); } @Override public CallAdapter<Object, Object> get(final Type returnType, Annotation[] annotations, Retrofit retrofit) { // if returnType is retrofit2.Call, do nothing if (returnType.toString().contains("retrofit2.Call")) { return null; } return new CallAdapter<Object, Object>() { @Override public Type responseType() { return returnType; } @Override public Object adapt(Call<Object> call) { try { return call.execute().body(); } catch (Exception e) { throw new RuntimeException(e); // do something better } } }; } } 

Then a simple SynchronousCallAdapterFactory register in Retrofit should solve your problem.

 Retrofit rest = new Retrofit.Builder() .baseUrl(endpoint) .addConverterFactory(SimpleXmlConverterFactory.create()) .addCallAdapterFactory(SynchronousCallAdapterFactory.create()) .build(); 

After that, you can return a simple type without retrofit2.Call .

 public interface SimpleService { @GET("/simple/{id}") Simple getSimple(@Path("id") String id); } 
+12
Jan 30 '16 at 16:23
source share

in my case using this

 compile 'com.jakewharton.retrofit:retrofit2-rxjava2-adapter:1.0.0' 

with this

 new Retrofit.Builder().addCallAdapterFactory(RxJava2CallAdapterFactory.create())... 

solved the problem when nothing worked

+5
Dec 28 '16 at 20:55
source share

Just to make call examples clearer for people who are migrating, not using Rx, or want synchronous calls - Call essentially replaces (wraps) Response, which means:

 Response<MyObject> createRecord(...); 

becomes

 Call<MyObject> createRecord(...); 

and not

 Call<Response<MyObject>> createRecord(...); 

(which still needs an adapter)




The call will then allow you to still use isSuccessful since it actually returns a response. So you can do something like:

 myApi.createRecord(...).execute().isSuccessful() 

Or access to your type (MyObject), like:

 MyObject myObj = myApi.createRecord(...).execute().body(); 
+1
May 30 '18 at 12:57
source share

You can implement a callback, get the Simple from onResponse function.

 public class MainActivity extends Activity implements Callback<Simple> { protected void onCreate(Bundle savedInstanceState) { final Retrofit rest = new Retrofit.Builder() .addConverterFactory(SimpleXmlConverterFactory.create()) .baseUrl(endpoint) .build(); SimpleService service = rest.create(SimpleService.class); Call<Simple> call = service.getSimple("572642"); //asynchronous call call.enqueue(this); return true; } @Override public void onResponse(Response<Simple> response, Retrofit retrofit) { // response.body() has the return object(s) } @Override public void onFailure(Throwable t) { // do something } } 
0
Dec 11 '15 at 22:17
source share
 public interface SimpleService { @GET("/simple/{id}") Simple getSimple(@Path("id") String id); } 

Communication with the network is done through a separate thread, so you should change your Simple with this.

 public interface SimpleService { @GET("/simple/{id}") Call<Simple> getSimple(@Path("id") String id); } 
0
Oct 23 '18 at 19:39
source share

In my case, I used

 com.squareup.retrofit2:adapter-rxjava:2.5.0 //notice rxjava 

instead

 com.squareup.retrofit2:adapter-rxjava2:2.5.0 //notice rxjava2 

you should use com.squareup.retrofit2:adapter-rxjava2:2.5.0 when using io.reactivex.rxjava2

0
Feb 19 '19 at 16:54
source share

If you are not using RxJava, then it makes no sense to add RxJava just for modernization. 2.5.0 has built-in support for CompletableFuture which you can use without adding any other library or adapter.

build.gradle.kts

 implementation("com.squareup.retrofit2:retrofit:2.5.0") implementation("com.squareup.retrofit2:retrofit-converters:2.5.0") 

Api.kt

 interface Api { @GET("/resource") fun listCompanies(): CompletableFuture<ResourceDto> } 

Using:

 Retrofit.Builder() .addConverterFactory(SimpleXmlConverterFactory.create()) .baseUrl("https://api.example.com") .build() .create(Api::class.java) 
0
Apr 12 '19 at 13:35
source share

for the latest modifications (July / 2017):

Use the library version correctly.

A new version

 compile 'io.reactivex.rxjava2:rxandroid:2.0.1' compile 'io.reactivex.rxjava2:rxjava:2.1.0' compile 'com.squareup.retrofit2:retrofit:2.3.0' compile 'com.squareup.retrofit2:adapter-rxjava2:2.3.0' 

1) Make sure you have similar adapters for retrofitting and reconfiguring RxJava.

2) Use

 compile 'com.squareup.retrofit2:adapter-rxjava2:2.3.0' 

not

 compile 'com.squareup.retrofit2:adapter-rxjava:2.3.0' 
-one
Jul 26 '17 at 6:21
source share

The way I fixed this problem, added this to the gradle application file, if the configuration is not installed, there will be conflicts, maybe this will be fixed in the stable version of the library:

 configurations { compile.exclude group: 'stax' compile.exclude group: 'xpp3' } dependencies { compile 'com.squareup.retrofit:retrofit:2.0.0-beta1' compile 'com.squareup.retrofit:converter-simplexml:2.0.0-beta1' } 

and create the adapter as follows:

  Retrofit retrofit = new Retrofit.Builder() .baseUrl(endPoint) .addConverterFactory(SimpleXmlConverterFactory.create()) .build(); 

Hope this helps!

-2
Sep 12 '15 at 14:30
source share



All Articles