I have setup Detekt in a multi module project. Below is my root level build.gradle
tasks.register("detektAll", Detekt) {
description = "Custom Detekt build for all modules"
parallel = true
setSource(file(projectDir))
config.setFrom(files("$rootDir/detekt.yml"))
jvmTarget = "1.8"
classpath.setFrom(project.configurations.getByName("detekt"))
include("**/*.kt")
exclude("**/build/**")
reports {
html {
enabled = true
destination = file("$rootDir/build/reports/detekt-results.html")
}
xml.enabled = false
txt.enabled = false
}
}
Now I am looking at setting up custom rule for which I followed this
This is what my build.gradle of customdetekt module looks like
apply plugin: 'kotlin'
repositories {
mavenCentral()
}
dependencies {
compileOnly "io.gitlab.arturbosch.detekt:detekt-api:1.17.1"
testImplementation "junit:junit:4.13.2"
testImplementation "org.assertj:assertj-core:3.20.2"
testImplementation "io.gitlab.arturbosch.detekt:detekt-api:1.17.1"
testImplementation "io.gitlab.arturbosch.detekt:detekt-test:1.17.1"
}
Now when I hook up custom rule module in my main module using this:
detektPlugins project(path: ':customdetekt', configuration: 'default')
I get an error:
Caused by: org.gradle.internal.metaobject.AbstractDynamicObject$CustomMessageMissingMethodException: Could not find method detektPlugins() for arguments [DefaultProjectDependency{dependencyProject='project ':customdetekt''
Please help
Related
I have been writing kotlin code for android apps for quite some time, but I decided to also start writing testing code too for my apps. I have been facing some problems though with the use of Hilt. What I tried is :
import android.app.Application
open class AbstractApplication: Application()
#HiltAndroidApp
class IgmeApplication : IgmeAbstractApplication() {
#Inject
lateinit var authenticationManager: AuthenticationManager
....
}
and then in the Android Test Directory:
import dagger.hilt.android.testing.CustomTestApplication
#CustomTestApplication(AbstractApplication::class)
open class HiltTestApplication
import android.app.Application
import android.content.Context
import androidx.test.runner.AndroidJUnitRunner
class HiltTestRunner : AndroidJUnitRunner() {
override fun newApplication(
cl: ClassLoader?,
className: String?,
context: Context?
): Application {
return super.newApplication(cl,HiltTestApp::class.java.name, context)
}
}
my Test class :
#HiltAndroidTest
class AuthenticationTest{
#get:Rule
var hiltRule = HiltAndroidRule(this)
#Test
fun useAppContext() {
// Context of the app under test.
val appContext = InstrumentationRegistry.getInstrumentation().targetContext
Assert.assertEquals("com.crowdpolicy.onext.igme", appContext.packageName)
}
#Before
fun setUp() {
// Populate #Inject fields in test class
hiltRule.inject()
}
#After
fun tearDown() {
}
}
my app level gradle file :
plugins {
id 'com.android.application'
id 'kotlin-android'
id 'kotlin-kapt'
id 'com.google.gms.google-services'
id 'com.google.firebase.crashlytics'
id 'com.google.firebase.firebase-perf' // Firebase Performance monitoring
id 'androidx.navigation.safeargs.kotlin'
id 'dagger.hilt.android.plugin'
id 'kotlin-parcelize'
id 'com.google.protobuf'
}
Properties localProperties = new Properties()
localProperties.load(new FileInputStream(rootProject.file('local.properties')))
Properties keyStoreProperties = new Properties()
keyStoreProperties.load(new FileInputStream(rootProject.file('keystore.properties')))
android {
buildToolsVersion "30.0.3"
ndkVersion localProperties['ndk.version']
signingConfigs {
release {
storeFile file(keyStoreProperties['key.release.path'])
keyAlias 'igme-key'
storePassword keyStoreProperties['key.release.keystorePassword']
keyPassword keyStoreProperties['key.release.keyPassword']
}
}
compileSdkVersion 30
compileOptions {
sourceCompatibility JavaVersion.VERSION_1_8
targetCompatibility JavaVersion.VERSION_1_8
}
kotlinOptions {
jvmTarget = JavaVersion.VERSION_1_8.toString()
freeCompilerArgs += '-Xopt-in=kotlin.RequiresOptIn'
}
defaultConfig {
applicationId "com.crowdpolicy.onext.igme"
minSdkVersion 21
targetSdkVersion 30
versionCode 1
versionName "1.0"
testInstrumentationRunner "com.crowdpolicy.onext.igme.HiltTestRunner"
}
buildTypes {
release {
minifyEnabled true
shrinkResources true
debuggable false
//signingConfig signingConfigs.release
firebaseCrashlytics {
// Enable processing and uploading o FirebaseCrashlytics.getInstance()f native symbols to Crashlytics
// servers. By default, this is disabled to improve build speeds.
// This flag must be enabled to see properly-symbolicated native
// stack traces in the Crashlytics dashboard.
nativeSymbolUploadEnabled true
unstrippedNativeLibsDir "$buildDir/ndklibs/libs"
}
proguardFiles getDefaultProguardFile('proguard-android-optimize.txt'), 'proguard-rules.pro'
ndk.debugSymbolLevel = "FULL" // Generate native debug symbols
}
}
packagingOptions {
exclude 'META-INF/DEPENDENCIES'
exclude 'META-INF/rxjava.properties'
}
kotlinOptions {
jvmTarget = '1.8'
}
testOptions {
unitTests {
includeAndroidResources = true
}
}
android.buildFeatures.viewBinding = true
dependencies {
// Testing-only dependencies
testImplementation 'junit:junit:4.13.2'
// Core library
androidTestImplementation 'androidx.test:core:1.4.0'
// AndroidJUnitRunner and JUnit Rules
androidTestImplementation 'androidx.test:runner:1.4.0'
androidTestImplementation 'androidx.test:rules:1.4.0'
// Assertions
androidTestImplementation 'androidx.test.ext:junit:1.1.3'
androidTestImplementation 'androidx.test.ext:truth:1.4.0'
// Espresso dependencies
androidTestImplementation "androidx.test.espresso:espresso-core:$espresso_version"
androidTestImplementation "androidx.test.espresso:espresso-intents:$espresso_version"
androidTestImplementation "androidx.test.espresso:espresso-web:$espresso_version"
androidTestImplementation "androidx.test.espresso.idling:idling-concurrent:$espresso_version"
// The following Espresso dependency can be either "implementation"
// or "androidTestImplementation", depending on whether you want the
// dependency to appear on your APK's compile classpath or the test APK
// classpath.
androidTestImplementation "androidx.test.espresso:espresso-idling-resource:$espresso_version"
//Dagger
implementation "com.google.dagger:dagger:$dagger_version"
kapt "com.google.dagger:dagger-compiler:$dagger_version"
// region Hilt
implementation "com.google.dagger:hilt-android:$hilt_version"
implementation "androidx.hilt:hilt-navigation-fragment:$hilt_fragment_version"
kapt "com.google.dagger:hilt-android-compiler:$hilt_version" // or : kapt 'com.google.dagger:hilt-compiler:2.37'
// Testing Navigation
androidTestImplementation("androidx.navigation:navigation-testing:$nav_version")
// region Hilt testing - for instrumentation tests
androidTestImplementation "com.google.dagger:hilt-android-testing:$hilt_version"
// Make Hilt generate code in the androidTest folder
kaptAndroidTest "com.google.dagger:hilt-android-compiler:$hilt_version"
// endregion
// For local unit tests
testImplementation 'com.google.dagger:hilt-android-testing:2.37'
kaptTest 'com.google.dagger:hilt-compiler:2.37'
androidTestImplementation 'com.google.dagger:hilt-android-testing:2.37'
}
}
kapt {
correctErrorTypes true
javacOptions {
// These options are normally set automatically via the Hilt Gradle plugin, but we
// set them manually to workaround a bug in the Kotlin 1.5.20: https://github.com/google/dagger/issues/2684
option("-Adagger.fastInit=ENABLED")
option("-Adagger.hilt.android.internal.disableAndroidSuperclassValidation=true")
}
}
// https://github.com/google/protobuf-gradle-plugin
protobuf {
protoc {
artifact = "com.google.protobuf:protoc:$protobuf_version"
// path = localProperties["protoc.dir"]
}
// Generates the java Protobuf-lite code for the Protobufs in this project. See
// https://github.com/google/protobuf-gradle-plugin#customizing-protobuf-compilation
// for more information.
generateProtoTasks {
all().each { task ->
task.builtins {
java {
option 'lite'
}
}
}
}
}
dependencies {
implementation 'androidx.legacy:legacy-support-v4:1.0.0'
implementation 'androidx.appcompat:appcompat:1.3.1'
implementation 'com.google.android.material:material:1.4.0'
implementation 'androidx.constraintlayout:constraintlayout:2.1.0'
}
(Above I added only the dependencies used for testing )
project gradle
// Top-level build file where you can add configuration options common to all sub-projects/modules.
buildscript {
ext.kotlin_version = "1.5.20"
ext.google_version = '4.3.4'
ext.timberVersion = '4.7.1'
ext.event_bus = '3.2.0'
ext.gson_version = '2.8.6'
ext.retrofit2_version = '2.9.0'
ext.datastore_version = '1.0.0-rc02'
ext.rxkotlin_version = '3.0.1'
ext.rxandroid_version = '3.0.0'
ext.lifecycle_version = '2.3.1'
ext.dagger_version = '2.37'
ext.hilt_version = '2.37'
ext.hilt_fragment_version = '1.0.0'
ext.nav_version = '2.3.5'
ext.fragment_version = '1.3.6'
ext.androidXTestCoreVersion = '1.4.0'
ext.espresso_version = '3.4.0'
ext.lottie_version = '3.6.1'
ext.facebook_version = '9.0.0'
ext.protobuf_version = '3.15.8'
ext.protobuf_gradle_plugin_version = '0.8.16'
repositories {
google()
mavenCentral()
}
dependencies {
classpath "com.android.tools.build:gradle:4.2.2"
classpath "org.jetbrains.kotlin:kotlin-gradle-plugin:$kotlin_version"
classpath "com.google.gms:google-services:$google_version"
classpath 'com.google.firebase:firebase-crashlytics-gradle:2.7.1'
classpath 'com.google.firebase:perf-plugin:1.4.0'
classpath "androidx.navigation:navigation-safe-args-gradle-plugin:$nav_version"
classpath "com.google.dagger:hilt-android-gradle-plugin:$hilt_version"
classpath "com.google.protobuf:protobuf-gradle-plugin:$protobuf_gradle_plugin_version"
// NOTE: Do not place your application dependencies here; they belong
// in the individual module build.gradle files
}
}
allprojects {
repositories {
google()
mavenCentral()
jcenter() // Warning: this repository is going to shut down soon
}
}
task clean(type: Delete) {
delete rootProject.buildDir
}
I followed the official documentation from dagger-hilt in this page : https://dagger.dev/hilt/testing.html, but I am still getting this error :
Caused by: java.lang.ClassCastException: com.crowdpolicy.onext.igme.HiltTestApplication cannot be cast to android.app.Application
at android.app.Instrumentation.newApplication(Instrumentation.java:997)
at android.app.Instrumentation.newApplication(Instrumentation.java:982)
at com.crowdpolicy.onext.igme.HiltTestRunner.newApplication(HiltTestRunner.kt:14)
at android.app.LoadedApk.makeApplication(LoadedApk.java:617)
and I do not know how to fix it, because I am really new to testing and it is the first time facing it !
line 14 in HIltTestRunner is :
return super.newApplication(cl,HiltTestApp::class.java.name, context)
I had the same Problem, while Testing i got a ClassCastException: HiltTestApplication cannot be cast to AbcApp (my Application class).
Solution is the #CustomTestApplication annotation, see Dagger Docs or Android Dev Docs and the use of the generated class
<interfacename>_Application.
Further on be aware that just using IgmeApplication (or AbcApp in my case) is not possible when it uses the #HiltAndroidApp annotation, see open Issue. Then you have to make an open class AbstractApplication: Application() like the questioner did. Which is then subclassed by your Application (AbcApp in my case or IgmeApplication in questioners case) and subclassed by the created class from annotation #CustomTestApplication. like:
#CustomTestApplication(AbstractApplication::class)
interface CustomTestApplicationForHilt
Note that interface is used instead of open class, but it also works with open class like the questioner did.
The created class is then CustomTestApplicationForHilt_Application which has to be used, when calling newApplication in your Testrunner class, like:
class HiltTestRunner : AndroidJUnitRunner() {
override fun newApplication(cl: ClassLoader?, className: String?, context: Context?): Application {
return super.newApplication(cl, CustomTestApplicationForHilt_Application::class.java.name, context)
}
}
Note that you can choose the name of the interface for the #CustomTestApplication annotation (here CustomTestApplicationForHilt) like you want, but the ending _Application will be added to the class name when the annotation is processed while building the app. Also note that the class will not be available before the build.
I tried to integrate sqldelight in my Multiplatform library project for Android/iOS but I'm having several unresolved dependency errors when syncing gradle.
ERROR: Unable to resolve dependency for ':SharedCode#debug/compileClasspath': Could not resolve com.squareup.sqldelight:runtime:1.1.3.
ERROR: Unable to resolve dependency for ':SharedCode#debug/compileClasspath': Could not resolve com.squareup.sqldelight:runtime-jvm:1.1.3.
ERROR: Unable to resolve dependency for ':SharedCode#release/compileClasspath': Could not resolve com.squareup.sqldelight:runtime:1.1.3.
ERROR: Unable to resolve dependency for ':SharedCode#release/compileClasspath': Could not resolve com.squareup.sqldelight:runtime-jvm:1.1.3.**
Gradle version 5.1.1
Gradle Plugin 3.4.0
sqldelight 1.1.3
enableFeaturePreview('GRADLE_METADATA') is present in my settings.gradle
My project gradle file looks like this:
buildscript {
ext {
kotlin_version = '1.3.31'
ktor_version = '1.2.1'
ktor_json_version = '1.2.1'
kotlinx_coroutines_version = '1.2.1'
serialization_version = '0.11.0'
sqldelight_version = '1.1.3'
dokka_version = '0.9.16'
}
repositories {
google()
jcenter()
mavenCentral()
gradlePluginPortal()
}
dependencies {
classpath 'com.android.tools.build:gradle:3.4.0'
classpath "org.jetbrains.kotlin:kotlin-gradle-plugin:$kotlin_version"
classpath "org.jetbrains.kotlin:kotlin-serialization:$kotlin_version"
classpath "org.jetbrains.dokka:dokka-android-gradle-plugin:$dokka_version"
classpath "com.squareup.sqldelight:gradle-plugin:$sqldelight_version"
}
}
allprojects {
repositories {
google()
jcenter()
mavenCentral()
maven { url "https://kotlin.bintray.com/kotlinx" }
}
}
task clean(type: Delete) {
setDelete rootProject.buildDir
}
my SharedCode lib gradle file:
apply plugin: 'kotlinx-serialization'
apply plugin: 'com.android.library'
apply plugin: 'org.jetbrains.kotlin.multiplatform'
apply plugin: 'com.squareup.sqldelight'
group = 'com.example.multiplatform'
version = '1.0'
android {
compileSdkVersion 27
defaultConfig {
minSdkVersion 15
}
buildTypes {
release {
minifyEnabled false
}
}
}
dependencies {
// Specify Kotlin/JVM stdlib dependency.
implementation 'org.jetbrains.kotlin:kotlin-stdlib-jdk7'
implementation "com.squareup.sqldelight:runtime:1.1.3"
testImplementation 'junit:junit:4.12'
testImplementation 'org.jetbrains.kotlin:kotlin-test'
testImplementation 'org.jetbrains.kotlin:kotlin-test-junit'
androidTestImplementation 'junit:junit:4.12'
androidTestImplementation 'org.jetbrains.kotlin:kotlin-test'
androidTestImplementation 'org.jetbrains.kotlin:kotlin-test-junit'
androidTestImplementation 'com.android.support.test:runner:1.0.2'
androidTestImplementation 'com.android.support.test.espresso:espresso-core:3.0.2'
}
kotlin {
targets {
final def iOSTarget = System.getenv('SDK_NAME')?.startsWith("iphoneos") \
? presets.iosArm64 : presets.iosX64
fromPreset(iOSTarget, 'ios') {
binaries {
framework('SharedCode')
}
}
fromPreset(presets.android, 'androidLib')
}
sourceSets {
commonMain {
dependencies {
//HTTP
implementation "io.ktor:ktor-client-json:$ktor_json_version"
implementation "io.ktor:ktor-client-serialization:$ktor_version"
//Coroutines
implementation "org.jetbrains.kotlinx:kotlinx-coroutines-core-common:$kotlinx_coroutines_version"
//Kotlinx serialization
implementation "org.jetbrains.kotlinx:kotlinx-serialization-runtime-common:$serialization_version"
//sqldelight
implementation "com.squareup.sqldelight:runtime:$sqldelight_version"
}
}
androidLibMain {
dependencies {
//HTTP
implementation "io.ktor:ktor-client-json-jvm:$ktor_json_version"
implementation "io.ktor:ktor-client-serialization-jvm:$ktor_version"
//Coroutines
implementation "org.jetbrains.kotlinx:kotlinx-coroutines-android:$kotlinx_coroutines_version"
//Kotlinx serialization
implementation "org.jetbrains.kotlinx:kotlinx-serialization-runtime:$serialization_version"
//sqldelight
implementation "com.squareup.sqldelight:android-driver:$sqldelight_version"
}
}
iosMain {
dependencies {
//HTTP
implementation "io.ktor:ktor-client-ios:$ktor_version"
implementation "io.ktor:ktor-client-json-native:$ktor_json_version"
implementation "io.ktor:ktor-client-serialization-native:$ktor_version"
//Coroutines
implementation "org.jetbrains.kotlinx:kotlinx-coroutines-core-native:$kotlinx_coroutines_version"
//kotlinx serialization
implementation "org.jetbrains.kotlinx:kotlinx-serialization-runtime-native:$serialization_version"
//sqldelight
implementation "com.squareup.sqldelight:ios-driver:$sqldelight_version"
}
}
}
}
sqldelight {
MyApp {
packageName = 'com.example.multiplatform'
}
}
configurations {
compileClasspath
}
task packForXCode(type: Sync) {
final File frameworkDir = new File(buildDir, "xcode-frameworks")
final String mode = project.findProperty("XCODE_CONFIGURATION")?.toUpperCase() ?: 'DEBUG'
final def framework = kotlin.targets.ios.binaries.getFramework("SharedCode", mode)
inputs.property "mode", mode
dependsOn framework.linkTask
from { framework.outputFile.parentFile }
into frameworkDir
doLast {
new File(frameworkDir, 'gradlew').with {
text = "#!/bin/bash\nexport 'JAVA_HOME=${System.getProperty("java.home")}'\ncd '${rootProject.rootDir}'\n./gradlew \$#\n"
setExecutable(true)
}
}
}
tasks.build.dependsOn packForXCode
I was solved this problem.
First: Apply sqldelight plugin right to all project:
apply plugin: 'com.squareup.sqldelight'
sqldelight {
MyDatabase {
packageName = "ru.trendagent.database"
sourceFolders = ["sqldelight"]
}
}
In android section add:
packagingOptions {
...
exclude 'META-INF/*.kotlin_module'
}
remove all implementations of sqldelight from CommonMain section
add implementation to AndroidMain section:
implementation "com.squareup.sqldelight:android-driver:1.1.3" //DataBase
add implementation to iosMain section if need:
implementation "com.squareup.sqldelight:ios-driver:1.1.3"//DataBase
add Metadata settings to gradle to settings.gradle file:
enableFeaturePreview("GRADLE_METADATA") // IMPORTANT!
Fully clean gradle files, reset gradle wrapper and other.
Don't use kotlin 1.4.0. It unsupport sqldelight 1.1.3 version
Change gradle to latest version. You can download latest gradle manually and set it on IDE. You need gradle 5.3.1 or latest (5.1.1 unsupported)
If error will remain - change IDE to intellij idea comunity edition
This is seems to me as an error occurred due to offline gradle or invalid cache as this error is not specific to com.squareup.sqldelight. To resolve this issue follow the following steps:
File
Settings
Build, Execution, Deployment
Gradle
Uncheck offline work
and then try to invalidate the cache and restart from file menu. Hope it helps!
Change this
classpath "com.squareup.sqldelight:gradle-plugin:$sqldelight_version"
Following
classpath "com.squareup.sqldelight:runtime:$sqldelight_version"
you are passing wrong metadata to sqldelight change with my solution it will work
The Gradle part of the readme of the library indicates, that gradle plugin is needed. There's no such sqldelight library as runtime. They only have android-driver, ios-driver and sqlite-driver.
Using the DroidConKotlin app project as an example, I upgraded gradle from 5.1.1 to 5.3.1 and it resolved all the dependencies issues.
You likely are trying to use a dependency on dependant libraries or even applications and not only in commonMain module. Just change:
commonMain {
dependencies {
...
implementation "com.squareup.sqldelight:runtime:$sqldelight_version"
}
}
to
commonMain {
dependencies {
...
api "com.squareup.sqldelight:runtime:$sqldelight_version"
}
}
Also change it on dependencies section
And do the same with any other dependency uncorrecly resolved
This can happen for example if you define a class that implements an interface provided by the dependency and you use or extend that class on dependant libraries or applications (Just an example of millions that could be).
If this is your case, for further understanding, just take a look to this answer:
I am coming because I can't make work my communication between my API (Go) and my client (Android).
I have this protobuf file:
syntax = "proto3";
option java_package = "com.emixam23.rushpoc.protobuf";
option java_outer_classname = "HelloWorld";
package helloworld;
// The greeting service definition.
service Greeter {
// Sends a greeting
rpc SayHello (HelloRequest) returns (HelloReply) {}
}
// The request message containing the user's name.
message HelloRequest {
string name = 1;
}
// The response message containing the greetings
message HelloReply {
string message = 1;
}
The protobuf file comes from the example of https://grpc.io/docs/quickstart/go.html, I just didn't implemented the SayHelloAgain. What i am trying to achieve is, from my android app, SayHello to my Go API and get a reply...
For android, I followed that tutorial (https://grpc.io/docs/quickstart/android.html) in order to, from the protobuf file, to communicate with my API. However, there is a stub, comming from I don't know where.
So I searched about how to create a stub (https://grpc.io/docs/tutorials/basic/android.html) and nothing.. ManagedChannelBuilder doesn't exist and I can't find the way to install it..
PS: to generate my Java class from the protobuf file, I followed that tutorial: https://proandroiddev.com/how-to-setup-your-android-app-to-use-protobuf-96132340de5c
Am I in the right direction or totally wrong?
My project structure:
APP build.gradle
apply plugin: 'com.android.application'
apply plugin: 'com.google.protobuf'
android {
compileSdkVersion 27
defaultConfig {
applicationId "com.rushpoc.emixam23.androidapp"
minSdkVersion 21
targetSdkVersion 27
versionCode 1
versionName "1.0"
testInstrumentationRunner "android.support.test.runner.AndroidJUnitRunner"
}
buildTypes {
release {
minifyEnabled false
proguardFiles getDefaultProguardFile('proguard-android.txt'), 'proguard-rules.pro'
}
}
}
dependencies {
implementation fileTree(dir: 'libs', include: ['*.jar'])
implementation 'com.android.support:appcompat-v7:27.1.1'
implementation 'com.android.support.constraint:constraint-layout:1.1.2'
testImplementation 'junit:junit:4.12'
androidTestImplementation 'com.android.support.test:runner:1.0.2'
androidTestImplementation 'com.android.support.test.espresso:espresso-core:3.0.2'
//Protobuf
implementation 'com.google.protobuf:protobuf-lite:3.0.0'
implementation 'io.grpc:grpc-okhttp:1.13.2'
implementation 'io.grpc:grpc-protobuf-lite:1.13.2'
implementation 'io.grpc:grpc-stub:1.13.2'
}
protobuf {
generatedFilesBaseDir = "$projectDir/generated"
protoc {
// You still need protoc like in the non-Android case
artifact = 'com.google.protobuf:protoc:3.0.0'
}
plugins {
javalite {
// The codegen for lite comes as a separate artifact
artifact = 'com.google.protobuf:protoc-gen-javalite:3.0.0'
}
grpc {
artifact = 'io.grpc:protoc-gen-grpc-java:1.13.2'
}
}
generateProtoTasks {
all().each { task ->
task.builtins {
java
}
task.plugins {
grpc {}
}
}
}
}
TOP-LEVEL/Root build.gradle
// Top-level build file where you can add configuration options common to all sub-projects/modules.
buildscript {
ext.protobufVersion = '0.8.6'
repositories {
google()
jcenter()
}
dependencies {
classpath 'com.android.tools.build:gradle:3.1.3'
classpath "com.google.protobuf:protobuf-gradle-plugin:$protobufVersion"
// NOTE: Do not place your application dependencies here; they belong
// in the individual module build.gradle files
}
}
allprojects {
repositories {
google()
jcenter()
}
}
task clean(type: Delete) {
delete rootProject.buildDir
}
I haven't checked the entire gradle files yet but I see in your screenshot the .proto file was in src/main/protobufs, which was not following either of the tutorials you mentioned. The protobuf gradle plugin does not detect this directory by default. Therefore I suggest you change it into the default directory src/main/proto. If you would like to insist putting the .proto file in src/main/protobufs, you might need let the protobuf gradle plugin know it by adding
// see https://github.com/google/protobuf-gradle-plugin#customizing-source-directories
sourceSets {
main {
proto {
// In addition to the default 'src/main/proto'
srcDir 'src/main/protobufs'
}
}
}
After that, the protobuf gradle plugin will generate the java code if there's no other mistake.
Normally i am able to build my project but whenever there is a database change i need to run OrmLiteConfigUtil and after running it i get error as below. it never succeeds. I tried exploring other question and found below solution but still it doesn't works.
I tried disabling Aapt2 by putting android.enableAapt2=false in gradle properties file.
Information:Gradle: Executing tasks: [:library:assembleDebug, :app:assembleDebug]
Information:Gradle: BUILD FAILED in 58s
Information:Modules "library", "app" were fully rebuilt due to project configuration/dependencies changes
Information:21-02-2018 05:09 PM - Compilation completed with 5 errors and 0 warnings in 1m 8s 524ms
Error:Gradle: failed to create directory 'D:\Working_folder\Fieldez_5.5.6.2\app\build\generated\source\r\debug\com\fieldez\mobile'.
Error:Gradle: java.util.concurrent.ExecutionException: java.util.concurrent.ExecutionException: com.android.tools.aapt2.Aapt2Exception: AAPT2 error: check logs for details
Error:Gradle: java.util.concurrent.ExecutionException: com.android.tools.aapt2.Aapt2Exception: AAPT2 error: check logs for details
Error:Gradle: com.android.tools.aapt2.Aapt2Exception: AAPT2 error: check logs for details
Error:Gradle: Execution failed for task ':app:processDebugResources'.
> Failed to execute aapt
My Project level gradle code
// Top-level build file where you can add configuration options common to all sub-projects/modules.
buildscript {
repositories {
jcenter()
google()
}
dependencies {
classpath 'com.android.tools.build:gradle:3.0.0'
}
}
allprojects {
repositories {
jcenter()
}
}
App level gradle file
apply plugin: 'com.android.application'
apply plugin: 'io.fabric'
apply plugin: 'let'
repositories {
mavenCentral()
jcenter()
maven {
url "https://oss.sonatype.org/content/repositories/snapshots"
}
maven {
url "https://jitpack.io"
}
/* maven {
url "https://mint.splunk.com/gradle/"
}*/
maven { url 'https://maven.fabric.io/public' }
maven { url "https://raw.githubusercontent.com/smilefam/SendBird-SDK-Android/master/" }
google()
}
buildscript {
repositories {
jcenter()
maven { url 'https://maven.fabric.io/public' }
}
dependencies {
classpath 'com.canelmas.let:let-plugin:0.1.10'
classpath 'io.fabric.tools:gradle:1.+'
}
}
android {
compileSdkVersion 'Google Inc.:Google APIs:23'
buildToolsVersion '26.0.2'
defaultConfig {
vectorDrawables.useSupportLibrary = true
applicationId "com.fieldez.mobile"
minSdkVersion 16
targetSdkVersion 23
multiDexEnabled true
dexOptions {
javaMaxHeapSize "4g"
}
}
compileOptions {
sourceCompatibility JavaVersion.VERSION_1_8
targetCompatibility JavaVersion.VERSION_1_8
}
buildTypes {
release {
shrinkResources true
minifyEnabled true
zipAlignEnabled true
debuggable false
proguardFiles getDefaultProguardFile('proguard-android.txt'), 'proguard-rules.pro'
}
// uncomment the below 4 lines to test release build
debug {
// minifyEnabled true
// shrinkResources true
// proguardFiles getDefaultProguardFile('proguard-android.txt'), 'proguard-rules.pro'
// zipAlignEnabled true
}
}
useLibrary 'org.apache.http.legacy'
/*productFlavors {
//configstring.xml debugMode == true
debugMode {
versionName '3.5.4'
applicationVariants.all { variant ->
variant.outputs.each { output ->
output.outputFile = new File(output.outputFile.parent,
output.outputFile.name.replace("app-debugMode-release", "FieldEZ Product" + "-${variant.versionName}")
)
}
}
}
//configstring.xml debugMode == false
releaseMode {
versionName '3.5.4'
applicationVariants.all { variant ->
variant.outputs.each { output ->
output.outputFile = new File(output.outputFile.parent,
output.outputFile.name.replace("app-releaseMode-release", "FieldEZ Product Release" + "-${variant.versionName}")
)
}
}
}
}*/
}
dependencies {
implementation fileTree(dir: 'libs', include: '*.jar')
// Play Services
implementation 'com.google.android.gms:play-services-maps:9.0.2'
implementation 'com.google.android.gms:play-services-location:9.0.2'
implementation 'com.google.android.gms:play-services-gcm:9.0.2'
//Support Libraries
implementation 'com.android.support:appcompat-v7:24.0.0'
implementation 'com.android.support:design:24.0.0'
implementation 'com.android.support:recyclerview-v7:24.0.0'
implementation 'com.android.support:cardview-v7:24.0.0'
implementation 'com.android.support:support-v4:24.0.0'
//ORMLite DB
implementation 'com.j256.ormlite:ormlite-core:4.48'
implementation 'com.j256.ormlite:ormlite-android:4.48'
// apache http
implementation 'org.apache.httpcomponents:httpmime:4.2.5'
// For Date and Time Pickers
implementation 'com.wdullaer:materialdatetimepicker:2.2.0'
//For Images
implementation 'com.squareup.picasso:picasso:2.5.2'
// RecyclerView Animations
implementation 'jp.wasabeef:recyclerview-animators:2.2.1'
// JSON Parsing
implementation 'com.google.code.gson:gson:2.6.2'
implementation 'com.google.android.gms:play-services-appindexing:9.0.2'
// For crash reports
// compile "com.splunk.mint:mint:5.0.0"
// Calendar
implementation 'com.github.nikhilpanju:material-calendarview:-SNAPSHOT'
implementation project(':library')
//okhttp
// compile 'com.squareup.okhttp3:okhttp:3.3.1'
//Retrofit
implementation 'com.squareup.retrofit2:retrofit:2.1.0'
//RecyclerViewEnhanced
implementation 'com.nikhilpanju.recyclerviewenhanced:recyclerviewenhanced:1.1.0'
//writeToPDF
// compile 'com.itextpdf:itextg:5.5.10'
//multidex
implementation 'com.android.support:multidex:1.0.1'
//Mixpanel for analytics
// compile "com.mixpanel.android:mixpanel-android:4.+"
//apteligent for crash reports
//compile 'com.crittercism:crittercism-android-agent:+'
implementation('com.crashlytics.sdk.android:crashlytics:2.6.8#aar') {
transitive = true;
}
// RecyclerViewHeader2
implementation 'com.bartoszlipinski:recyclerviewheader2:2.0.1'
// FabtoDialog
implementation 'konifar:fab-transformation:1.0.0'
// seeing database
// debugCompile 'com.amitshekhar.android:debug-db:1.0.1'
// SendBird Chat API
implementation 'com.sendbird.sdk:sendbird-android-sdk:3.0.26'
// sendbird using external libraries
// External libraries
implementation 'com.github.bumptech.glide:glide:3.7.0'
implementation 'org.jsoup:jsoup:1.10.2'
// Butterknife
// compile 'com.jakewharton:butterknife:8.8.1'
// annotationProcessor 'com.jakewharton:butterknife-compiler:8.8.1'
// FAB Menu (Temporarily using my PR for this library until it's merged)
//compile 'com.github.clans:fab:1.6.4'
implementation 'com.github.nikhilpanju:FloatingActionButton:-SNAPSHOT'
// RXJava for Concurrency and Multithreading
implementation 'io.reactivex.rxjava2:rxandroid:2.0.2'
implementation 'io.reactivex:rxjava:1.1.0'
}
Which is my project level gradle.propeties file in these or i dont have it ?
Having experienced this problem in a separate project, I made a test project to verify the issue.
Opening Android Studio 3.0, I created a new basic project. Its main module was called app.
I added a library module, called libraryone.
In libraryone, I added a dependency to Gson, and added a single class with a single static method using Gson.
In app, I added a dependency to libraryone. I tested it plain, as well as with transitive = true, as the internet seemed to vaguely concur that doing so might help. (It did not.)
In app, in MainActivity, I used the class from libraryone. This worked (as long as I didn't have transitive = false set, instead).
However, I cannot reference Gson from MainActivity itself. It gives a "Cannot resolve symbol 'Gson'" error, both from Android Studio, as well as from the command line Gradle. This is...unusual and aggravating, as it means you have to repeat common dependencies all throughout a group of projects, and the classes are included in the output anyway. Surely either I'm doing something wrong, or this is a bug?
My code is as follows:
MainActivity.java (in app)
package com.erhannis.test.dependencytest;
import android.support.v7.app.AppCompatActivity;
import android.os.Bundle;
import com.erhannis.test.libraryone.LibClass;
public class MainActivity extends AppCompatActivity {
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
String s = LibClass.convert(new Object());
System.out.println("out: " + s);
new com.google.gson.Gson(); // This line gives a compile-time error: "Cannot resolve symbol 'Gson'"
}
}
LibClass.java (in libraryone)
package com.erhannis.test.libraryone;
import com.google.gson.Gson;
public class LibClass {
public static String convert(Object o) {
Gson gson = new Gson();
return gson.toJson(o);
}
}
build.gradle (app)
apply plugin: 'com.android.application'
android {
compileSdkVersion 26
defaultConfig {
applicationId "com.erhannis.test.dependencytest"
minSdkVersion 18
targetSdkVersion 26
versionCode 1
versionName "1.0"
testInstrumentationRunner "android.support.test.runner.AndroidJUnitRunner"
}
buildTypes {
release {
minifyEnabled false
proguardFiles getDefaultProguardFile('proguard-android.txt'), 'proguard-rules.pro'
}
}
}
dependencies {
implementation fileTree(dir: 'libs', include: ['*.jar'])
implementation 'com.android.support:appcompat-v7:26.1.0'
implementation 'com.android.support.constraint:constraint-layout:1.0.2'
testImplementation 'junit:junit:4.12'
androidTestImplementation 'com.android.support.test:runner:1.0.1'
androidTestImplementation 'com.android.support.test.espresso:espresso-core:3.0.1'
implementation (project(path: ':libraryone'))
}
build.gradle (libraryone)
apply plugin: 'com.android.library'
android {
compileSdkVersion 26
defaultConfig {
minSdkVersion 18
targetSdkVersion 26
versionCode 1
versionName "1.0"
testInstrumentationRunner "android.support.test.runner.AndroidJUnitRunner"
}
buildTypes {
release {
minifyEnabled false
proguardFiles getDefaultProguardFile('proguard-android.txt'), 'proguard-rules.pro'
}
}
}
dependencies {
implementation fileTree(dir: 'libs', include: ['*.jar'])
implementation 'com.android.support:appcompat-v7:26.1.0'
testImplementation 'junit:junit:4.12'
androidTestImplementation 'com.android.support.test:runner:1.0.1'
androidTestImplementation 'com.android.support.test.espresso:espresso-core:3.0.1'
implementation 'com.google.code.gson:gson:2.8.2'
}
It is because you declared the transitive dependency as implementation. Use api instead of implementation change:
implementation 'com.google.code.gson:gson:2.8.2'
to:
api 'com.google.code.gson:gson:2.8.2'
The reason why you should declare the transitive dependency in your library can be found here
You are using:
implementation (project(path: ':libraryone'))
implementation 'com.google.code.gson:gson:2.8.2'
Check the official doc:
When your module configures an implementation dependency, it's letting Gradle know that the module does not want to leak the dependency to other modules at compile time. That is, the dependency is available to other modules only at runtime.
Here you can find a very good blog about it.
The best solution for this is to create a private Github/Gitlab repository for the aar dependency. You can also make it public if you want. The aar file does not contain transitive dependencies when used locally. We need to publish it somewhere with the .pom file. Here's how to do it,
create a personal access token in Github
Github -> Settings -> Developer Settings -> Personal Access token - with write:packages / read:packages access level
(create two tokens if you need to distribute privately
Add id 'maven-publish' to plugins in module level gradle
Add the below code to module level gradle
task sourceJar(type: Jar) {
from android.sourceSets.main.java.srcDirs
archiveClassifier.set("sources")
}
publishing {
publications {
bar(MavenPublication) {
groupId 'com.your'
artifactId 'artifact'
version '1.0'
artifact sourceJar
artifact("$buildDir/outputs/aar/YourLibraryName-release.aar")
pom.withXml {
final dependenciesNode = asNode().appendNode('dependencies')
ext.addDependency = { Dependency dep, String scope ->
if (dep.group == null || dep.version == null || dep.name == null || dep.name == "unspecified")
return
final dependencyNode = dependenciesNode.appendNode('dependency')
dependencyNode.appendNode('groupId', dep.group)
dependencyNode.appendNode('artifactId', dep.name)
dependencyNode.appendNode('version', dep.version)
dependencyNode.appendNode('scope', scope)
if (!dep.transitive) {
final exclusionNode = dependencyNode.appendNode('exclusions').appendNode('exclusion')
exclusionNode.appendNode('groupId', '*')
exclusionNode.appendNode('artifactId', '*')
} else if (!dep.properties.excludeRules.empty) {
final exclusionNode = dependencyNode.appendNode('exclusions').appendNode('exclusion')
dep.properties.excludeRules.each { ExcludeRule rule ->
exclusionNode.appendNode('groupId', rule.group ?: '*')
exclusionNode.appendNode('artifactId', rule.module ?: '*')
}
}
}
configurations.compile.getDependencies().each { dep -> addDependency(dep, "compile") }
configurations.api.getDependencies().each { dep -> addDependency(dep, "compile") }
configurations.implementation.getDependencies().each { dep -> addDependency(dep, "runtime") }
}
}
}
repositories {
maven {
name = "GitHubPackages"
url = uri("https://maven.pkg.github.com/GITHUB_USERID/REPOSITORY")
credentials {
username = "GITHUB_USERID" // Better if you use env variable
password = "WRITE_ACCESS_TOKEN"
}
}
}
}
In the Gradle toolbar you can find publish under the publishing subdirectory in your library module directory. ( Make sure to build the aar from build->build in module directory before publish)
To use it in your project, add following to your app level gradle file inside android{ }tag
repositories {
maven {
name = "GitHubPackages"
url = uri("https://maven.pkg.github.com/GITHUB_USERID/REPOSITORY")
credentials {
username = "GITHUB_USERID" // Better if you use env variable
password = "READ_ACCESS_TOKEN"
}
}
}
Finally in dependencies
implementation 'com.your:artifact:1.0'
*Gitlab is also pretty similar to this