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-store
-
sam build
- Populate
test-event.json
with content from below -
Note: I had to correct the
Handler
property of the function in theSAM
template 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
JacksonLibHandler
is 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
JacksonJsonHandler
andJacksonXmlHandler
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 invoke
again - 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
JacksonLibHandler
did 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?