Basic maven question: Does maven transitively install dependencies? - java

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.

Related

Provide dependencies in the implementing app / module

I'm writing a library that I'd like to compile into implementable jar which then will be used in other projects / tests.
In my library I depend on various jars: okHttp, guava, etc., What I want to do is to tell maven not to put those dependencies into the final JAR but make that projects / modules that depend on this library provide those dependencies
How can this be done in maven?
library pom.xml
<groupId>com.example</groupId>
<artifactId>testing-library</artifactId>
<packaging>jar</packaging>
<version>1.0.0-SNAPSHOT</version>
<dependencies>
<dependency>
<groupId>com.google.guava</groupId>
<artifactId>guava</artifactId>
<version>28.2-jre</version>
<scope>compile</scope>
</dependency>
<dependency>
<groupId>com.squareup.okhttp3</groupId>
<artifactId>okhttp</artifactId>
<version>4.3.1</version>
<scope>compile</scope>
</dependency>
</dependencies>
implementation module pom.xml
<groupId>com.example</groupId>
<artifactId>implementation-</artifactId>
<version>1.0.0-SNAPSHOT</version>
<dependencies>
<dependency>
<groupId>com.example</groupId>
<artifactId>testing-library</artifactId>
<version>1.0.0-SNAPSHOT</version>
<scope>test</scope>
</dependency>
</dependencies>
But I'm getting java.lang.NoClassDefFoundError: com/google/common/base/Preconditions error
If you put code into src/test/java, this code will not be part of the final jar. The code is meant for tests during the build of the jar.
If your library is a helper library for tests, put the code into src/main/java and reference it in other projects with <scope>test</scope>.
BTW, don't use Maven shade plugin or Maven assembly plugin for a library. These are mainly meant for standalone jars that run on their own.
Ok, I solved the issue. It seems that the generated POM.xml for the testing-library did not contain any dependencies.
I was using mvn install:install-file ... -DgeneratePom=true for installing jar into local repository for quick debugging and the pom generated this way seemed to be lacking library dependencies'

maven build error: package org.apache.http does not exist

I am attempting to send a simple HTTP post from a java program (for deploying on Heroku).
I started with the demo project here.
Using mvn package builds the project successfully.
I then added my own additional file TestPost.java with a few lines of code, added it to the pom.xml, and still built fine.
Then I tried to add the HTTP code from this example (minus the package line), which uses the Apache HttpClient library.
Using mvn package results in the following error:
package org.apache.http does not exist
After searching for solutions I tried including a dependency in the pom.xml:
<dependencies>
<dependency>
<groupId>org.apache.httpcomponents</groupId>
<artifactId>httpclient</artifactId>
<version>4.5.2</version>
<scope>compile</scope>
</dependency>
</dependencies>
My understanding was that this should force a download of the necessary package but no download was shown on the next compile (just the same error), and the package is not visible in my user .m2\repository\ folder.
I tried inserting this dependency at different points in my pom.xml without success.
Why is the apache library not being downloaded? Please note that I am new to maven.
Here is the pom.xml that you should have if indeed you need to depend on httpclient.
<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>demo</groupId>
<artifactId>httpclient-demo</artifactId>
<version>1.0-SNAPSHOT</version>
<packaging>jar</packaging>
<name>httpclient-demo</name>
<url>http://maven.apache.org</url>
<properties>
<project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
</properties>
<dependencies>
<dependency>
<groupId>org.apache.httpcomponents</groupId>
<artifactId>httpclient</artifactId>
<version>4.5.2</version>
</dependency>
</dependencies>
</project>
Now if you put your Java sources in src/main/java, where src and pom.xml are in the same directory, Maven should resolve the dependency from your local repository, and download it, should it not already be there. Your local repository is defined in the conf/settings.xml in your Maven installation directory.

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>

Maven not pulling down correct JClouds-Chef dependency tree

I'm trying to figure out how to use the JClouds-Chef library to configure VMs. According to their Installation Guide I can just create a pom.xml that looks like:
<?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>
<jclouds.version>1.7.3</jclouds.version>
</properties>
<groupId>com.mycompany.app</groupId>
<artifactId>my-app</artifactId>
<version>1.0-SNAPSHOT</version>
<dependencies>
<dependency>
<groupId>org.apache.jclouds</groupId>
<artifactId>jclouds-all</artifactId>
<version>${jclouds.version}</version>
</dependency>
</dependencies>
</project>
And run mvn dependency:copy-dependencies and it should pull down all the JARs that JClouds-Chef requires.
So I did this, and then added all the JARs (there were a lot) to my project's buildpath. I then tried to create ChefContext instance (like their tutorials show examples of):
ChefContext context = null;
And Eclipse can't resolve/find the ChefContext class. After scanning the JARs that Maven downloaded, sure enough, ChefContext doesn't appear anywhere!
So I ask: **what are the exact steps I need to get all the JARs that comprise JClouds-Chef and all of its dependencies?*
You must explicitly add chef to your dependencies stanza:
<dependency>
<groupId>org.apache.jclouds.api</groupId>
<artifactId>chef</artifactId>
<version>${jclouds.version}</version>
</dependency>
You can consult chef-basics in jclouds-examples for a working example.
Adding that dependency should be enough. Alternatively, if you want to use Enterprise Chef specific features, you can add the following one instead:
<dependency>
<groupId>org.apache.jclouds.provider</groupId>
<artifactId>enterprisechef</artifactId>
<version>${jclouds.version}</version>
</dependency>
That's the only thing you need to configure. jclouds will take care of installing Chef and all the required dependencies in the nodes you provision.

How do I add the storm mongo library as a maven dependency?

I'm trying to use a SimpleMongoBolt from storm-contrib. I downloaded the source, entered the storm-contrib-mongo directory and ran mvn package and mvn install. Everything worked fine and IntelliJ was able to resolve things while coding. When I try to build my project, however, it tries to find a pom for this library on an external repository. When it can't find it, it fails. What do I need to do to fix this?
<?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>StormTest</groupId>
<artifactId>StormTest</artifactId>
<version>1.0</version>
<packaging>jar</packaging>
<name>StormTest</name>
<repositories>
<repository>
<id>clojars.org</id>
<url>http://clojars.org/repo</url>
</repository>
</repositories>
<dependencies>
<dependency>
<groupId>storm</groupId>
<artifactId>storm</artifactId>
<version>0.7.2</version>
<scope>Test</scope>
</dependency>
<dependency>
<groupId>com.rapportive</groupId>
<artifactId>storm-amqp-spout</artifactId>
<version>0.1.1</version>
</dependency>
<dependency>
<groupId>com.rapportive</groupId>
<artifactId>storm-json</artifactId>
<version>0.0.1</version>
</dependency>
<dependency>
<groupId>storm</groupId>
<artifactId>storm-contrib-mongo</artifactId>
<version>0.1-SNAPSHOT</version>
</dependency>
</dependencies>
</project>
You can try to check if you have proper dependencies defined in your project pom and compare them to storm artifact one. groupId, artifactId and version must be the same or Maven will try to download it from external repository and probably failed as it has never been installed on any public Maven repo.
When you install your artifact, it goes to user-directory/.m2/repostiory/group/id/path/*artifact/id/path*/version.
For your storm-amqp-spout you should have it in:
user-directory/.m2/repository/com/rapportive/storm-amqp-spout/0.1.1 folder.
There you should have few files:
jar itself (if it was packaged as jar file).
pom.xml file (the same you created for your project and you used to built and install it).
optionally sha1 files for both above.
If you don't have them, you probably made some mistake installing the artifact into repository. You can try to install it again or manually create pom just copying it from artifact source directory.
If there's correct pom.xml, I don't really have idea as I have never worked with IntelliJ (idea? ;)).
SimpleMongoBolt in Storm-Contrib was actually out of date. I updated the module myself and submitted a pull request, which has yet to be merged. Currently you can retrieve the updated code from my Storm-Contrib fork.

Categories