Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Maven 3 does not update snapshot dependency from local repository

Tags:

java

maven

I am trying to use external library inside my maven project. Since I want the project to build out of the box on any machine, I don't want to use mvn install solution. I have therefore defined local repository in my pom.xml:

    <dependency>
        <groupId>com.test</groupId>
        <artifactId>fooLib</artifactId>
        <version>1.0-SNAPSHOT</version>
    </dependency>
    ....
    <repository>
        <id>in-project</id>
        <snapshots>
            <updatePolicy>always</updatePolicy>
            <enabled>true</enabled>
        </snapshots>
        <name>In Project Repo</name>
        <url>file://${project.basedir}/libRepo</url>
    </repository>

The problem is when I replace the jar in libRepo (without updating version number since it is just another snapshot) that this updated jar is not used (old version from .m2 directory is used instead) even for mvn -U clean install How to make maven to update this jar?

EDIT: According to What exactly is a Maven Snapshot and why do we need it? maven shall try to find never version of SNAPSHOT dependency, "even if a version of this library is found on the local repository". What is wrong with my setting?

DIRTY SOLUTION: Based on answer from Maven 2 assembly with dependencies: jar under scope "system" not included following extension of my original solution seems to work:

        <plugin>
            <groupId>org.apache.maven.plugins</groupId>
            <artifactId>maven-install-plugin</artifactId>
            <executions>
                <execution>
                    <id>hack-binary</id>
                    <phase>validate</phase>
                    <configuration>
                        <file>${repo.path.to.jar}</file>
                        <repositoryLayout>default</repositoryLayout>
                        <groupId>com.test</groupId>
                        <artifactId>fooLib</artifactId>
                        <version>1.0-SNAPSHOT</version>
                        <packaging>jar</packaging>
                        <generatePom>true</generatePom>
                    </configuration>
                    <goals>
                        <goal>install-file</goal>
                    </goals>
                </execution>
            </executions>
        </plugin>

As mentioned in comment to that solution, it does not work alone, thus it works in combination with in-project repository (which works when the dependency is not available in local .m2 repository) and this second parts refreshes .m2 during every build.

However it is still not clear to me why ordinary "SNAPSHOT" mechanism does not work (i.e. current dirty solution would work also without SNAPSHOTs as local .m2 repo is explicitly updated every time). Is there any cleaner way?

SOLUTION (based on Aaron's answer & discussion): The problem was that I tried to install file into libRepo using install-file. The actual solution is that if library updates, use

mvn deploy:deploy-file -Dfile=fooLib.jar  -DgroupId=com.test \
    -DartifactId=fooLib -Dversion=1.0-SNAPSHOT -Dpackaging=jar \
    -Durl=file://..\libRepo -DrepositoryId=in-project

to deployed it to repo. After proper deploy, maven correctly handles SNAPSHOTs.

like image 249
sodik Avatar asked Feb 25 '14 13:02

sodik


People also ask

How do I force Maven to update dependencies?

In Maven, you can use Apache Maven Dependency Plugin, goal dependency:purge-local-repository to remove the project dependencies from the local repository, and re-download it again.

How do I force Maven to download dependencies from remote repository?

We can use -U/--update-snapshots flag when building a maven project to force maven to download dependencies from the remote repository. Here, -U,--update-snapshots : Forces a check for missing releases and updated snapshots on remote repositories.

What argument do you pass to Maven in order to update snapshots from remote repository?

It's important to add that executing mvn -U will override your local SNAPSHOT jars with remote SNAPSHOT jars. Without -U argument, local SNAPSHOTS won't be override.

How do I update my local Maven repository?

You can check your local maven repository in the Maven | Repositories settings and try to update it. You can check the jar file of the local . m2 repository to see if it was downloaded correctly.


2 Answers

If you use a repository for this, then Maven will copy the JAR once into it's local repository (usually in $HOME/.m2/repository/). Unless the version number changes, Maven won't consider this file to have changed and it won't copy it. Note that the version number is the only thing that Maven looks at; it doesn't care about checksums or file sizes or dates.

Incidentally, snapshots are assigned a version number internally for just this purpose: So that Maven can internally notice that a snapshot has been updated.

I suggest to use a system dependency instead. That way, the actual JAR is going to be added to the classpath (without any copying or stuff). You also don't need to replicate a repo structure for this approach and it will clearly communicate your intent.

[EDIT] I understand that Maven handles dependencies with scope system differently. I'm not sure whether this makes sense or not (if it uses the dependency to compile, it surely can use it to run?)

As I see it, you have these options:

  1. Install the dependency into your libRepo using deploy:deploy-file instead of copying it yourself. That should update the meta data in such a way that Maven will copy it again when you run mvn install again on the real project.

    Note that file:install doesn't work. The file plugin is used to access the local repository but you need to use the deploy plugin which knows how to update a shared / server repository.

  2. Install the dependency into your local repo; I suggest to use a script for this that you can include in your project. That way, you avoid all the problems and it will be easy to set this up on a new machine.

  3. Change the version number of the dependency but that's tedious and you might get into trouble when the real version number of the dependency changes.

  4. Set up a local repo server for your company and deploy the dependency to it. That will take a few hours but a) you will get a local cache of all your dependencies, making your initial builds faster and b) it will make setup for additional developers much faster.

like image 113
Aaron Digulla Avatar answered Oct 14 '22 05:10

Aaron Digulla


Maven will never read the jar present inside any library folder. You must first understand how maven works. The only place where maven looks for jar is the localRepository (.m2), if absent it searches the other repository, mentioned in your POM.xml

like image 32
ItachiUchiha Avatar answered Oct 14 '22 05:10

ItachiUchiha