Deploying an assembly to a FTP server using Maven 2 - maven-2

I have a project divided into several sub-modules (each of them are jar libraries):
myapp
myapp-commons
myapp-client
myapp-server
I've configured my pom.xml in order to create 3 assemblies (client.zip, oracle.tar.gz and server.tar.gz) that are finally stored in the myapp/target directory.
I want now is to distribute two of them (oracle.tar.gz and server.tar.gz) to a server using FTP.
Even if I didn't try yet, I know that I can do that quite easily using some lines of Ant inside my pom.xml, but I don't really like this option (I will solve my problem with Ant only if there are no other solution).
There are some SO questions (here or here) that offer solutions for that.
My question is to know if there is a better way to do that? I know about the Wagon Maven2 plugin but I didn't succeed in configuring it in order to deploy the assemblies (and not the JAR created).

As you say in your question, the Ant approach is not ideal, but if you don't find an alternative, this answer shows how to use the antrun plugin to deploy with FTP. The
Update, based on your updated question this part is less relevant, I'll leave it in to help others though.
The wagon-ftp plugin allows you to connect to FTP servers. I've not tried this, but you may then be able to bind the deploy-plugin's deploy-file goal to an appropriate phase to deliver the files to the FTP server (some hints on usage at this blog).

The way to deploy artifacts using FTP is documented in Deployment of artifacts with FTP:
In order to deploy artifacts using FTP
you must first specify the use of an
FTP server in the
distributionManagement element of
your POM as well as specifying an
extension in your build element
which will pull in the FTP artifacts
required to deploy with FTP:
...
<!-- Enabling the use of FTP -->
<distributionManagement>
<repository>
<id>ftp-repository</id>
<url>ftp://repository.mycompany.com/repository</url>
</repository>
</distributionManagement>
<build>
<extensions>
<extension>
<groupId>org.apache.maven.wagon</groupId>
<artifactId>wagon-ftp</artifactId>
<version>1.0-alpha-6</version>
</extension>
</extensions>
</build>
Your settings.xml would contain a server element where the id of that element matches id of the FTP repository specified in the POM above:
<settings>
...
<servers>
<server>
<id>ftp-repository</id>
<username>user</username>
<password>pass</password>
</server>
</servers>
...
</settings>
Now, my understanding is that you want to use such settings for a subset of the produced assemblies only. To do so, I'd create a dedicated module to produced the assemblies to be distributed using FTP and override the distributionManagement element with the FTP setup in this module only.

Related

Creating a link to the latest release with maven's deploy plugin

My pom.xml contains:
<distributionManagement>
<repository>
<id>ssh-myown-repository</id>
<url>scpexe://user#host/path/to/repository</url>
</repository>
</distributionManagement>
So whenever I issue:
mvn deploy
My project is, well, deployed properly on my remote repository, under a name such as this:
http://host/repository/project/0.7.0-SNAPSHOT/project-0.7.0-20120518.212052-3.jar
I know file "maven-metadata.xml" contains information about which file is the latest release, but I'd very much like the mvn deploy stage to create a link to the latest jar file, say:
http://host/repository/project/0.7.0-SNAPSHOT/project-0.7.0-latest.jar
I understand "scpexe" has no way of doing this directly as links are part of the file system on which the web server is running (ie.: they are not represented as uploadable file content).
I have shell access on this remote server, so is there a way to hook on maven's deploy action to execute a script after deployment is complete ?
You know that the -SNAPSHOT is a thing like the "LATEST". Furthermore i recommend to use a repository manager.

Ivy Configuration Help

I've read the Ivy docs and a few other tutorials but am now trying to actually use it in a project for the first time and I am immediately presented with some roadblocks.
For the practice, I would like to write all my own config (XML) files. Not sure where to put ivy.xml, ivyconf.xml or ivy-settings.xml: do I put them in the same directory as my build.xml?
Besides ivy.xml, ivyconf.xml and ivy-settings.xml, are there any other config files that I should know about? Where do I place those?
Is the IvyDE just a graphical Eclipse plugin that graphically edits ivyconf.xml or does it edit other files?
Thanks for any input - it's been surprisingly difficult finding good info on this amazing tool!
You need only one file ivysettings.xml. You could place it beside build.xml or in any desired project directory. Optionally you could use one or more properties files for different uses.
Besides ivysettings.xml remeber about ivy cache directory. Often the best solution for all dependency resolution problems is to clean ivy cache by deleting this directory.
IvyDE allows you to resolve project dependencies inside Eclipse. IvyDE creates new classpath container named ivy.xml. Inside this container you'll find resolved libraries.
And I recomend you to use local or intranet ivy repository with Eclipse, because if resolving takes some time it will slow down loading of your projects.
For example I placed my ivysettings.xml that I use in my projects. As you can see for Eclipse there is eclipse-ivy.properties file. In this file I order Ivy to use local repository inside Eclipse. In Ant script I use remote repository by default, but there is an option to choose local repository.
<?xml version="1.0" encoding="UTF-8" ?>
<ivysettings>
<settings defaultResolver="${ivy.resolver}" />
<statuses default="development">
<status name="release" integration="false"/>
<status name="integration" integration="true"/>
<status name="development" integration="true"/>
</statuses>
<resolvers>
<ssh name="remote" checkconsistency="true" checkmodified="true" descriptor="required">
<ivy pattern="ssh://***/home/ivy/repository/[organisation]/[module]/[revision]/ivy.xml"/>
<artifact pattern="ssh://***/home/ivy/repository/[organisation]/[module]/[revision]/[artifact]-[revision].[ext]"/>
</ssh>
<filesystem name="local">
<ivy pattern="${user.home}/.local-ivy-repository/[organisation]/[module]/[revision]/ivy.xml"/>
<artifact pattern="${user.home}/.local-ivy-repository/[organisation]/[module]/[revision]/[artifact]-[revision].[ext]"/>
</filesystem>
</resolvers>
</ivysettings>
elipse-ivy.properties:
ivy.resolver=local
In general, it's best to create a single standardized ivy-settings.xml file and host it in a location where your builds can get to it easily. This file will usually be the same for all projects and rarely change once you've got it setup properly. In my development group, we host the ivy-settings.xml file on a web server so that it can easily be referenced by URL.
We build with Ant so we've also come up with a standardized ant build file which can either be hosted somewhere and imported into an Ant build script or simply copied to a project's directory if any kind of customization is necessary.
I've found that it's best to leave the Ivy configuration files as is and do any kind of customization by overriding the default values in your build scripts and/or ivy.xml files. Just about anything you'd need to change can be overridden. I recommend leaving the Ivy configuration files unchanged because it makes it much easier for other users to build your projects. If you've got a bunch of changes to your config files, any other developer wishing to build your project will have to replicate those changes on their local Ivy installs just to run a local build. That's bad mojo.
The IvyDE plugin provides editors for your ivy.xml and ivy-settings.xml files. According to the documentation, it also provides ways to automatically download your project's dependencies, includes a custom console and a reverse dependency explorer to help troubleshoot and resolve dependency conflicts. I only use the editors, though, so I can't vouch for the other tools.
Like Alexey, I'd recommend using a repository manager with Ivy. Artifactory does the job nicely; It's easy to setup and rock solid once it's running.
I agree that the documentation leaves much to be desired; it took me several weeks of experimentation to really grasp how all the pieces fit together. In the end, it was entirely worth it. Once you've got all the kinks ironed out, a well tuned artifact management system is truly something beautiful to behold.

Maven + Mercurial + Site Deploy issues

I'm trying to deploy my Maven generated site to a googlecode project using mercurial.
When I do a
mvn site:deploy
I get Transfer error: org.apache.maven.scm.NoSuchCommandScmException: No such command 'list'.
Its like its trying to do a "svn list" even though I am using mercurial.
In my pom I have maven wagon and mercurial setup (I think correctly):
org.apache.maven.wagon
wagon-scm
1.0-beta-6
org.apache.maven.scm
maven-scm-provider-hg
1.4
Then for my site deploy I have a separate mercurial repository:
<distributionManagement>
<site>
<id>googlecode</id>
<name>googlecode site</name>
<url>scm:hg:${project.site.scm}/</url>
</site>
</distributionManagement>
In my settings.xml I have:
<servers>
<server>
<id>googlecode</id>
<username>...</username>
<password>...</password>
</server>
</servers>
Stumbled upon this question and thought I would provide an answer for anyone else as the documentation for how to do this is sparse:
For quite some time now I've been successfully hosting my website in a Google Code repository that uses Mercurial. It works well and I've had very little issues
First, you have to go to your project, tab "Administer", subtab "Source" and create a new repository called "site". Then, you have to commit and push at least one file, conveniently called "index.html" to that repository because "hg locate", which is called by the SCM plugin, fails on completely empty repositories.
I have this in my POM to deploy to http://site.MYREPO.googlecode.com/hg
<build>
<plugins>
...
<!--Deploy site with Mercurial (Hg)-->
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-site-plugin</artifactId>
<version>3.0-beta-3</version>
<dependencies>
<dependency>
<groupId>org.apache.maven.scm</groupId>
<artifactId>maven-scm-api</artifactId>
<version>1.5</version>
</dependency>
<dependency>
<groupId>org.apache.maven.scm</groupId>
<artifactId>maven-scm-provider-hg</artifactId>
<version>1.5</version>
</dependency>
</dependencies>
</plugin>
...
</plugins>
</build>
<!--
Distribution
-->
<distributionManagement>
<!--Site deploy repository-->
<site>
<id>MYREPO.googlecode.com</id>
<url>scm:hg:https://site.MYREPO.googlecode.com/hg</url>
</site>
</distributionManagement>
You then have to tell Maven your username and password, so add this to your Maven settings.xml file (note the # character is HTML encoded as Mercurial will choke on it normally)
<settings>
<servers>
<server>
<id>MYREPO.googlecode.com</id>
<username>MYEMAIL%40gmail.com</username>
<password>MYPASSWORD</password>
</server>
</servers>
</settings>
Now you can mvn clean site site:deploy and visit http://site.MYREPO.googlecode.com/hg/index.html to get your complete maven site.
site:deploy uses the scp or file protocol for deploying a site to the server (see here). I configure this along normal ssh lines (authorized_keys, etc). And in the pom have something along the lines:
<!-- The location for generating the website. -->
<distributionManagement>
<site>
<id>website</id>
<url>scp://username#server.com/path/to/deploy/directory/</url>
</site>
</distributionManagement>
It takes everything from the target/site directory and copies it across to the defined destination. However, the downside is, that it is up to me to ensure that what I have deployed is actually checked into my version control system. i.e:
hg push (use mercurial directly to push my changes to other developers).
mvn site:deploy (deploys from my local machine using scp).
First of all, I tried TheLQ's answer and even voted for that one (above), because it works for simple projects, especially if you also add wagon-scm and wagon-ssh dependencies to the maven-site-plugin and update all versions to the latest ;) With a multi-module project though I had an issue: each sub-module's site overwrites previously pushed content instead of nesting them (same problem with mvn deploy, i.e., deploying directly to a Hg managed remote maven repo does not create right folder hierarchy).
Therefore, here is an alternative solution, which also makes less commits to the remote repository (though, it requires a bit of manual work).
First, go to your Google Code project, https://code.google.com/p/MYPROJECT, tab "Administer", "Source" and create a new repository called, e.g., "site" (or how you'd like to call it). Then, you have to commit and push at least one file, conveniently called "index.html" to that repository.
Second, have the following in the parent project's pom.xml (only):
<distributionManagement>
<!-- ... other content ...-->
<site>
<id>MYPROJECT.googlecode.com</id>
<name>MYPROJECT auto-generated site</name>
<url>http://site.MYPROJECT.googlecode.com/hg</url>
</site>
</distributionManagement>
and also -
<url>http://site.MYPROJECT.googlecode.com/hg</url>
Note: Aye, it's "http:" and not "https:"; in my example, the URL is NOT going to be used by Maven to actually deploy the site content there (I am not going to execute site-deploy); instead, will use mvn site site:stage (see below). Also, you do not have to touch the settings.xml (the one in ~/.m2/ on *nix systems).
Third, simply clone the remote ('site') repository to your local machine (target directory can be under the parent project's dir as well as under anywhere else's - just cd to THAT_DIR where you want it):
cd THAT_DIR
hg clone https://USERNAME#code.google.com/p/MYPROJECT.site/
Note: if it existed, you do not have to clone again, just do hg pull, hg update (optionally remove old content using hg rm * and commit). You can also use e.g. free SourceTree software instead of console.
Next, from the projects root, do normally (skip 'clean, install' goals if you did already before; I used Maven 3.0.5):
mvn clean install site site:stage -DstagingDirectory=FullPathTo/MYPROJECT.site
Finally, switch to the clone/stage directory, THAT_DIR/MYPROJECT.site, test the website locally (open index.html in a browser), and if happy do:
hg add *
hg commit -m "re-generated MYPROJECT"
hg push
Check it out at http://site.MYREPO.googlecode.com/hg/index.html and the sources and changes at https://code.google.com/p/MYPROJECT.site/
Done.

Maven repository for Google Code project

I'm hosting a small open source project on Google Code, and I have been asked to submit the jar to a publicly accessible Maven repository. I have almost no practical knowledge of Maven. What would be the best way to do this?
Is there some central repository that I can submit to, or can I host my own? What would I need to do when I want to release a new version of the jar?
I've been Googling and found this, which looks nice and simple, but it seems a bit ... contrary to the spirit of Maven, to commit jar files to SVN :).
Also, would there be a way to still keep track of the download count, as Google Code does?
EDIT
I've been getting some answers, some of which containing hints on what to add to my pom.xml. Thanks guys! But obviously I forgot to mention one important thing: my build script is in ANT, and to put it bluntly, I intend to keep it that way :). I just want to make it easier for Maven users to include my jar in their projects.
The solution I went with in the end
In the end, I did use the solution I referenced before, where I simply commit a Maven repo to SVN. I have the ANT script call Maven to set up the local repo, and then call SVN to commit it to Google Code. For those interested: look at my build script here, in the publish-maven target.
There is a guide to the central repository that has a section on uploading projects that may help. If nothing else you can check the naming conventions and minimal information requirements against your project.
Sonatype also do OSS Repository hosting, see their guide for details.
Update: I'm not saying you should change your build process - if Ant works for you stick with it. It's worth following the Maven conventions in your POM regardless of your build method. As the point of putting your jar in a Maven repository is to make it accessible to Maven users, you will therefore need to define a POM for your published artifact. Following the naming conventions will help your users so you might as well do it. For example adding the SCM details to the pom will (amongst other things) allow your users to import the project into their workspace using the IDE integrations for Maven.
Basically, you have 4 options:
Perform a standard Maven build against a Maven repository (already ruled out)
Set up a Maven repository, do your builds with Ant, and use Maven to deploy the jar and POM.
Set up a Maven repository, ad use an Ant HTTP task to publish the artifacts
Use a Subversion "repository", and use the SvnAnt task to publish the artifacts
Option 1
Use Maven to build and deploy the artifacts (see the Maven book and the above links for details).
Option 2
Assuming you have a build process that creates your jar, and you've defined the POM, your best bet is to publish it to the Sonatype OSS repository as above.
Deploying an existing jar to a standard Maven repository is simple with the Maven deploy plugin's deploy-file goal:
Set up your repository (e.g on the Sonatype servers by raising a Jira request)
Build your jar with Ant.
If you have defined a POM, put it in the same directory as the jar.
Run the deploy-file goal:
mvn deploy:deploy-file -Durl=http://path/to/your/repository\
-DrepositoryId=some.id \
-Dfile=path-to-your-artifact-jar \
-DpomFile=path-to-your-pom.xml
Note that the Maven deploy goal will automatically translate the pom.xml to [project-name]-[version].pom. If you are doing either of the other two alternatives, you will need to ensure you commit the POM with the final name, i.e. [project-name]-[version].pom. You'll also need to ensure you compose the relative paths for the artifacts following the Maven conventions.
E.g. for groupId=com.foo.bar, artifactId=my-project version=1.0.0, the path to the files will be:
/com/foo/bar/my-project/my-project-1.0.0.jar
/com/foo/bar/my-project/my-project-1.0.0.pom
Option 3
If you want to use Ant to deploy to a Maven repository, you can use an Ant HTTP library (Note I've not tried this myself) . You would compose two HTTP put tasks, one for the jar and one for the POM.
<httpput url="http://path/to/your/repository" putFile="/path/to/yourproject.pom">
<userCredentials username="user" password="password"/>
</httpput>
<httpput url="http://path/to/your/repository" putFile="/path/to/yourproject.jar">
<userCredentials username="user" password="password"/>
</httpput>
Option 4
If you want to avoid Maven completely and use Ant to deploy to an SVN-backed repository, you can use the SvnAnt Subversion library. you would simply need to do configure the Svn import task to add your artifacts to the Remote Subversion repository.
<import path ="/dir/containing/the/jar/and/pom"
url="svn://your/svn/repository"
message="release"/>
Check wagon-svn. It will allow you to 'deploy' to a Subversion repository. It's a little convoluted, but it's better than nothing. I know of a few projects that use it at java.net, and I also came across some projects using it at code.google.com.
If you want to use it, then you first need to load wagon-svn as an extension:
<build>
...
<extensions>
<extension>
<groupId>org.jvnet.wagon-svn</groupId>
<artifactId>wagon-svn</artifactId>
<version>...</version>
</extension>
</extensions>
Next, you need to set your deployment targets using the svn: protocol identifier. Here's an example I copied from the Internet.
<distributionManagement>
<repository>
<id>maven-config-processor-plugin-repo-releases</id>
<name>Maven Repository for Config Processor Plugin (releases)</name>
<url>svn:https://maven-config-processor-plugin.googlecode.com/svn/maven-repo/releases</url>
<uniqueVersion>false</uniqueVersion>
</repository>
<snapshotRepository>
<id>maven-config-processor-plugin-repo-releases</id>
<name>Maven Repository for Config Processor Plugin (snapshots)</name>
<url>svn:https://maven-config-processor-plugin.googlecode.com/svn/maven-repo/snapshots</url>
<uniqueVersion>false</uniqueVersion>
</snapshotRepository>
</distributionManagement>
Check if the Maven repository support maven deploy plugin. This would be the easiest approach.
Most repositories uses ssh as the transport. See this for details.
Once it's setup, all you have to do is:
mvn deploy:deploy
You can submit your jar to https://clojars.org/
In your pom.xml:
<repositories>
<repository>
<id>clojars.org</id>
<url>http://clojars.org/repo</url>
</repository>
</repositories>

hudson/maven publishing snapshots

I would like to be able to publish snapshots to the repository using maven (or have hudson publish snapshots after each build using maven). I've been reading up on the SCM section of the POM, and I have a couple of questions. Sorry if I'm off base here - this part is new to me.
I don't want to put my username and password in SCM section the POM (under developer connection). Is there any other way for hudson (or anyone else using the maven task) to gain authorization to publish using maven without putting a username/password in the POM?
For just pulling from the repository using maven, can the SCM connection tag point to web svn (the URL tag does right now). In our repository, you need a username and password just to pull down the code.
Thanks,
Jeff
For publishing your login data can be placed in $HOME/.m2/settings.xml
<settings>
<servers>
<server>
<id>internal</id>
<username>admin</username>
<password>admin</password>
</server>
</servers>
</settings>
For pulling from source control you'll need to configure Hudson, and it does not need to read from the POM.
You could remove the SCM section from your pom and have hudson pass "-Dproject.scm.developerConnection=scm:type:user#pass:foobase://footron/fooproj" on to maven.
Hudson doesn't need the SCM section. As far as I can tell, you only the scm info (either by tag or by passing it in) for release. You can deploy snapshots without the SCM tags.