Issue
- We developed a custom service using service builder. The service method receives a string as parameter.
- We access it through JSON API.
- When the string length is short (some hundred of kilobytes), the service works correctly.
- But when the string length is longer (some megabytes -p.e. 4 or 5-) we get following error in log:
[JSONWebServiceServiceAction:114] Unable to deserialize object
Environment
Liferay DXP 7.2-
Tomcat 9.0.33application server.
Resolution
The analysis:
- Firstly, following configuration would be added to get additional information about the error.
- Set next property in
portal-ext.propertiesfile to true:
- Set next property in
json.service.serialize.throwable=true
- Restart the server, and add next log category with DEBUG value:
com.liferay.portal.jsonwebservice.JSONWebServiceServiceAction
- Now,
Liferay DXP'slog should show following trace:
2022-11-21 13:57:41.055 DEBUG [http-nio-8080-exec-2][JSONWebServiceServiceAction:111] Unable to deserialize object
java.lang.IllegalStateException: Unable to deserialize object
at com.liferay.portal.json.JSONFactoryImpl.looseDeserialize(JSONFactoryImpl.java:229)
at com.liferay.portal.kernel.json.JSONFactoryUtil.looseDeserialize(JSONFactoryUtil.java:103)
at com.liferay.portal.jsonwebservice.action.JSONWebServiceInvokerAction.invoke(JSONWebServiceInvokerAction.java:84)
at com.liferay.portal.jsonwebservice.JSONWebServiceServiceAction.getJSON(JSONWebServiceServiceAction.java:68)
at com.liferay.portal.struts.JSONAction.execute(JSONAction.java:74)
at com.liferay.portal.servlet.JSONServlet.service(JSONServlet.java:63)
at com.liferay.portal.jsonwebservice.JSONWebServiceServlet.service(JSONWebServiceServlet.java:63)
at javax.servlet.http.HttpServlet.service(HttpServlet.java:741)
....Caused by: jodd.json.JsonException: Syntax error! Invalid char: c_offset: 0 near: "cmd=%7B%22..." [Sanitized]
at jodd.json.JsonParser.syntaxError(JsonParser.java:1012)
at jodd.json.JsonParser.parseValue(JsonParser.java:421)
at jodd.json.JsonParser._parse(JsonParser.java:271)
at jodd.json.JsonParser.parse(JsonParser.java:240)
at com.liferay.portal.json.JSONDeserializerImpl.deserialize(JSONDeserializerImpl.java:41)
at com.liferay.portal.json.JSONFactoryImpl.looseDeserialize(JSONFactoryImpl.java:222)
... 75 more
- The root cause is focused in how the application server manages the POST request. Tomcat has a maximum value for POST size requests. By default, this limit is 2 megabytes.
- If this limit is over, the parameters' values will not be returned by Tomcat.
-
Liferay DXPchecks the returned parameters, and if they are null it gets the JSON object contained into the request:
public JSONWebServiceInvokerAction(HttpServletRequest httpServletRequest) {
_httpServletRequest = httpServletRequest;
String command = httpServletRequest.getParameter(Constants.CMD);
if (command == null) {
try {
command = ServletUtil.readRequestBody(httpServletRequest);
}
catch (IOException ioException) {
throw new IllegalArgumentException(ioException);
}
}
_command = command;
}
- Parameter CMD starts with the
'cmd='string, so it is not a valid JSON object and therefore it causes the parsing error:
Caused by: jodd.json.JsonException: Syntax error! Invalid char: c_offset: 0 near: "cmd=%7B%22..."The solution
- So, the solution is to configure Tomcat application server with a higher value for POST size requests in HTTP Connector. Basically, the configuration is done in
server.xmlfile, definingmaxPostSizeattribute in<Connector>element.In any case, please, refer to Tomcat's documentation about how to apply this configuration.
Additional Information
- Tomcat's maximum POST size parameter limit:
-
Liferay DXPgets full request if parameter is null:
- Tomcat application server configuration: POST size request