NullPointerException in AbstractRestClientHelper derived class [message #1840755] |
Fri, 23 April 2021 12:26 |
J D Messages: 102 Registered: February 2021 |
Senior Member |
|
|
Hi there everyone,
I am having a new problem.
I have an endpoint in my REST server that clients call to test if a handshake can be established between the clients and the server. When successful, the server sends the following JSON document to the client that called it:
{
"result": [
{
"remoteip": "",
"useragent": "insomnia/2021.2.2",
"header": "",
"servergreeting": "Bienvenue! Le serveur est en marche!. Vous pouvez envoyez vos rêquetes."
}
],
"id": 1
}
The user agent depends on what type of client called the server.
To call the server from an Eclipse Scout REST client, I created the following 4 classes:
a) YGHelloRestClientHelper.java
@Bean
public class YGHelloRestClientHelper extends AbstractRestClientHelper {
@Override
protected String getBaseUri() {
return "http://localhost:28200/ygserver/v2/root";
}
@Override
protected RuntimeException transformException(RuntimeException e, Response response) {
if (response != null && response.hasEntity()) {
ErrorDo error = response.readEntity(ErrorResponse.class).getError();
throw new VetoException(error.getMessage()).withTitle(error.getTitle());
}
return e;
}
}
b) YGHelloResourceClient.java
public class YGHelloResourceClient implements IRestResourceClient {
protected static final String RESOURCE_PATH = "/sayhello";
protected YGHelloRestClientHelper helper() {
return BEANS.get(YGHelloRestClientHelper.class);
}
/**
* Fetches the server greeting message
*/
public YGHelloDoMapEntity getServerGreeting() {
WebTarget target = helper().target(RESOURCE_PATH).queryParam("schema", "my_company");
return target.request().accept(MediaType.APPLICATION_JSON).get(YGHelloDoMapEntity.class);
}
}
c) YGHelloDoEntity.java
@TypeName("YGHelloDoEntity")
public class YGHelloDoEntity extends DoEntity {
@AttributeName("remoteip")
public DoValue<String> remoteIp() {
return doValue("remoteip");
}
@AttributeName("useragent")
public DoValue<String> userAgent() {
return doValue("useragent");
}
@AttributeName("header")
public DoValue<String> header() {
return doValue("header");
}
@AttributeName("servergreeting")
public DoValue<String> servergreeting() {
return doValue("servergreeting");
}
}
And finally
d) YGHelloDoMapEntity.java
// Builds a map of data objects (YGHelloDoMapEntity in this case)
@TypeName("YGHelloDoMapEntity")
public class YGHelloDoMapEntity extends DoMapEntity<YGHelloDoEntity> {
}
When I try to GET the server greeting using the following code:
@Order(10000)
public class GetMessageButton extends AbstractButton {
@Override
protected void execClickAction() {
YGHelloDoMapEntity greeting = BEANS.get(YGHelloResourceClient.class).getServerGreeting();
System.out.println(greeting);
}
}
it throws the following exception:
2021-04-23 13:41:11,005 ERROR [scout-model-thread-23 Processing JSON request] org.eclipse.scout.rt.platform.exception.ExceptionHandler.handleThrowable(ExceptionHandler.java:135) - NullPointerException:n/a - MDC[principal=jd, uiSession=1:do2658ks25e9niqa60336mv22p74af4br13ac8gluemjojthnja, scoutSession=1mkq0brl45dbs3mb2hlq5kbs2qaunb3lebenpcf1g4ml62frshqh, jobName=Processing JSON request, cid=NA8CV9ZA9tR/9]
java.lang.NullPointerException: null
at org.eclipse.scout.apps.ygclient.client.rest.common.YGHelloRestClientHelper.transformException(YGHelloRestClientHelper.java:23)
at org.eclipse.scout.rt.rest.client.proxy.RestClientProxyFactory$RestProxyInvcationHandler.transformException(RestClientProxyFactory.java:256)
at org.eclipse.scout.rt.rest.client.proxy.RestClientProxyFactory$RestProxyInvcationHandler.invoke(RestClientProxyFactory.java:206)
at com.sun.proxy.$Proxy66.get(Unknown Source)
at org.eclipse.scout.apps.ygclient.client.rest.common.YGHelloResourceClient.getServerGreeting(YGHelloResourceClient.java:22)
at org.eclipse.scout.apps.ygclient.client.integrationproject.employee.EmployeeForm$MainBox$ProjectExitDataBox$ProjectExitSaveButton.execClickAction(EmployeeForm.java:3184)
at org.eclipse.scout.rt.client.ui.form.fields.button.AbstractButton$LocalButtonExtension.execClickAction(AbstractButton.java:583)
at org.eclipse.scout.rt.client.extension.ui.form.fields.button.ButtonChains$ButtonClickActionChain$1.callMethod(ButtonChains.java:59)
at org.eclipse.scout.rt.client.extension.ui.form.fields.button.ButtonChains$ButtonClickActionChain$1.callMethod(ButtonChains.java:1)
at org.eclipse.scout.rt.shared.extension.AbstractExtensionChain.callChain(AbstractExtensionChain.java:113)
at org.eclipse.scout.rt.client.extension.ui.form.fields.button.ButtonChains$ButtonClickActionChain.execClickAction(ButtonChains.java:62)
at org.eclipse.scout.rt.client.ui.form.fields.button.AbstractButton.interceptClickAction(AbstractButton.java:567)
at org.eclipse.scout.rt.client.ui.form.fields.button.AbstractButton.doClick(AbstractButton.java:409)
at org.eclipse.scout.rt.client.ui.form.fields.button.AbstractButton$P_UIFacade.fireButtonClickFromUI(AbstractButton.java:537)
at java.base/jdk.internal.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
at java.base/jdk.internal.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:62)
at java.base/jdk.internal.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)
at java.base/java.lang.reflect.Method.invoke(Method.java:566)
at org.eclipse.scout.rt.client.ModelContextProxy.lambda$1(ModelContextProxy.java:49)
at org.eclipse.scout.rt.platform.chain.callable.CallableChain$Chain.continueChain(CallableChain.java:227)
at org.eclipse.scout.rt.platform.transaction.TransactionProcessor.runTxMandatory(TransactionProcessor.java:156)
at org.eclipse.scout.rt.platform.transaction.TransactionProcessor.runTxRequired(TransactionProcessor.java:139)
at org.eclipse.scout.rt.platform.transaction.TransactionProcessor.intercept(TransactionProcessor.java:78)
at org.eclipse.scout.rt.platform.chain.callable.CallableChain$Chain.continueChain(CallableChain.java:222)
at org.eclipse.scout.rt.platform.chain.callable.CallableChain.call(CallableChain.java:170)
at org.eclipse.scout.rt.platform.context.RunContext.call(RunContext.java:158)
at org.eclipse.scout.rt.client.ModelContextProxy.lambda$0(ModelContextProxy.java:49)
at com.sun.proxy.$Proxy43.fireButtonClickFromUI(Unknown Source)
at org.eclipse.scout.rt.ui.html.json.form.fields.button.JsonButton.handleUiEvent(JsonButton.java:170)
at org.eclipse.scout.rt.ui.html.json.JsonEventProcessor.processEvent(JsonEventProcessor.java:52)
at org.eclipse.scout.rt.ui.html.json.JsonEventProcessor.processEvents(JsonEventProcessor.java:37)
at org.eclipse.scout.rt.ui.html.UiSession.processJsonRequestInternal(UiSession.java:817)
at org.eclipse.scout.rt.platform.util.concurrent.Callables.lambda$0(Callables.java:31)
at org.eclipse.scout.rt.platform.chain.callable.CallableChain$Chain.continueChain(CallableChain.java:227)
at org.eclipse.scout.rt.platform.job.internal.ExceptionProcessor.intercept(ExceptionProcessor.java:41)
at org.eclipse.scout.rt.platform.chain.callable.CallableChain$Chain.continueChain(CallableChain.java:222)
at org.eclipse.scout.rt.platform.chain.callable.CallableChain$Chain.continueChain(CallableChain.java:227)
at org.eclipse.scout.rt.platform.transaction.TransactionProcessor.runTxMandatory(TransactionProcessor.java:156)
at org.eclipse.scout.rt.platform.transaction.TransactionProcessor.runTxRequired(TransactionProcessor.java:139)
at org.eclipse.scout.rt.platform.transaction.TransactionProcessor.intercept(TransactionProcessor.java:78)
at org.eclipse.scout.rt.platform.chain.callable.CallableChain$Chain.continueChain(CallableChain.java:222)
at org.eclipse.scout.rt.platform.chain.callable.CallableChain.call(CallableChain.java:170)
at org.eclipse.scout.rt.platform.context.RunContext.call(RunContext.java:158)
at org.eclipse.scout.rt.platform.context.RunContextRunner.intercept(RunContextRunner.java:38)
at org.eclipse.scout.rt.platform.chain.callable.CallableChain$Chain.continueChain(CallableChain.java:222)
at org.eclipse.scout.rt.platform.job.internal.CallableChainExceptionHandler.intercept(CallableChainExceptionHandler.java:33)
at org.eclipse.scout.rt.platform.chain.callable.CallableChain$Chain.continueChain(CallableChain.java:222)
at org.eclipse.scout.rt.platform.chain.callable.CallableChain.call(CallableChain.java:170)
at org.eclipse.scout.rt.platform.job.internal.JobFutureTask.lambda$0(JobFutureTask.java:106)
at java.base/java.util.concurrent.FutureTask.run(FutureTask.java:264)
at org.eclipse.scout.rt.platform.job.internal.JobFutureTask.run(JobFutureTask.java:175)
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:834)
at org.eclipse.scout.rt.platform.job.internal.NamedThreadFactory$1.run(NamedThreadFactory.java:63)
There is a NullPointerException for YGHelloRestClientHelper.
What is it that I'm doing wrong?
Thanks a million.
Cheers,
JD
[Updated on: Fri, 23 April 2021 12:32] Report message to a moderator
|
|
|
|
|
Re: NullPointerException in AbstractRestClientHelper derived class [message #1840797 is a reply to message #1840793] |
Fri, 23 April 2021 22:26 |
J D Messages: 102 Registered: February 2021 |
Senior Member |
|
|
Hi there Paolo & Andre,
Thanks for your suggestions. They were very helpful.
I finally found out the souce of the problem. It was the forward slash in RESOURCE_PATH = "/sayhello" Removing it cleared the NullPointerException.
I then cleaned up the code and tried again.
I got another exception: a java.lang.IllegalStateException: Entity input stream has already been closed.
Please be patient with me. I snooped around for a while and I discovered that the issue was the JSON object returned by the REST server (It is not a Scout server, it was developed in another programming language). The structure of the JSON object in general is:
{
"result": [{ }],
"id": a number
}
I use the EntityDo below for the server response:
@TypeName("YGBaseEntityDo")
public class YGBaseEntityDo extends DoEntity {
@AttributeName("result")
public DoList<String> result() {
return doList("result");
}
@AttributeName("id")
public DoValue<String> id() {
return doValue("id");
}
}
I added the methods below in my YGBaseRestResourceClient and tested again:
public YGBaseEntityDo getServerGreeting() {
WebTarget target = helper().target(RESOURCE_PATH).queryParam("schema", "mycompany");
return target.request().accept(MediaType.APPLICATION_JSON).get(YGBaseEntityDo.class);
}
public String getGreeting() {
WebTarget target = helper().target(RESOURCE_PATH).queryParam("schema", "mycompany");
return target.request().accept(MediaType.APPLICATION_JSON).get(String.class);
}
The getServerGreeting method above is the one that threw up the exception java.lang.IllegalStateException: Entity input stream has already been closed
The getGreeting method that just returns a plain Java String class worked!!!!
My Scout REST client received the following message from the server:
{
"result": [
{
"remoteip": "",
"useragent": "Jersey/2.31 (HttpUrlConnection 11.0.10)",
"header": "",
"servergreeting": "Bienvenue! Le serveur est en marche!. Vous pouvez envoyez vos rêquetes."
}
],
"id": 11
}
I do not understand why my EntityDo failed. Any ideas?
Thanks a lot.
Cheers,
JD
|
|
|
|
Re: NullPointerException in AbstractRestClientHelper derived class [message #1840822 is a reply to message #1840798] |
Mon, 26 April 2021 07:43 |
Paolo Bazzi Messages: 33 Registered: January 2017 Location: Switzerland |
Member |
|
|
Using "object" as Data Object Attribute definition is possible, but you afterwards need to check which type was deserialized. If the structure of the response is quite stable, I would recomment to use concrete data objects to model the structure:
For this kind of response:
{
"result": [
{
"remoteip": "",
"useragent": "Jersey/2.31 (HttpUrlConnection 11.0.10)",
"header": "",
"servergreeting": "Bienvenue! Le serveur est en marche!. Vous pouvez envoyez vos rêquetes."
}
],
"id": 11
}
I would use a structure like this:
@TypeName("YGBaseEntityDo")
public class YGBaseEntityDo extends DoEntity {
public DoList<YGResultEntityDo > result() {
return doList("result");
}
public DoValue<Integer> id() {
return doValue("id");
}
}
and
@TypeName("YGResultEntityDo")
public class YGResultEntityDo extends DoEntity {
public DoValue<String> remoteip() {
return doValue("remoteip");
}
public DoValue<String> useragent() {
return doValue("useragent");
}
public DoValue<String> header() {
return doValue("header");
}
public DoValue<String> servergreeting() {
return doValue("servergreeting");
}
}
Regards,
Paolo
Eclipse Scout Homepage | Documentation | GitHub
|
|
|
Powered by
FUDForum. Page generated in 0.05294 seconds