Java only project not adding dependecies on Android Studio - java

I am using Android Studio 0.8.2 and in my project I have one Android module and one Java only module.
The java only module depends on a external library. I have tried adding it in the libs dir of the project:
dependencies {
compile fileTree(dir: 'libs', include: ['*.jar'])
}
And using maven repositories:
repositories {
mavenCentral()
}
dependencies {
compile 'net.sf.kxml:kxml2:2.3.0+'
}
Both systems allows compilation but the library is not included on final jar. I have unzipped the jar and the classes are not there!
Exception in thread "main" java.lang.NoClassDefFoundError: org/xmlpull/v1/XmlPullParserException
A Gradle sync shows this warning message:
"A top-level `dependencies` block should only appear in build files that correspond to a module"
Any idea? Thanks advanced.

Looks like you are not declaring dependencies in build.gradle in app folder, but in the main roof of project? Am I right? You should compare declaring dependencies with other projects like hmm on github. Example: https://github.com/loopj/android-async-http/blob/master/sample/build.gradle (this is build.gradle file in module project, if you go up to root, in build.gradle file there is not declaring not connected to gradle depenncies). Read carefuly the comments and warnings.

Related

How to put local dependencies first when calling gradle idea?

When calling gradle idea, external dependencies are ordered first in the class path relatively to local Jar inclusions. As such :
dependencies {
compile fileTree(dir: 'libs', include:['*.jar'])
compile group: 'foo', name:'bar', version:'1.0.0'
}
will include my local jars last. This is a problem in my project as these jars' purpose is to partially overwrite the external library.
The same behavior is observed when specifying the repository as a source of dependencies using flatDir and loading the jar without fileTree. It is put last in the classpath.
I have found several mentions of the problem when researching, such as https://discuss.gradle.org/t/gradle-messes-up-the-classpath-order-in-generated-projects-when-there-are-mixed-dependency-types/13130, but no workarounds.
I suppose these exist, gradle being very customisable, but being very new to it my attempts to make one fail. How to proceed?
I'm not using IntelliJ on a regular basis but tried it in the context of this question and my impression is that gradle's idea plugin and IntelliJ's gradle plugin don't go well together. That is you should either use the idea gradle plugin and import as plain Java project or import as gradle project using IntelliJ's gradle plugin. Main reason is that the idea plugin and the IntelliJ plugin are generating slightly different iml-files (those files are holding the project dependencies - amongst others) which leads to lot of confusion when using both plugins together. As you specifically asked for the gradle idea plugin, I used this plugin and imported into IntelliJ as plain java project.
But to answer your question I found no evidence that the order of libraries on the classpath differs from the order as declared in the dependencies section of the gradle file, when using a flatDir repo. When using compile fileTree(dir: 'libs', include:['*.jar']) the order was actually broken as described in your question. That is, you should stick to using a flatDir repo.
I'm using gradle 4.9 and IntelliJ 2018.2.
This is my gradle file
apply plugin: 'java'
apply plugin: 'idea'
repositories {
jcenter()
flatDir {
dirs 'libs'
}
}
dependencies {
compile 'zzz:zzz-0.0.0'
compile 'aaa:aaa-0.0.0'
compile 'com.google.guava:guava:24.0-jre'
compile group: 'javax.websocket', name: 'javax.websocket-api', version: '1.1'
}
task wrapper(type: Wrapper) {
gradleVersion = '4.9'
distributionUrl = "http://services.gradle.org/distributions/gradle-${gradleVersion}-bin.zip"
}
In my libs folder there are two jars aaa-0.0.0.jar and zzz-0.0.0.jar both are copies of guava-24.0-jre.jar. That is all guava classes are present in both jars as well. As zzz:zzz-0.0.0 is the first dependency in the gradle file, the expectation would be that guava classes are being loaded from zzz-0.0.0.jar instead of guava-24.0-jre.jar or aaa-0.0.0.jar. I used the following main class to test this:
package test;
import com.google.common.math.LongMath;
public class Test {
public static void main(String[] args) throws Exception {
System.out.println(LongMath.class.getProtectionDomain().getCodeSource().getLocation().toURI());
}
}
And the output when running it from IntelliJ is
file:/C:/ws/gradle-idea-test/libs/zzz-0.0.0.jar
That is the com.google.common.math.LongMath class is indeed being loaded from the local libs/zzz-0.0.0.jar instead of the guava-24.0-jre.jar.
I noticed that the list of external dependencies in IntelliJ doesn't show the local libraries. And even more confusing the libraries are ordered alphabetically and don't reflect the actual order on the classpath which might be quite confusing:
To get the actual order of elements on the classpath you will have to look in the module dependencies section in the module settings ("Open Module Settings" > "Project" > "Modules" > "Dependencies Tab") which looks like this:
As you can see the dependencies are listed in correct order and include the local libraries as well. The order of libs in this dialog is basically the same as in the generated iml-file.
When using the IntelliJ gradle plugin instead of gradle's idea plugin, IntelliJ basically behaved the same way but the generated iml-file looked different and the external libraries were displayed in a different format. But there was no difference regarding the classpath order.

How to recursively add a list of Jars to your classpath in gradle with groovy script [duplicate]

I have tried to add my local .jar file dependency to my build.gradle file:
apply plugin: 'java'
sourceSets {
main {
java {
srcDir 'src/model'
}
}
}
dependencies {
runtime files('libs/mnist-tools.jar', 'libs/gson-2.2.4.jar')
runtime fileTree(dir: 'libs', include: '*.jar')
}
And you can see that I added the .jar files into the referencedLibraries folder here: https://github.com/WalnutiQ/wAlnut/tree/version-2.3.1/referencedLibraries
But the problem is that when I run the command: gradle build on the command line I get the following error:
error: package com.google.gson does not exist
import com.google.gson.Gson;
Here is my entire repo: https://github.com/WalnutiQ/wAlnut/tree/version-2.3.1
According to the documentation, use a relative path for a local jar dependency as follows.
Groovy syntax:
dependencies {
implementation files('libs/something_local.jar')
}
Kotlin syntax:
dependencies {
implementation(files("libs/something_local.jar"))
}
If you really need to take that .jar from a local directory,
Add next to your module gradle (Not the app gradle file):
repositories {
flatDir {
dirs("libs")
}
}
dependencies {
implementation("gson-2.2.4")
}
However, being a standard .jar in an actual maven repository, why don't you try this?
repositories {
mavenCentral()
}
dependencies {
implementation("com.google.code.gson:gson:2.2.4")
}
You could also do this which would include all JARs in the local repository. This way you wouldn't have to specify it every time.
dependencies {
compile fileTree(dir: 'libs', include: ['*.jar'])
}
The following works for me:
compile fileTree(dir: 'libs', include: '*.jar')
Refer to the Gradle Documentation.
You can try reusing your local Maven repository for Gradle:
Install the jar into your local Maven repository:
mvn install:install-file -Dfile=utility.jar -DgroupId=com.company -DartifactId=utility -Dversion=0.0.1 -Dpackaging=jar
Check that you have the jar installed into your ~/.m2/ local Maven repository
Enable your local Maven repository in your build.gradle file:
repositories {
mavenCentral()
mavenLocal()
}
dependencies {
implementation ("com.company:utility:0.0.1")
}
Now you should have the jar enabled for implementation in your project
A solution for those using Kotlin DSL
The solutions added so far are great for the OP, but can't be used with Kotlin DSL without first translating them. Here's an example of how I added a local .JAR to my build using Kotlin DSL:
dependencies {
compile(files("/path/to/file.jar"))
testCompile(files("/path/to/file.jar"))
testCompile("junit", "junit", "4.12")
}
Remember that if you're using Windows, your backslashes will have to be escaped:
...
compile(files("C:\\path\\to\\file.jar"))
...
And also remember that quotation marks have to be double quotes, not single quotes.
Edit for 2020:
Gradle updates have deprecated compile and testCompile in favor of implementation and testImplementation. So the above dependency block would look like this for current Gradle versions:
dependencies {
implementation(files("/path/to/file.jar"))
testImplementation(files("/path/to/file.jar"))
testImplementation("junit", "junit", "4.12")
}
The accepted answer is good, however, I would have needed various library configurations within my multi-project Gradle build to use the same 3rd-party Java library.
Adding '$rootProject.projectDir' to the 'dir' path element within my 'allprojects' closure meant each sub-project referenced the same 'libs' directory, and not a version local to that sub-project:
//gradle.build snippet
allprojects {
...
repositories {
//All sub-projects will now refer to the same 'libs' directory
flatDir {
dirs "$rootProject.projectDir/libs"
}
mavenCentral()
}
...
}
EDIT by Quizzie: changed "${rootProject.projectDir}" to "$rootProject.projectDir" (works in the newest Gradle version).
Shorter version:
dependencies {
implementation fileTree('lib')
}
The Question already has been answered in detail. I still want to add something that seems very surprising to me:
The "gradle dependencies" task does not list any file dependencies. Even though you might think so, as they have been specified in the "dependencies" block after all..
So don't rely on the output of this to check whether your referenced local lib files are working correctly.
A simple way to do this is
compile fileTree(include: ['*.jar'], dir: 'libs')
it will compile all the .jar files in your libs directory in App.
Some more ways to add local library files using Kotlin DSL (build.gradle.kts):
implementation(
files(
"libs/library-1.jar",
"libs/library-2.jar",
"$rootDir/foo/my-other-library.jar"
)
)
implementation(
fileTree("libs/") {
// You can add as many include or exclude calls as you want
include("*.jar")
include("another-library.aar") // Some Android libraries are in AAR format
exclude("bad-library.jar")
}
)
implementation(
fileTree(
"dir" to "libs/",
// Here, instead of repeating include or exclude, assign a list of paths
"include" to "*.jar",
"exclude" to listOf("bad-library-1.jar", "bad-library-2.jar")
)
)
The above code assumes that the library files are in libs/ directory of the module (by module I mean the directory where this build.gradle.kts is located).
You can use Ant patterns in includes and excludes as shown above.
See Gradle documentations for more information about file dependencies.
Thanks to this post for providing a helpful answer.
I couldn't get the suggestion above at https://stackoverflow.com/a/20956456/1019307 to work. This worked for me though. For a file secondstring-20030401.jar that I stored in a libs/ directory in the root of the project:
repositories {
mavenCentral()
// Not everything is available in a Maven/Gradle repository. Use a local 'libs/' directory for these.
flatDir {
dirs 'libs'
}
}
...
compile name: 'secondstring-20030401'
The best way to do it is to add this in your build.gradle file and hit the sync option
dependency{
compile files('path.jar')
}
The solution which worked for me is the usage of fileTree in build.gradle file.
Keep the .jar which need to add as dependency in libs folder. The give the below code in dependenices block in build.gradle:
dependencies {
compile fileTree(dir: 'libs', include: ['*.jar'])
}
You can add jar doing:
For gradle just put following code in build.gradle:
dependencies {
...
compile fileTree(dir: 'lib', includes: ['suitetalk-*0.jar'])
...
}
and for maven just follow steps:
For Intellij:
File->project structure->modules->dependency tab-> click on + sign-> jar and dependency->select jars you want to import-> ok-> apply(if visible)->ok
Remember that if you got any java.lang.NoClassDefFoundError: Could not initialize class exception at runtime this means that dependencies in jar not installed for that you have to add all dependecies in parent project.
For Gradle version 7.4 with Groovy build file
repositories {
flatDir {
dirs 'libs'
}
}
dependencies {
implementation ':gson-2.2.4'
}
If you are on gradle 4.10 or newer:
implementation fileTree(dir: 'libs', includes: ['*.jar'])
Goto File -> Project Structure -> Modules -> app -> Dependencies Tab -> Click on +(button) -> Select File Dependency - > Select jar file in the lib folder
This steps will automatically add your dependency to gralde
Very Simple
Be careful if you are using continuous integration, you must add your libraries in the same path on your build server.
For this reason, I'd rather add jar to the local repository and, of course, do the same on the build server.
An other way:
Add library in the tree view. Right click on this one. Select menu "Add As Library".
A dialog appear, let you select module. OK and it's done.

How to add classpath in an Android Studio project

I have an Android project with an Android application that depends on a pure Java library (and the Java library uses some others compiled jars libraries). I added the dependencies, I can build the project, but at run time I have a ClassNotFoundException error.I had to add to theCLASSPATHenvironment variable the path to the jars.Is there a way to set the classpath locally for the project only, like using the command line option
java –classpath <path to the jars>
in the Android studio Run/Debug Configurations?
First off all, be sure there's a "libs" subfolder in the "app" folder of your project. If there's not, create one.
Next, in the app/build.gradle file, add this line of code:
dependencies {
...
compile fileTree(dir:'libs', include: ['*.jar'])
...
}
Place all of your .jar files in the "libs" folder, and voila, you're done
Thanks to Arnold Layne, I created a folder named libs.
Then, I went to
Files -> Project Structure (new menu opens) -> Modules (on the left) -> app -> Dependencies
There, I could add the library with the + Button.
This created this entry:
dependencies {
implementation files('libs/commons-lang3-3.7.jar')
}
Add this lines to build.gradle of app module.
dependencies {
...
implementation fileTree(dir: 'libs', include: ['*.jar'])
implementation files('libs/mysql-connector-java-8.0.16')
...
}

Android studio library project dependencies

I have imported an Android Studio project as a library for another of my projects. My original question for that is here. It worked excellently for a while, until today. Today I finished updating my library (in its own project) and copied the new files over. I edited the settings.gradle and build.gradle files as I did before but I am getting the error:
Project with path 'Eed:libraries:Overt:Util' could not be found in project ':CES'.
The library's original project is structured like this:
Overt/
+ Visible/
+ Control/
+ CES/
+ Util/
In that project, CES is dependent upon Util
dependencies {
compile 'com.android.support:appcompat-v7:19.+'
compile fileTree(dir: 'libs', include: ['*.jar'])
compile project(':Util')
}
When I copied the new version of Overt over I modified the project level settings.gradle and module level build.gradle.
Structure:
Eed/
Eed/
libraries/
Overt/
+ Visible/
+ Control/
+ CES/
+ Util/
settings.gradle
include ':Eed'
include ':Eed:libraries:Overt:Visible'
include ':Eed:libraries:Overt:Control'
include ':Eed:libraries:Overt:Util'
include ':Eed:libraries:Overt:CES'
and build.gradle (Eed module)
dependencies {
compile 'com.android.support:appcompat-v7:+'
compile fileTree(dir: 'libs', include: ['*.jar'])
compile project('libraries:Overt:Visible')
compile project('libraries:Overt:Control')
compile project('libraries:Overt:Util')
compile project('libraries:Overt:CES')
}
I have played with modifying the build.gradle in CES but cannot figure out a solution. What am I doing wrong?
If your CES project still has this dependency, then it looks fishy:
compile project(':Util')
It works best if your dependency statements use the same paths as what appears in settings.gradle, to wit:
compile project(':Eed:libraries:Overt:Util')
I don't know if you can build up a relative Gradle project path to refer to a sibling project at the same level as the referring project. What I mean is that CES and Util are both at the same level, :Eed:libraries:Overt:, what what you really want is something like what you can do in a filesystem path with ../Util, but I don't know offhand if that's possible in Gradle.
It could be that if you're expecting your complex module to be able to be imported somewhere and still maintain its module relationships with relative paths, you may be asking a lot. Having said that, if it's a firm requirement, then you can look into remapping directories in settings.gradle via projectDir. See Gradle subproject name different than folder name for a hint on how to get started with that if you want to go that route.

Add library to gradle build

I'm trying to add org.apache.commons.lang3 to my build. I've downloaded the library which is directory containing jar files.
My group is using gradle to build the project, and I know just enough to maybe ask the right question. So what I think the build is doing is
copying a bunch of .bnds to the build directory
compiles the java we have in src/main/java (via source sourceSets.main.java.srcDirs?)
I would like to add the lang3 library, but I'm not sure how to go about doing that. Can I just dump it into src/main/java? Or do I have to tell gradle about it?
This is what I think is relevant from the current build.gradle
ext.releaseDir = "${buildDir}/release/${tpVersion.getProgramName()}"
ext.bundlesDir = "${releaseDir}/nucleus/bin/nucleus_java/bundles/"
dependencies {
compile fileTree(dir: bundlesDir, include: '*.jar')
bnd {
source sourceSets.main.java.srcDirs
include '**/*.bnd'
You could declare it as a dependency, if it exists in any remote repository. That's the way I would do it.
But if you want to use the local file, do not put it in src/main. Use an extra folder called lib or similar on the same directory level as src or you build script.
Then you can add the local dependency to the build.gradle as in this sample:
repositories {
//central maven repo
mavenCentral()
}
dependencies {
//local file
compile files('libs/toxiclibscore.jar')
//dependencies from a remote repository
compile 'java3d:vecmath:1.3.1', 'commons-lang:commons-lang:2.6'
}
The simplest way is to use maven repository for accessing dependencies.
You can also access this jar directly from filesystem with file dependencies.
dependencies {
compile files('libs/a.jar', 'libs/b.jar')
compile fileTree(dir: 'libs', include: '*.jar')
}

Categories