With gradle how to get the dependency tree of a library? - java

Say I want to retrieve with graddle the dependancy tree of this artifact : com.google.firebase:firebase-firestore:24.4.0
How can I do ?

You can't do that, An aar does not contain any dependency information by itself.
All the information of this aar is stored in pom.xml which can be found here over google maven repo.
And this will only show you what Gradle dependencies command will do, and those are the transitive dependencies meaning the direct dependencies for this aar, Which By default, Gradle resolves them automatically.
the pom.xml for com.google.firebase:firebase-firestore:24.4.0
<?xml version='1.0' encoding='UTF-8'?>
<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
<modelVersion>4.0.0</modelVersion>
<groupId>com.google.firebase</groupId>
<artifactId>firebase-firestore</artifactId>
<version>24.4.0</version>
<packaging>aar</packaging>
<dependencies>
<dependency>
<groupId>androidx.annotation</groupId>
<artifactId>annotation</artifactId>
<version>1.1.0</version>
<scope>compile</scope>
<type>jar</type>
</dependency>
<dependency>
<groupId>com.google.android.gms</groupId>
<artifactId>play-services-base</artifactId>
<version>18.0.1</version>
<scope>compile</scope>
<type>aar</type>
</dependency>
</dependencies>
<name>firebase-firestore</name>
<licenses>
<license>
<name>The Apache Software License, Version 2.0</name>
<url>http://www.apache.org/licenses/LICENSE-2.0.txt</url>
<distribution>repo</distribution>
</license>
</licenses>
</project>
This pom.xml include com.google.android.gms which has its own pom.xml
<?xml version='1.0' encoding='UTF-8'?>
<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
<modelVersion>4.0.0</modelVersion>
<groupId>com.google.android.gms</groupId>
<artifactId>play-services-basement</artifactId>
<version>18.1.0</version>
<packaging>aar</packaging>
<dependencies>
<dependency>
<groupId>androidx.collection</groupId>
<artifactId>collection</artifactId>
<version>1.0.0</version>
<scope>compile</scope>
<type>jar</type>
</dependency>
<dependency>
<groupId>androidx.core</groupId>
<artifactId>core</artifactId>
<version>1.2.0</version>
<scope>compile</scope>
<type>aar</type>
</dependency>
<dependency>
<groupId>androidx.fragment</groupId>
<artifactId>fragment</artifactId>
<version>1.0.0</version>
<scope>compile</scope>
<type>aar</type>
</dependency>
</dependencies>
<name>play-services-basement</name>
<licenses>
<license>
<name>Android Software Development Kit License</name>
<url>https://developer.android.com/studio/terms.html</url>
<distribution>repo</distribution>
</license>
</licenses>
</project>
What I am trying to say, Is that unless you iterate the process and fetch the POM files of the dependencies yourself, with a custom task, All you can use is gradle dependencies command to check the transitive dependencies used by your project or module.
UPDATE:
You can easily start a new gradle project by following these simple steps.
mkdir gradleExp
cd gradleExp
gradle init # 1.basic 1.groovy random name
update the empty build.gradle with the following
plugins {
id 'java'
}
repositories {
google()
mavenCentral()
}
dependencies {
implementation "com.google.firebase:firebase-firestore:24.4.0"
}
gradle dependencies # to list all
gradle dependencies --configuration compileClasspath # reduce output to show only Compile classpath for source set 'main'
NOTE: missing either google() or mavenCentral() will show some failure in the result shown.

If it is a dependency of your project you should be able to run
gradle dependencies
and see the dependency tree for your whole project (including the subtree for this artifact)
There are more details in the answer(s) to this question:
Using Gradle to find dependency tree

Related

Basic maven question: Does maven transitively install dependencies?

I've looked here https://blog.packagecloud.io/eng/2017/03/09/how-does-a-maven-repository-work/ and that does seem to be the case.
However, I tried to experiment with mvn install and I'm not sure if it's worked as expected. Here's what I did
(1) I created a lib.
(2) Ran mvn install from the command line
(3) Copied the path of my newly created jar
(4) Opened a new maven project, stuck the path into my pom.xml
I'm able to reuse my library methods, BUT: one of my library methods returns a TransportClient which is part of the elasticsearch api. Using intellij inside my new project, it seems like I don't have elasticsearch even though I'm referencing the jar.
Is this expected? I was expecting it to have transitively installed elasticsearch when it referenced my jar.
I'd love a pointer or two in the right direction, I'm completely new to this. :)
My pom.xml for the lib that uses elasticsearch as dependency.
<?xml version="1.0" encoding="UTF-8"?>
<project xmlns="http://maven.apache.org/POM/4.0.0"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
<modelVersion>4.0.0</modelVersion>
<properties>
<maven.compiler.source>1.8</maven.compiler.source>
<maven.compiler.target>1.8</maven.compiler.target>
</properties>
<groupId>estutorial</groupId>
<artifactId>estutorial</artifactId>
<version>1.0-SNAPSHOT</version>
<dependencies>
<!-- https://mvnrepository.com/artifact/org.projectlombok/lombok -->
<dependency>
<groupId>org.projectlombok</groupId>
<artifactId>lombok</artifactId>
<version>1.18.2</version>
<scope>provided</scope>
</dependency>
<dependency>
<groupId>org.elasticsearch.client</groupId>
<artifactId>elasticsearch-rest-high-level-client</artifactId>
<version>6.4.2</version>
</dependency>
<dependency>
<groupId>org.elasticsearch.client</groupId>
<artifactId>transport</artifactId>
<version>6.4.2</version>
</dependency>
<!-- https://mvnrepository.com/artifact/org.apache.logging.log4j/log4j-core -->
<dependency>
<groupId>org.apache.logging.log4j</groupId>
<artifactId>log4j-core</artifactId>
<version>2.11.1</version>
</dependency>
</dependencies>
</project>
My pom.xml for the new maven project that tries to reference the lib for the above pom.xml:
<?xml version="1.0" encoding="UTF-8"?>
<project xmlns="http://maven.apache.org/POM/4.0.0"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
<modelVersion>4.0.0</modelVersion>
<properties>
<maven.compiler.target>1.8</maven.compiler.target>
<maven.compiler.source>1.8</maven.compiler.source>
</properties>
<groupId>sth</groupId>
<artifactId>sth</artifactId>
<version>1.0-SNAPSHOT</version>
<dependencies>
<dependency>
<!-- https://mvnrepository.com/artifact/org.projectlombok/lombok -->
<groupId>org.projectlombok</groupId>
<artifactId>lombok</artifactId>
<version>1.18.4</version>
<scope>provided</scope>
</dependency>
<dependency>
<groupId>estutorial</groupId>
<artifactId>estutorial</artifactId>
<version>1.0</version>
<scope>system</scope>
<systemPath>/home/dell/.m2/repository/estutorial/estutorial/1.0-SNAPSHOT/estutorial-1.0-SNAPSHOT.jar
</systemPath>
</dependency>
</dependencies>
</project>
So, if I understand your steps, your dependency declaration in your referencing application uses a direct classpath to the jar file in your local repository? If so, this is unusual. You shouldn't need to know direct file locations for any of your dependencies of a Maven project. What you should be doing.
In the referenced project (that which requires the Elasticsearch library), it's pom.xml file would defined the elasticsearch dependency itself. This should follow maven standards for dependency declaration (groupId, artifactId and artifactVerion). If you don't have the elasticsearch artifact, maven will attempt to find it and store it in your local repository. You shouldn't have to have any path in your pom.xml file.
When you install the referenced project, it will install into your local repostory both the JAR file and the pom.xml.
In the referencing project, you should define the dependency to your referenced artifact in it's pom file. Same format: groupId, artifactId and artifactVersion. You shouldn't need to provide a specific path. What maven will do is find your referenced jar, but also use the installed POM.xml file for the referenced jar to find the transitive dependencies and include them in your classpath.
From what you've described, your dependency declarations aren't correct. If you can provide your POM file more details can be provided. Otherwise, review the maven intro to dependencies.
No. mvn install is a nearly useless command. It stuffs a jar file into your local repository, for subsequent use by other maven builds. You use the term 'path'. If you run mvn install:install-file to put a jar into your local repo under some coordinates, you can reference those coordinates from another pom; but it will generally lead to future problems as compare to deploying the jar into a proper repository manager.

Include jars in pom.xml

So here is the scenario.
I have a maven project for which I am using some(7) jars for unit testing. All these jars are present on maven remote/local(.m2) repository. and I have to add them individually as dependency.
I want to create a pom (parent) which contain these jars as dependency so that if I include this pom(parent) as dependency, all 7 dependencies are automatically resolved.
I tried this code but i think there are some issues with packaging type. (pom packaging didn't work either).
<?xml version="1.0" encoding="UTF-8"?>
<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
<modelVersion>4.0.0</modelVersion>
<groupId>some.package</groupId>
<artifactId>full-PACK</artifactId>
<version>1.1</version>
<packaging>jar</packaging>
<dependencies>
<dependency>
<groupId>org.javassist</groupId>
<artifactId>javassist</artifactId>
<version>3.21.0</version>
<scope>test</scope>
</dependency>
<!-- 6 more similar dependencies -->
</dependencies>
</project>
I want this pom to just act as pointer, and this should resolve dependencies in their respective packages not in package of this pom. I don't want to create a fat jar for this pom.
Is there a way in which I can use this pom as kind of pointer so that it just tells project to import those 7 jars?
I have not tested it, but following the Maven logic, this should work:
Create a project with packaging pom that references the 7 jars as compile dependencies:
<?xml version="1.0" encoding="UTF-8"?>
<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
<modelVersion>4.0.0</modelVersion>
<groupId>some.package</groupId>
<artifactId>full-PACK</artifactId>
<version>1.1</version>
<packaging>pom</packaging>
<dependencies>
<dependency>
<groupId>org.javassist</groupId>
<artifactId>javassist</artifactId>
<version>3.21.0</version>
<scope>compile</scope>
</dependency>
<!-- 6 more similar dependencies -->
</dependencies>
</project>
Now declare a test dependency on this pom in your project like
<dependency>
<groupId>some.package</groupId>
<artifactId>full-PACK</artifactId>
<version>1.1</version>
<type>pom</type>
<scope>test</scope>
</dependency>
Your approach failed because test dependencies are not transitive. Have a look at the table on
https://maven.apache.org/guides/introduction/introduction-to-dependency-mechanism.html

Trying to use maven with android eclipse project not working?

This is the first time I've used maven, I am trying to integrate zopim sdk and I followed the tutorial and converted my project to a maven project and added the repository and dependencies, but now eclipse does not compile and gives me the following error :
Description Resource Path Location Type
Missing artifact com.android.support:appcompat-v7:jar:23.0.0 pom.xml /4SaleApp line 2 Maven Dependency Problem
Missing artifact com.android.support:design:jar:23.0.0 pom.xml /4SaleApp line 2 Maven Dependency Problem
Missing artifact com.android.support:recyclerview-v7:jar:23.0.0 pom.xml /4SaleApp line 2 Maven Dependency Problem
What should I do ?
EDIT
my pom.xml file
<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
<modelVersion>4.0.0</modelVersion>
<groupId>4SaleApp</groupId>
<artifactId>4SaleApp</artifactId>
<version>0.0.1-SNAPSHOT</version>
<packaging>pom</packaging>
<repositories>
<repository>
<id>chatsdk-repo</id>
<name>Chat SDK Repo</name>
<url>https://zendesk.artifactoryonline.com/zendesk/repo</url>
</repository>
</repositories>
<dependencies>
<dependency>
<groupId>com.zopim.android</groupId>
<artifactId>sdk</artifactId>
<version>1.1.0</version>
<type>aar</type>
</dependency>
</dependencies>
</project>
This seems like a conflicting issue when changing from Gradle to Maven. This questions provides a lot more info on the issue.
But it looks like you are missing the android support dependencies in the pom. Maybe try adding the missing support libraries to the pom. For example as shown here for appcompat-v7:
<dependency>
<groupId>android.support</groupId>
<artifactId>compatibility-v7-appcompat</artifactId>
<version>${compatibility.version}</version>
<type>apklib</type>
</dependency>
<dependency>
<groupId>android.support</groupId>
<artifactId>compatibility-v7-appcompat</artifactId>
<version>${compatibility.version}</version>
<type>jar</type>
</dependency>

Gradle search dependency in repository from maven pom.xml

I have an Android library dependency which I pull in from my own Maven repository (Artifactory based):
compile "com.jmolsmobile.mylibrary:mylibrary:1.0.4"
This dependency depends on another library, which is located in another Maven repository with a custom URL:
repositories {
maven { url 'https://mint.splunk.com/gradle/' }
}
What I want to do is to include my Android library in another project, without having to add the repository URL explicitly to my Gradle files, but rather have my project inherit the repository URL via the Maven pom.xml.
But Gradle does not search in the custom repository URL:
> Could not resolve all dependencies for configuration ':app:_debugCompile'.
> Could not find com.splunk.mint:mint:4.2.1.
Searched in the following locations:
https://jcenter.bintray.com/com/splunk/mint/mint/4.2.1/mint-4.2.1.pom
https://jcenter.bintray.com/com/splunk/mint/mint/4.2.1/mint-4.2.1.jar
http://10.0.190.250:8081/artifactory/android-snapshot-local/com/splunk/mint/mint/4.2.1/mint-4.2.1.pom
http://10.0.190.250:8081/artifactory/android-snapshot-local/com/splunk/mint/mint/4.2.1/mint-4.2.1.jar
file:/Applications/Android-SDK/extras/android/m2repository/com/splunk/mint/mint/4.2.1/mint-4.2.1.pom
file:/Applications/Android-SDK/extras/android/m2repository/com/splunk/mint/mint/4.2.1/mint-4.2.1.jar
file:/Applications/Android-SDK/extras/google/m2repository/com/splunk/mint/mint/4.2.1/mint-4.2.1.pom
file:/Applications/Android-SDK/extras/google/m2repository/com/splunk/mint/mint/4.2.1/mint-4.2.1.jar
Even though the repository is explicitly defined in my pom.xml:
<?xml version="1.0" encoding="UTF-8"?>
<project xmlns="http://maven.apache.org/POM/4.0.0"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
<modelVersion>4.0.0</modelVersion>
<groupId>com.jmolsmobile.mylibrary</groupId>
<artifactId>mylibrary</artifactId>
<version>1.0.4</version>
<packaging>aar</packaging>
<repositories>
<repository>
<id>splunk</id>
<url>https://mint.splunk.com/gradle/</url>
</repository>
</repositories>
<dependencies>
<dependency>
<groupId>com.splunk.mint</groupId>
<artifactId>mint</artifactId>
<version>4.2.1</version>
</dependency>
</dependencies>
</project>
Any ideas why this is going wrong?

Gradle + bintray: Specifying Dependencies of dependencies correctly

I have the following scenario:
I want to use a project of mine (hosted on bintray.com) in another project of mine.
I set up a maven repository, uploaded artifacts and pom files and then was able to utilize the jar file(s) uploaded to the bintray maven repo just fine, with the following build.gradle file:
apply plugin: 'java'
apply plugin: 'application'
mainClassName = 'randers.test.usageTest.UsageTest'
repositories {
maven { url 'http://dl.bintray.com/randers00/NotEnoughVocab' }
jcenter()
}
dependencies {
compile(group: 'randers.notenoughvocab.core', name: 'notenoughvocab-core', version: '0.0.1', ext: 'jar')
}
jar {
manifest {
attributes "Main-Class": mainClassName
}
}
This build file successfully equips the project with my core library and even makes sources, etc. available in the IDE (IntelliJ IDEA I use)
The problem is: The core itself uses libraries, which are not gotten by gradle.
This is the pom file that is on bintray:
<?xml version="1.0" encoding="UTF-8"?>
<project xmlns="http://maven.apache.org/POM/4.0.0" xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance">
<modelVersion>4.0.0</modelVersion>
<groupId>randers.notenoughvocab.core</groupId>
<artifactId>notenoughvocab-core</artifactId>
<version>0.0.1</version>
<dependencies>
<dependency>
<groupId>ch.qos.logback</groupId>
<artifactId>logback-classic</artifactId>
<version>1.1.3</version>
<scope>compile</scope>
</dependency>
<dependency>
<groupId>joda-time</groupId>
<artifactId>joda-time</artifactId>
<version>2.7</version>
<scope>compile</scope>
</dependency>
<dependency>
<groupId>org.jdom</groupId>
<artifactId>jdom2</artifactId>
<version>2.0.6</version>
<scope>compile</scope>
</dependency>
<dependency>
<groupId>commons-configuration</groupId>
<artifactId>commons-configuration</artifactId>
<version>1.10</version>
<scope>compile</scope>
</dependency>
<dependency>
<groupId>commons-collections</groupId>
<artifactId>commons-collections</artifactId>
<version>3.2.1</version>
<scope>compile</scope>
</dependency>
</dependencies>
<licenses>
<license>
<name>GNU General Public License, Version 3.0</name>
<url>http://www.gnu.org/licenses/gpl.txt</url>
<distribution>repo</distribution>
</license>
</licenses>
<contributors>
<contributor>
<name>Ruben Anders</name>
<email>RAnders00#users.noreply.github.com</email>
<url>https://github.com/RAnders00</url>
</contributor>
</contributors>
</project>
I looked at other projects on bintray and their pom files look similar.
Declaring the dependecy the traditional and simple way works fine:
compile 'randers.notenoughvocab.core:notenoughvocab-core:0.0.1'
It doesn't work when you specify ext: 'jar', because that is used to download a single artifact. From the user guide:
Artifact only notation
As said above, if no module descriptor file can be found, Gradle by default downloads a jar with the name of the module. But sometimes, even if the repository contains module descriptors, you want to download only the artifact jar, without the dependencies. [14] And sometimes you want to download a zip from a repository, that does not have module descriptors. Gradle provides an artifact only notation for those use cases - simply prefix the extension that you want to be downloaded with '#' sign:
Example 50.5. Artifact only notation
build.gradle
dependencies {
runtime "org.groovy:groovy:2.2.0#jar"
runtime group: 'org.groovy', name: 'groovy', version: '2.2.0', ext: 'jar'
}

Categories