AWS SAM CLI FileNotFoundError: WinError 3: The system cannot find the path specified .class class Kotlin 1.7 Windows 10
Introduction
The AWS SAM CLI command
sam.cmd build MyFunction --template C:\techie\workspace\my-function\local\template.yaml --build-dir C:\techie\workspace\my-function\local\.aws-sam\build --debug
fails in an IntelliJ commandline terminal due to this
FileNotFoundError: [WinError 3] The system cannot find the path specified
error.
Setup
- Windows 10 Pro laptop
- IntelliJ 2022
- Kotlin 1.7
- Java 11 at least for compilation
- Serverless lambda written in Kotlin
- AWS SAM CLI, version 1.67.0
- AWS Toolkit plugin for IntelliJ
Investigation
First I tried to install SAM AWS CLI using HomeBrew (formerly Brew) in WSL 1 (ubuntu) under Windows 10 using these steps:
https://docs.aws.amazon.com/serverless-application-model/latest/developerguide/install-homebrew.html
But that failed during Homebrew installation. Probably upgrading to WSL 2 would fix that. But then I also realized: IntelliJ then doesn't know about that at all, since SAM CLI is then installed in WSL, not in Windows.
It kept on saying after running brew postinstall --verbose --debug gcc:
==> Installing aws-sam-cli from aws/tap
Error: An exception occurred within a child process:
Errno::EFAULT: Bad address - /home/linuxbrew/.linuxbrew/bin/gcc-12
And also:
Warning: The post-install step did not complete successfully
You can try again using:
brew postinstall gcc
Also trying brew postinstall --verbose --debug gcc didn't succeed. This error mentioned here was also applicable: https://github.com/orgs/Homebrew/discussions/4052
I also didn't dare wsl --update because other configurations I already had set up might fail after that. Guess I will do that at a more quiet moment :)
So then I went for the manual installation in Windows, as found here: https://docs.aws.amazon.com/serverless-application-model/latest/developerguide/install-sam-cli.html
In IntelliJ you then have to set the path to the executable to where you installed it:
So IntelliJ will use the Windows AWS SAM CLI, not the one in the terminal (WSL 1).
Than I ran my command, first outside IntelliJ to be able to control the parameters more easily:
C:\Users\techie>C:\Amazon\AWSSAMCLI\bin\sam.cmd build MyFunction --template C:\techie\workspace\my-function\local\template.yaml --build-dir C:\techie\workspace\my-function\local\.aws-sam\build --debug
But that gave this error:
FileNotFoundError: [WinError 3] The system cannot find the path specified: 'C:\\Users\\techie\\AppData\\Local\\Temp\\tmpmjdhug40\\7c98ad184709dded6b1c874ece2a0edea9c55b0a\\build\\classes\\kotlin\\test\\com\\mycompany\\myfunction\\domain\\MyServiceTest$should register valid make this a long text to exceed this successfully$2.class'
First I thought it was due to spaces in the test-methodname. But replacing them with an underscore didn't work either. Or maybe case-insensitive-ness; but my test-methodname is all lowercase.
I tried many things to exclude the whole test-class from the process, because why is it even included during the sam build command?
Options I tried were:
- Setting GRADLE_OPTS before running the command -x test, similar to the MAVEN_OPTS example here: https://github.com/aws/aws-sam-cli/issues/1105#issuecomment-777703158
- Excluding the test-file or even just all tests in build.gradle, like:
jar {
sourceSets {
main {
java {
exclude '**/TestExcludeClass.java'
}
kotlin {
exclude '**/TestExcludeKotlinClass.kt'
}
}
}
}
Note that excluding everything with 'exclude '**/*.kt' did make the sam build fail, so the changes were taken into account. - In build.gradle add: excludeTestsMatching "com.mycompany.myfunction.lambda.MyServiceTest"
- test.onlyIf { ! Boolean.getBoolean(skipTests) } and then specifying as GRADLE_OPTS="-DskipTests=true"
It seems the initial step of the sam build (JavaGradleWorkflow:JavaGradleCopyArtifacts) just takes all .class files anyway, even test classes.
I tried turning off Telemetry That did have no affect on the error.
Solution
Then I found this comment: https://github.com/aws/aws-sam-cli/issues/4031#issuecomment-1173730737
Could it be that, that the path is just too long? Typical Windows limit so that could definitely be it.
And yes after applying below command in PowerShell as an Administrator
New-ItemProperty -Path "HKLM:\SYSTEM\CurrentControlSet\Control\FileSystem" `-Name "LongPathsEnabled" -Value 1 -PropertyType DWORD -Force
it worked!
Detailed explanation: https://learn.microsoft.com/en-us/windows/win32/fileio/maximum-file-path-limitation?tabs=powershell#enable-long-paths-in-windows-10-version-1607-and-later
The command ran fine! This is then the output:
Build Succeeded
Built Artifacts : ..\..\techie\workspace\my-function\local\.aws-sam\build
Built Template : ..\..\techie\workspace\my-function\local\.aws-sam\build\template.yaml
Commands you can use next
=========================
[*] Validate SAM template: sam validate
[*] Invoke Function: sam local invoke -t ..\..\techie\workspace\my-function\local\.aws-sam\build\template.yaml
[*] Test Function in the Cloud: sam sync --stack-name {{stack-name}} --watch
[*] Deploy: sam deploy --guided --template-file ..\..\techie\workspace\my-function\local\.aws-sam\build\template.yaml