How can I prevent Maven from ever updating a SNAPSHOT dependency from a particular group?
I'm stuck depending on a library that insists on daily updates to 1.0-SNAPSHOT, but only makes releases every few months. I need changes from a daily SNAPSHOT build that was made recently, but I'm getting fed up with the developers of this framework introducing breaking changes. Hence, I'd like to tell Maven to never update anything from this groupId unless I specifically say so.
Any ideas? The only other approach I can think of is to fork the repo, edit the POM to a version number all of my own, and then depend on that.
Using snapshots this can always happen. But you could install the version you need with a specific version number in your local repository and then use your version. Something like:
<dependency>
<groupId>my.group</groupId>
<artifactId>my.artifact</artifactId>
<version>1.2-TEMPVERSION</version>
</dependency>
It's a workaround and should not go in Production like this.
Assuming you use maven 3, you can use a timestamed snapshot, i.e. replace the dependency with its timestamped version. Something like:
<dependency>
<groupId>my.group</groupId>
<artifactId>my.artifact</artifactId>
<version>1.2-20140401.124312.1</version>
</dependency>
You can also convert a SNAPSHOT dependency automatically to its corresponding timestamped version ("locking a version") using the [versions-maven-plugin][1]:
mvn versions:lock-snapshots -Dincludes=my.group:my.artifact:jar::1.2-SNAPSHOT
Of course, if your repository manager throws out old SNAPSHOTS after a while, this might cease to work when the needed SNAPSHOT is no longer in your local repository.
I think setting the update policy to never for snapshots solves the issue; see here
like
<repository>
<id>my_id</id>
<name>my_name</name>
<releases>[...]</releases>
<snapshots>
<enabled>true</enabled>
<updatePolicy>never</updatePolicy>
<checksumPolicy>warn</checksumPolicy>
</snapshots>
<url>http://the-repository.org/repositories/</url>
<layout>default</layout>
</repository>
Haven't (successfuly) tried yet. But I went into the same problem and that's my attempt to handle it.
Related
I am using Vaadin version 21.0.7 with Spring Boot and i want to import Paginator add-on.
I have added addon's groupId in applicaton.properties as follows: vaadin.whitelisted-packages=com.test.demo,com.vaadin.componentfactory.
The problem is that i get the following error: Paginator cannot be resolved to a type.
Some questions you may want to update your question with answers to:
Are you using Maven? Gradle? Something else?
JDK version?
Is the error a compile-time one? If so, you should add the full output to your question.
Now, for a potential solution:
Assuming you are using Maven...
(1) Make sure that Maven resolved the dependency.
Your IDE should tell you if not, or you can check your local .m2 directory. On Windows, it is located at ${user.home}. On macOS and most Unix/Linux distributions, it is located at ~. Check .m2/repositories/com/vaadin/componentfactory/paginator/<version>/ and ensure that the JARs were downloaded.
If they were not, make sure you
(a) defined the Vaadin Addons repository in your POM, e.g.,
<repositories>
<repository>
<id>vaadin-addons</id>
<url>https://maven.vaadin.com/vaadin-addons</url>
</repository>
<repository>
<id>central</id>
<url>https://repo1.maven.org/maven2/</url>
</repository>
</repositories>
(b) and defined the dependency, e.g.,
<dependencies>
<dependency>
<groupId>com.vaadin.componentfactory</groupId>
<artifactId>paginator</artifactId>
<version>2.0.0</version>
</dependency>
</dependencies>
(2) Are you using Jigsaw (Java 9+ modules)?
If you are, make sure you specified the dependency:
module myModule {
requires paginator;
}
Forgive my ignorance here, as I'm new to maven. I have a Remote Repository that my project pom is using to download dependencies from. A general structure of my pom.xml is like this:
<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>MVNProject</groupId>
<artifactId>MVNProject</artifactId>
<version>0.0.1</version>
<packaging>war</packaging>
<dependency>
<groupId>org.scala-lang.modules</groupId>
<artifactId>scala-parser-combinators_2.11</artifactId>
<version>1.0.1</version>
</dependency>
</dependencies>
</project>
Now I know that if I have to get a new version of the dependency scala-parser-combinators I just have to specify the new version. Something like this:
<dependency>
<groupId>org.scala-lang.modules</groupId>
<artifactId>scala-parser-combinators_2.11</artifactId>
<version>1.0.1</version>
</dependency>
But what I would like to do is, without making any change to pom.xml I'd like to replace my old jar with the upgraded jar in my remote repository(which I'm able to do).
So what I'd like to know is whether there is a way to specify in pom to take whatever version is available in the remote repository for a particular artifact i.e., something like this(and this is just a guess):
<dependency>
<groupId>org.scala-lang.modules</groupId>
<artifactId>scala-parser-combinators_2.11</artifactId>
<version>${CurrentVersion}</version>
</dependency>
Some guidance would be very much appreciated.
If you are using maven2, then using LATEST or RELEASE value in version tag can solve the dependency updation automatically. Albeit , this solution will not work in maven3 (it is deprecated).
If you are using maven3, then you have to update the settings.xml a bit. The snapshots repository will get an addition updatePolicy tag. Something like this:-
<repositories>
<repository>
<id>you-snapshots</id>
<url>http://host/nexus/repos/snapshots</url>
<snapshots>
<updatePolicy>always</updatePolicy>
</snapshots>
<releases>
<updatePolicy>always</updatePolicy>
</releases>
</repository>
</repositories>
Also , There is a Versions plugin for Maven which allows you to update your pom to the latest greatest SNAPSHOTS in visible repositories. It does this by inspecting your pom and comparing against remote repositories and then modifying as required.
It is a useful tool but I would definitely like to see an equivalent to the deprecated LATEST option. I find this kind of dependency particularly useful in continuous integration scenarios.
Some things to notice:
You should not delete a specific release version of an artifact from a remote repository and replace it, like having 1.0.1 in your remote repository, removing it and uploading a different artifact under 1.0.1 again. Maven caches release versions in the local repository, so you will never know which artifact you get.
If you have a newer version, give it a newer version number (like 1.0.2).
Now the way to go is not to use RELEASE or LATEST, but to use the versions plugin to update your dependencies (like versions:use-latest-releases).
I am using snapshot dependency just for tests in my project
<dependency>
<groupId>com.my-company</groupId>
<artifactId>my-test-library</artifactId>
<version>LATEST</version>
<scope>test</scope>
</dependency>
I am aware about the risks of using LATEST but that's exactly what I want to achieve in tests. However, this test dependency blocks release of production code when I invoke mvn release:prepare with exception:
[INFO] Checking dependencies and plugins for snapshots ...
There are still some remaining snapshot dependencies.
...
Caused by: org.apache.maven.shared.release.ReleaseFailureException: Can't release project due to non released dependencies :
com.my-company:my-test-library:jar:LATEST:test
in project 'My Project'
My dependencyManagement:
<distributionManagement>
<repository>
<uniqueVersion>true</uniqueVersion>
<id>rep-releases</id>
<name>Release Repo</name>
<url>${url}</url>
</repository>
<snapshotRepository>
<uniqueVersion>true</uniqueVersion>
<id>rep-snapshots</id>
<name>Snapshots Repo</name>
<url>${url}</url>
</snapshotRepository>
</distributionManagement>
Why test code has anything to do with release procedure? How can I proceed with release and leave the dependency as it is?
What you're doing is really against all rules and you should also be making a release for your test dependency first, then releasing and then switching the version of the project to a snapshot and restoring the test-scoped dependency to a snapshot.
If you really, really, really must do stupid things, then you can specify the -DignoreSnapshots=true option. However, this will ignore any SNAPSHOT dependencies defined in your pom.xml which is even worse.
You have been warned. Proceed at your own risk and may God have mercy!
if you aware of all consequences of using LATEST. you may use the command:
mvn release:prepare -DignoreSnapshots=true
property ignoreSnapshots=true to allow SNAPSHOT dependencies
In my company's parent POM I specify corporate repositories, that we all use. The URLs contain server name and the path of course. Each time I change the POM I publish a new version.
Now imagine, that the server hosting our repos gets renamed. I can change all URLs in the parent POM (not a problem) and publish a new version with fixed URLs. But I can't change URLs in the existing versions of the parent POM.
This means, that I can't rebuild any artifact from the past.
Is there some standard way to get around this problem? Like:
Central property file
A configuration POM with a fixed 1.0.0-SNAPSHOT version, that get republished on any change?
You never put repositories except for distMngt in your POM. Again -- never. You have burned your POMs forever. This exists in Maven because repo managers did not exist back then. It is bad practice for years now and shall be removed.
Always use a Nexus instance with a repo group. This shall be added to your settings.xml which will mirror everything.
For those who don't believe, I am a long year Maven committer.
Another approach that we employ at work is to replace the URLs in the <distributionManagement> with parameters, like so:
<distributionManagement>
<repository>
<id>my-repo</id>
<name>My Release Repo</name>
<url>${url.deploy.releases}</url>
</repository>
<snapshotRepository>
<id>my-repo</id>
<name>My Release Repo</name>
<url>${url.deploy.snapshots}</url>
</snapshotRepository>
</distributionManagement>
This way, we use settings.xml to control where the artifacts should be deployed. This has the advantage that if you ever migrate a repository (which we did) you only need to update settings.xml for new builds/releases.
If you need to go back to an earlier release and republish (for whatever reason) you just checkout the release tag, set up settings.xml to point to the new repo and do a mvn clean deploy.
If you can't modify settings.xml you can always just copy it, change the copy and point out the new settings file with the -s flag.
This approach also works for <scm> tags.
If you use repositories in your parent pom and may change over time, the best strategy is in the URL or it use ALIAS (DNS, Apache redirect, Rewriting) and especially not the IP address directly , and you do not have to change the address of the repository every time.
Example:
<repositories>
<repository>
<id>myrepo</id>
<url>http://myrepo.me/content/repositories/public/</url>
</repository>
</repositories>
and:
http://myrepo.me/content/repositories/public/ => ip address 1.2.3.4/*/*/
In the command line help, I see that maven "checks" for updates:
-U,--update-snapshots Forces a check for updated
releases and snapshots on remote
repositories
However, most questions on Stack Overflow imply that this option forces Maven to update. Does this mean it forces a re-download of the dependencies?
e.g. https://stackoverflow.com/a/9697970/1119779
If you do not use -U, maven might cache results - even if a dependency could not be found previously (e.g. because your nexus [or alike] was unavailable, misconfigured, didn't contain the dependency [yet] or whatever). SNAPSHOT versioned jars are cached similarly.
If that's the case. Maven follows the repository's updatePolicy, which tells it how often (if ever) maven checks if a dependency has been updated (in the case of SNAPSHOT), or has become available, in the case of a released version. Default is daily therefore if a temp error causes maven to not download a dependency, it might take one day before maven tries again. -U overwrites that and tells it to check now.
-U does not re-download a SNAPSHOT dependency if it has already been downloaded and if the checksum is the same! It only checks for the checksum.
Update: as #Stas pointed out, if the checksum differs, it will re-download and override you local JARs with the ones from the remote repository.
** -U also checks for "updated" release versions if you specify a "version" range etc.
BTW: Maven uses a timestamp file that has the same name as the dependency + ".lastUpdated" to know when a dependency has been last checked on which server. E.g. ~/.m2/repository/org/springframework/spring-webmvc/3.1.2.RELEASE/spring-webmvc-3.1.2.RELEASE.jar.lastUpdated
Example for updatePolicy:
<repositories>
<repository>
<releases>
<enabled>false</enabled>
<updatePolicy>always</updatePolicy>
</releases>
<snapshots>
<enabled>true</enabled>
<updatePolicy>never</updatePolicy>
</snapshots>
<!-- ... -->
</repository>
<!-- ... -->
</repositories>
See http://maven.apache.org/pom.html#Repositories for further information about the updatePolicy.
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.
when you will get https://repo.spring.io/milestone was
cached in the local repository, resolution will not be reattempted until the update interval of spring-milestones has elapsed or updates are forced
in that case you have to use mvn clean package -U