16

I have a few projects with LOTS of maven dependencies. When I invoke the command mvn deploy (or some variation of it), I would like to not only have the project itself deployed to the remote repository, but also all of its dependencies as well. Is this possible? I see many 'similar questions' on this site, but I can't seem to find anything that is as simply put as this. Everything else I've seen seems to expect some additional functionality. I simply want to deploy my project, plus all of its dependencies to the remote repo. I'm using the maven compiler plugin 1.5

This is a snippet of my settings.xml. Any idea what I'm missing?

<mirrors>
<mirror>
  <!--This is used to direct the public snapshots repo in the 
      profile below over to a different nexus group -->
  <id>nexus-public-snapshots</id>
  <mirrorOf>public-snapshots</mirrorOf>
  <url>http://{ourServer}/nexus/content/groups/public-snapshots</url>
</mirror>
<mirror>
  <!--This sends everything else to /public -->
  <id>nexus</id>
  <mirrorOf>*</mirrorOf>
  <url>http://{ourServer}/nexus/content/groups/public</url>
</mirror>
  </mirrors>
<profiles>
<profile>
  <id>development</id>
  <repositories>
    <repository>
      <id>central</id>
      <url>http://central</url>
      <releases><enabled>true</enabled></releases>
      <snapshots><enabled>true</enabled></snapshots>
    </repository>
  </repositories>
 <pluginRepositories>
    <pluginRepository>
      <id>central</id>
      <url>http://central</url>
      <releases><enabled>true</enabled></releases>
      <snapshots><enabled>true</enabled></snapshots>
    </pluginRepository>
  </pluginRepositories>
</profile>
<profile>
  <!--this profile will allow snapshots to be searched when activated-->
  <id>public-snapshots</id>
  <repositories>
    <repository>
      <id>public-snapshots</id>
      <url>http://public-snapshots</url>
      <releases><enabled>false</enabled></releases>
      <snapshots><enabled>true</enabled></snapshots>
    </repository>
  </repositories>
 <pluginRepositories>
    <pluginRepository>
      <id>public-snapshots</id>
      <url>http://public-snapshots</url>
      <releases><enabled>false</enabled></releases>
      <snapshots><enabled>true</enabled></snapshots>
    </pluginRepository>
  </pluginRepositories>
</profile>
 </profiles>

Thanks in advance
~j

jacosta
  • 447
  • 1
  • 7
  • 19
  • I think you are getting it wrong, using maven you build it in your development environment and deploy the deliverable(jar,war,ear, or osgi bundle) to the server. what do you mean exactly by the remote repository??? is it a server?? or a code repository??? – Rajesh Pantula Jan 12 '12 at 19:24
  • No. i'm referring to deploying to my corporate remote maven repository, using 'mvn deploy' in the command line (or "Run As -> Maven Deploy" using m2Eclipse Eclipse plugin) – jacosta Jan 12 '12 at 19:34
  • we are using sonatype nexus, if that makes a difference, although i think mvn install/mvn deploy are specific to maven, not nexus – jacosta Jan 12 '12 at 19:35
  • possible duplicate of http://stackoverflow.com/questions/207281/what-is-the-difference-between-mvn-deploy-to-a-local-repo-and-mvn-install – Rajesh Pantula Jan 12 '12 at 20:22
  • 1
    No. I'm not asking for the difference between mvn install and mvn deploy. I already know that mvn install 'installs' to the local repository, and mvn deploy 'deploys' to the remote repository. I'm asking for a possible way to use mvn deploy to not only deploy the project to the remote repository, but also all of its dependencies. – jacosta Jan 12 '12 at 20:57
  • Where and How do you get those dependencies initially? shouldn't they download from the "remote repository" when you initially setup you project, for instance mvn eclipse:eclipse. – yorkw Jan 12 '12 at 21:27
  • these are typically third party artifacts, downloaded from the internet, such as commons-email and fast-md5, for example. These artifacts have been added to users' local repositories, but never added to the remote (actually the remote repository hasn't really been used at all for a couple of years). So what i have now, is a remote repository that is not current, and is also missing certain dependencies. I could obviously go through all of the artifacts in my \.m2 directory and use mvn deploy:deploy-file, but that would take forever. – jacosta Jan 12 '12 at 21:32

3 Answers3

21

I propose the following solution which looks a lot less like trial and error for resolving dependencies compared to the existing answers.

What you can do is to call mvn -Dmdep.copyPom=true dependency:copy-dependencies after deploying the main project. This will copy transitively all dependencies of your project to target/dependency including their respective pom files.

You can then iterate through all of the dependencies and deploy them to the repository using deploy:deploy-file, e.g. with such a bash loop:

for pom in target/dependency/*.pom; do mvn deploy:deploy-file -Durl=http://your/repo -Dfile="${pom%%.pom}.jar" -DgeneratePom=false -DpomFile="$pom"
languitar
  • 6,554
  • 2
  • 37
  • 62
  • 2
    I think this is the only way and only correct answer to the question. This way you can have much flexibility if you don't want transitive dependencies to be included. – FranXho Aug 07 '18 at 11:08
  • 1
    @Ianguitar awesome solution, congratulations! thks! – Ady Junior Mar 28 '19 at 19:19
  • @languitar, your solution worked on my project. Do you know we can achieve the same goal by using maven plugin on pom.xml file?? and we will show the path of the containing folder of jars and maven will deploy to remote repository – Eric Jul 09 '20 at 13:55
  • @Eric I am not aware of other solutions, but haven't looked into this since ages. – languitar Jul 09 '20 at 15:08
  • Note: In case you get the `Unknown lifecycle phase ".copyPom=true"` error, use `mvn -D"mdep.copyPom"=true dependency:copy-dependencies` instead. – Avestura Oct 25 '22 at 07:40
4

Here's how it works in a nutshell, assuming your remote repository (Nexus, or Artifactory, or the like) and settings.xml are configured correctly.

Let's say you have a project with one dependency on commons-logging. When Maven resolves your project's dependencies as part of a build, it does these steps:

  1. Checks local repo for commons-logging.
  2. If found, done. Continue with build.
  3. If not found: checks for commons-logging in the remote repo.
  4. If found, download artifact to local repo. Done; continue with build.
  5. If not found in remote repo: remote repo contacts central to download commons-logging. Then it's available for Maven to download to local repo. Done; continue with build.

At the end of these steps, commons-logging should be in both your local and remote repos with nothing further to do. If this is not the case, then either your settings.xml is not configured to connect to the remote repo when searching for dependencies (is it contacting central directly?) or Nexus isn't configured correctly.

---- Edit ----

Here's a snippet of my settings.xml that works. @Raghuram gave you a good tip when he suggested you enable both profiles; if you somehow enabled only the public-snapshots profile your builds would continue to hit maven central directly.

....
<mirrors>
    <!-- redirects all traffic to internal Nexus repo instead of Maven central -->
    <mirror>
        <id>maven2</id>
        <mirrorOf>*</mirrorOf>
        <url>http://repository.someCompany.com/maven2RepoOrGroupInNexus</url>
    </mirror>
</mirrors>
....
<profiles>
    <profile>
        <id>repo-profile</id>
        <repositories>
            <repository>
                <id>central</id>
                <url>http://gotoNexus</url>  <!-- URL is unimportant here -->
                <snapshots>
                    <enabled>true</enabled>
                    <updatePolicy>daily</updatePolicy>
                </snapshots>
                <releases>
                    <enabled>true</enabled>
                    <updatePolicy>daily</updatePolicy>
                </releases>
            </repository>
        </repositories>
    </profile>
</profiles>
<activeProfiles>
    <activeProfile>repo-profile</activeProfile>  <!-- important -->
</activeProfiles>

Note the activeProfiles element at the bottom; that's how to ensure you'll use Nexus instead of Maven central with every mvn command.

You still need to make sure Nexus is configured so that the URL defined in the <mirror> includes content from Maven central, but how to configure Nexus would be a separate question.

Reference: Nexus docs for Maven configuration

user944849
  • 14,524
  • 2
  • 61
  • 83
  • I thought i had this working, but i still can't seem to install from both my remote repository and central at the same time. I'm able to get it to install from one or the other. I added a snippet of my settings.xml to my original question if you wouldn't mind giving it a look. – jacosta Mar 27 '12 at 13:25
2

You could start with a clean local repository, attempt to build your application and for any dependency failure, deploy that application to your corporate repository. This would ensure that all the dependencies that your application needs resides in the corporate repository prior to your application getting built and deployed.

Prior to this, you would configure your local repository to mirror central and other well-known repositories, so that open source third-party libraries automatically get into your remote repository instead of having to be manually uploaded.

It may turn out that you may not have too many third-party libraries which you would need to manually deploy.

Raghuram
  • 51,854
  • 11
  • 110
  • 122
  • Can you elaborate on your point about "configuring the local repository to mirror central and other well-known repositories"? I'm not sure what you mean by this. If my local repository mirrors central, how will the libraries end up in the remote repository? I apologize, i'm not extremely well-versed in this.... – jacosta Feb 13 '12 at 19:18
  • @jacosta. Typically a repository manager is configured to both `mirror` `central` and other needed repositories, as well as allow deployment of project-specific artifacts. The latter would be done using `mvn deploy`. – Raghuram Feb 14 '12 at 13:37
  • so if i mirror central, and do an `mvn deploy`, it will pull everything necessary from central to my local repo, and also deploy everything necessary to the remote repo? – jacosta Feb 14 '12 at 20:05
  • I thought i had this working, but i still can't seem to install from both my remote repository and central at the same time. I'm able to get it to install from one or the other. I added a snippet of my settings.xml to my original question if you wouldn't mind giving it a look. – jacosta Mar 27 '12 at 13:24
  • @jacosta. `can't seem to install` is vague. Can you provide more details - maybe a separate question? – Raghuram Mar 28 '12 at 04:12
  • i can certainly post a different question, but this issue is basically still related as far as i'm concerned.... What i want to do is do is invoke 'mvn install' in my eclipse workspace for my application and have it pull dependencies from maven central as well as my remote repository from that same command, as opposed to changing the settings.xml to point to one or the other. Does that make sense? I added a sample of my settings.xml in the original question, if that helps. I've tried deploying the dependencies to my remote repo, but there seems to be a TON of dependencies. – jacosta Mar 29 '12 at 20:18
  • essentially, my experience is not matching up with what user944849 is saying. Both items 4 and 5 do not happen. Only one or the other happens depending on what i put in my settings.xml. So i'm thinking my issue is related somehow to my settings.xml configuration – jacosta Mar 29 '12 at 20:21
  • @jacosta. What happens if you specify all the repositories in a single profile instead of separate `development` and `public-snapshots` profile? – Raghuram Mar 30 '12 at 04:01