no suitable HttpMessageConverter found for response type [com.enimbus.book.Post] and content type [text/html;charset=UTF-8] - rest

I am developing android app using restful service. I call get request from a url and it returns content type application/json;charset=UTF-8. I want to show return json data in my android view. to do that I use below code in android mainactivity
private class HttpRequestTask extends AsyncTask<Void, Void, Post> {
#Override
protected Post doInBackground(Void... params) {
try {
final String url = "http://192.168.0.100:8080/rposts/view/46";
RestTemplate restTemplate = new RestTemplate();
restTemplate.getMessageConverters().add(new MappingJackson2HttpMessageConverter());
Post post = restTemplate.getForObject(url, Post.class);
return post;
} catch (Exception e) {
Log.e("MainActivity", e.getMessage(), e);
}
return null;
}
#Override
protected void onPostExecute(Post post) {
TextView PostIdText = (TextView) findViewById(R.id.post_title);
TextView PostContentText = (TextView) findViewById(R.id.post_body);
PostIdText.setText(post.getTitle());
PostContentText.setText(post.getBody());
}
}
when I run my app it gives an error
Could not extract response: no suitable HttpMessageConverter found for response type [com.enimbus.book.Post] and content type [text/html;charset=UTF-8]
org.springframework.web.client.RestClientException: Could not extract response: no suitable HttpMessageConverter found for response type [com.enimbus.book.Post] and content type [text/html;charset=UTF-8]
at org.springframework.web.client.HttpMessageConverterExtractor.extractData(HttpMessageConverterExtractor.java:79)
at org.springframework.web.client.RestTemplate.doExecute(RestTemplate.java:484)
at org.springframework.web.client.RestTemplate.execute(RestTemplate.java:439)
at org.springframework.web.client.RestTemplate.getForObject(RestTemplate.java:237)
at com.enimbus.book.MainActivity$HttpRequestTask.doInBackground(MainActivity.java:123)
at com.enimbus.book.MainActivity$HttpRequestTask.doInBackground(MainActivity.java:116)
at android.os.AsyncTask$2.call(AsyncTask.java:288)
at java.util.concurrent.FutureTask.run(FutureTask.java:237)
at android.os.AsyncTask$SerialExecutor$1.run(AsyncTask.java:231)
at java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1112)
at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:587)
at java.lang.Thread.run(Thread.java:841)
11-02 14:34:39.194 27146-27146/com.enimbus.book D/AndroidRuntime: Shutting down VM
11-02 14:34:39.194 27146-27146/com.enimbus.book W/dalvikvm: threadid=1: thread exiting with uncaught exception (group=0x41e90da0)
11-02 14:34:39.204 27146-27146/com.enimbus.book E/AndroidRuntime: FATAL EXCEPTION: main
Process: com.enimbus.book, PID: 27146
java.lang.NullPointerException
at com.enimbus.book.MainActivity$HttpRequestTask.onPostExecute(MainActivity.java:137)
at com.enimbus.book.MainActivity$HttpRequestTask.onPostExecute(MainActivity.java:116)
at android.os.AsyncTask.finish(AsyncTask.java:632)
at android.os.AsyncTask.access$600(AsyncTask.java:177)
at android.os.AsyncTask$InternalHandler.handleMessage(AsyncTask.java:645)
at android.os.Handler.dispatchMessage(Handler.java:102)
at android.os.Looper.loop(Looper.java:146)
at android.app.ActivityThread.main(ActivityThread.java:5653)
at java.lang.reflect.Method.invokeNative(Native Method)
at java.lang.reflect.Method.invoke(Method.java:515)
at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:1291)
at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:1107)
at dalvik.system.NativeStart.main(Native Method)
I am using below dependencies in gradle app
dependencies {
compile fileTree(include: ['*.jar'], dir: 'libs')
testCompile 'junit:junit:4.12'
compile 'com.android.support:appcompat-v7:23.4.0'
compile 'com.android.support:design:23.4.0'
compile 'org.springframework.android:spring-android-rest-template:1.0.1.RELEASE'
compile 'com.fasterxml.jackson.core:jackson-databind:2.3.2'
}
returned json data when I test with postman
{
"id": 46,
"title": "hellov",
"slug": "tharu",
"postedOn": "08/12/2016 3:04:58 PM",
"keywords": [
"i"
],
"tags": [
"love"
],
"active": true,
"author": {
"id": 20,
"firstName": "Tharindu",
"lastName": "Gihan",
"email": "gihan#gmail.com"
},
"teaser": "<p>to</p>",
"body": "<p>you</p>"
}
Server side spring boot rest controller
package com.gihangreen.controller.rest;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.PathVariable;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestMethod;
import org.springframework.web.bind.annotation.RequestParam;
import org.springframework.web.bind.annotation.RestController;
import com.gihangreen.domain.Post;
import com.gihangreen.service.CommentService;
import com.gihangreen.service.PostService;
#RestController
#RequestMapping("/rposts")
public class PostRestController {
private PostService postService;
private CommentService commentService;
#Autowired
public PostRestController(PostService postService, CommentService commentService) {
super();
this.postService = postService;
this.commentService = commentService;
}
//get all posts
#RequestMapping( value = "/list", method = RequestMethod.GET )
public Iterable<Post> list(){
return postService.list();
}
//get post content by id
#RequestMapping(value="/view/{id}", method = RequestMethod.GET)
public Post read(#PathVariable(value = "id") long id) {
return postService.get(id);
}
//get post by author id
#RequestMapping(value="/byAuthor/{id}", method = RequestMethod.GET)
public Iterable<Post> byAuthor(#PathVariable(value = "id") long id) {
return postService.listByAuthor(id);
}
//search post by string
#RequestMapping(value="/search", method = RequestMethod.GET)
public Iterable<Post> search(#RequestParam("search") String search) {
return postService.searching(search);
}
}
How I fixed this issue? help

Might be better to first see what the data is being sent back?
CURL http://192.168.0.100:8080/rposts/view/46 -v

Related

ResourceAccessException received instead HttpServerErrorException

I have invoked rest Api in my microservice using RestTemplate. However incase of exceptions i have returned error data with HTTP response code as 500. But when i receive this response in my microservice , it is received as ResourceAccessException instead of HttpServerErrorException. Hence i lose the response body which i returned in my rest API. Spring web is of version 5.2.5
Add below component
import java.io.IOException;
import org.springframework.http.HttpStatus;
import org.springframework.http.client.ClientHttpResponse;
import org.springframework.stereotype.Component;
import org.springframework.web.client.HttpClientErrorException;
import org.springframework.web.client.HttpServerErrorException;
import org.springframework.web.client.ResponseErrorHandler;
#Component
public class RestTemplateResponseErrorHandler implements ResponseErrorHandler {
#Override
public boolean hasError(ClientHttpResponse httpResponse) throws IOException {
return (httpResponse.getStatusCode().series() == HttpStatus.Series.CLIENT_ERROR
|| httpResponse.getStatusCode().series() == HttpStatus.Series.SERVER_ERROR);
}
#Override
public void handleError(ClientHttpResponse httpResponse) throws IOException {
if (httpResponse.getStatusCode().series() == HttpStatus.Series.SERVER_ERROR) {
throw new HttpServerErrorException(HttpStatus.SERVICE_UNAVAILABLE);
} else if (httpResponse.getStatusCode().series() == HttpStatus.Series.CLIENT_ERROR) {
throw new HttpClientErrorException(HttpStatus.UNAUTHORIZED);
}
}
}
And handle exception like below while calling API
ResponseEntity<Object> res = null;
try {
res = restTemplate.exchange(completeUrl, HttpMethod.GET, null, Object.class);
if (res.getStatusCodeValue() == HttpStatus.OK.value()) {
}
} catch (HttpServerErrorException e) {
} catch (HttpClientErrorException e) {
}
The reason why you are getting this ResourceAccessException may be because you are using BufferingClientHttpRequestFactory. Without a full stack trace, I cannot be sure.
Look here for more details:
Throwing ResourceAccessException vs HttpClientErrorException for RestTemplate client in Spring

java.io.BufferedReader().map Cannot infer type argument(s) for <T> fromStream(Stream<? extends T>)

Scenario: a Spring WebFlux triggering CommandLineRunner.run in order to load data to MongoDb for testing purpose.
Goal: when starting the microservice locally it is aimed to read a json file and load documents to MongDb.
Personal knowledge: "bufferedReader.lines().filter(l -> !l.trim().isEmpty()" reads each json node and return it as stream. Then I can map it to "l" and access the get methods. I guess I don't have to create a list and then stream it since I have already load it as stream by "new InputStreamReader(getClass().getClassLoader().getResourceAsStream()" and I assume I can use lines() since it node will result in a string line. Am I in right direction or I am messing up some idea?
This is a json sample file:
{
"Extrato": {
"description": "credit",
"value": "R$1.000,00",
"status": 11
},
"Extrato": {
"description": "debit",
"value": "R$2.000,00",
"status": 99
}
}
model
import org.springframework.data.annotation.Id;
import org.springframework.data.mongodb.core.mapping.Document;
#Document
public class Extrato {
#Id
private String id;
private String description;
private String value;
private Integer status;
public Extrato(String id, String description, String value, Integer status) {
super();
this.id = id;
this.description = description;
this.value = value;
this.status = status;
}
... getters and setter accordinly
Repository
import org.springframework.data.mongodb.repository.Query;
import org.springframework.data.repository.reactive.ReactiveCrudRepository;
import com.noblockingcase.demo.model.Extrato;
import reactor.core.publisher.Flux;
import org.springframework.data.domain.Pageable;
public interface ExtratoRepository extends ReactiveCrudRepository<Extrato, String> {
#Query("{ id: { $exists: true }}")
Flux<Extrato> retrieveAllExtratosPaged(final Pageable page);
}
command for loading from above json file
import org.springframework.boot.CommandLineRunner;
import org.springframework.stereotype.Component;
import com.noblockingcase.demo.model.Extrato;
import com.noblockingcase.demo.repository.ExtratoRepository;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import reactor.core.publisher.Flux;
#Component
public class TestDataLoader implements CommandLineRunner {
private static final Logger log = LoggerFactory.getLogger(TestDataLoader.class);
private ExtratoRepository extratoRepository;
TestDataLoader(final ExtratoRepository extratoRepository) {
this.extratoRepository = extratoRepository;
}
#Override
public void run(final String... args) throws Exception {
if (extratoRepository.count().block() == 0L) {
final LongSupplier longSupplier = new LongSupplier() {
Long l = 0L;
#Override
public long getAsLong() {
return l++;
}
};
BufferedReader bufferedReader = new BufferedReader(
new InputStreamReader(getClass().getClassLoader().getResourceAsStream("carga-teste.txt")));
//*** THE ISSUE IS NEXT LINE
Flux.fromStream(bufferedReader.lines().filter(l -> !l.trim().isEmpty())
.map(l -> extratoRepository.save(new Extrato(String.valueOf(longSupplier.getAsLong()),
l.getDescription(), l.getValue(), l.getStatus()))))
.subscribe(m -> log.info("Carga Teste: {}", m.block()));
}
}
}
Here is the MongoDb config althought I don't think it is relevant
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import com.mongodb.MongoClientOptions;
#Configuration
public class MongoDbSettings {
#Bean
public MongoClientOptions mongoOptions() {
return MongoClientOptions.builder().socketTimeout(2000).build();
}
}
If I tried my original code and adjust it for reading a text file I can successfully read text file instead of json. Obvisouly it doesn't fit my demand since I want read json file. By the way, it can clarify a bit more where I am blocked.
load-test.txt (available in https://github.com/jimisdrpc/webflux-worth-scenarious/blob/master/demo/src/main/resources/carga-teste.txt)
crédito de R$1.000,00
débito de R$100,00
snippet code working with simple text file
BufferedReader bufferedReader = new BufferedReader(
new InputStreamReader(getClass().getClassLoader().getResourceAsStream("carga-teste.txt")));
Flux.fromStream(bufferedReader.lines().filter(l -> !l.trim().isEmpty())
.map(l -> extratoRepository
.save(new Extrato(String.valueOf(longSupplier.getAsLong()), "Qualquer descrição", l))))
.subscribe(m -> log.info("Carga Teste: {}", m.block()));
Whole project working succesfully reading from text file: https://github.com/jimisdrpc/webflux-worth-scenarious/tree/master/demo
Docker compose for booting MongoDb https://github.com/jimisdrpc/webflux-worth-scenarious/blob/master/docker-compose.yml
To summarize, my issue is: I didn't figure out how read a json file and insert the data into MongoDb during CommandLineRunner.run()
I found an example with Flux::using Flux::fromStream to be helpful for this purpose. This will read your file into a Flux and then you can subscribe to and process with .flatmap or something. From the Javadoc
using(Callable resourceSupplier, Function> sourceSupplier, Consumer resourceCleanup)
Uses a resource, generated by a supplier for each individual Subscriber, while streaming the values from a Publisher derived from the same resource and makes sure the resource is released if the sequence terminates or the Subscriber cancels.
and the code that I put together:
private static Flux<Account> fluxAccounts() {
return Flux.using(() ->
new BufferedReader(new InputStreamReader(new ClassPathResource("data/ExportCSV.csv").getInputStream()))
.lines()
.map(s->{
String[] sa = s.split(" ");
return Account.builder()
.firstname(sa[0])
.lastname(sa[1])
.build();
}),
Flux::fromStream,
BaseStream::close
);
}
Please note your json is invalid. Text data is not same as json. Json needs a special handling so always better to use library.
carga-teste.json
[
{"description": "credit", "value": "R$1.000,00", "status": 11},
{"description": "debit","value": "R$2.000,00", "status": 99}
]
Credits goes to article here - https://www.nurkiewicz.com/2017/09/streaming-large-json-file-with-jackson.html.
I've adopted to use Flux.
#Override
public void run(final String... args) throws Exception {
BufferedReader bufferedReader = new BufferedReader(
new InputStreamReader(getClass().getClassLoader().getResourceAsStream("carga-teste.json")));
ObjectMapper mapper = new ObjectMapper();
Flux<Extrato> flux = Flux.generate(
() -> parser(bufferedReader, mapper),
this::pullOrComplete,
jsonParser -> {
try {
jsonParser.close();
} catch (IOException e) {}
});
flux.map(l -> extratoRepository.save(l)).subscribe(m -> log.info("Carga Teste: {}", m.block()));
}
}
private JsonParser parser(Reader reader, ObjectMapper mapper) {
JsonParser parser = null;
try {
parser = mapper.getFactory().createParser(reader);
parser.nextToken();
} catch (IOException e) {}
return parser;
}
private JsonParser pullOrComplete(JsonParser parser, SynchronousSink<Extrato> emitter) {
try {
if (parser.nextToken() != JsonToken.END_ARRAY) {
Extrato extrato = parser.readValueAs(Extrato.class);
emitter.next(extrato);
} else {
emitter.complete();
}
} catch (IOException e) {
emitter.error(e);
}
return parser;
}

Unable to get an Observable List using Gluon Connect - Multiple Exceptions

I'm trying to populate multiple tables with JSON streaming data. News, Twitter and Forex Data.
I am trying to populate a list or table with REST data using Gluon Connect.
I've followed the documentation to the letter but i am not getting anywhere. From what i can see, REST client connects successfully, but is unable to return an Observable List.
I've followed the sample code from the documentation, I've included a piece of the sample code.
// create a RestClient to the specific URL
RestClient restClient = RestClient.create()
.method("GET")
.host("https://api.stackexchange.com")
.path("/2.2/errors");
// create a custom converter
InputStreamIterableInputConverter<Error> converter = new ItemsIterableInputConverter<>(Error.class);
// retrieve a list from the DataProvider using the custom converter
GluonObservableList<Error> errors = DataProvider.retrieveList(restClient.createListDataReader(converter));
//ItemsIterableInputConverter is not a valid command, Ive tried InterableInputConverter and JsonInputIterableConverter, non of which wo
//JSON Output Looks like this
{
"status": "ok",
"totalResults": 70,
-"articles": [
-{
-"source": {
"id": null,
"name": "Marketwatch.com"
},
"author": "Greg Robb",
"title": "Fed officials shied away ...",
"description": "Federal Reserve officials ...",
"url": "https://www.marketwatch.com/",
"urlToImage": "http://s.20190821101018.jpg",
"publishedAt": "2019-08-21T18:24:00Z",
"content": "President Trumps criticism of ...+2840 chars]"
},
My POJO:
Article.java
package app;
import lombok.Getter;
import lombok.Setter;
import org.apache.commons.lang3.builder.ToStringBuilder;
#Getter
#Setter
public class Article {
private Source source;
private String author;
private String title;
private String description;
private String url;
private String urlToImage;
private String publishedAt;
private String content;
/**
* No args constructor for use in serialization
*/
public Article() {
}
public Article(Source source, String author, String title, String description, String url, String urlToImage, String publishedAt, String content) {
super();
this.source = source;
this.author = author;
this.title = title;
this.description = description;
this.url = url;
this.urlToImage = urlToImage;
this.publishedAt = publishedAt;
this.content = content;
}
JavaFX - NewsController
#FXML
private ListView<Article> newsList;
// create a RestClient to the specific URL
RestClient restClient = RestClient.create()
.method("GET")
.host("https://newsapi.org")
.path("//v2/everything?q=GBP_USD&from=2019-08-21&to=2019-08-21&sortBy=popularity&apiKey=API_KEY");
InputStreamIterableInputConverter<Article> converter = new JsonIterableInputConverter<>(Article.class);
GluonObservableList<Article> articles = DataProvider.retrieveList(restClient.createListDataReader(converter));
articles.initializedProperty().addListener((obv,ov,nv)-> {
newsList.setItems(articles);
}
);
//Here I tried to use a TableView instead
// newsTbl.setItems(articles);
//
// newsDateCol.setCellValueFactory(new PropertyValueFactory<>("newsDateCol"));
// newsPublisherCol.setCellValueFactory(new PropertyValueFactory<>("newsPublisherCol"));
// newsHeadlineCol.setCellValueFactory(new PropertyValueFactory<>("newsHeadlineCol"));
// newsLinkCol.setCellValueFactory(new PropertyValueFactory<>("newsLinkCol"));
This is my output
Task :App.main()
Connection Successful
Exception in thread "DataProviderThread-0" java.lang.ExceptionInInitializerError
at com.gluonhq.connect.converter.JsonIterableInputConverter.iterator(JsonIterableInputConverter.java:136)
at com.gluonhq.connect.provider.RestListDataReader.iterator(RestListDataReader.java:80)
at com.gluonhq.connect.provider.DataProvider.lambda$retrieveList$23(DataProvider.java:206)
at java.base/java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1128)
at java.base/java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:628)
at java.base/java.lang.Thread.run(Thread.java:835)
Caused by: javax.json.JsonException: Provider org.glassfish.json.JsonProviderImpl not found
at javax.json.spi.JsonProvider.provider(JsonProvider.java:75)
at javax.json.Json.createReaderFactory(Json.java:215)
at com.gluonhq.impl.connect.converter.JsonUtil.<clinit>(JsonUtil.java:48)
... 6 more
Caused by: java.lang.ClassNotFoundException: org.glassfish.json.JsonProviderImpl
at java.base/jdk.internal.loader.BuiltinClassLoader.loadClass(BuiltinClassLoader.java:583)
at java.base/jdk.internal.loader.ClassLoaders$AppClassLoader.loadClass(ClassLoaders.java:178)
at java.base/java.lang.ClassLoader.loadClass(ClassLoader.java:521)
at java.base/java.lang.Class.forName0(Native Method)
at java.base/java.lang.Class.forName(Class.java:332)
at javax.json.spi.JsonProvider.provider(JsonProvider.java:72)
... 8 more
Task :App.main() FAILED
Update :
My build.gradle file.
plugins {
id 'java'
id 'application'
id 'org.openjfx.javafxplugin' version '0.0.8'
}
version '1.0-SNAPSHOT'
sourceCompatibility = 12
repositories {
mavenCentral()
}
javafx {
version = "12.0.2"
modules =["javafx.controls","javafx.fxml"]
}
dependencies {
testCompile group: 'junit', name: 'junit', version: '4.12'
compile group: 'com.jfoenix', name: 'jfoenix', version: '9.0.2'
compile group: 'mysql', name: 'mysql-connector-java', version: '8.0.17'
compile group: 'org.twitter4j', name: 'twitter4j-core', version: '4.0.7'
compileOnly 'org.projectlombok:lombok:1.18.8'
annotationProcessor 'org.projectlombok:lombok:1.18.8'
compile group: 'com.gluonhq', name: 'connect', version: '2.0.1'
compile group: 'org.apache.commons', name: 'commons-lang3', version: '3.0'
compile 'org.apache.httpcomponents:httpclient:4.5.9'
compile group: 'com.fasterxml', name: 'jackson-module-json-org', version: '0.9.1'
}
task Customrun(type: JavaExec, dependsOn: classes) {
mainClassName = 'app.App'
classpath = sourceSets.main.runtimeClasspath
}
I've taken Jose's advice and imported the 'org.glassfish', name: 'javax.json', version: '1.0.4', which cleared up the Error.
Table is still not populating, so i did a System.out.println on the ObservableList 'articles' and only receive empty brackets []. The default "no content in table" has disapeared which seems like it did work, only thing is i receive a empty list.
UPDATE :
Created a custom converter class ArticlesIterableInputConverter
// modified the Iterator Method
#Override
public Iterator<E> iterator() {
index = 0;
try (JsonReader reader = Json.createReader(getInputStream())) {
JsonObject jsonObject = reader.readObject();
jsonArray = jsonObject.getJsonArray("articles");
}
return this;
}
REST CLient Call and GluonObservable List Creation
// create a RestClient to the specific URL
RestClient restClient = RestClient.create()
.method("GET")
.host("https://newsapi.org")
.path("//v2/everything?q=GBP_USD&from=2019-08-21&to=2019-08-21&sortBy=popularity&apiKey=9a7a9daab76f440fb796350c83db0694");
InputStreamIterableInputConverter<Article> converter = new ArticlesIterableInputConverter<>(Article.class);
GluonObservableList<Article> articles = DataProvider.retrieveList(restClient.createListDataReader(converter));
articles.initializedProperty().addListener((obv,ov,nv)-> {
newsList.setItems(articles);
}
);
Screenshot of List Output
*** Need to figure out how to format the output into the fields I actually need.
Added a toString Method to the Article Class
#Override
public String toString() {
return new ToStringBuilder(this).append("publishedAt", publishedAt).append("name", source.name).append("title", title).append("url", url).toString();
}
New Output :
Output after adding toString Method

ClassCastException When Trying to Make JAXRS Call in Errai 4

I am using Errai 4.0.0.Beta1, and I am trying to make a simple JAX RS call.
Here is the code I am using:
final RemoteCallback<List<Company>> remoteCallback = new RemoteCallback<List<Company>>() {
#Override
public void callback(List<Company> companies) {
Window.alert("rpcServiceCaller - Callback");
Window.alert("Number of companies returned: " + companies.size());
}
};
final RestErrorCallback errorCallback = new RestErrorCallback() {
#Override
public boolean error(Request message, Throwable throwable) {
Window.alert(throwable.getMessage());
logger.error(throwable.getMessage(), throwable);
return false;
}
};
RestClient.create(ErraiJAXRSService.class,
remoteCallback,
errorCallback,
200).getCompaniesJSON();
I am seeing the following exception in Super Dev Mode:
Error caused by: ClassCastException: undefined
at f9b_g$ [as collect_0_g$] (StackTraceCreator.java:198)
at H8b_g$ (StackTraceCreator.java:343)
at Iz_g$ [as fillInStackTrace_0_g$] (Throwable.java:114)
at Bz_g$ (Throwable.java:53)
at Xz_g$ (Exception.java:25)
at cA_g$ (RuntimeException.java:25)
at Ymb_g$ (ClassCastException.java:23)
at Mzg_g$ (InternalPreconditions.java:45)
at Xzg_g$ (InternalPreconditions.java:33)
at n1d_g$ (Cast.java:75)
at rrh_g$ (RestClient.java:192)
at srh_g$ (RestClient.java:158)
at wrh_g$ (RestClient.java:113)
at ynf_g$ [as erraiJSON_0_g$] (JAXRSPage.java:94)
at gKh_g$ [as onClick_0_g$] (Type_factory__c_i_e_c_j_JAXRSPage__quals__j_e_i_Any_j_e_i_Default.java:76)
at Exd_g$ [as dispatch_4_g$] (ClickEvent.java:56)
at Fxd_g$ [as dispatch_1_g$] (ClickEvent.java:55)
at Awd_g$ [as dispatch_0_g$] (GwtEvent.java:76)
at ZGd_g$ (EventBus.java:40)
at iHd_g$ [as doFire_0_g$] (SimpleEventBus.java:193)
at oHd_g$ [as fireEvent_2_g$] (SimpleEventBus.java:88)
at RGd_g$ [as fireEvent_1_g$] (HandlerManager.java:127)
at Lve_g$ [as fireEvent_1_g$] (Widget.java:129)
at Lwd_g$ (DomEvent.java:125)
at Tve_g$ [as onBrowserEvent_0_g$] (Widget.java:177)
at gne_g$ (DOM.java:1480)
at fne_g$ (DOM.java:1419)
at HTMLButtonElement.xte_g$ (DOMImplStandard.java:317)
at k6b_g$ (Impl.java:233)
at n6b_g$ (Impl.java:285)
at HTMLButtonElement.<anonymous> (Impl.java:71)
The proxy is returned, but any line that attempts to cast it to an AbstractJaxrsProxy fails with the above exception.
The JaxrsProxyLoaderImpl.java has been created, and my JAX RS Service is there:
package org.jboss.errai.enterprise.client.jaxrs;
import com.google.gwt.http.client.RequestBuilder;
import com.insclix.erraiPOC.shared.domain.Company;
import com.insclix.erraiPOC.shared.service.jaxrs.ErraiJAXRSService;
import java.util.List;
import org.jboss.errai.common.client.api.ErrorCallback;
import org.jboss.errai.common.client.api.RemoteCallback;
import org.jboss.errai.common.client.framework.ProxyProvider;
import org.jboss.errai.common.client.framework.RemoteServiceProxyFactory;
import org.jboss.errai.security.client.local.interceptors.SecurityExceptionMapper;
public class JaxrsProxyLoaderImpl implements JaxrsProxyLoader { public void loadProxies() {
class com_insclix_erraiPOC_shared_service_jaxrs_ErraiJAXRSServiceImpl extends AbstractJaxrsProxy implements ErraiJAXRSService {
private RemoteCallback remoteCallback;
private ErrorCallback errorCallback;
public com_insclix_erraiPOC_shared_service_jaxrs_ErraiJAXRSServiceImpl() {
setExceptionMapper(new SecurityExceptionMapper());
}
public RemoteCallback getRemoteCallback() {
return remoteCallback;
}
public void setRemoteCallback(RemoteCallback callback) {
remoteCallback = callback;
}
public ErrorCallback getErrorCallback() {
return errorCallback;
}
public void setErrorCallback(ErrorCallback callback) {
errorCallback = callback;
}
public List getCompaniesJSON() {
StringBuilder url = new StringBuilder(getBaseUrl());
url.append("company/jaxrs");
RequestBuilder requestBuilder = new RequestBuilder(RequestBuilder.GET, url.toString());
requestBuilder.setHeader("Accept", "application/json");
sendRequest(requestBuilder, null, new ResponseDemarshallingCallback() {
public Object demarshallResponse(String response) {
return MarshallingWrapper.fromJSON(response, List.class, Company.class);
}
});
return null;
}
public List getCompaniesXML() {
StringBuilder url = new StringBuilder(getBaseUrl());
url.append("company/jaxrs");
RequestBuilder requestBuilder = new RequestBuilder(RequestBuilder.GET, url.toString());
requestBuilder.setHeader("Accept", "application/xml");
sendRequest(requestBuilder, null, new ResponseDemarshallingCallback() {
public Object demarshallResponse(String response) {
return MarshallingWrapper.fromJSON(response, List.class, Company.class);
}
});
return null;
}
public Long createCompanyJSON(final Company a0) {
StringBuilder url = new StringBuilder(getBaseUrl());
url.append("company/jaxrs");
RequestBuilder requestBuilder = new RequestBuilder(RequestBuilder.POST, url.toString());
requestBuilder.setHeader("Content-Type", "application/json");
sendRequest(requestBuilder, MarshallingWrapper.toJSON(a0), new ResponseDemarshallingCallback() {
public Object demarshallResponse(String response) {
return MarshallingWrapper.fromJSON(response, Long.class, null);
}
});
return 0L;
}
public Long createCompanyXML(final Company a0) {
StringBuilder url = new StringBuilder(getBaseUrl());
url.append("company/jaxrs");
RequestBuilder requestBuilder = new RequestBuilder(RequestBuilder.POST, url.toString());
requestBuilder.setHeader("Content-Type", "application/xml");
sendRequest(requestBuilder, MarshallingWrapper.toJSON(a0), new ResponseDemarshallingCallback() {
public Object demarshallResponse(String response) {
return MarshallingWrapper.fromJSON(response, Long.class, null);
}
});
return 0L;
}
}
RemoteServiceProxyFactory.addRemoteProxy(ErraiJAXRSService.class, new ProxyProvider() {
public Object getProxy() {
return new com_insclix_erraiPOC_shared_service_jaxrs_ErraiJAXRSServiceImpl();
}
});
}
}
This turned out to be an issue with the way JAX-RS / Errai class and interface were configured. According to the JAX-RS specification, the #Path annotation needs to be on the implementation, but Errai needs it on the interface.
So, the solution was to have the #Path annotation on BOTH the interface (for Errai), and the class that implements it (for JAX-RS).
Note that if the annotation is on the interface, Wildfly allows for this, Jersey ignores the interface, and Resteasy fails (if running through the ResteasyServletInitializer.

Servlet.service() for servlet [FitbitApiAuthExampleServlet] in context with path [/Webfit]

I'm having a problem.
I'm developing web application in Eclipse IDE and using Tomcat 7.
Everything was working fine, when suddenly my debugger doesn't work anymore as it should and everything collapsed to pieces. I was looking for same errors, but I haven't found soulution yet. Please help me.
I'm getting this error:
SEVERE: Servlet.service() for servlet [FitbitApiAuthExampleServlet] in context with path [/Webfit] threw exception
java.lang.NullPointerException
at java.net.URLEncoder.encode(Unknown Source)
at com.fitbit.api.client.http.OAuth.encode(OAuth.java:254)
at com.fitbit.api.client.http.OAuth.encodeParameters(OAuth.java:233)
at com.fitbit.api.client.http.OAuth.encodeParameters(OAuth.java:217)
at com.fitbit.api.client.http.OAuth.normalizeRequestParameters(OAuth.java:196)
at com.fitbit.api.client.http.OAuth.generateAuthorizationHeader(OAuth.java:85)
at com.fitbit.api.client.http.OAuth.generateAuthorizationHeader(OAuth.java:129)
at com.fitbit.api.client.http.HttpClient.setHeaders(HttpClient.java:522)
at com.fitbit.api.client.http.HttpClient.httpRequest(HttpClient.java:422)
at com.fitbit.api.client.http.HttpClient.get(HttpClient.java:398)
at com.fitbit.api.client.FitbitApiClientAgent.httpGet(FitbitApiClientAgent.java:2563)
at com.fitbit.api.client.FitbitApiClientAgent.httpGet(FitbitApiClientAgent.java:2513)
at com.fitbit.api.client.FitbitApiClientAgent.getLoggedHeartRate(FitbitApiClientAgent.java:1779)
at com.fitbit.web.FitbitApiAuthExampleServlet.doGet(FitbitApiAuthExampleServlet.java:108)
at javax.servlet.http.HttpServlet.service(HttpServlet.java:621)
at javax.servlet.http.HttpServlet.service(HttpServlet.java:722)
at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:305)
at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:210)
at org.apache.catalina.core.StandardWrapperValve.invoke(StandardWrapperValve.java:225)
at org.apache.catalina.core.StandardContextValve.invoke(StandardContextValve.java:169)
at org.apache.catalina.authenticator.AuthenticatorBase.invoke(AuthenticatorBase.java:472)
at org.apache.catalina.core.StandardHostValve.invoke(StandardHostValve.java:168)
at org.apache.catalina.valves.ErrorReportValve.invoke(ErrorReportValve.java:98)
at org.apache.catalina.valves.AccessLogValve.invoke(AccessLogValve.java:927)
at org.apache.catalina.core.StandardEngineValve.invoke(StandardEngineValve.java:118)
at org.apache.catalina.connector.CoyoteAdapter.service(CoyoteAdapter.java:407)
at org.apache.coyote.http11.AbstractHttp11Processor.process(AbstractHttp11Processor.java:999)
at org.apache.coyote.AbstractProtocol$AbstractConnectionHandler.process(AbstractProtocol.java:565)
at org.apache.tomcat.util.net.JIoEndpoint$SocketProcessor.run(JIoEndpoint.java:309)
at java.util.concurrent.ThreadPoolExecutor.runWorker(Unknown Source)
at java.util.concurrent.ThreadPoolExecutor$Worker.run(Unknown Source)
at java.lang.Thread.run(Unknown Source)
Servlet code:
package com.fitbit.web;
import com.fitbit.api.FitbitAPIException;
import com.fitbit.api.client.*;
import com.fitbit.api.client.service.FitbitAPIClientService;
import com.fitbit.api.common.model.body.Body;
import com.fitbit.api.common.model.body.BodyWithGoals;
import com.fitbit.api.common.model.bp.Bp;
import com.fitbit.api.common.model.heart.Heart;
import com.fitbit.api.common.model.user.UserInfo;
import com.fitbit.api.model.APIResourceCredentials;
import com.fitbit.api.model.FitbitUser;
import javax.servlet.ServletConfig;
import javax.servlet.ServletException;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import org.joda.time.LocalDate;
import java.io.IOException;
import java.util.Properties;
/**
* Created by IntelliJ IDEA.
* User: Kiryl
* Date: 6/22/11
* Time: 7:05 AM
*/
public class FitbitApiAuthExampleServlet extends HttpServlet {
public static final String OAUTH_TOKEN = "oauth_token";
public static final String OAUTH_VERIFIER = "oauth_verifier";
private FitbitAPIEntityCache entityCache = new FitbitApiEntityCacheMapImpl();
private FitbitApiCredentialsCache credentialsCache = new FitbitApiCredentialsCacheMapImpl();
private FitbitApiSubscriptionStorage subscriptionStore = new FitbitApiSubscriptionStorageInMemoryImpl();
private String apiBaseUrl;
private String fitbitSiteBaseUrl;
private String exampleBaseUrl;
private String clientConsumerKey;
private String clientSecret;
private FitbitUser fitbitUser = new FitbitUser("-");
private int year = 2012;
private int month = 5;
private int day = 5;
public void init(ServletConfig config) throws ServletException {
super.init(config);
try {
Properties properties = new Properties();
properties.load(getClass().getClassLoader().getResourceAsStream("config.properties"));
apiBaseUrl = properties.getProperty("apiBaseUrl");
fitbitSiteBaseUrl = properties.getProperty("fitbitSiteBaseUrl");
exampleBaseUrl = properties.getProperty("exampleBaseUrl").replace("/app", "");
clientConsumerKey = properties.getProperty("clientConsumerKey");
clientSecret = properties.getProperty("clientSecret");
} catch (IOException e) {
throw new ServletException("Exception during loading properties", e);
}
}
protected void doGet(HttpServletRequest request, HttpServletResponse response) throws IOException, ServletException {
FitbitAPIClientService<FitbitApiClientAgent> apiClientService = new FitbitAPIClientService<FitbitApiClientAgent>(
new FitbitApiClientAgent(apiBaseUrl, fitbitSiteBaseUrl, credentialsCache),
clientConsumerKey,
clientSecret,
credentialsCache,
entityCache,
subscriptionStore
);
if (request.getParameter("completeAuthorization") != null) {
// Get temporary token and verifier returned by Fitbit from query string
String tempTokenReceived = request.getParameter(OAUTH_TOKEN);
String tempTokenVerifier = request.getParameter(OAUTH_VERIFIER);
// Fetch user credentials from cache by temporary token from query string
APIResourceCredentials resourceCredentials = apiClientService.getResourceCredentialsByTempToken(tempTokenReceived);
/*Handle error when there is no record of credentials in cache for the temporary token provided
As implementation of the credentials cache in this example is not persistant,
this error will popup if you restart application, while user's browser will be on Fitbit*/
if (resourceCredentials == null) {
throw new ServletException("Unrecognized temporary token when attempting to complete authorization: " + tempTokenReceived);
}
// Call method of Fitbit4J to get token credentials only if necessary (they haven't been cached yet)
if (!resourceCredentials.isAuthorized()) {
resourceCredentials.setTempTokenVerifier(tempTokenVerifier); // The verifier token is required in the request to get token credentials
try {
apiClientService.getTokenCredentials(new LocalUserDetail(resourceCredentials.getLocalUserId())); // get token credentials for user
} catch (FitbitAPIException e) {
throw new ServletException("Unable to finish authorization with Fitbit.", e);
}
}
try {
// get UserInfo
UserInfo userInfo = apiClientService.getClient().getUserInfo(new LocalUserDetail(resourceCredentials.getLocalUserId()));
request.setAttribute("userInfo", userInfo);
//get HeartRate
Heart heartInfo = apiClientService.getClient().getLoggedHeartRate(new LocalUserDetail(resourceCredentials.getLocalUserId()), fitbitUser, new LocalDate(year,month,day));
//HeartRate heartAverage = new HeartRate(heartInfo.getTrackerAverage());
request.setAttribute("heartRate", heartInfo);
/*double weight = apiClientService.getClient().getWeight(new LocalUserDetail(resourceCredentials.getLocalUserId()), new FitbitUser("-"), new LocalDate(2012,5,5));
request.setAttribute("weight", weight);*/
// get BodyInfo (weight, fat, bmi)
Body bodyInfo = apiClientService.getClient().getBody(new LocalUserDetail(resourceCredentials.getLocalUserId()), fitbitUser, new LocalDate(year,month,day));
//BodyWithGoals bodyGoals = apiClientService.getClient().getBodyWithGoals(new LocalUserDetail(resourceCredentials.getLocalUserId()), new FitbitUser("-"), new LocalDate(year,month,day));
request.setAttribute("bodyInfo", bodyInfo);
// get BloodPressure (BP) Info
Bp bloodPressureInfo = apiClientService.getClient().getLoggedBp(new LocalUserDetail(resourceCredentials.getLocalUserId()), fitbitUser, new LocalDate(year,month,day));
request.setAttribute("bloodPressureInfo", bloodPressureInfo);
// forward result to .jsp page
request.getRequestDispatcher("/fitbitApiAuthExample.jsp").forward(request, response);
} catch (FitbitAPIException e) {
throw new ServletException("Exception during getting user info", e);
}
} else {
try {
response.sendRedirect(apiClientService.getResourceOwnerAuthorizationURL(new LocalUserDetail("-"), exampleBaseUrl + "/fitbitApiAuthExample?completeAuthorization="));
} catch (FitbitAPIException e) {
throw new ServletException("Exception during performing authorization", e);
}
}
}
}