Configure .jar to expose its dependencies - java

I have 3 modules: annotations, annotation_processor and app.
annotations/build.gradle
apply plugin: 'java-library'
dependencies {
implementation fileTree(dir: 'libs', include: ['*.jar'])
}
annotation_processor/build.gradle
apply plugin: 'java-library'
dependencies {
implementation fileTree(dir: 'libs', include: ['*.jar'])
api project(":annotations")
api "com.squareup:javapoet:1.11.1"
}
repositories {
mavenCentral()
}
sourceCompatibility = "1.8"
targetCompatibility = "1.8"
task deleteJar(type: Delete) {
delete 'libs/annotations.jar'
}
task createJar(type: Copy) {
from('build/intermediates/bundles/release/')
into('libs/')
include('classes.jar')
rename('classes.jar', 'annotations.jar')
}
createJar.dependsOn(deleteJar, build)
and app/build.gradle
dependencies {
...
implementation files('libs/annotation_processor.jar')
annotationProcessor files('libs/annotation_processor.jar')
...
}
When I run the project I get the following error.
error: package com.annotations does not exist
If I include annotations as a project the project I can skip this error but then I get.
Caused by: java.lang.NoClassDefFoundError: com/annotations/ProviderApi
at com.annotation_processor.ProviderAnnotationProcessor.getSupportedAnnotationTypes(ProviderAnnotationProcessor.java:45)
at org.gradle.api.internal.tasks.compile.processing.DelegatingProcessor.getSupportedAnnotationTypes(DelegatingProcessor.java:47)
at org.gradle.api.internal.tasks.compile.processing.NonIncrementalProcessor.getSupportedAnnotationTypes(NonIncrementalProcessor.java:33)
at org.gradle.api.internal.tasks.compile.processing.DelegatingProcessor.getSupportedAnnotationTypes(DelegatingProcessor.java:47)
at org.gradle.api.internal.tasks.compile.processing.TimeTrackingProcessor.access$101(TimeTrackingProcessor.java:37)
at org.gradle.api.internal.tasks.compile.processing.TimeTrackingProcessor$2.create(TimeTrackingProcessor.java:68)
at org.gradle.api.internal.tasks.compile.processing.TimeTrackingProcessor$2.create(TimeTrackingProcessor.java:65)
at org.gradle.api.internal.tasks.compile.processing.TimeTrackingProcessor.track(TimeTrackingProcessor.java:117)
at org.gradle.api.internal.tasks.compile.processing.TimeTrackingProcessor.getSupportedAnnotationTypes(TimeTrackingProcessor.java:65)
I can't access any of the dependencies (Java Poet and annotation module) from annotation_processor even though I have replaced implementation with api. Which should've expose the dependencies, but haven't.
I need the dependencies of the .jar file in the app module.
I'm new to Java Library and it may be I'm making a basic mistake, but can't seem to figure out, I've been at it for more than a day now.

You have to create a multi module gradle project.
I provide a small snippet of a multi module project.
project(':module1') {
dependencies {
compile project(':module-service-api')
compile 'org.apache.commons:commons-lang3:3.3.2'
compile 'log4j:log4j:1.2.17'
}
}
//module-app depends on module-service-impl
project(':module2') {
dependencies {
compile project(':module1')
}
For more details about multi module project, refer to the file build.gradle in the following project.
https://github.com/debjava/gradle-multi-module-project-1
If you want to create a fat jar or one jar, you have to include Gradle shadow plugin so that you can distribute the jar file along with other dependencies.
Refer below the link.
https://plugins.gradle.org/plugin/com.github.johnrengelman.shadow

Related

Error in .java that cannot be resolved after changing in gradle android

App works fine till yesterday but today when I opened the project, I get error only in .java
In a class, only in .java I get error as unresolved error java.
intent = Intent(this#UserImageActivity, UserDetailsActivity::class.java)
I used invalidate cache and restart but still I couldn't resolve the compile error.
build.gradle (app)
dependencies {
implementation fileTree(dir: 'libs', include: ['*.jar'])
implementation "org.jetbrains.kotlin:kotlin-stdlib-jdk8:$kotlin_version"
}
build.gradle (AppProject)
buildscript {
ext.kotlin_version = '1.3.11'
repositories {
google()
jcenter()
}
dependencies {
classpath 'com.android.tools.build:gradle:3.2.1'
classpath "org.jetbrains.kotlin:kotlin-gradle-plugin:$kotlin_version"
// NOTE: Do not place your application dependencies here; they belong
// in the individual module build.gradle files
}
}
build.gradle (app)
implementation "org.jetbrains.kotlin:kotlin-stdlib-jdk8:$kotlin_version"

Inject UnitTest classes

Hello I have the following problem using Dagger 2 in my (part) project being completely pure-Java with no android dependencies.
When I run the unit tests using some mocks (e.g. Injecting a Mock Network Connector returning static Strings) over the Gradle view or console (businessModule:test) there are no problems and all tests Succeed. But when I open the files in Android Studio the Studio says that the Return of my DaggerMockComponent is not compatible with the target type. Opening the generated Component-Implementation, I see that Android Studio thinks the TestUnit-Class (and the interface MockComponent) is not available so it does not know what the inject method returns.
I have the following gradle file:
apply plugin: 'java'
// allow inject of core into core. https://github.com/griffio/dagger2-example
sourceSets {
dagger {
java {
srcDirs = ['src/dagger/java']
}
}
daggerTest {
java {
srcDirs = ['src/daggerTest/java']
}
}
}
configurations {
compileDagger
}
compileJava {
description = "dagger annotation processor is loaded automatically from classpath"
sourceSets.dagger.java.srcDirs*.mkdirs()
classpath += configurations.compileDagger
options.compilerArgs += [
'-s', sourceSets.dagger.java.srcDirs.iterator().next()
]
}
compileTestJava {
//dependsOn compileDaggerTestJava
description = "dagger annotation processor is loaded automatically from classpath"
sourceSets.daggerTest.java.srcDirs*.mkdirs()
classpath += configurations.compileDagger
options.compilerArgs += [
'-s', sourceSets.daggerTest.java.srcDirs.iterator().next()
//'-s src/testDaggerJava'
]
}
task deleteDagger(type: Delete) {
delete 'src/dagger', 'src/daggerTest'
}
clean.dependsOn deleteDagger
dependencies {
compile fileTree(dir: 'libs', include: ['*.jar'])
// Force Java 7 as newer versions can not be processed by dex for API 21
targetCompatibility = '1.7'
sourceCompatibility = '1.7'
[...]
// Dagger for dependency injection
compile 'com.google.dagger:dagger:2.8'
testCompile 'com.google.dagger:dagger:2.8'
compileOnly 'com.google.dagger:dagger-compiler:2.8'
testCompileOnly 'com.google.dagger:dagger-compiler:2.8'
[...]
testCompile 'junit:junit:4.12'
}
Thanks for your help.
Ok everybody, after an additional night and some research on the android-apt plugin I stumbled over the pure-Java apt (net.ltgt.apt) and now I have a working solution in combination with the idea-plugin
apply plugin: 'java'
apply plugin: "net.ltgt.apt"
apply plugin: "idea"
task cleanGenerated(type: Delete) {
delete 'build'
}
clean.dependsOn cleanGenerated
dependencies {
compile fileTree(dir: 'libs', include: ['*.jar'])
// Force Java 7 as newer versions can not be processed by dex for API 21
targetCompatibility = '1.7'
sourceCompatibility = '1.7'
[...]
// Dagger for dependency injection
compile 'com.google.dagger:dagger:2.8'
apt 'com.google.dagger:dagger-compiler:2.8'
testCompile 'com.google.dagger:dagger:2.8'
testApt 'com.google.dagger:dagger-compiler:2.8'
[...]
testCompile 'junit:junit:4.12'
}
Of course you have to add the dependency and plugin-name in the root gradle file but that is written down in the documentation for net.ltgt.apt - hope this works for you, too.

How to insert a new dependency into a Gradle project?

I am very new to Gradle (I always have used Maven in the past.
I have to add this dependence to an Android project: https://github.com/nostra13/Android-Universal-Image-Loader/wiki/Quick-Setup
So, reading into the library documentation it only say that using Gradle I have to add this dependency:
https://github.com/nostra13/Android-Universal-Image-Loader/wiki/Quick-Setup
My problem is that, into my project, I have 2 differents build.gradle files:
1) build.gradle refered to the project:
// Top-level build file where you can add configuration options common to all sub-projects/modules.
buildscript {
repositories {
jcenter()
}
dependencies {
classpath 'com.android.tools.build:gradle:1.5.0'
// NOTE: Do not place your application dependencies here; they belong
// in the individual module build.gradle files
}
}
allprojects {
repositories {
jcenter()
}
}
task clean(type: Delete) {
delete rootProject.buildDir
}
2) build.gradle refered to Module app
apply plugin: 'com.android.application'
android {
compileSdkVersion 23
buildToolsVersion "23.0.1"
defaultConfig {
applicationId "com.example.android.pastafromrome"
minSdkVersion 15
targetSdkVersion 23
versionCode 1
versionName "1.0"
}
buildTypes {
release {
minifyEnabled false
proguardFiles getDefaultProguardFile('proguard-android.txt'), 'proguard-rules.pro'
}
}
}
dependencies {
compile fileTree(dir: 'libs', include: ['*.jar'])
testCompile 'junit:junit:4.12'
compile 'com.android.support:appcompat-v7:23.1.1'
}
What are the difference between these 2 files? Where exacctly I have to put the previous new dependency?
app\build.gradle or referred to Module app is specific for app module. As in Android Studio one can more than one module for a project. For example, an app module that you have now, you can add a watch module for your project that will have the work related to your smart watch, like watch faces etc.
build.gradle is a "Top-level build file" where you can add configuration options common to all modules.
You should add the dependencies to your required module. For example, as now you are adding UIL to your project which is directly related to your app module. So you should add it your app module in the dependencies part or function ( I honestly don't know what this is called, if someone can guide me on this I'll be grateful). So you dependencies part should look like this
dependencies {
compile fileTree(dir: 'libs', include: ['*.jar'])
testCompile 'junit:junit:4.12'
compile 'com.android.support:appcompat-v7:23.1.1'
compile 'com.nostra13.universalimageloader:universal-image-loader:1.9.5'
}
You need to put dependency in Module level build.gradle file in dependencies section
compile 'com.nostra13.universalimageloader:universal-image-loader:1.9.5'
Each project contains one top-level Gradle build file. This file is named build.gradle and can be found in the top level directory.
This file usually contains common config for all modules, common functions..
All modules have a specific build.gradle file. This file contains all info about this module (because a project can contain more modules), as config,build tyoes, info for signing your apk, dependencies
Any new dependency that you want to add to your application or module should go under build.gradle(Module app) and to add the dependency just write the compile statement that is given on the github page..
compile 'com.nostra13.universalimageloader:universal-image-loader:1.9.5'
So, final code should be like..
dependencies {
compile fileTree(dir: 'libs', include: ['*.jar'])
testCompile 'junit:junit:4.12'
compile 'com.android.support:appcompat-v7:23.1.1'
compile 'com.nostra13.universalimageloader:universal-image-loader:1.9.5'
}

Gradle - download dependencies, lock versions and update dependencies manually

The issue.
Gradle dependency management made so:
there is no easy way to check availability of dependencies updates (only using some third-party plugins like ben-manes/gradle-versions-plugin) and download updates replacing old versions;
dependencies artifacts are downloaded from remote repositories and then stored in gradle cache and reused in succeeding builds; but successful compilation of your project must not depend on having a connection to Internet, availability of remote repositories and existence of specific versions of dependencies in these repositories.
The goal.
download and store all dependencies artifacts in VCS;
manually check updates for these dependencies and download them.
My solution works for Gradle configuration using java or android plugins.
java plugin defines compile and testCompile configurations.
compile is for dependencies that are required to compile the production source of the project. testCompile is for dependencies that are required to compile the test source of the project.
Let's define our own configurations in build.gradle:
configurations {
download
testDownload
}
Next let's create directories:
libs/compile/downloaded is where download dependencies will be stored;
libs/testCompile/downloaded is where testDownload dependencies will be stored.
Next we define several tasks.
Delete dependencies from download configuration:
task cleanDownloadedDependencies(type: Delete) {
delete fileTree('libs/compile/downloaded')
}
Delete dependencies from testDownload configuration:
task cleanDownloadedTestDependencies(type: Delete) {
delete fileTree('libs/testCompile/downloaded')
}
Download dependencies from download configuration:
task downloadDependencies(type: Copy) {
from configurations.download
into "libs/compile/downloaded/"
}
Download dependencies from testDownload configuration:
task downloadTestDependencies(type: Copy) {
from configurations.testDownload
into "libs/testCompile/downloaded/"
}
Execute all above tasks to update dependencies:
task updateDependencies {
dependsOn cleanDownloadedDependencies, cleanDownloadedTestDependencies, downloadDependencies, downloadTestDependencies
}
Next we define our dependencies:
dependencies {
download(
'com.google.code.gson:gson:+',
'joda-time:joda-time:+',
)
testDownload(
'junit:junit:+'
)
And then we tell where compile and testCompile configurations should take dependencies used for compilation.
compile fileTree(dir: 'libs/compile', include: '**/*.jar')
testCompile fileTree(dir: 'libs/testCompile', include: '**/*.jar')
}
Now you can download or update already downloaded dependencies:
./gradlew updateDependencies
If you are using android plugin then you can also add androidTestDownload configuration for dependencies that are required for compilation and running tests on Android device. Also some dependencies can be provided as aar artifacts.
This is the example for Gradle configuration using android plugin:
...
repositories {
...
flatDir {
dirs 'libs/compile', 'libs/compile/downloaded',
'libs/testCompile', 'libs/testCompileDownloaded',
'libs/androidTestCompile', 'libs/androidTestCompile/downloaded'
}
}
configurations {
download
testDownload
androidTestDownload
}
android {
...
}
dependencies {
download(
'com.android.support:support-v4:+',
'com.android.support:appcompat-v7:+',
'com.google.android.gms:play-services-location:+',
'com.facebook.android:facebook-android-sdk:+',
'com.vk:androidsdk:+',
'com.crashlytics.sdk.android:crashlytics:+',
'oauth.signpost:signpost-core:+',
'oauth.signpost:signpost-commonshttp4:+',
'org.twitter4j:twitter4j-core:+',
'commons-io:commons-io:+',
'com.google.code.gson:gson:+',
'org.jdeferred:jdeferred-android-aar:+'
)
compile fileTree(dir: 'libs/compile', include: '**/*.jar')
testCompile fileTree(dir: 'libs/testCompile', include: '**/*.jar')
androidTestCompile fileTree(dir: 'libs/androidTestCompile', include: '**/*.jar')
}
task cleanDownloadedDependencies(type: Delete) {
delete fileTree('libs/compile/downloaded')
}
task cleanDownloadedTestDependencies(type: Delete) {
delete fileTree('libs/testCompile/downloaded')
}
task cleanDownloadedAndroidTestDependencies(type: Delete) {
delete fileTree('libs/androidTestCompile/downloaded')
}
task downloadDependencies(type: Copy) {
from configurations.download
into 'libs/compile/downloaded/'
}
task downloadTestDependencies(type: Copy) {
from configurations.testDownload
into 'libs/testCompile/downloaded/'
}
task downloadAndroidTestDependencies(type: Copy) {
from configurations.androidTestDownload
into 'libs/androidTestCompile/downloaded/'
}
task updateDependencies {
dependsOn cleanDownloadedDependencies, cleanDownloadedTestDependencies, cleanDownloadedAndroidTestDependencies, downloadDependencies, downloadTestDependencies, downloadAndroidTestDependencies
}
fileTree(dir: 'libs/compile', include: '**/*.aar')
.each { File file ->
dependencies.add("compile",
[name: file.name.lastIndexOf('.').with { it != -1 ? file.name[0..<it] : file.name }, ext: 'aar'])
}
fileTree(dir: 'libs/testCompile', include: '**/*.aar')
.each { File file ->
dependencies.add("testCompile",
[name: file.name.lastIndexOf('.').with { it != -1 ? file.name[0..<it] : file.name }, ext: 'aar'])
}
fileTree(dir: 'libs/androidTestCompile', include: '**/*.aar')
.each { File file ->
dependencies.add("androidTestCompile",
[name: file.name.lastIndexOf('.').with { it != -1 ? file.name[0..<it] : file.name }, ext: 'aar'])
}
For locking versions of downloaded dependencies (library/ etc versions to hard-coded versions) for making the builds reproducible, now Gradle 4.8 and onwards, we'll have inbuilt "dependency lock" support. This will help greatly to make builds reproducible if someone is using dynamic versions (M.m.p/i) Major.minor.patch/interimBranch etc (ex: 4.+ or 3.1.+) or version range for pulling artifacts from a binary repository tool (ex: Artifactory / Nexus).
Any Gradle user who is using Gradle version 4.8+ should start using this new feature.
https://docs.gradle.org/4.8/userguide/dependency_locking.html
For Gradle 4.8 Release Notes: https://docs.gradle.org/4.8/release-notes.html
In past, this dependency lock feature was provided to Gradle community and made available via a FOSS plugin available to Gradle from Netflix Nebula's https://github.com/nebula-plugins/gradle-dependency-lock-plugin and https://plugins.gradle.org/plugin/nebula.dependency-lock

How To Include Transitive Dependencies

I have 2 gradle projects: an Android app and a RoboSpock test.
My build.gradle for the Android app has
. . .
dependencies {
compile fileTree(dir: 'libs', include: '*.jar')
compile ('com.actionbarsherlock:actionbarsherlock:4.4.0#aar') {
exclude module: 'support-v4'
}
}
. . .
and builds correctly by itself, e.g assembleRelease works.
I'm stuck getting the test to work. I gets lots of errors such as:
package com.google.zxing does not exist
Those seem to indicate that the .jar files aren't being picked up.
Here's my build.gradle for the test project:
buildscript {
repositories {
mavenLocal()
mavenCentral()
}
dependencies {
classpath 'com.android.tools.build:gradle:0.9.+'
classpath 'org.robospock:robospock-plugin:0.4.0'
}
}
repositories {
mavenLocal()
mavenCentral()
}
apply plugin: 'groovy'
dependencies {
compile "org.codehaus.groovy:groovy-all:1.8.6"
compile 'org.robospock:robospock:0.4.4'
}
dependencies {
compile fileTree(dir: ':android:libs', include: '*.jar')
compile (project(':estanteApp')) {
transitive = true
}
}
sourceSets.test.java.srcDirs = ['../android/src/', '../android/build/source/r/debug']
test {
testLogging {
lifecycle {
exceptionFormat "full"
}
}
}
project.ext {
robospock = ":estanteApp" // project to test
}
apply plugin: 'robospock'
As that shows, I've tried adding transitive = true and including the .jar files explicitly. But no matter what I try, I end up with the package does not exist error.
In Android Studio you no longer need a different project for testing. Put your testing code in the same module under "src/androidTest/java"
Then add the following to "build.gradle" in the "defaultConfig"
testPackageName "com.yourpackage.test"
testInstrumentationRunner "android.test.InstrumentationTestRunner"
testFunctionalTest true

Categories

Resources