I have a project that uses Google App Engine with Android.
I got the following "gradle project sync failed" error after I upgraded to Android Studio 3.4 (gradle 5.1.1).
It was working well prior in the previous android studio version which uses gradle 4.10.1.
Any pointers are welcomed. do tell me if you need me to provide more information
Caused by: java.lang.NoSuchMethodError: org.gradle.api.tasks.SourceSetOutput.getClassesDir()Ljava/io/File;
at com.google.cloud.tools.gradle.endpoints.framework.server.EndpointsServerPlugin$2$1.execute(EndpointsServerPlugin.java:108)
at com.google.cloud.tools.gradle.endpoints.framework.server.EndpointsServerPlugin$2$1.execute(EndpointsServerPlugin.java:98)
the following is the build.gradle file for the backend module.
This was after I migrated to GAE V2 using the migration guide (https://cloud.google.com/endpoints/docs/frameworks/java/migrating-android)
buildscript {
repositories {
jcenter()
}
dependencies {
classpath 'com.google.cloud.tools:endpoints-framework-gradle-plugin:1.0.2'
classpath 'com.google.cloud.tools:appengine-gradle-plugin:1.3.2'
}
}
repositories {
jcenter()
}
apply plugin: 'java'
apply plugin: 'war'
apply plugin: 'com.google.cloud.tools.appengine'
apply plugin: 'com.google.cloud.tools.endpoints-framework-server'
sourceCompatibility = JavaVersion.VERSION_1_8
targetCompatibility = JavaVersion.VERSION_1_8
dependencies {
// V2: Endpoints Framework v2 migration
implementation 'com.google.endpoints:endpoints-framework:2.0.9'
implementation 'javax.inject:javax.inject:1'
implementation 'javax.servlet:servlet-api:2.5'
implementation 'com.googlecode.objectify:objectify:5.1.9'
}
Updating from:
classpath 'com.google.cloud.tools:endpoints-framework-gradle-plugin:1.0.2'
to:
classpath 'com.google.cloud.tools:endpoints-framework-gradle-plugin:1.0.3'
Fixed this problem in my project
to get it working again, I had to comment off the following from the build.gradle (module:app )
//buildscript {
// repositories {
// jcenter()
// }
// dependencies {
// // V2: Add the new Endpoints Framework plugin dependencies
// classpath 'com.google.cloud.tools:endpoints-framework-gradle-plugin:1.0.3'
// }
//}
instead, add the classpath into the build.gradle (project)
buildscript {
repositories {
jcenter()
google()
}
dependencies {
// V2: Include this dependency when using Endpoints Framework v2
classpath 'com.google.guava:guava:24.1-jre'
//**moved from the build.gradle in module:app**
classpath 'com.google.cloud.tools:endpoints-framework-gradle-plugin:1.0.3'
///... <snips> the rest of the build.gradle file
I'm trying to connect a backend module in Android Studio to Firebase using the tutorial here - https://cloud.google.com/solutions/mobile/firebase-app-engine-android-studio#adding_dependencies_to_the_backend_module
I cannot add the dependencies for some reason. I can't find them on the list. If I try to add them manually, I get a Gradle sync error.
For the main app module, Firebase is connected and it's functioning correctly. I set this up using Android Studio's build in Firebase tool. I've tried using this tool again but it's made no difference.
Here's my build.gradle for the backend:
buildscript {
repositories {
jcenter()
}
dependencies {
classpath 'com.google.appengine:gradle-appengine-plugin:1.9.42'
}
}
repositories {
jcenter();
}
apply plugin: 'java'
apply plugin: 'war'
apply plugin: 'appengine'
sourceCompatibility = JavaVersion.VERSION_1_7
targetCompatibility = JavaVersion.VERSION_1_7
dependencies {
appengineSdk 'com.google.appengine:appengine-java-sdk:1.9.42'
compile 'javax.servlet:servlet-api:2.5'
compile 'com.google.appengine:appengine-api-1.0-sdk'
compile 'com.google.firebase:firebase-server-sdk'
compile 'org.apache.httpcomponents:httpclient'
}
appengine {
downloadSdk = true
appcfg {
oauth2 = true
}
}
Here's the error I get if I add the dependencies manually, as shown in the code above:
Click here
You're probably getting errors on these dependencies. They don't have versions specified:
compile 'com.google.appengine:appengine-api-1.0-sdk'
compile 'com.google.firebase:firebase-server-sdk'
compile 'org.apache.httpcomponents:httpclient'
Every maven dependency requires a group id, artifact id, and a version string.
Also, the "firebase-server-sdk" dependency doesn't make sense to me. Access to firebase backend services is now done through the Admin SDK.
My guess is that the tutorial you linked to is simply very much out of date, and you can no longer follow it exactly, but maybe you can still learn something from it otherwise.
I have created a backend module that contains the endpoints classes. It also has libraries that contain the endpointapi classes. During compile time, I am able to import both, the classes of that module and its library in the MainActivity file of the app. During run time however, it fails to detect the classes present in the library of the module. What could be the issue?
The error while running code is as follows:
Error:(10, 66) error: package com.example.shashank_pc.myapplication.backend.tempClassApi does not exist
The folder structure for backend module inside project is as follows:
For some reason, the classes inside the backend libraries, such as the those present in the tempClassApi and myApi folder, are not being detected
settings gradle file:
include ':app', ':backend'
App module gradle build file:
apply plugin: 'com.android.application'
android {
compileSdkVersion 25
buildToolsVersion "26.0.1"
defaultConfig {
applicationId "com.example.shashank_pc.testcloudendpoints"
minSdkVersion 22
targetSdkVersion 25
versionCode 1
versionName "1.0"
testInstrumentationRunner "android.support.test.runner.AndroidJUnitRunner"
}
buildTypes {
release {
minifyEnabled false
proguardFiles getDefaultProguardFile('proguard-android.txt'), 'proguard-rules.pro'
}
}
packagingOptions {
exclude 'com/google/appengine/repackaged/org/apache/commons/codec/language/bm/*'
exclude 'com/google/appengine/repackaged/org/codehaus/jackson/impl/*'
exclude 'com/google/appengine/repackaged/org/apache/commons/codec/language/*'
}
}
dependencies {
compile fileTree(dir: 'libs', include: ['*.jar'])
androidTestCompile('com.android.support.test.espresso:espresso-core:2.2.2',
{
exclude group: 'com.android.support', module: 'support-annotations'
})
compile 'com.android.support:appcompat-v7:25.3.1'
compile 'com.android.support.constraint:constraint-layout:1.0.2'
compile 'com.google.code.findbugs:jsr305:2.0.1'
testCompile 'junit:junit:4.12'
compile project(':backend')
}
I have a Google App Engine project in Android Studio. In the past I have successfully deployed to my project to GAE many times. However, some project setting has changed and I can no longer deploy. I get the message:
java.lang.IllegalArgumentException: Class file is Java 8 but max supported is Java 7: javax/ws/rs/ApplicationPath.class in /Users/rob/AndroidStudioProjects/SpeedyMovingInventory/backend/build/exploded-app/WEB-INF/lib/javax.ws.rs-api-2.1-m02.jar
Unable to update app: Class file is Java 8 but max supported is Java 7: javax/ws/rs/ApplicationPath.class in /Users/rob/AndroidStudioProjects/SpeedyMovingInventory/backend/build/exploded-app/WEB-INF/lib/javax.ws.rs-api-2.1-m02.jar
Please see the logs [/var/folders/cn/3ktx4pj50hs7338v88b0sckh0000gn/T/appcfg3087406806803083082.log] for further information.
I have tried to set the source and target compatibility in my build.gradle, it is shown below:
// If you would like more information on the gradle-appengine-plugin please refer to the github page
// https://github.com/GoogleCloudPlatform/gradle-appengine-plugin
buildscript {
repositories {
jcenter()
}
dependencies {
classpath 'com.google.appengine:gradle-appengine-plugin:1.9.34'
}
}
repositories {
jcenter();
}
apply plugin: 'java'
apply plugin: 'war'
apply plugin: 'appengine'
sourceCompatibility = JavaVersion.VERSION_1_7
targetCompatibility = JavaVersion.VERSION_1_7
dependencies {
appengineSdk 'com.google.appengine:appengine-java-sdk:1.9.34'
compile 'javax.servlet:servlet-api:2.5'
compile 'com.google.appengine:appengine-api-1.0-sdk:1.9.34'
compile 'joda-time:joda-time:2.8.2'
compile 'net.sargue:mailgun:1.0.0'
compile 'com.google.code.gson:gson:2.7'
testCompile 'junit:junit:4.12'
testCompile 'org.mockito:mockito-core:1.10.19'
// Set this dependency if you want to use Hamcrest matching
testCompile 'org.hamcrest:hamcrest-library:1.1'
testCompile fileTree(include: ['*.jar'], dir: '/Users/rob/appengine-java-sdk-1.9.34/lib/impl')
testCompile fileTree(include: ['*.jar'], dir: '/Users/rob/appengine-java-sdk-1.9.34/lib/testing')
}
appengine {
downloadSdk = true
appcfg {
oauth2 = true
}
}
I have also used Android Studio to generate a sample GAE module and successfully deployed the sample to GAE. I compared the gradle files and settings and I don't see any differences. Please help, what am I doing wrong?
After lots of research, I have figured a fix. The library 'net.sargue:mailgun:1.0.0' apparently has a dependency of some sort on a java 8 lib (or something along those lines). I don't know why this hasn't caused me issues in the past, but it is now. Upgrading the lib to 'net.sargue:mailgun:1.3.2" resolves the issue.
I have had a conversation with the author of the mailgun library:
https://github.com/sargue/mailgun/issues/11
He had a dependency which were updated to Java 8, he fixed it in the new release.
I'm writing a simple Twitter app using react-native. Using twit module to get twitter feeds and stream. Below is the code, it works fine node. However, when included into my react-native app, seeing error "Requiring unknown module "crypto"". Dependency seems to be myapp->twit->oauth->crypto (thats part of node v0.12.2). Any suggestions to get this working inside react-native environment?
var Twit = require('twit')
var T = new Twit({
consumer_key:''
, consumer_secret:''
, access_token:''
, access_token_secret:''
})
var filtered_tweets=[];
var error;
var isSuccess=false;
function getTweets(searchString){
T.get('search/tweets',{q:searchString, count:100}, getResponse);
}
function getResponse(err,data,response){
if(err) {
handleGetErr(err);
}
handleGetData(data.statuses);
}
function handleGetErr(err){
enter code here
error = err;
}
function handleGetData(data){
data.map(function(tweet){
var twit={
twit:tweet.id,
created_at:tweet.created_at,
text:tweet.text,
retweet_count:tweet.retweet_count,
favorite_count:tweet.favorite_count
};
filtered_tweets.push(twit);
});
console.log(filtered_tweets);
isSuccess=true;
}
getTweets("#sahaswaranamam");
module.exports = getTweets;
![attached][2]
The crypto module is a built-in Node module; React Native runs JS on JavaScriptCore (when on the device or simulator) and on Chrome itself (when using Chrome debugging), so modules that depend on built-in Node.js modules won't work. See the JavaScript Runtime section of the React Native docs for more info.
I'm not sure how hard it would be to integrate into a React Native app, but browser module bundlers like Browserify often have browser versions of core Node.js modules, like this one for crypto.
If you are using rn-nodeify as #emmby suggests, then you can use react-native-crypto. Instructions from the README:
Install
npm i --save react-native-crypto
# install peer deps
npm i --save react-native-randombytes
react-native link react-native-randombytes
# install latest rn-nodeify
npm i --save-dev mvayngrib/rn-nodeify
# install node core shims and recursively hack package.json files
# in ./node_modules to add/update the "browser"/"react-native"
# field with relevant mappings
./node_modules/.bin/rn-nodeify --hack --install
rn-nodeify will create a shim.js in the project root directory
// index.ios.js or index.android.js
// make sure you use `import` and not require!
import './shim.js'
// ...the rest of your code
But rn-nodeify also states:
If you're looking for a saner approach, check out ReactNativify. I haven't tested it myself, but I think philikon will be happy to help
With ReactNativify you create a rn-cli.config.js and then in a transformer.js you let Babel transform bundle dependencies using babel-plugin-rewrite-require:
// The following plugin will rewrite imports. Reimplementations of node
// libraries such as `assert`, `buffer`, etc. will be picked up
// automatically by the React Native packager. All other built-in node
// libraries get rewritten to their browserify counterpart.
[require('babel-plugin-rewrite-require'), {
aliases: {
crypto: 'crypto-browserify',
// ...
},
throwForNonStringLiteral: true,
}]
(Note: You can also do this in without these 2 js files directly in .babelrc)
(Note2: Though ReactNativify is the cleaner way, it is still giving me issues wiring up crypto.getRandomValues for production-use in RN. See this question)
You can use the rn-nodeify module to get crypto on react-native.
Add rn-nodeify to your devDependencies in package.json:
"devDependencies": {
"rn-nodeify": "^6.0.1"
}
Add the following to the scripts section of the same file:
"scripts": {
…
"postinstall": "node_modules/.bin/rn-nodeify --install crypto --hack"
}
Be aware that rn-nodeify will modify your package.json.
More information available here: https://www.npmjs.com/package/rn-nodeify
React Native packager uses Babel under the hood. This means that you can use babel-plugin-rewrite-require Babel plugin to rewrite all require('crypto') calls to require('crypto-browserify'), assuming that the latter is installed in your node_modules.
As of January 2016, you can use .babelrc file to define optional configuration, so this becomes really easy. First, install the dependencies:
npm install --save crypto-browserify
npm install --save-dev babel-plugin-rewrite-require
Then add plugins config to your .babelrc file:
{
"presets": ["react-native"],
"plugins": [
["babel-plugin-rewrite-require", {
"aliases": {
"crypto": "crypto-browserify"
}
}]
]
}
Restart the packager and that should be it.
This is the same approach that ReactNativify uses, except that here we use .babelrc instead of defining custom transformer. When ReactNativify was written, it was not supported, so they had to go with more complex solution. See this file from ReactNativify for almost complete list of node polyfills.
I was having the same issue when implementing the Twilio package in my React Native app, and having React Native break over the crypto dependency.
As a work around I ended up creating a separate, stand alone Node/Express app to act as my server and take care of the Twilio logic I had. That way I removed all Twilio logic from my React Native app and moved it to Node. I then just called my Express route in React Native using fetch, which triggered the functionality I wanted to happen with Twilio. If you're unfamiliar with fetch here's a good starting point -
Making AJAX calls with Fetch in React Native
In addition, here's my question on the crypto dependency breaking my app:
twilio-react-native-unable-to-resolve-module-crypto
As far I can see amazon-cognito-identity-js uses crypto-js 3.3.0 without any additional magic... If that version of the package works then perhaps try that.
After having tried a bunch of these solutions and never really having been satisfied with any of them (some didn't even work), I managed to stumble upon react-native-quick-crypto, which honestly worked much more effortlessly than trying to lift the existing crypto library to the front-end