2

I am just trying to understand the logic behind custom remote repositories with Maven. In one experiment (in OS X, using the command line) I am declaring a remote repository in a POM like this: (in fact is not really remote, since I am using file:///...):

<repositories>
    <repository>
      <id>myRepository</id>
      <url>file:///test_mvrepository/repository</url>
      <snapshots>
        <enabled>true</enabled>
      </snapshots>
    </repository>
</repositories>

This POM also declares a dependency on certain artifact X (the JPL library in my example), that is present only in the 'remote' repository, not in the local one:

<dependencies>
    <dependency>
        <groupId>jpl</groupId>
        <artifactId>jpl</artifactId>
        <version>[3.1.4-alpha,]</version>
    </dependency>
    ...
</dependencies>

When I execute this:

mvn package

The project is built as expected only once. If I repeat the operation I will have a message saying that my artifact X is not accessible:

[ERROR] Failed to execute goal on project projectname: Could not resolve dependencies for project groupid:artifactid:jar:0.0.1-SNAPSHOT: Could not find artifact jpl:jpl:jar:3.1.4-alpha -> [Help 1]

Here is the complete POM:

<?xml version="1.0" encoding="UTF-8"?>
<project>
  <modelVersion>4.0.0</modelVersion>
  <groupId>groupId</groupId>
  <artifactId>artifactId</artifactId>
  <version>0.0.1-SNAPSHOT</version>

  <repositories>
    <repository>
      <id>repId</id>
      <url>file:///test_mvrepository/repository</url>
      <snapshots>
        <enabled>true</enabled>
      </snapshots>
    </repository>
  </repositories>
  <dependencies>
    <dependency>
        <groupId>jpl</groupId>
        <artifactId>jpl</artifactId>
        <version>[3.1.4-alpha,]</version>
    </dependency>
    ...
  </dependencies>

</project>

After some debugging I found out that, though I did not install the POM with mvn install, the artifact X is in the local repository (its POM, jar and additional files). Only if I delete the entry from my local repository I could repeat the operation again without getting the error message. In fact, I do not have to delete all the entry in the local repository, just the file maven-metadata-local.xml. This is how this file looks like:

<?xml version="1.0" encoding="UTF-8"?>
<metadata>
  <groupId>jpl</groupId>
  <artifactId>jpl</artifactId>
  <versioning>
    <release>3.1.4-alpha</release>
    <versions>
      <version>3.1.4-alpha</version>
    </versions>
    <lastUpdated>20111214230431</lastUpdated>
  </versioning>

In my remote repository that file is called maven-metadata.xml.

Finally, if instead I type

mvn install

Then X is always accessible as expected, not only once as in the previous case.

I cannot understand the logic of this. Why I cannot ask Maven to package my artifact many times in this setting?. For me is evident that if I am not installing it in the local repository, then it should go again and again to the remote repository. Or at least, it should install the necessary objects in the local repository in a way that I can refer to them later, instead of blocking all future package requests until I manually delete the entry? Is this a bug in Maven ? thanks for any clarification !

Update: In case it is important, this is how I built my test scenario:

  • I installed in my local repository the JPL library (its dependency is the one that is giving me problems). I did it with this command:

    mvn install:install-file -Dfile=jpl.jar -DgroupId=jpl -DartifactId=jpl -Dversion=3.1.4-alpha -Dpackaging=jar

  • I copied the local repository to a new location in the file system (my 'remote' repository), and in this new location I changed the name of the maven-metadata-local.xml of the JPL entry to just maven-metadata.xml, as explained here: http://www.javaworld.com/community/node/3968.

  • I deleted from my local repository the JPL entry.

Sergio
  • 8,532
  • 11
  • 52
  • 94

2 Answers2

2

If you want to create a remote repository to hold your artifacts, you must upload your artifacts to it using deploy phase, instead of install phase.

install phase uploads your artifacts to your local repository, which is located under ~/.m2/ or {USER.HOME}/.m2/ by default. Your local repository is only a cache for remote repositories.

deploy phase uses the distributionManagement information provided in the pom file to deploy the artifact to a remote repository. You can create your distributionManagement definition as such:

<distributionManagement>
  <repository>
    <id>SomeId</id>
    <name>SomeName</name>
    <url>file:///test_mvrepository/repository</url>
  </repository>
</distributionManagement>

For further reference on distribution management, you can refer to this site.

Since you already have a reference of your remote repository in your repositories definition, when you deploy your artifacts to remote repository once, they will be fetched and cached into your local repository during your future builds.

You may consider reading more about information on repositories and maven lifecycles. There are also some similar questions on SO that are really well answered here and here.

Community
  • 1
  • 1
melihcelik
  • 4,531
  • 1
  • 21
  • 25
  • thanks for your feedback @melihcelik. I am using the deploy command instead of install and it seems to be working. But there is something weird that still I do not understand: When I deploy to a remote repository, the artifact is also installed in my local repository (its jar, pom, etc), that would lead me to think that after that I could skip the repository section in any POM where I need it. However, that is not the case, I still need the repository section in the POMs that need such artifact, though it exists already in my local repository(!). Could you tell me why ?. Thanks in advance. – Sergio Dec 15 '11 at 14:55
1

mvn install adds the current project to the local repository. Dependencies are cached in the local repository when you invoke any Maven goal or phase. So you would always expect X to end up in the local repository, no matter phase you use.

However the behaviour you're seeing is strange. Is there a problem with the file permissions? Could you update the post the exact error you get when you run mvn package the second time?

EDIT

OK I suspect something odd is going on with m2e. Does this behaviour happen when you use the command line?

Can you try binding the copy-dependencies plugin to package instead? That should prevent m2e doing odd things in Eclipse.

artbristol
  • 32,010
  • 5
  • 70
  • 103
  • Hi @artbristol, I have updated my question with the exact error message. Thanks for any tip. – Sergio Dec 15 '11 at 09:23
  • Can you post your POM? Is this on unix? What are the permissions of the created files in your local repo? – artbristol Dec 15 '11 at 09:38
  • I have just upload the POM. My environment is OS X. The file permissions of the entry generated in the local repository are: 1) read & write for my user, 2) read for everyone. – Sergio Dec 15 '11 at 09:55
  • I tried commenting out the 'build' section in the POM with an identical result: Works only once and the second time I see the 'Could not find artifact' message (I updated the POM in the question without this section in order to simplify the problem). I am using the command line for my test. – Sergio Dec 15 '11 at 12:21