I am doing a project that has dependencies on some classes from the mahout and hadoop core jars. I was using javac with the classpath option to include them before, but someone suggested to me that I should use maven to build my project instead. However, I am not sure how to add the dependencies to these jar files which are located in my /usr/local directory.
<dependency>
<groupId>org.apache.hadoop</groupId>
<artifactId>hadoop-core</artifactId>
<version>0.20.205.0</version> <!-- or whatever version -->
</dependency>
<dependency>
<groupId>org.apache.mahout</groupId>
<artifactId>mahout-core</artifactId>
<version>0.5</version>
</dependency>
Add this to your pom:
<dependencies>
<dependency>
<groupId>org.apache.mahout</groupId>
<artifactId>mahout-core</artifactId>
<version>0.5</version>
</dependency>
<dependency>
<groupId>some.group</groupId>
<artifactId>hadoop</artifactId>
<version>some.version</version>
</dependency>
</dependencies>
If you have a copy of the jar to be used for say the hadoop example above, execute this command:
mvn install:install-file -Dfile=/some/path/my-hadoop.jar -DgroupId=some.group -DartifactId=hadoop -Dversion=some.version -Dpackaging=jar
Have a look at the maven documentation, especially the part on dependency management. If you want to use Maven you should get to know the basics (one of which is dependency management).
Basially you define your project's dependencies in the <dependencies> section of your pom. Look up maven central (the most common online repository) for the dependencies you want or search for other online repositories that might contain them.
If you can't find them, add the dependencies you want anyways (think of a sensible group id, artifact id and version) and try to compile. Maven will complain about the dependencies missing and provide a basic command to put those dependencies into the local repository. Copy those commands and fill in the appropriate path to the jar file and maven will deploy that dependency in your local repository.
Note that you should first look for the dependencies in an online repository since otherwise you'd have to manually deploy each new version in your local repo.
Related
I have a main project and a commons project which has a dependency that is not in any repository and needs to be included using <scope>system</scope>.
Because the system dependency is defined using a relative url using a maven property ${project.basedir}, I made it <optional>true</optional> so that it doesn't bother other projects and so depending projects need to redefine this dependency with the correct path.
Commons pom.xml:
<dependency>
<groupId>thirdparty-group</groupId>
<artifactId>artifact</artifactId>
<version>1.4.2</version>
<scope>system</scope>
<systemPath>${project.basedir}/lib/dependency.jar</systemPath>
<optional>true</optional>
</dependency>
In main project's pom:
<dependency>
<groupId>my-group</groupId>
<artifactId>commons</artifactId>
<version>1.0-SNAPSHOT</version>
<scope>compile</scope>
</dependency>
<dependency>
<groupId>thirdparty-group</groupId>
<artifactId>artifact</artifactId>
<version>1.4.2</version>
<scope>system</scope>
<systemPath>${project.basedir}/lib/dependency.jar</systemPath>
</dependency>
Obviously dependency.jar is in both the commons and main project.
The commons jar installs properly without a hitch. But when used in the main project however, the result is:
[WARNING] The POM for my-group:commons:jar:1.0-SNAPSHOT is invalid, transitive dependencies (if any) will not be available: 1 problem was encountered while building the effective model for my-group:commons:1.0-SNAPSHOT
[ERROR] 'dependencies.dependency.systemPath' for thirdparty-group:artifact:jar must specify an absolute path but is ${project.basedir}/lib/dependency.jar #
The build continues, but transitive runtime dependencies are now excluded breaking the application.
Why is maven complaining about a dependency from commons that is not even relevant to the main project (as it is optional, why is it even included as transitive dependency)?
How to work around this problem?
Putting the system dependency in the repo is not an option unfortunately.
Going by #PascalThivent's excellent answer, I worked around the issue by defining a local repo inside the commons project, and then changing the scope to compile with <optional>true</optional>.
In commons pom.xml:
<dependencies>
<dependency>
<groupId>thirdparty-group</groupId>
<artifactId>artifact</artifactId>
<version>0.0.1</version>
<scope>compile</scope>
<optional>true</optional>
</dependency>
</dependencies>
<repositories>
<repository>
<id>local-repo</id>
<url>file://${basedir}/lib/local-repo</url>
</repository>
</repositories>
To install the library:
mvn org.apache.maven.plugins:maven-install-plugin:2.3.1:install-file \
-Dfile=./lib/dependency.jar \
-DgroupId=thirdparty-group \
-DartifactId=artifact \
-Dversion=0.0.1 \
-Dpackaging=jar \
-DlocalRepositoryPath=.\lib\local-repo
I can just commit this to the VCS directly so other developers don't have to do this every time on checkout.
In the main project's pom.xml nothing changes. It can still use its own system dependency, or go this approach as well. Both approaches work for the WAR file that comes out there...
I have a small maven web project. Its pom includes dependencies to other libraries. One of them has a dependency to slf4j-api.
When running maven's clean install from inside IntelliJ IDEA the resulting war file includes slf4j-api.jar in WEB-INF/lib
Now we have configured a TeamCity maven build for the project. It builds without any errors, but it doesn't include this specific transitive dependency (whereas it includes others).
Do you have any general hints to why this might happen?
Currently we added the dependency directly to the main pom even though we don't need it there...
In the main pom
<dependency>
<groupId>xxxxxxxxx</groupId>
<artifactId>mylibrary</artifactId>
<version>1.0.20</version>
</dependency>
in mylibrary's pom
<dependency>
<groupId>org.slf4j</groupId>
<artifactId>slf4j-api</artifactId>
<version>1.7.5</version>
</dependency>
I haven't specified any scope, so I suppose it's compile in any case.
Sorry for the spelling, I'm french
I try to install with scope a jar for oracle in my project
Here my pom.xml
<dependency>
<groupId>com.oracle</groupId>
<artifactId>ojdbc7</artifactId>
<version>12.1.0.2</version>
<scope>system</scope>
<systemPath>C:/Users/bin/Desktop/dossier_access/instantclient_12_1/ojdbc7.jar</systemPath>
</dependency>
The maven compile didn't function
I did after (it works)
mvn -X install:install-file -Dfile=C:/Users/bin/Desktop/dossier_access/instantclient_12_1/ojdbc7.jar -DgroupId=com.oracle -DartifactId=ojdbc7 -Dversion=12.1.0.2 -Dpackaging=jar -DpomFile=C:/Users/Documents/Projets/version7/integration-archetype/batch/packaging/integration-archetype-batch/pom.xml
but mvn install gives :
[WARNING] The POM for oracle.jdbc:ojdbc7:jar:12.1.0.2 is missing, no dependency information available
[WARNING] The POM for oracle.jdbc:ucp:jar:12.1.0.2 is missing, no dependency information available
BUILD FAILURE
Thank you for your responses,
i'm beginner with Maven and I have already see on the other posts...
What i usually do is first install jdbc driver in local repository so it is available for all apps in local machine.
Then just use regular dependency tag to include it in you pom file.
Look at this quick tutorial:
http://www.mkyong.com/maven/how-to-add-oracle-jdbc-driver-in-your-maven-local-repository/
After installing a 3rd party into your local repo (that is what you did with mvn install:install-file) you can reference it the following way:
<dependency>
<groupId>com.oracle</groupId>
<artifactId>ojdbc7</artifactId>
<version>12.1.0.2</version>
</dependency>
And no path information is required anymore.
I'm following this guide:
https://github.com/maxmind/GeoIP2-java
It says:
We recommend installing this package with Maven. To do this, add the dependency to your pom.xml:
<dependency>
<groupId>com.maxmind.geoip2</groupId>
<artifactId>geoip2</artifactId>
<version>2.2.0</version>
</dependency>
There is also pom.xml file in the Git repository of GeoIP2 which is much longer - what is the difference between them?
Cited from the official homepage:
Apache Maven is a software project management and comprehension tool. Based on the concept of a project object model (POM), Maven can manage a project's build, reporting and documentation from a central piece of information.
Think of the pom.xml as the heart of Maven. In the file you can specify dependencies (most typically jar files), and other information, such as how the project should be built. Without digging to deep into this, one of Maven's strengths is that it manages the dependencies of projects.
To answer your concrete question, GeoIP2 manages its dependencies using Maven. This section of its pom.xml defines them:
<dependencies>
<dependency>
<groupId>com.maxmind.db</groupId>
<artifactId>maxmind-db</artifactId>
<version>1.0.0</version>
</dependency>
<dependency>
<groupId>junit</groupId>
<artifactId>junit</artifactId>
<version>4.12</version>
<scope>test</scope>
</dependency>
<dependency>
<groupId>com.google.http-client</groupId>
<artifactId>google-http-client</artifactId>
<version>1.20.0</version>
</dependency>
<dependency>
<groupId>com.fasterxml.jackson.core</groupId>
<artifactId>jackson-databind</artifactId>
<version>2.5.3</version>
</dependency>
</dependencies>
By using Maven in your own project, you will only need to add the one dependency to GeoIP2. Maven will then search for the dependency in a repository, typically the Maven Central Repository if Maven isn't configured to use another. It will also automatically download all other needed dependencies (transitive dependencies), in this case it would be the dependencies listed above, plus any other dependencies those in turn depend on, and so on.
So, a short recap: Without a dependency management tool like Maven, you would need to manually make sure you have all the correct dependencies on the classpath. Maven fixes this for you.
I have installed maven dependency using the command below
mvn install:install-file -Dfile=d2_lib.war -DgroupId=com.emc.d2fs -DartifactId=d2_lib -Dversion=1.0 -Dpackaging=war -DlocalRepositoryPath="C:\Users\kumarr23\.m2\repository"
I have added this dependency in my root pom.xml as below
<dependency>
<groupId>com.emc.d2fs</groupId>
<artifactId>d2_lib</artifactId>
<version>1.0</version>
<type>war</type>
<scope>runtime</scope>
</dependency>
I can see when I do maven install the jars inside my final war,
when i try importing these classes from eclipse these classes are not included, Is there some thing I am missing?
I am new to maven and i am stuck here !
please advise
Please check if you have d2_lib.war file at the location from where you are running command or else mention the full path of d2_lib.war in command and try again , i believe with the command you specify it is not copying the war file since war file path is not defined properly , you can confirm this by checking if war file is copied to your local maven repository
mvn install:install-file -Dfile=d2_lib.war -DgroupId=com.emc.d2fs -DartifactId=d2_lib -Dversion=1.0 -Dpackaging=war -DlocalRepositoryPath="C:\Users\kumarr23.m2\repository"
There is a convention in maven that java code lives in a .jar file and web classes live in a .war file. When you include a dependency with the war type in your web project, maven will treat the included file as an overlay. This basically means that maven will package the contents of the dependency into your war file, however it will not include the libraries in that war as java code the way you are looking for.
When a war file is created, if the creator also wants people to get at the java code and transitive dependencies the code is based off of, they can use the maven-war-plugin to set a configuration tag of <attachClasses>true</attachClasses>. This will generate an additional artifact in the form of artifactId-version-classes.jar, along with the normal artifactId-version.war file.
When you include both the war as an overlay and the classes jar as a normal dependency, you will be able to see in your dependency tree that maven is only pulling in transitive dependencies from the jar file dependency, not the war.
In your case, you need to find the classes jar file and install it along with the war file in your local maven repository. Then you can add the classes jar to your pom.xml like so:
old pom.xml
<dependency>
<groupId>com.emc.d2fs</groupId>
<artifactId>d2_lib</artifactId>
<version>1.0</version>
<type>war</type>
<scope>runtime</scope>
</dependency>
new pom.xml
<dependency>
<groupId>com.emc.d2fs</groupId>
<artifactId>d2_lib</artifactId>
<version>1.0</version>
<type>war</type>
<scope>runtime</scope>
</dependency>
<dependency>
<groupId>com.emc.d2fs</groupId>
<artifactId>d2_lib</artifactId>
<version>1.0</version>
<classifier>classes</classifier>
</dependency>