apache / cordova-android

Apache Cordova Android
https://cordova.apache.org/
Apache License 2.0
3.59k stars 1.52k forks source link

gradlew: 'sh' is not recognized as an internal or external command, #1027

Open mikebridge opened 3 years ago

mikebridge commented 3 years ago

Bug Report

Problem

When I run the following command in PowerShell on Windows 10, I get an error:

cordova build android --verbose

=> 
...
Running command: C:\MyPath\platforms\android\gradlew cdvBuildDebug -b C:\MyPath\platforms\android\build.gradle
'sh' is not recognized as an internal or external command,
operable program or batch file.
Command finished with error code 1: C:\MyPath\platforms\android\gradlew cdvBuildDebug,-b,C:\MyPath\platforms\android\build.gradle
C:\MyPath\platforms\android\gradlew: Command failed with exit code 1 Error output:
'sh' is not recognized as an internal or external command,
operable program or batch file.
Error: C:\MyPath\platforms\android\gradlew: Command failed with exit code 1 Error output:
'sh' is not recognized as an internal or external command,
operable program or batch file.
    at ChildProcess.whenDone (C:\MyPath\node_modules\cordova-common\src\superspawn.js:135:23)
    at ChildProcess.emit (events.js:315:20)
    at ChildProcess.cp.emit (C:\MyPath\node_modules\cross-spawn\lib\enoent.js:34:29)
    at maybeClose (internal/child_process.js:1021:16)
    at Process.ChildProcess._handle.onexit (internal/child_process.js:286:5)

What is expected to happen?

I am able to run this command on Ubuntu (non-WSL) and it successfully finds the correct version of gradlew. However, in Windows, I think it should find gradlew.bat.

What does actually happen?

It runs gradlew on Windows, rather than gradlew.bat

Information

check_reqs.js locates Android Studio and then gradle in this location:

C:\Program Files\Android\Android Studio\gradle\gradle-4.6\bin\gradle

However, ProjectBuilder.js shows this:

build (opts) {
    var wrapper = path.join(this.root, 'gradlew');
    ...

It looks to me like there is no attempt to append .bat to the filename if it's on Windows. Maybe execa is supposed to append it, but it doesn't seem to. If I hack this to 'gradlew.bat', it builds successfully.

Command or Code

cordova build android --verbose

Environment, Platform, Device

Windows 10

Version information

Cordova 9.0.0 It seems to find Android Studio 3.2.1, although I'm not actually using it.

Checklist

breautek commented 3 years ago

I believe this is a regression from the shelljs refactor. I'm assuming shelljs, which executed commands as a shell which caused windows to use PATHEXT, so windows will automatically find the proper extension for files. Moving to execa must simply just use node child processes which does not.

breautek commented 3 years ago

This may be more complicated...

I just installed all the dev tools on my windows machine and I was able to build a cordova-android@9 hello world project without reproducing this issue.

My environment:

cordova requirements android

Requirements check results for android:
Java JDK: installed 1.8.0
Android SDK: installed true
Android target: installed android-29
Gradle: installed C:\Users\norman\development\gradle\gradle-6.5.1\bin\gradle.BAT

cordova platform ls
Installed platforms:
  android 9.0.0

cordova -v
9.0.0 (cordova-lib@9.0.1)

node -v
v12.18.2

Tested on both Command Prompt and Powershell. We may need more information about your environment.

killroy42 commented 3 years ago

I have the same issue. My requirements output is: c:\gitroot\ctcmobile>cordova requirements android

Requirements check results for android: Java JDK: installed 1.8.0 Android SDK: installed true Android target: installed android-30,android-29,android-28 Gradle: installed C:\Gradle\gradle-6.6\bin\gradle.BAT

It seems to try to run the "gradlew" file instead of "gradlew.bat". How can I correct this?

breautek commented 3 years ago

I have the same issue. My requirements output is: c:\gitroot\ctcmobile>cordova requirements android

Requirements check results for android: Java JDK: installed 1.8.0 Android SDK: installed true Android target: installed android-30,android-29,android-28 Gradle: installed C:\Gradle\gradle-6.6\bin\gradle.BAT

It seems to try to run the "gradlew" file instead of "gradlew.bat". How can I correct this?

Can you confirm that your PATHEXT system variable contains .BAT? If not, if you add it, does it solve your issue?

killroy42 commented 3 years ago

It's there, I can execute bat files just fine, but the script never tries to.

breautek commented 3 years ago

Thanks, that was kind of my expected response, just wanted to rule it out...

We are using execa, which behind the scenes, uses cross-spawn for improved windows support, as the native node APIs don't respect PATHEXT, which cross-spawn is suppose to address.

execa depends on cross-spawn@^7.0.0, and they have been 3 patches, with version 7.0.3 actually have a fix for detecting paths in windows. When I attempted to reproduce this issue, using a fresh install, I was probably testing with the patched version of cross-spawn, and thus could not reproduce the issue.

You can confirm which version you have of cross-spawn by looking at node_modules/cross-spawn/package.json. The _id field should contain cross-spawn@7.0.3. If yours contains a lower version, perhaps you're hitting a cross-spawn bug.

Running the following commands should make sure all the subdependencies are using the latest satisfiable versions: (Forgive me, I don't know the windows equivalent of these commands, so these are based in bash...)

rm package-lock.json
rm -rf node_modules
npm install
killroy42 commented 3 years ago

Hmm, in the meantime, I have been able to get it to work both in WSL/Ubuntu and on the windows side on the same machine. I think it mostly boiled down to getting everything into the right folders, etc. Sadly, most of the default install locations and documentation seem to disagree, with Android, android-sdk and other folders being used interchangeably and never quite explained what they should be, and which set of commands does what exactly. For example, on the WSL/Ubuntu side, I used apt install, followed by manually moving things into the home folder after manually changing ownership.

killroy42 commented 3 years ago

Ok, it's getting weirder. I started a new project, and it has that problem. Then the old project wouldn't build. But removing the android platform and adding it worked and it builds again. On the new, almost empty project I tried that, I tried what you write, and STILL get the "'sh' is not recognized as an internal or external command," error. This is on the same machine with the same environment set up...

garethedwards commented 2 years ago

Found this issue thread while investigating the same " 'sh' is not recognized" occurring on Windows 10 after upgrading to cordova-android.

All the above didn't resolve the issue, and I was at the point of installing the WSL.

And then... it just worked. And the next time... it didn't.

The difference? I'd opened the emulator, and then closed it.

So it seems, for me at least, when the Android Studio emulator isn't running, the 'sh' error occurs.

Hope that helps anyone else afflicted with this, and maybe @breautek et al root out the cause or at least catch and issue a more meaningful message

avpengage commented 2 years ago

I've confirmed the same. 'sh' error without emulator running. Success with emulator running...

LynxTR commented 2 years ago

I also have confirmed that without emulator running 'sh' error throwed.

AyatoKirishima commented 2 years ago

I've confirmed the same. 'sh' error without emulator running. Success with emulator running...

Same and i've got Command failed with exit code 1: apkanalyzer manifest target-sdk :(

It builds but never launch :/

AyatoKirishima commented 2 years ago

image

An android emulator has to be running ! phew 6hours later it's working <3

EnginKARATAS commented 2 years ago

I have confirmed "sh" error caused by when emulator not start

vahost commented 2 years ago

Same result here. With Android Studio open but emulator not running, I get the sh error. Open an emulator and re-build, and the error goes away.

1aerostorm commented 2 years ago

Faced this issue on Windows when using device, but it is disconnected, so cordova-android tried to running emulator.

It uses emulator and run that command when adb devices returns empty list, so you can run adb devices and ensure that here is your device (or pre-runned emulator?)

Problem is in apkanalyzer which is a file in

C:\Users\<username>\AppData\Local\Android\Sdk\tools\bin

and it is shell script, not cmd...

I think it is a bug in Android SDK. More info: https://stackoverflow.com/questions/47081004/apkanalyzer-is-not-recognized-as-an-internal-or-external-command But if they aren't fixing it, it should be work-arounded in cordova-android...

SuryaT1999 commented 1 year ago

Command failed with exit code 1: apkanalyzer manifest target-sdk C:...\Documents\Cordova\Jul-30\eTHICApp3\platforms\android\app\build\outputs\apk\debug\app-debug.apk 'sh' is not recognized as an internal or external command, operable program or batch file. Error: Command failed with exit code 1: apkanalyzer manifest target-sdk C:...\Documents\Cordova\Jul-30\eTHICApp3\platforms\android\app\build\outputs\apk\debug\app-debug.apk 'sh' is not recognized as an internal or external command, operable program or batch file. at makeError (C:...\Documents\Cordova\Jul-30\eTHICApp3\node_modules\execa\lib\error.js:60:11) at handlePromise (C:...\Documents\Cordova\Jul-30\eTHICApp3\node_modules\execa\index.js:118:26) at processTicksAndRejections (node:internal/process/task_queues:96:5) at async getTargetSdkFromApk (C:...\Documents\Cordova\Jul-30\eTHICApp3\node_modules\cordova-android\lib\target.js:102:38) at async resolveToOfflineEmulator (C:...\Documents\Cordova\Jul-30\eTHICApp3\node_modules\cordova-android\lib\target.js:88:27) at async Object.exports.resolve (C:/...\Documents\Cordova\Jul-30\eTHICApp3\node_modules\cordova-android\lib\target.js:118:10) at async Api.module.exports.run (C:...\Documents\Cordova\Jul-30\eTHICApp3\node_modules\cordova-android\lib\run.js:73:28) at async Promise.all (index 0)

--this type error will get on my pc when excute a code (cordova run android). Any idea to solve this issue and ajax call not hit my java end it return a status 404.

Rademenes16 commented 1 year ago

I am using real phone instead of emulator

here's what worked for me:

Afterwards I can deploy apk without problems. Hope it helps