Unexpected token ( on build.gradle file
Closed this issue · 9 comments
I'm submitting a ... (check one with "x"):
- bug report
- feature request
- documentation issue
Bug report
Current behavior:
I recently added cordova-android-play-services-gradle-release to a project containing cordova-android-support-gradle-release (due to play service 12.0 issue, came here through this SO answer).
When I run cordova build android
, I get following error :
------------------------------------------------------------------------------------------
Copying notification icon resources to android resources directory...
------------------------------------------------------------------------------------------
cordova-android-play-services-gradle-release PLAY_SERVICES_VERSION: 11.8.0
cordova-android-support-gradle-release ANDROID_SUPPORT_VERSION: 25.+
notification_icon resources copied !
cordova-android-play-services-gradle-release : WROTE /path/to/my/project/platforms/android/build.gradle > 11.8.0
cordova-android-support-gradle-release : WROTE /path/to/my/project/platforms/android/build.gradle > 25.+
ANDROID_HOME=/Users/fcamblor/tools/homebrew/Cellar/android-sdk/24.4.1_1
JAVA_HOME=/Library/Java/JavaVirtualMachines/jdk1.8.0_144.jdk/Contents/Home
Reading build config file: /path/to/my/project/build.json
Reading the keystore from: /path/to/my/project/certs/cma-key.jks
Subproject Path: CordovaLib
FAILURE: Build failed with an exception.
* Where:
Build file '/path/to/my/project/platforms/android/build.gradle' line: 322
* What went wrong:
Could not compile build file '/path/to/my/project/platforms/android/build.gradle'.
> startup failed:
build file '/path/to/my/project/platforms/android/build.gradle': 322: unexpected token: ( @ line 322, column 1.
()
^
1 error
* Try:
Run with --stacktrace option to get the stack trace. Run with --info or --debug option to get more log output.
BUILD FAILED
Total time: 0.734 secs
Error: /path/to/my/project/platforms/android/gradlew: Command failed with exit code 1 Error output:
FAILURE: Build failed with an exception.
* Where:
Build file '/path/to/my/project/platforms/android/build.gradle' line: 322
build.gradle file is looking like :
for (def func : cdvPluginPostBuildExtras) {
func()
}
// This can be defined within build-extras.gradle as:
// ext.postBuildExtras = { ... code here ... }
if (hasProperty('postBuildExtras')) {
postBuildExtras()
}
()
}
()
}
I suspect there are some conflict between plugins collaborating to build.gradle (see my cordova plugins list below)
Expected behavior:
No build.gradle code generation resulting into compilation errors
Environment information
- Cordova CLI version : 6.5.0
- Cordova platforms :
Installed platforms:
android 6.2.3
browser 4.1.0
ios 4.5.2
- Plugins & versions installed in project (including this plugin)
cordova-android-play-services-gradle-release 1.2.1 "cordova-android-play-services-gradle-release"
cordova-android-support-gradle-release 1.2.1 "cordova-android-support-gradle-release"
cordova-background-geolocation 2.7.3 "BackgroundGeolocation"
cordova-custom-config 2.0.3 "cordova-custom-config"
cordova-plugin-background-fetch 5.1.1 "CDVBackgroundFetch"
cordova-plugin-cocoalumberjack 0.0.4 "CocoaLumberjack"
cordova-plugin-compat 1.2.0 "Compat"
cordova-plugin-device 1.1.2 "Device"
cordova-plugin-dialogs 1.3.3 "Notification"
cordova-plugin-geolocation 2.4.3 "Geolocation"
cordova-plugin-google-analytics 1.7.11 "Google Universal Analytics Plugin"
cordova-plugin-inappbrowser 1.7.0 "InAppBrowser"
cordova-plugin-network-information 1.2.1 "Network Information"
cordova-plugin-request-location-accuracy 2.2.2 "Request Location Accuracy"
cordova-plugin-splashscreen 3.2.2 "Splashscreen"
cordova-plugin-statusbar 2.1.3 "StatusBar"
cordova-plugin-whitelist 1.3.2 "Whitelist"
cordova.plugins.diagnostic 3.7.0 "Diagnostic"
phonegap-plugin-barcodescanner 6.0.4 "BarcodeScanner"
- Dev machine OS and version, e.g.
ProductName: Mac OS X
ProductVersion: 10.12.6
BuildVersion: 16G1114
- Node JS version : v8.5.0
- Gradle version : 4.1
- Target Android SDK version : 25
Other information:
https://stackoverflow.com/a/49431381
dpa99c/cordova-android-support-gradle-release#18
dpa99c/cordova-android-support-gradle-release#19
Regards,
Weird thing is if I do :
cordova plugin rm cordova-android-play-services-gradle-release --save
cordova platform rm android
git checkout -- config.xml
cordova prepare
cordova build android
The build is ok only the first time (on the subsequent builds, I meet the same error as described above).
I read and re-read the after-prepare.js
script (which is called before_build
) but I don't see where would there be any bug :/
I'm wondering if the problem is not related to a concurrency issue : both plugins are reading then writing build.gradle
at the same time (so, latest write wins)
Which explains why, most of the time, I only see changes concerning android-support
libs and not android-play-services
libs
I added a timestamp in the log before/after the fs.write()
callback and it seems like callback my assumption sounds true :
cordova-android-play-services-gradle-release BEFORE write @1522175172240
cordova-android-support-gradle-release BEFORE write @1522175172240
notification_icon resources copied !
cordova-android-play-services-gradle-release AFTER write @1522175172245
cordova-android-play-services-gradle-release : WROTE /path/to/my/project/platforms/android/build.gradle > 11.8.0
cordova-android-support-gradle-release AFTER write @1522175172246
cordova-android-support-gradle-release : WROTE /path/to/my/project/platforms/android/build.gradle > 25.+
=> plugins are executed in parallel, not sequentially
Thanks for the detailed issue and investigation.
I think what I need to do is have the scripts return a promise rather than return immediately which should enforce synchronous (rather than concurrent) execution. This will ensure Cordova doesn't proceed to the next script until the previous has finished.
This is a method I've used previously in another of my plugins, cordova-custom-config, as you can see here in the source code.
Yep
Another option would be to merge both plugins.
I'm currently working on it here (need to make a release by tomorrow :-D)
Merging both plugins would mean that an app which uses one library but not the other would get both libraries pulled into their build. I think the promise approach will work and I'll implement it when I have some time.
Merging both plugins would mean that an app which uses one library but not the other would get both libraries pulled into their build.
Not sure about that ... given how the Gradle build works
Are you sure ?
My understanding is as soon as the lib will be found in the dependencies, version will be changed (but lib won't be "added" to the dependencies if not already present)
Am I wrong ?
Hmm, I thought I'd added config to add the libs if they weren't present, but no, it seems you are right.
However, combining to 1 plugin doesn't entirely solve the issue as their writing to build.gradle could still run concurrently with other plugins which write to it. So I think I'll implement the promise approach which should prevent this.
👍
Both plugins republished as v1.3.0 containing reworked scripts which use promises to enforce synchronous file access.