serverless-java-container
serverless-java-container copied to clipboard
Struts2 sample doesn't work
To help us debug your issue fill in the basic information below using the options provided
Serverless Java Container version: 1.10
Implementations: Struts2
Framework version: Struts 6.0.3
Frontend service: None (plain Lambda exercises the issue)
Deployment method: SAM
Scenario
Build and run the struts sample
Expected behavior
sam local invoke works, the function works deployed to Lambda
Actual behavior
Error finding the required classes in the built ZIP file
Steps to reproduce
cd samples/struts/pet-storesam build- Populate
test-event.jsonwith content from below - Note: I had to correct the
Handlerproperty of the function in theSAMtemplate to even get this far. The correct handler string iscom.amazonaws.serverless.proxy.struts2.Struts2LambdaHandler::handleRequest sam local invoke -e test-event.json
Full log output
Baseline (no changes to struts.xml)
Caused by: Unable to load bean: type:org.apache.struts2.rest.handler.ContentTypeHandler class:org.apache.struts2.rest.handler.JacksonLibHandler - bean - file:/var/task/struts.xml:26:70
at com.opensymphony.xwork2.config.providers.XmlConfigurationProvider.register(XmlConfigurationProvider.java:274)
at org.apache.struts2.config.StrutsXmlConfigurationProvider.register(StrutsXmlConfigurationProvider.java:98)
at com.opensymphony.xwork2.config.impl.DefaultConfiguration.reloadContainer(DefaultConfiguration.java:167)
at com.opensymphony.xwork2.config.ConfigurationManager.getConfiguration(ConfigurationManager.java:66)
... 22 more
Caused by: java.lang.ClassNotFoundException: org.apache.struts2.rest.handler.JacksonLibHandler. Current classpath: file:/var/task/:file:/var/task/lib/asm-9.2.jar:file:/var/task/lib/asm-analysis-9.2.jar:file:/var/task/lib/asm-commons-9.2.jar:file:/var/task/lib/asm-tree-9.2.jar:file:/var/task/lib/aws-lambda-java-core-1.2.1.jar:file:/var/task/lib/aws-lambda-java-log4j2-1.5.1.jar:file:/var/task/lib/aws-serverless-java-container-core-1.8.2.jar:file:/var/task/lib/aws-serverless-java-container-struts2-1.8.2.jar:file:/var/task/lib/classmate-1.3.4.jar:file:/var/task/lib/commons-codec-1.11.jar:file:/var/task/lib/commons-fileupload-1.4.jar:file:/var/task/lib/commons-io-2.2.jar:file:/var/task/lib/commons-lang3-3.10.jar:file:/var/task/lib/commons-logging-1.2.jar:file:/var/task/lib/freemarker-2.3.31.jar:file:/var/task/lib/hibernate-validator-6.1.7.Final.jar:file:/var/task/lib/httpclient-4.5.13.jar:file:/var/task/lib/httpcore-4.4.13.jar:file:/var/task/lib/httpmime-4.5.13.jar:file:/var/task/lib/jackson-annotations-2.13.4.jar:file:/var/task/lib/jackson-core-2.13.4.jar:file:/var/task/lib/jackson-databind-2.13.4.jar:file:/var/task/lib/jackson-module-afterburner-2.13.3.jar:file:/var/task/lib/jakarta.activation-1.2.2.jar:file:/var/task/lib/jakarta.validation-api-2.0.2.jar:file:/var/task/lib/javassist-3.20.0-GA.jar:file:/var/task/lib/javax.servlet-api-3.1.0.jar:file:/var/task/lib/javax.ws.rs-api-2.1.jar:file:/var/task/lib/jboss-logging-3.3.2.Final.jar:file:/var/task/lib/jsp-api-2.0.jar:file:/var/task/lib/log4j-api-2.19.0.jar:file:/var/task/lib/log4j-core-2.19.0.jar:file:/var/task/lib/log4j-slf4j-impl-2.19.0.jar:file:/var/task/lib/objenesis-3.2.jar:file:/var/task/lib/ognl-3.1.29.jar:file:/var/task/lib/servlet-api-2.4.jar:file:/var/task/lib/slf4j-api-1.7.36.jar:file:/var/task/lib/struts2-aws-lambda-support-plugin-1.4.0.jar:file:/var/task/lib/struts2-bean-validation-plugin-6.0.3.jar:file:/var/task/lib/struts2-convention-plugin-6.0.3.jar:file:/var/task/lib/struts2-core-2.5.30.jar:file:/var/task/lib/struts2-rest-plugin-6.0.3.jar:file:/var/task/lib/validation-api-2.0.1.Final.jar:file:/var/task/lib/xstream-1.4.19.jar
at lambdainternal.CustomerClassLoader.findClass(CustomerClassLoader.java:63)
at java.base/java.lang.ClassLoader.loadClass(Unknown Source)
at java.base/java.lang.ClassLoader.loadClass(Unknown Source)
at com.opensymphony.xwork2.util.ClassLoaderUtil.loadClass(ClassLoaderUtil.java:179)
at com.opensymphony.xwork2.config.providers.XmlConfigurationProvider.register(XmlConfigurationProvider.java:247)
... 25 more
END RequestId: 693f3245-d782-4d96-82bd-30557b5438cc
REPORT RequestId: 693f3245-d782-4d96-82bd-30557b5438cc Init Duration: 0.14 ms Duration: 1695.86 ms Billed Duration: 1696 ms Memory Size: 512 MB Max Memory Used: 512 MB
{"statusCode":502,"multiValueHeaders":{"Content-Type":["application/json"]},"body":"{\"message\":\"Gateway timeout\"}","isBase64Encoded":false}% (samcli38) greenwd@dev-dsk-greenwd-2c-523a372f] ~/workspace/blink-profiling/src/LambdaSnapStartProfilingTools/snapstart-profiling-sam
Analysis
- looked through the ZIP and I think
JacksonLibHandleris expected to be in the JARlib/struts2-rest-plugin-6.0.3.jar - unpacking that JAR, I don't see that class (see below)
- I do see
JacksonJsonHandlerandJacksonXmlHandler
less lib/struts2-rest-plugin-6.0.3.jar
Archive: lib/struts2-rest-plugin-6.0.3.jar
Zip file size: 51779 bytes, number of entries: 46
-rw-r--r-- 2.0 unx 2679 b- defN 22-Sep-02 12:37 META-INF/MANIFEST.MF
drwxr-xr-x 2.0 unx 0 b- stor 22-Sep-02 12:37 META-INF/
drwxr-xr-x 2.0 unx 0 b- stor 22-Sep-02 12:37 org/
drwxr-xr-x 2.0 unx 0 b- stor 22-Sep-02 12:37 org/apache/
drwxr-xr-x 2.0 unx 0 b- stor 22-Sep-02 12:37 org/apache/struts2/
drwxr-xr-x 2.0 unx 0 b- stor 22-Sep-02 12:37 org/apache/struts2/rest/
drwxr-xr-x 2.0 unx 0 b- stor 22-Sep-02 12:37 org/apache/struts2/rest/config/
drwxr-xr-x 2.0 unx 0 b- stor 22-Sep-02 12:37 org/apache/struts2/rest/config/entities/
drwxr-xr-x 2.0 unx 0 b- stor 22-Sep-02 12:37 org/apache/struts2/rest/handler/
drwxr-xr-x 2.0 unx 0 b- stor 22-Sep-02 12:37 META-INF/maven/
drwxr-xr-x 2.0 unx 0 b- stor 22-Sep-02 12:37 META-INF/maven/org.apache.struts/
drwxr-xr-x 2.0 unx 0 b- stor 22-Sep-02 12:37 META-INF/maven/org.apache.struts/struts2-rest-plugin/
-rw-r--r-- 2.0 unx 6157 b- defN 22-Sep-02 12:37 META-INF/DEPENDENCIES
-rw-r--r-- 2.0 unx 11358 b- defN 22-Sep-02 12:37 META-INF/LICENSE
-rw-r--r-- 2.0 unx 173 b- defN 22-Sep-02 12:37 META-INF/NOTICE
-rw-r--r-- 2.0 unx 375 b- defN 22-Sep-02 12:37 NOTICE.txt
-rw-r--r-- 2.0 unx 2191 b- defN 22-Sep-02 12:37 XPP3-LICENSE.txt
-rw-r--r-- 2.0 unx 1506 b- defN 22-Sep-02 12:37 XSTREAM-LICENSE.txt
-rw-r--r-- 2.0 unx 1027 b- defN 22-Sep-02 12:37 org/apache/struts2/rest/ContentTypeHandlerManager.class
-rw-r--r-- 2.0 unx 2274 b- defN 22-Sep-02 12:37 org/apache/struts2/rest/ContentTypeInterceptor.class
-rw-r--r-- 2.0 unx 8012 b- defN 22-Sep-02 12:37 org/apache/struts2/rest/DefaultContentTypeHandlerManager.class
-rw-r--r-- 2.0 unx 4563 b- defN 22-Sep-02 12:37 org/apache/struts2/rest/DefaultHttpHeaders.class
-rw-r--r-- 2.0 unx 363 b- defN 22-Sep-02 12:37 org/apache/struts2/rest/HttpHeaders.class
-rw-r--r-- 2.0 unx 11592 b- defN 22-Sep-02 12:37 org/apache/struts2/rest/RestActionInvocation.class
-rw-r--r-- 2.0 unx 9418 b- defN 22-Sep-02 12:37 org/apache/struts2/rest/RestActionMapper.class
-rw-r--r-- 2.0 unx 1932 b- defN 22-Sep-02 12:37 org/apache/struts2/rest/RestActionProxyFactory.class
-rw-r--r-- 2.0 unx 3053 b- defN 22-Sep-02 12:37 org/apache/struts2/rest/RestActionSupport.class
-rw-r--r-- 2.0 unx 1667 b- defN 22-Sep-02 12:37 org/apache/struts2/rest/RestConstants.class
-rw-r--r-- 2.0 unx 4916 b- defN 22-Sep-02 12:37 org/apache/struts2/rest/RestWorkflowInterceptor.class
-rw-r--r-- 2.0 unx 5693 b- defN 22-Sep-02 12:37 org/apache/struts2/rest/config/entities/RestConstantConfig.class
-rw-r--r-- 2.0 unx 1283 b- defN 22-Sep-02 12:37 org/apache/struts2/rest/handler/AbstractContentTypeHandler.class
-rw-r--r-- 2.0 unx 255 b- defN 22-Sep-02 12:37 org/apache/struts2/rest/handler/AllowedClassNames.class
-rw-r--r-- 2.0 unx 248 b- defN 22-Sep-02 12:37 org/apache/struts2/rest/handler/AllowedClasses.class
-rw-r--r-- 2.0 unx 770 b- defN 22-Sep-02 12:37 org/apache/struts2/rest/handler/ContentTypeHandler.class
-rw-r--r-- 2.0 unx 1541 b- defN 22-Sep-02 12:37 org/apache/struts2/rest/handler/FormUrlEncodedHandler.class
-rw-r--r-- 2.0 unx 1208 b- defN 22-Sep-02 12:37 org/apache/struts2/rest/handler/HtmlHandler.class
-rw-r--r-- 2.0 unx 2593 b- defN 22-Sep-02 12:37 org/apache/struts2/rest/handler/JacksonJsonHandler.class
-rw-r--r-- 2.0 unx 2378 b- defN 22-Sep-02 12:37 org/apache/struts2/rest/handler/JacksonXmlHandler.class
-rw-r--r-- 2.0 unx 3410 b- defN 22-Sep-02 12:37 org/apache/struts2/rest/handler/JuneauXmlHandler.class
-rw-r--r-- 2.0 unx 1536 b- defN 22-Sep-02 12:37 org/apache/struts2/rest/handler/MultipartFormDataHandler.class
-rw-r--r-- 2.0 unx 1128 b- defN 22-Sep-02 12:37 org/apache/struts2/rest/handler/XStreamHandler$CollectionTypePermission.class
-rw-r--r-- 2.0 unx 5262 b- defN 22-Sep-02 12:37 org/apache/struts2/rest/handler/XStreamHandler.class
-rw-r--r-- 2.0 unx 318 b- defN 22-Sep-02 12:37 org/apache/struts2/rest/handler/XStreamPermissionProvider.class
-rw-r--r-- 2.0 unx 6028 b- defN 22-Sep-02 12:37 struts-plugin.xml
-rw-r--r-- 2.0 unx 3448 b- defN 22-Sep-02 12:37 META-INF/maven/org.apache.struts/struts2-rest-plugin/pom.xml
-rw-r--r-- 2.0 unx 71 b- defN 22-Sep-02 12:37 META-INF/maven/org.apache.struts/struts2-rest-plugin/pom.properties
46 files, 110426 bytes uncompressed, 44463 bytes compressed: 59.7%
attempt 2: modify bean
- modified the bean that refers to the
JacksonLibHandler, like so:
<bean type="org.apache.struts2.rest.handler.ContentTypeHandler" name="jackson"
class="org.apache.struts2.rest.handler.JacksonJsonHandler"/>
- now rebuild and try
sam local invokeagain - now, there's a different error:
Caused by: java.lang.ClassNotFoundException: com.fasterxml.jackson.dataformat.xml.XmlMapper. Current classpath: file:/var/task/:file:/var/task/lib/asm-9.2.jar:file:/var/task/lib/asm-analysis-9.2.jar:file:/var/task/lib/asm-commons-9.2.jar:file:/var/task/lib/asm-tree-9.2.jar:file:/var/task/lib/aws-lambda-java-core-1.2.1.jar:file:/var/task/lib/aws-lambda-java-log4j2-1.5.1.jar:file:/var/task/lib/aws-serverless-java-container-core-1.8.2.jar:file:/var/task/lib/aws-serverless-java-container-struts2-1.8.2.jar:file:/var/task/lib/classmate-1.3.4.jar:file:/var/task/lib/commons-codec-1.11.jar:file:/var/task/lib/commons-fileupload-1.4.jar:file:/var/task/lib/commons-io-2.2.jar:file:/var/task/lib/commons-lang3-3.10.jar:file:/var/task/lib/commons-logging-1.2.jar:file:/var/task/lib/freemarker-2.3.31.jar:file:/var/task/lib/hibernate-validator-6.1.7.Final.jar:file:/var/task/lib/httpclient-4.5.13.jar:file:/var/task/lib/httpcore-4.4.13.jar:file:/var/task/lib/httpmime-4.5.13.jar:file:/var/task/lib/jackson-annotations-2.13.4.jar:file:/var/task/lib/jackson-core-2.13.4.jar:file:/var/task/lib/jackson-databind-2.13.4.jar:file:/var/task/lib/jackson-module-afterburner-2.13.3.jar:file:/var/task/lib/jakarta.activation-1.2.2.jar:file:/var/task/lib/jakarta.validation-api-2.0.2.jar:file:/var/task/lib/javassist-3.20.0-GA.jar:file:/var/task/lib/javax.servlet-api-3.1.0.jar:file:/var/task/lib/javax.ws.rs-api-2.1.jar:file:/var/task/lib/jboss-logging-3.3.2.Final.jar:file:/var/task/lib/jsp-api-2.0.jar:file:/var/task/lib/log4j-api-2.19.0.jar:file:/var/task/lib/log4j-core-2.19.0.jar:file:/var/task/lib/log4j-slf4j-impl-2.19.0.jar:file:/var/task/lib/objenesis-3.2.jar:file:/var/task/lib/ognl-3.1.29.jar:file:/var/task/lib/servlet-api-2.4.jar:file:/var/task/lib/slf4j-api-1.7.36.jar:file:/var/task/lib/struts2-aws-lambda-support-plugin-1.4.0.jar:file:/var/task/lib/struts2-bean-validation-plugin-6.0.3.jar:file:/var/task/lib/struts2-convention-plugin-6.0.3.jar:file:/var/task/lib/struts2-core-2.5.30.jar:file:/var/task/lib/struts2-rest-plugin-6.0.3.jar:file:/var/task/lib/validation-api-2.0.1.Final.jar:file:/var/task/lib/xstream-1.4.19.jar
at lambdainternal.CustomerClassLoader.findClass(CustomerClassLoader.java:63)
at java.base/java.lang.ClassLoader.loadClass(Unknown Source)
at java.base/java.lang.ClassLoader.loadClass(Unknown Source)
... 72 more
- it would appear that
JacksonLibHandlerdid some sort of multiplexing logic across both the XML and JSON handlers? and that directing Struts at one or the other doesn't help.
test-event.json
{
"body": "eyJ0ZXN0IjoiYm9keSJ9",
"resource": "/pets",
"path": "/pets",
"httpMethod": "GET",
"isBase64Encoded": true,
"headers": {
"Accept": "text/html,application/xhtml+xml,application/xml;q=0.9,image/webp,*/*;q=0.8",
"Accept-Encoding": "gzip, deflate, sdch",
"Accept-Language": "en-US,en;q=0.8",
"Cache-Control": "max-age=0",
"CloudFront-Forwarded-Proto": "https",
"CloudFront-Is-Desktop-Viewer": "true",
"CloudFront-Is-Mobile-Viewer": "false",
"CloudFront-Is-SmartTV-Viewer": "false",
"CloudFront-Is-Tablet-Viewer": "false",
"CloudFront-Viewer-Country": "US",
"Host": "1234567890.execute-api.us-west-2.amazonaws.com",
"Upgrade-Insecure-Requests": "1",
"User-Agent": "Custom User Agent String",
"Via": "1.1 08f323deadbeefa7af34d5feb414ce27.cloudfront.net (CloudFront)",
"X-Amz-Cf-Id": "cDehVQoZnx43VYQb9j2-nvCh-9z396Uhbp027Y2JvkCPNLmGJHqlaA==",
"X-Forwarded-For": "127.0.0.1, 127.0.0.2",
"X-Forwarded-Port": "443",
"X-Forwarded-Proto": "https"
},
"multiValueHeaders": {
"Accept": [
"text/html,application/xhtml+xml,application/xml;q=0.9,image/webp,*/*;q=0.8"
],
"Accept-Encoding": [
"gzip, deflate, sdch"
],
"Accept-Language": [
"en-US,en;q=0.8"
],
"Cache-Control": [
"max-age=0"
],
"CloudFront-Forwarded-Proto": [
"https"
],
"CloudFront-Is-Desktop-Viewer": [
"true"
],
"CloudFront-Is-Mobile-Viewer": [
"false"
],
"CloudFront-Is-SmartTV-Viewer": [
"false"
],
"CloudFront-Is-Tablet-Viewer": [
"false"
],
"CloudFront-Viewer-Country": [
"US"
],
"Host": [
"0123456789.execute-api.us-west-2.amazonaws.com"
],
"Upgrade-Insecure-Requests": [
"1"
],
"User-Agent": [
"Custom User Agent String"
],
"Via": [
"1.1 08f323deadbeefa7af34d5feb414ce27.cloudfront.net (CloudFront)"
],
"X-Amz-Cf-Id": [
"cDehVQoZnx43VYQb9j2-nvCh-9z396Uhbp027Y2JvkCPNLmGJHqlaA=="
],
"X-Forwarded-For": [
"127.0.0.1, 127.0.0.2"
],
"X-Forwarded-Port": [
"443"
],
"X-Forwarded-Proto": [
"https"
]
},
"requestContext": {
"accountId": "123456789012",
"resourceId": "123456",
"stage": "prod",
"requestId": "c6af9ac6-7b61-11e6-9a41-93e8deadbeef",
"requestTime": "09/Apr/2015:12:34:56 +0000",
"requestTimeEpoch": 1428582896000,
"identity": {
"cognitoIdentityPoolId": null,
"accountId": null,
"cognitoIdentityId": null,
"caller": null,
"accessKey": null,
"sourceIp": "127.0.0.1",
"cognitoAuthenticationType": null,
"cognitoAuthenticationProvider": null,
"userArn": null,
"userAgent": "Custom User Agent String",
"user": null
},
"path": "/pets",
"resourcePath": "/pets",
"httpMethod": "POST",
"apiId": "1234567890",
"protocol": "HTTP/1.1"
}
}
@jogep can you take a look, please?
Fixed as part of 1.9.1 release.