Section 4.8. Publishing Maven Artifacts


4.8. Publishing Maven Artifacts

The previous labs covered how to add project visibility on quality and progress. Now let's add visibility on deliverables by publishing a project's artifacts. Let's consider the QOTD project. It has several artifacts: a JAR in qotd/core, a WAR in qotd/web, and a zip in qotd/packager. Imagine you want to deploy them to a Maven remote repository.

4.8.1. How do I do that?

Several Maven plug-insincluding the JAR, WAR, EAR, and RAR plug-insdeploy the artifact they generate. Thus, to deploy a JAR you use jar:deploy, to deploy a WAR you use war:deploy, to deploy an EAR you use ear:deploy, etc.

Under the hood all these deploy goals use the Artifact plug-in's artifact:deploy Jelly tag to perform the actual deployment. Thus, to properly deploy an artifact you need to find out how to configure the Artifact plug-in.

Let's practice by deploying the qotd/core JAR. The first thing to decide is what deployment protocol you're going to use. The Artifact plug-in supports several deployment protocols: SCP, file copy, FTP, and SFTP (see http://maven.apache.org/reference/plugins/artifact/protocols.html for more details).

You are going to use the SCP method to deploy the JAR artifact, as it is one of the most commonly used protocols, and it's secure. You also need to tell the Artifact plug-in where to deploy to. Let's imagine you'd like to publish to www.mavenbook.org, for example.

As these properties are true for any subproject in QOTD, add the following Artifact plug-in properties to common/project.properties:

maven.repo.list = mavenbook    maven.repo.mavenbook = scp://www.mavenbook.org maven.repo.mavenbook.directory = /var/www/html/mavenbook/maven

Unfortunately, you won't be able to publish to mavenbook.org. If you want to try this, you'll need your own SSH server. Sorry!

Deployment properties are defined for the mavenbook deployment repository using the following syntax: maven.repo.[repository name].*, where [repository name] is mavenbook. maven.repo.list is a comma-separated list containing all the repositories to deploy to, and in this case you are publishing to only one remote repositorymavenbook. The maven.repo.mavenbook property defines both the protocol to use (SCP here) and the deployment host. maven.repo.mavenbook.directory specifies the deployment directory on the host server.

You also need to specify deployment credentials. It's best to define those in a build.properties file, as this file is not meant to be checked in your SCM and you want your password to remain secret. If your deployment server uses username/password authentication, you'll define:

maven.repo.mavenbook.username = vmassol maven.repo.mavenbook.password = somepassword

Simply define the following properties:

maven.repo.mavenbook = ftp://www.mavenbook.org maven.repo.mavenbook.directory = /var/www/html/mavenbook/maven maven.repo.mavenbook.username = vmassol maven.repo.mavenbook.password = somepassword

to publish using FTP.

If your SSH server supports private key authentication, you can use the maven.repo.mavenbook.privatekey and maven.repo.mavenbook.passphrase properties instead of a password. A more secure approach is to configure an authentication key for SSH in a user account on the machine you want to deploy from.

The Artifact plug-in uses the JSch framework (http://www.jcraft.com/jsch/) under the hood for supporting the SSH protocol. You'll get the following kind of stack trace error:

com.jcraft.jsch.JSchException: Auth fail         at com.jcraft.jsch.Session.connect(Unknown Source)         at org.apache.maven.deploy.deployers.GenericSshDeployer...

if you have not configured authentication correctly.

Publish the core JAR artifact:

C:\dev\mavenbook\code\reporting\core>maven jar:deploy [...] jar:deploy:     [echo] maven.repo.list is set - using artifact deploy mode Will deploy to 1 repository(ies): mavenbook Deploying to repository: mavenbook Deploying: C:\dev\mavenbook\code\reporting\core\project.xml-->mdn/poms/qotd-core-1.0.pom Executing command: mkdir -p /var/www/html/mavenbook/maven/mdn/poms    Executing command: chmod g+w /var/www/html/mavenbook/maven/mdn/poms/qotd-core-1.0.pom    Deploying: C:\dev\mavenbook\code\reporting\core\project.xml.md5-->mdn/poms/qotd-core-1.0.pom.md5 Executing command: mkdir -p /var/www/html/mavenbook/maven/mdn/poms    Executing command: chmod g+w /var/www/html/mavenbook/maven/mdn/poms/qotd-core-1.0.pom.md5    Will deploy to 1 repository(ies): mavenbook Deploying to repository: mavenbook Deploying: C:\dev\mavenbook\code\reporting\core\target\qotd-core-1.0.jar-->mdn/jars/qotd-core-1.0.jar Executing command: mkdir -p /var/www/html/mavenbook/maven/mdn/jars    Executing command: chmod g+w /var/www/html/mavenbook/maven/mdn/jars/qotd-core-1.0.jar    Deploying: C:\dev\mavenbook\code\reporting\core\target\qotd-core-1.0.jar.md5-->mdn/jars/qotd-core-1.0.jar.md5 Executing command: mkdir -p /var/www/html/mavenbook/maven/mdn/jars    Executing command: chmod g+w /var/www/html/mavenbook/maven/mdn/jars/qotd-core-1.0.jar.md5    BUILD SUCCESSFUL

4.8.2. What just happened?

The artifact:deploy tag is executing commands on the remote machine using SSH. The structure of the repository is being created, and all directories and files are made group-writable with chmod. As you can see from the console, the artifact:deploy tag has deployed not only the core JAR, but also the core project's POM. This is because the POM is the identity of a Maven project and it may be useful for a user browsing the repository to know more about the project producing the artifacts he's looking for. In practice the POMs will also enable Maven 2 to support transitive dependencies. This means that in the future you'll be able to specify only the direct dependencies your project is depending upon, and Maven will auto-discover the dependencies of your dependencies.


Note: Transitive dependencies are going to be a huge timesaver.

Because you can never be too security conscious, the artifact:deploy tag creates MD5 signatures for every deployed artifact. Maven currently does not use them when downloading artifacts, but they'll certainly be implemented in the future.

4.8.3. What about...

...publishing the packager's zip file?

Publishing the JAR was easy because there's an existing jar:deploy goal. However, there's no zip plug-in, and thus no zip:deploy goal! The solution is to write a custom goal in your maven.xml file. Edit the qotd/packager/maven.xml file and add the code in bold:

<?xml version="1.0"?>    <project default="qotd:build"      xmlns:ant="jelly:ant"     xmlns:artifact="artifact">      <goal name="qotd:build">     <ant:mkdir dir="${maven.build.dir}"/>     <ant:zip destfile=         "${maven.build.dir}/${pom.artifactId}-${pom.currentVersion}.zip">       <ant:fileset file="${pom.getDependencyPath('mdn:qotd-web')}"/>       <ant:fileset dir="${maven.src.dir}/conf"/>     </ant:zip>   </goal>      <goal name="qotd:deploy" prereqs="qotd:build">     <artifact:deploy         artifact="${maven.build.dir}/${pom.artifactId}-${pom.currentVersion}.zip"         type="zip"         project="${pom}"/>   </goal>    </project>

The qotd:build goal creates the QOTD zip (see Chapter 3 for a refresher). You've now added a qotd:deploy goal that uses the artifact:deploy Jelly tag to deploy the zip file, and then passed in the artifact attribute. The type attribute corresponds to the artifact extension that is used to decide in which directory to put the artifact in the remote repository. You need to pass a reference to the current project's POM in the project attribute. Running qotd:deploy deploys the zip to the remote repository, in [REMOTE_REPO_ROOT]/mdn/zips/qotd-packager-1.0.zip, following the standard repository mapping rule, [REPO_ROOT]/<groupId>/<type>s/<artifactId>-<currentVersion>.<type>, discussed in Section 1.1.



Maven. A Developer's Notebook
Maven: A Developers Notebook (Developers Notebooks)
ISBN: 0596007507
EAN: 2147483647
Year: 2003
Pages: 125

flylib.com © 2008-2017.
If you may any questions please contact us: flylib@qtcs.net