Is there any way to force Maven to use remote artifacts and not those installed on your machine? since I worry about runtime errors and not compilation errors build server is not valid option.
P.S. I know I could delete or rename the .m2 folder, but I bet there is some more clever way of doing this. Maybe some plugin or special command param?
Having no local repository would mean your classpath consisting almost entirely of URLs on remote servers. I can't see why this would be supported as execution would be awful, and any dropped connection would result in classloader issues. Having a local repository ensures the jars are available before compilation/execution begins.
Also consider that WAR and EAR projects (and many using the dependency plugin) rely on downloading the jars to complete their packaging. There would be a huge overhead if these had to be retrieved from a remote repository on every build. I'm pretty sure the managers of central would not be keen on dealing with that load.
Some alternatives for you to consider:
If you want to force a clean local repository on each build, you can use the purge goal of the dependency plugin.
If you want to keep builds isolated, you can use separate Maven settings by passing -Dorg.apache.maven.global-settings=/path/to/global/settings.xml
Alternatively you can override the local repository on a per build basis by passing -Dmaven.repo.local=/some/repo/path
If you want to avoid hitting remote repositories on each build, add <updatePolicy>never</updatePolicy> to your remote repository configurations. This means Maven will only check for updates if you force it to with a "-U" switch on the command line
If you want to take the latest version of a dependency, you can use the LATEST keyword in the version declaration (instead of the version number), though this can be risky if the dependency is incompatible.
If you want to take the current release version of a dependency, you can use the RELEASE keyword in the version declaration (instead of the version number). This is like LATEST, but tends to be the newest stable build, rather than the newest.
If you want to take the latest version of a dependency within a range, use Maven's version range notation, for example [1.0.0,2.0.0) means any version from 1.0.0 inclusive to 2.0.0 exclusive
For more details on LATEST and RELEASE, see section 9.3.1.3 of the Maven book.
If you use an internal repository manager (obligatory Nexus and Artifactory references here), the overhead of purging the local repository is greatly reduced - you'll just have an increased local network traffic load.
I don't think there's really a way to do what you are asking for. You could look into depending on SNAPSHOT releases (but that means changing your version string of the upstream projects to be SNAPSHOT versions).
Incidentally, this was discussed at length in a recent Java Posse episode (#268). I don't think they ended up with a solution, but you may get some good ideas there.
I also like some of Rich Seller's ideas, which I'll be looking into myself.
Related
Is it best practise to store snapshot versions in Artifactory in maven applications?
As snapshot versions should be used only for development purposes.
It's not true that SNAPSHOT versions should be used only for development. When SNAPSHOT version is uploaded it's not uploaded as is - it gets transformed into a unique version, something like this: 1-20150904.140213-59. When referencing such dependency you can:
either use SNAPSHOT word like 1-SNAPSHOT, then you don't really know which exact version is used
or use a resolved version: 1-20150904.140213-59
Using the 1st option is discouraged for any purpose - be it a deployment, or a <dependency> in pom.xml (even for development purposes), because it leads to non-repeatable actions. You run build once - you get a dependency with version 1-20150904.140213-59 downloaded, you run it for the 2nd time you may get another version like 1-20150904.140214-60.
But there's nothing wrong with referencing the full (resolved) version. So you can leverage snapshots the same way you do with release versions. Note though that remote repositories (e.g. Nexus) can be configured to delete old snapshot versions - so you need to take this into consideration.
By the way, snapshots are very convenient for releases.
A SNAPSHOT version is meant to be used for development. You can store it in Artifactory, but for using an artifact productively, you should build a release version.
#Stanislav is right that timestamped SNAPSHOTs could technically be used like release versions, and I believe him that this works, but I wouldn't do it because it is not how SNAPSHOTs and releases were meant to be.
Currently I'm in the transition of moving ANT projects to Maven and struggling on how to get the project versioning working correctly. Currently I have about 30+ projects/modules that all rely on each other so everything must be at the latest version to work correctly. This was easily done with ANT but when it comes to Maven I would need to make constant changes to all other released project POM's to allow them to pick up these new changes.
I discussed with a few other developers and we decided we might not even need a maven repo with version numbers, we just have everything at the same version number and build locally or through Jenkins to update our .m2 folders. Does this sound like the correct route for our situation? Are we missing anything doing this?
I did suggest having our test Jenkins to deploy to a repo with version numbers like 1.0.Beta-SNAPSHOT. We have Jenkins setup to build when our testing branches are updated. This means I would not have to locally compile every project on that branch to update my .m2, I could just change the POM to pull all these Beta-SNAPSHOT versions in one place. Would there be a good way for me to do this that would not affect the release if it was pushed and released with this version number set? If I wanted to use my local versions I would then just switch this version number to 1.0.0 which isn't within the repo but my local .m2.
Any suggestions on how to properly manage the maven projects/modules with version numbers would be welcome! Something that reduces the need to change every POM when releasing 1 of the projects/modules would be best!
Our developer struggle with this problem a lot. It is a lot of manual work to update all the POMs for a release.
We are going to aim for multi-module projects, which also seems like a good fit for you.
If you say, that everything must be using the latest versions all the time, I would put all the projects into one large multi-module project. This means that you have one (git) repository with a main POM in the root directory and a directory for each module (sub-project) with its own POM references the main POM as parent.
Then you can run mvn clean install on the parent and build all the modules with consistent version numbers. So releasing is then just one large build.
You should note, though, that you tie the projects (modules) closely together in this way, but it I understood you correctly, they are already tightly interrelated.
I have a project that has 3rd party dependencies, as well as dependencies on internal projects. I need to strip the version numbers from the dependent artifacts that are developed in-house.
For example: spring-2.5.6.jar should be in the final output as spring-2.5.6.jar but MyInternalProject-1.0.17.jar needs to be changed to MyInternalProject.jar.
I can identify the internal dependencies easily enough by their group ID (they are all something like com.mycompany.*). The maven-dependency-plugin has a stripVersion option, but it does not seem to be selective enough. Is there a way to do this, short of explicitly naming each dependency and what their final name should be?
Phrased another way:
I would like to have different outputFileNameMappings for the maven-assembly-plugin for artifacts based on group ID. Is there a way to do this?
I think you can using the following recipe:
First, in your aggregator pom use the dependency:copy-dependencies goal to copy your jars to some intermediate location. You will need two executions, one with <stripVersion>true</stripVersion> for your internal dependencies; and one with <stripVersion>false</stripVersion> for 3rd party libraries. You may include/exclude artifacts based on GroupId, see http://maven.apache.org/plugins/maven-dependency-plugin/copy-dependencies-mojo.html for full details.
Then it should be a simple task to build a .zip using the maven-assembly-plugin!
Based on the comments, I would re-evaluate your approach here. Generally checking jars into source control is not a good idea, especially unversioned jars. Imagine if I just had a project that referenced someArtifact.jar and I was trying to debug it - how would I know which version it used?
Tools like artifactory and nexus were built for storing versions of your jars, both internal and 3rd party (they can also proxy public repositories like maven central). In order to keep builds reproducible, I would check your binaries into a tool designed for that, and then you can reference them by version. During development, you can reference SNAPSHOT versions of your jars to get the latest, and then when you do a release, you can reference stable versions of your binaries.
Source control systems were meant for storing source, not binaries.
I am on Netbeans and don't know Maven much. Whenever I import, open some Maven project, it starts donwloading something from some central repository, sometimes huge. It downloads things in .m2\repository.cache\m2e. I have limited bandwidth and don't want this. How to stop this?
I have set Options>Java>Maven>Dependency Download Strategy to never. Also tried mvn -o install and mvn -o for offline. Not solved.
The Maven way is to get you what the project says it needs, but you have not already downloaded to your local repository.
The huge file is the list of what is actually available in Maven Central, and for some reason unknown to me it is downloaded on a regular basis. If you do it once, it should be kept for future sessions.
Maven will download all the dependency only once to the local repository and not again and again.
Weather you have limited or unlimited bandwidth you have to download it to execute your project.
Maven has a very modular architecture. That means the the thing you get when you download the Maven distribution is in reality small core functionality.
The rest is downloaded from a Maven artifact repository, like Maven Central (which is the default repo).
Note that this applies not only for dependencies (the library your project uses), but also your plugins (i.e. the stuff that compiles, packages, and otherwise builds the projects). Hence the large number of downloads.
Like the other answers said, if you don't delete your local repository it should eventually contain all the artifacts (dependencies and plugins) you need without re-downloading. The only exception are SNAPHSOT dependencies which can get re-downloaded periodically, depending what's in your POM and settings.
Ultimately, you have two possibilities:
If you have access to a higher-bandwith connection somewhere, you can build the projects while using it, and your local repo will still store the needed artifacts.
If you have several computers/configurations behind a local network, you can set up a Maven repository manager, like Nexus or Artifactory, and use it as a local mirror. Note that those still need to download the artifacts at first as well.
But there isn't much else you can do. "Maven downloading the Internet" is, unfortunately in your case, by design.
Warning: I have just picked up Maven, so things mentioned might be wrong or not best practice.
I have a medium size open source project that I am migrating to Maven from the basic
NetBeans project management. This is not a developer team sharing the same room, this is 1-5 people over the internet sharing a SVN repo. Reading over the how-tos on dependencies, it seems that the only way to get dependencies is to get them from an online repo or install them locally.
This is not what I was looking for. I want to keep all dependencies in the SVN for many reasons including portability (anybody can pass by, check out the repo, build, and use; all that simply without manual adding to local repo's and whatnot), getting newer versions (discussed below), and manual versioning.
The other issue I have with the maven repository is that they are quite behind in versions. Logback for example is 0.9.18 in mvnbrowser but 0.9.24 officially. PircBot is 1.4.6 in mvnbrowser but 1.5.0 officially. Why such old versions?
Issue 3 is that I have dependencies that don't even exist in the repos, like Easier Java Persistence.
So
How can I force all dependencies to come from /lib for example
On a related note, can mvn build from library's SVN repo directly? Just curious
Is there an automatic way to get the newest version directly from a dependencies site/svn repo if they also use Maven? IE libraries like commons-lang or logback
Is there a better way of managing dependencies? (IE Ivy or some weird POM option I'm missing)
FYI, this is a Java project with 3 modules, project global dependencies and module specific dependencies.
Bonus points if it can work with the bundled version of Maven that comes with NetBeans.
Not a duplicate of
Maven: add a dependency to a jar by relative path - Not wanting to install to local repository
maven compile fails because i have a non-maven jar - Don't think a System dependency is the right answer
maven look for new versions of dependencies - Still uses(?) repository, just the latest (old) version
This is not what I was looking for. I want to keep all dependencies in the SVN for many reasons (...)
I will come back on this but the solution I described in Maven: add a dependency to a jar by relative path (using a file-based repository) allows to implement such a solution.
The other issue I have with the maven repository is that they are quite behind in versions. Logback for example is 0.9.18 in mvnbrowser but 0.9.24 officially. PircBot is 1.4.6 in mvnbrowser but 1.5.0 officially. Why such old versions?
It looks like mvnbrowser indices are totally out of date (making it useless as repository search engine) because the maven central repository does have logback-core-0.9.24.jar (the logback project is doing what has to be done to make this happen) but only has an old pircbot-1.4.2.jar. Why? Ask the pircbot team. Anyway, you're right, the central repository might not always have ultimate versions.
Issue 3 is that I have dependencies that don't even exist in the repos, like Easier Java Persistence.
Yeah, this happens too.
How can I force all dependencies to come from /lib for example
As previously hinted, you should re-read carefully the solution suggested in Maven: add a dependency to a jar by relative path. This solution is not about installing libraries to the local repository but is about using a file-based repository (that could thus be stored in SVN). You might have missed the point, this matches your use case. And also check Brett's answer for a variation.
On a related note, can mvn build from library's SVN repo directly? Just curious
Didn't get that one. Can you clarify?
Is there an automatic way to get the newest version directly from a dependencies site/svn repo if they also use Maven? IE libraries like commons-lang or logback
Maven supports version ranges and you could use a syntax allowing to use "any version greater than X". But I do NOT recommend using version ranges at all, for the sake of build reproducibility. You don't want the build to suddenly fail because of some automatic update that happened on your back. Only upgrade if you need bug fixes or new features, but do it explicitly (if it ain't broke, don't fix it).
You might also find mentions of the LATEST and RELEASE version markers. I don't recommend them neither for the same reasons as above and even less since they're removed from Maven 3.x.
Is there a better way of managing dependencies? (IE Ivy or some weird POM option I'm missing)
Can't say for Ivy. But in the Maven land, if you can't host up a "corporate" repository for your project (Nexus, Archiva, Artifactory), then the file-based repository is IMO the best approach.
Setup your own Maven repository.
http://archiva.apache.org/