dherault / dherault/serverless-offline
serverless offline doesn't work with Java package that has many class files
- Dominant language
- JavaScript
- Stars
- 5.3k
- Forks
- 811
- Avg merge
- 2d 4h
- Merged PRs (30d)
- 3
Description
## Bug Report
**Current Behavior**
If you run `serverless offline` with the `serverless.yml` file below, and the Java package contains many class files, `serverless offline` fails with the following message when invoking the GET endpoint (the name of the class file is random):
> × EMFILE: too many open files, open 'C:\Users\\...\Documents\BugServerlessOffline\\.serverless-offline\services\bugserverlessoffline\hello\efc4c712-3754-45b6-a153-6f14049501d3\code\software\amazon\awssdk\services\route53\model\UpdateHostedZoneCommentRequest$1.class'

The serverless.yml file is as follows:
```
service: bugserverlessoffline
frameworkVersion: '3'
provider:
name: aws
runtime: java8
plugins:
- serverless-offline
package:
artifact: target/hello-dev.jar
functions:
hello:
handler: com.serverless.Handler
events:
- http:
path: /hello
method: GET
```
`serverless offline` fails while unpacking the `hello-dev.jar`-file to the `.serverless-offline` folder. Either while extracting there are too many files opened at the same moment or the files are not closed.
I fixed this problem by modifying `serverless-offline\src\lambda\LambdaFunction.js` as follows:
1. Added import: `import { writeFileSync } from 'fs'`
2. In the function `extractArtifact` I replaced the line `return writeFile(join(this.#codeDir, filename), fileData, {` by `return writeFileSync(join(this.#codeDir, filename), fileData, {`
Here is the patch for these changes:
[LambdaFunction.js.patch](https://github.com/dherault/serverless-offline/files/11323140/LambdaFunction.js.patch)
**Sample Code**
I've created a simple sample application with `serverless create --template aws-java-maven`, and added a lot of dependencies to the `pom.xml` file:
```
software.amazon.awssdk
bom
2.20.49
pom
import
org.junit
junit-bom
5.9.2
pom
import
com.amazonaws
aws-lambda-java-log4j2
1.5.0
org.apache.logging.log4j
log4j-core
2.20.0
org.apache.logging.log4j
log4j-api
2.20.0
com.fasterxml.jackson.core
jackson-core
2.14.2
com.fasterxml.jackson.core
jackson-databind
2.14.2
com.fasterxml.jackson.core
jackson-annotations
2.14.2
software.amazon.awssdk
s3
software.amazon.awssdk
dynamodb
software.amazon.awssdk
dynamodb-enhanced
software.amazon.awssdk
route53
com.amazonaws
aws-lambda-java-events
3.11.0
org.junit.jupiter
junit-jupiter
test
com.google.code.gson
gson
2.10.1
io.jsonwebtoken
jjwt-api
0.11.5
io.jsonwebtoken
jjwt-impl
0.11.5
runtime
io.jsonwebtoken
jjwt-jackson
0.11.5
runtime
io.jsonwebtoken
jjwt-root
0.11.5
pom
```
I then also modified the `serverless.yml` slightly (added `GET /hello` endpoint).
Here is the complete sample application: [BugServerlessOffline.zip](https://github.com/dherault/serverless-offline/files/11323371/BugServerlessOffline.zip)
**Expected behavior/code**
Serverless offline shouldn't fail.
**Environment**
- `serverless` version: 3.30.1
- `serverless-offline` version: 12.0.4
- `node.js` version: v18.14.2
- `OS`: Windows 10
**Possible Solution**
See above.
**Additional context/Screenshots**
None.
Contributor guide
Research direction
Start in serverless-offline/src/lambda/LambdaFunction.js and inspect extractArtifact, especially the asynchronous file writes during JAR extraction. Reproduce with the linked BugServerlessOffline sample and its large Java artifact, then verify that serverless offline completes extraction and invokes GET /hello without EMFILE.
Written by the indexing model from the issue text.
Assessment
- Tech stack
- aws, java, javascript, node.js
- Domain
- tooling
- Issue type
- Bug
- Difficulty
- 2/5
- Estimated time
- 1-3 hours
- Activity status
- Stale
- Clarity
- Clearly specified
- Newbie friendliness
- 48/100