12

I need to use a third-party JAR library in my project (actually it's Dresden OCL for Eclipse) that is not provided as a Maven artifact. Instead, it's just a downloadable JAR file. Can I instruct Maven to use this JAR file the same way I'm using <dependencies>? I suppose that there should be some plugin for this purpose?

ps. I just don't want to add 35Mb of third-party binaries into my SVN repository.

Would be nice to have it configured this way:

<build>
  <plugins>
    <plugin>
      <groupId>com.example</groupId>
      <artifactId>non-maven-dependencies-injector</artifactId>
      <configuration>
        <libraries>
          <library>http://www.example.com/something*.jar</library>
          <library>http://www.example.com/something-else*.jar</library>
        </libraries>
      </configuration>
    </plugin>
  <plugins>
</build>

And this plugin would 1) download these JAR files, and 2) add them as dependencies into pom.xml. Maybe this plugin could store them somewhere in ~/.m2/temp/...

yegor256
  • 102,010
  • 123
  • 446
  • 597

8 Answers8

12

yes you can install it into your local repository with maven-install plugin

mvn install:install-file -Dfile=your-artifact-1.0.jar \
                         -DgroupId=org.some.group \
                         -DartifactId=your-artifact \
                         -Dversion=1.0 \
                         -Dpackaging=jar \
                         -DgeneratePom=true

If you want your other team members to be able to download this dependency without having to install it them thelves, you need to setup your own artifact repo, and deploy the artifact there with maven-deploy-plugin in same way as you installed it localy.

lweller
  • 11,077
  • 3
  • 34
  • 38
  • Great, I didn't know about generatePom=true until now. This saves you the info-message that maven could not find the pom. – Boris Feb 05 '11 at 10:14
  • 1
    Well, this is a workaround, not a solution. I don't want to duplicate some third-party JAR in my repo, and of course I don't want every programmer to install it locally. Keep in mind, that Dresden OCL (for example) has over 20 JAR files... – yegor256 Feb 05 '11 at 13:23
  • @yegor256 if this jars are not available in a public repo (like http://http://www.ibiblio.org/maven/) the only solution is to install it in a repo that you setup for your team (I agree that manually installation by each developper is not a solution of course). – lweller Feb 05 '11 at 14:41
  • @lweller please review my question, I just added an example of what I'm looking for. Do you think it's achievable? – yegor256 Feb 05 '11 at 17:18
  • @yegor256 such a plugin may be implemented, but I think it's definitively not mave way to go I think, because you add an other redundant dependency management. A corporate maven repo is more state of the art and belongs in my opinion to required infrastucture as a source code repository does (a of course some kind of continous integration server ;) – lweller Feb 05 '11 at 19:50
  • @lweller I'm trying to configure a project as a one-click build-able artifact, which doesn't require any preliminary steps to be built. In your scenario I will always have to remember, that in order to build this project I should install some files into some repository. See my point? Would be much better to have this preliminary procedure configured **inside** `pom.xml`, somehow.. – yegor256 Feb 06 '11 at 08:40
  • @yegor256 it's absolutely possible to include your corporate maven repo in pom.xml (see http://maven.apache.org/pom.html#Repositories) so your artifact is still one-click-buildable with after check out from source control – lweller Feb 06 '11 at 09:51
  • @lweller what if my "corporate maven repo" is gone/lost? I have to remember that I need to re-install some artifacts into it? Manually?? I hate this idea :) – yegor256 Feb 06 '11 at 10:11
  • @yegor256 what is if your source control system is lost? and depending on some third party location that may also be relocaded or removed without you can do something... – lweller Feb 06 '11 at 10:16
6

Yes. This (using non-Mavenized dependencies) is supported by the maven-external-dependency-plugin.

Example:

<artifactItem>
    <groupId>jwbroek.cuelib</groupId>
    <artifactId>cuelib</artifactId>
    <version>${cuelib-version}</version>
    <packaging>jar</packaging>
    <downloadUrl>http://cuelib.googlecode.com/files/cuelib-${cuelib-version}.jar</downloadUrl>
    <checksum>d03b6b960b3b83a2a419e8b5f07b6ba4bd18387b</checksum>
</artifactItem>

It can also extract artifacts from zip files:

<artifactItem>
    <groupId>mediautil</groupId>
    <artifactId>mediautil</artifactId>
    <version>${mediautil-version}</version>
    <packaging>jar</packaging>
    <install>true</install>
    <force>false</force>
    <downloadUrl>http://downloads.sourceforge.net/project/mediachest/MediaUtil/Version%201.0/mediautil-1.zip</downloadUrl>
    <checksum>aa7ae51bb24a9268a8e57c6afe478c4293f84fda</checksum>
    <extractFile>mediautil-${mediautil-version}/mediautil-${mediautil-version}.jar</extractFile>
    <extractFileChecksum>e843cd55def75dce57123c79b7f36caca4841466</extractFileChecksum>
</artifactItem>
chocolateboy
  • 1,693
  • 1
  • 19
  • 21
2

You can use "system"-scope in your pom.xml for local library dependencies:

system
This scope is similar to provided except that you have to provide the JAR which contains it explicitly. The artifact is always available and is not looked up in a repository.

systemPath
is used only if the the dependency scope is system. Otherwise, the build will fail if this element is set. The path must be absolute, so it is recommended to use a property to specify the machine-specific path (more on properties below), such as ${java.home}/lib. Since it is assumed that system scope dependencies are installed a priori, Maven will not check the repositories for the project, but instead checks to ensure that the file exists. If not, Maven will fail the build and suggest that you download and install it manually.

<dependency>
    <groupId>some.id</groupId>
    <artifactId>artifact</artifactId>
    <version>1.2.3</version>
    <scope>system</scope>
    <systemPath>${basedir}/path/to/jarFile.jar</systemPath>
</dependency>

AFAIK, you can use pretty much what you want for groupId, artifactId and version. See Maven System Depencies and this question.

Community
  • 1
  • 1
esaj
  • 15,875
  • 5
  • 38
  • 52
  • where the `jarFile.jar` file should be located? Who should place it there? I checkout a project from SVN and run `mvn package`. Where this file will come from? – yegor256 Feb 06 '11 at 08:42
  • ${basedir} in < systemPath> points to your project root (where the pom.xml is). Not 100% sure on this, but you probably need to place the files in a "source folder" (like under src/main/resources) for them to get picked up by 'mvn package'. I used this once maybe six months ago, so the details are already blurry. It did work though, but then we decided to just use the 'mvn install'-route to insert our libraries into the local repositories, so we didn't need to copy new versions of the library to the other project all the time. – esaj Feb 06 '11 at 09:12
2

Taking that your example Dresden OCL has over 20 JAR files, and you need to distribute it to many developers, the best solution would be to install a repository manager somewhere (like nexus or artifactory), take your time to upload these 20 jars to that repository, and use them. Best bet would be to put them in a private groupId, so if they'll get published to a m2 repo sometime, you won't end up with name conflicts.

Another point, would be to ask the Dresden OCL Maintainers, if they can offer a m2 repository. Now that m2eclipse is an eclipse incubator project, this might interest more people.

mglauche
  • 3,344
  • 4
  • 28
  • 31
0
I think the below answer will help you...just place jar files on your SVN and tell them all to e synch with SVN and here the ${lib.directory}    will be t he local path

 <plugin>
                  <groupId>org.apache.maven.plugins</groupId>
                  <artifactId>maven-install-plugin</artifactId>
                  <version>2.4</version>
                  <executions>
                      <execution>
                          <id>db2jcc9</id>
                          <phase>compile</phase>
                          <goals>
                              <goal>install-file</goal>
                          </goals>
                          <configuration>
                              <groupId>com.ibm</groupId>
                              <artifactId>db2jcc</artifactId>
                              <version>9</version>
                              <packaging>jar</packaging>
                              <file>${lib.directory}\db2jcc-9.jar</file>
                          </configuration>
                      </execution>
                      </executions>
    <plugin>
0

You can install it local or deploy it to your site-local (e.g. company-wide) repository. If you use a dependency maven cannot find in the configured repositories, it even gives you the required commands:

Then, install it using the command: mvn install:install-file -DgroupId=mygid -DartifactId=myaid -Dversion=1.0 -Dpackaging=jar -Dfile=/path/to/file

Alternatively, if you host your own repository you can deploy the file there: mvn deploy:deploy-file -DgroupId=mygid -DartifactId=myaid -Dversion=1.0 -Dpackaging=jar -Dfile=/path/to/file -Durl=[url] -DrepositoryId=[id]

Please note: This way you only add the .jar to your repository, there will be no pom along with it to specify transient dependencies. So if your third-party library has dependencies of it's own you'll have to add them manually to your pom.xml as there will be no automatic resolution.

Boris
  • 4,327
  • 2
  • 19
  • 27
0

"mvn install:install-file" mentioned here will help you to install the jars into your local repository. However, if you want to make these jars subsequently available to the developers on the project automaticall, copy the relevant pieces to a repository available to everybody on the project and make this repository available using the tag, for example by checking all the files into the SVN. See http://code.google.com/p/codebistro/wiki/BuildNumber#Maven_Plugin_Example which refers to a SVN-hosted repository for example.

P.S. Have a safe trip to the SV!

Sasha O
  • 3,710
  • 2
  • 35
  • 45
  • Glad to see you here :) The procedure of "copy the relevant pieces to a repository available to everybody" is done by who? Is it automated somehow? As I said in the question, there are 30+ files in the library I'm going to use. I should copy them all manually? And what happens when they are updated? Who will copy them again? :) Take a look at (dependency-copy](http://maven.apache.org/plugins/maven-dependency-plugin/copy-mojo.html), it "copies a list of artifacts from the repository to defined locations". I need exactly the opposite: "from locations to repository"... – yegor256 Feb 06 '11 at 10:25
  • @Yegor I used to have a script with a bunch of mvn install:install-file's which goes over all the external artifacts and puts them in. You can specify -DlocalRepositoryPath= to install it directly into your repository. Frankly, don't see a way to automate it any further. – Sasha O Feb 06 '11 at 23:26
0

Here's a different approach that'll let add a Maven repository inside the project directory, use that as a repository in you pom.xml, and share the repository on SVN with anyone checking out the project. Crosspost from here.

In your project directory, create a folder called repo, which we'll use as a folder based Maven repository.

Add the following file repository to your project pom.xml:

<repositories>
    <repository>
        <id>file.repo</id>
        <url>file://${project.basedir}/repo</url>
    </repository>
</repositories>

Deploy the external jar(s) to the file repository with the following command:

mvn deploy:deploy-file
-Durl=file:///absolute/path/to/your-project/repo \
-DrepositoryId=file.repo \
-Dfile=path-to-your.jar \
-DgroupId=some.external.project.group \
-DartifactId=the-artifact-name \
-Dversion=1.0 \
-Dpackaging=jar;

Following this you can just add a normal dependency on the jar in your project pom.xml, using the values for groupId, artifactId and version you passed above. You can then add the repo folder to SVN, and commit the changes to your pom.xml. Any developer checking out your project will now be able to use the same dependency without any effort.

Community
  • 1
  • 1
Tim
  • 19,793
  • 8
  • 70
  • 95
  • "package your classes as a jar and deploy them" - who is going to do this? Me manually every time I change the integration/build platform? – yegor256 Apr 06 '11 at 09:07
  • @yegor256: Whoops, sorry,that was a copy-paste error from posting the same solution to two different questions. (See my edit above) In your case just deploy the external jar to the file repository with the same command. No need to alter or package any of your own code! – Tim Apr 06 '11 at 09:37
  • The same problem: I need to "deploy the jars" manually. I'm trying to find a fully automated mechanism, that will download, deploy, install and make them jars available for maven build. – yegor256 Apr 06 '11 at 09:41
  • Yes, but would only have to add your jars once and add them to SVN, after which anyone checking out from SVN can use them directly. Contrast this with some of the other solutions which require either every developer to install the jars manually, or to maintain and backup a company-wide Maven repository, which you seem not to want to do. However, as @lweller said, it's probably bad form to implement a duplicate dependency resolution mechanism, as URLs change, links break, and then you'd be back in Jar hell. – Tim Apr 06 '11 at 09:52