<?xml version="1.0" encoding="UTF-8"?>
<rss version="2.0"
	xmlns:content="http://purl.org/rss/1.0/modules/content/"
	xmlns:wfw="http://wellformedweb.org/CommentAPI/"
	xmlns:dc="http://purl.org/dc/elements/1.1/"
	xmlns:atom="http://www.w3.org/2005/Atom"
	xmlns:sy="http://purl.org/rss/1.0/modules/syndication/"
	xmlns:slash="http://purl.org/rss/1.0/modules/slash/"
	>

<channel>
	<title>aheritier.net &#187; Apache Archiva</title>
	<atom:link href="http://blog.aheritier.net/tag/apache-archiva/feed/" rel="self" type="application/rss+xml" />
	<link>http://blog.aheritier.net</link>
	<description></description>
	<lastBuildDate>Mon, 30 Jan 2012 16:35:07 +0000</lastBuildDate>
	<language>en</language>
	<sy:updatePeriod>hourly</sy:updatePeriod>
	<sy:updateFrequency>1</sy:updateFrequency>
	<generator>http://wordpress.org/?v=3.3.1</generator>
		<item>
		<title>From Apache Archiva to Sonatype Nexus</title>
		<link>http://blog.aheritier.net/from-apache-archiva-to-sonatype-nexus/</link>
		<comments>http://blog.aheritier.net/from-apache-archiva-to-sonatype-nexus/#comments</comments>
		<pubDate>Tue, 09 Feb 2010 07:00:51 +0000</pubDate>
		<dc:creator>Arnaud Héritier</dc:creator>
				<category><![CDATA[Technologie]]></category>
		<category><![CDATA[Apache Archiva]]></category>
		<category><![CDATA[Apache Maven]]></category>
		<category><![CDATA[Sonatype Nexus]]></category>

		<guid isPermaLink="false">http://blog.aheritier.net/?p=597</guid>
		<description><![CDATA[This article was firstly published in this blog in french in May 2009 and later in english in Sonatype Blog. I put a copy here as an archive. &#60;disclaimer&#62; As a member of the Archiva team (though rarely active, I &#8230; <a href="http://blog.aheritier.net/from-apache-archiva-to-sonatype-nexus/">Continue reading <span class="meta-nav">&#8594;</span></a><br /><div><img src="http://blog.aheritier.net/wp-content/plugins/gd-star-rating/gfx.php?value=10.0" /></div><div>Rating: 10.0/<strong>10</strong> (2 votes cast)</div><br />]]></description>
			<content:encoded><![CDATA[<p><em>This article was firstly published <a href="http://blog.aheritier.net/dapache-archiva-a-sonatype-nexus-introduction/" title="D’Apache Archiva à Sonatype Nexus – Introduction" >in this blog</a> in french in May 2009 and later in english in <a href="http://www.sonatype.com/people/2009/07/from-apache-archiva-to-sonatype-nexus/">Sonatype Blog</a>. I put a copy here as an archive.</em></p>
<p><em>&lt;disclaimer&gt; As a member of the <a href="http://archiva.apache.org/">Archiva</a> team (though rarely active, I admit) I will try to defend it throughout this article. However, being a professional consultant first and foremost, I hope to keep my objectivity. I&#8217;ll let you be the judge &#8230;  &lt;/disclaimer&gt;<br />
</em></p>
<p>Having recently migrated a significant number of repository servers from <a href="http://archiva.apache.org/">Apache Archiva</a> to <a href="http://nexus.sonatype.org/">Sonatype Nexus</a>, I would like to share with you the process I followed, some tips, and point out a few pitfalls I encountered.<a href="http://blog.aheritier.net/wp-content/uploads/2009/05/nexus-real-logo.png"><img class="alignright size-medium wp-image-458" title="nexus-real-logo" src="http://blog.aheritier.net/wp-content/uploads/2009/05/nexus-real-logo-300x99.png" alt="nexus-real-logo" width="300" height="99" /></a><br />
A big Thank you to <a href="http://www.tarpoon.org/">Tarpoon</a>, <a href="http://www.cestpasdur.com/">C&#8217;est pas dur</a> and all of my team for helping.</p>
<p><span id="more-597"></span></p>
<h1>Introduction</h1>
<h2>Background</h2>
<p>A little background to this migration: We had a large enterprise-scale implementation with dozens of JEE projects of all sizes (from a mouse to the ocean liner &#8211; and NO! I am not talking about the Titanic!), and at least 200 active developers accessing the system simultaneously during the day.<br />
Most projects are using Maven. To help teams to <strong>make </strong> better and faster builds we offered a complete infrastructure for continuous integration: a big server (Dual QuadCore Xeon with 16GB RAM running Red Hat Enterprise Linux 5.1),  hosting an <a href="http://www.atlassian.com/software/bamboo/">Atlassian Bamboo</a> continuous integration server with (approximately): 110 (real time) continuous integration builds, 40 (daily) maven sites builds, 20 (daily) <a href="http://sonar.codehaus.org/">Sonar</a> builds. It also hosted a Maven repository server  (Archiva 1.1.1 before migrating), which stored a little less than a dozen local repositories and provided a proxy and cache for twenty external repositories (for almost 400GB of data).<br />
The majority of that space was used by the repository of internal snapshots (200GB) and the repository of internal releases (150GB). To understand these sizes you must know that some projects may produce (for good or bad reasons) some EARs up to 100MB in size. By adding the sizes of JARs and WARs that compose these EARs, each deployment quickly grows to take up a lot of space.</p>
<h2>Why change?</h2>
<p>For several months we were having stability issues with our integration environment. From one build to another we would see execution times fluctuate widely. We also had intermittent errors that were not related to projects, but to the infrastructure :</p>
<ul>
<li>500 or 502 errors on uploads in Archiva without any apparent reason (I tried to track down the issues without success),</li>
<li>Many periods of unavailability of Archiva or Bamboo after exceeding the maximum number of open file descriptors allowed for the user. We must concede that these tools handle a lot of files (downloads, uploads, and other manipulations on a large number of artifacts). Archiva easily exceeds the default limit of 1024 descriptors which forced us to increase it. But even at 2048 Archiva would still occasionally exceed the limit.</li>
<li>Inability to download snapshots if the local repository used by Bamboo was emptied just prior to that. This resulted in regular failures of our Maven sites or Sonar builds.</li>
</ul>
<p>We recently submitted a bug against Archiva (<a href="http://jira.codehaus.org/browse/MRM-1136">MRM-1136</a>), for which I spent several hours diagnosing the issue (problems with management of meta-data issued by Maven 2.1.0). To resolve the issue would require us to quickly upgrade to Archiva 1.1.4 or 1.2.</p>
<p>All of these problems, even though they were only occasional, strongly discredited our continuous integration service. How could we criticize a project for not using our CI if it kept sending them false negatives? They already have enough work with addressing real errors in their builds. The continuous integration environment must be as reliable as a Swiss watch.</p>
<p>It was time for us to act.</p>
<p>We could update Archiva, which would entail significant validation costs without much improvement. Apart from the incompatibility with Maven 2.1.0, nothing suggested that the new version fixed any of our problems and there were few improvements/new features at that time, due to lack of time by the maintainers.</p>
<p>The other choice was to get another tool with the potential to meet the new requirements.</p>
<p>The feedback from the community about Nexus was very encouraging. Moreover, the latter pro version opens up new possibilities for the future with its innovative features:</p>
<ul>
<li>Staging repositories to put artifacts being validated in a temporary area prior to delivery.</li>
<li>Opportunity to proxy and aggregate eclipse update sites. Currently we are doing it by hand, which is expensive, complicated (I hate P2), and boring.</li>
<li>and more&#8230;</li>
</ul>
<p>As the situation seemed to be calling for it, we decided to try our luck with Nexus.</p>
<h1>Migration</h1>
<p>Let&#8217;s get started.</p>
<h2>Existing environment</h2>
<p>A little overview of our existing environment. Before the migration, our environment was like this:</p>
<div id="attachment_609" class="wp-caption aligncenter" style="width: 310px"><a href="http://blog.aheritier.net/wp-content/uploads/2009/07/ArchivaNexusBeforeMigration.png"><img class="size-medium wp-image-609" title="The environment before the migration" src="http://blog.aheritier.net/wp-content/uploads/2009/07/ArchivaNexusBeforeMigration-300x227.png" alt="The environment before the migration" width="300" height="227" /></a><p class="wp-caption-text">The environment before the migration</p></div>
<p>We were hosting our internal repositories in what Archiva calls managed repositories. There is one for releases, one for snapshots and another one for third-party libraries (often those delivered by closed-source vendors).<br />
To cache external repositories (configured as &#8220;remote repositories&#8221;) we are using two more repositories (one for external releases and one for external snapshots).</p>
<p>Our Archiva shows two groups: One to access released artifacts, and another one for snapshots. We never set up a unique group with access to both of them because in our tests we noticed that Archiva often had issues merging descriptors coming from several repositories (maven-metadata.xml), and it can have dramatic consequences if you mix up releases and snapshots.</p>
<p>Groups allow to greatly simplify Maven configuration, avoiding the need to declare too many repositories. Moreover, they enhance your Maven experience, speeding up your builds. Each missing dependency request is sent only once to each group, while the process in the background polls each repository in the group and maintains a cache about missing dependencies to further speed up the build. Sending missing dependency requests to several repositories is an inexcusable waste of time.</p>
<p>Repository users (developers and the continuous integration server) access them using these settings :<br />
[xml]<br />
<settings></p>
<profiles>
<profile>
      <id>default</id><br />
      <repositories><br />
        <repository><br />
          <id>central</id><br />
          <url>http://serveur.entreprise.fr/archiva/repository/releases/ </url><br />
          <releases><enabled>true</enabled></releases><br />
          <snapshots><enabled>false</enabled></snapshots><br />
        </repository><br />
        <repository><br />
          <id>snapshots</id><br />
          <url>http://serveur.entreprise.fr/archiva/repository/snapshots/ </url><br />
          <releases><enabled>false</enabled></releases><br />
          <snapshots><enabled>true</enabled></snapshots><br />
        </repository><br />
      </repositories></p>
<pluginrepositories>
<pluginrepository>
          <id>central</id><br />
          <url>http://serveur.entreprise.fr/archiva/repository/releases/ </url><br />
          <releases><enabled>true</enabled></releases><br />
          <snapshots><enabled>false</enabled></snapshots>
        </pluginrepository>
<pluginrepository>
          <id>snapshots</id><br />
          <url>http://serveur.entreprise.fr/archiva/repository/snapshots/ </url><br />
          <releases><enabled>false</enabled></releases><br />
          <snapshots><enabled>true</enabled></snapshots>
        </pluginrepository>
      </pluginrepositories>
    </profile>
  </profiles>
  <activeprofiles><br />
    <activeprofile>default</activeprofile><br />
  </activeprofiles><br />
</settings><br />
[/xml]</p>
<p>By redefining the central server address (normally located here: <a href="http://repo1.maven.org/maven2/">http://repo1.maven.org/maven2/</a>) we configured Maven to look only for released artifacts in our group in Archiva. This gives us access to both internal and external releases. In the same way, the repository snapshots allow us to obtain development versions of all artifacts.</p>
<h2>Constraints</h2>
<p>Migrating a server isn&#8217;t easy when you have 200 developers using it every day.</p>
<p>First, we had to be sure to only stop the service for a very short time (or we would have to do it outside of working hours&#8230; ouch!!!). Stopping the continuous integration server temporarily isn&#8217;t such a big problem. Asking all teams to use maven in offline mode, and not to use our repositories is more difficult. Usually, we don&#8217;t have to wait long before someone needs to download a new artifact or a project has to do a release.</p>
<p>Secondly, it was mandatory for us to keep the compatibility with preexisting Maven settings. Due to the large number of projects and developers it would be impossible to change all repositories settings in Maven configuration. It would impact all projects and all developers if we changed the upload URLs (distributionManagement) and download settings (repositories).</p>
<h2>The process</h2>
<p>To reduce cost, we decided to not perform our tests in a test environment. This would require us to duplicate the entire integration environment we have in production.<br />
After some basic tests performed on the tool, the real baptism by fire was the scalability of the server (with an increasing volume of data and number of users).<br />
During migration system resources allowed us to easily handle both servers in parallel. We chose the strategy to run Archiva and Nexus in parallel and to switch services to the new server one after another, while keeping the fallback option to revert if necessary.</p>
<p>We had enough space to rebuild caches of external repositories (this required only a few gigabytes), however we could not duplicate our internal repositories, which are too large, and we could have consistency issues. We also did not want to give both products access to internal repositories, because we feared they might access them simultaneously and corrupt our data. Therefore we began our migration leaving our internal repositories on Archiva planning to move them to Nexus at the end of migration.</p>
<p>For URL compatibility we used rewriting rules on the Apache server. It would switch between old and new URLs in a transparent manner.</p>
<h2>Installing Nexus</h2>
<p>We performed a classic installation of Nexus 1.3.2 (the opensource and standalone bundle) adjusting a few parameters such as the HTTP port, the paths of data and log directories to conform to the organization of our server. All this was quickly done because unlike Archiva we did not have to create a database (which had to be in mysql to follow our standards). Our server was up and ready to be configured.</p>
<h2>Configuration of groups and external repositories</h2>
<p>We started the Nexus configuration by creating proxy repositories. We also added, for purposes of migration, proxies for our internal repositories hosted on Archiva.</p>
<p>The GUI is ergonomic which makes the registration of 20 external repositories very bearable. Thank you <a href="http://extjs.com/">ExtJS</a>!</p>
<p>Unlike Archiva which proposes to store the artifacts of external repositories in the same local repository, Nexus stores the contents of each in a dedicated repository (proxy).</p>
<p>Regarding settings of external repositories, it should be noted that we lose the opportunity provided by Archiva to have white and black lists of artifacts coming from each external repository. Nexus uses the concept of &#8220;routes&#8221; for this type of filtering. Unfortunately we can apply those routes only at a group level and not on a repository.<br />
Since some lists that we have in Archiva are only for performance issues (e.g. do not query a repository in which we know that a certain artifact is not located), we decided to not duplicate this setup in Nexus waiting to see if there were real problems.</p>
<p>In our setting we faced a first disappointment. As we have to proxy some repositories hosted internally (the one delivered by the Sonar server and all of those always on Archiva during the migration) we were forced to declare the company web proxy on each proxy repository. It is impossible to define the web proxy in the global configuration of Nexus and to disable it on a given proxy repository (<a href="https://issues.sonatype.org/browse/NEXUS-2317">NEXUS-2317</a>).</p>
<p>While our external repositories configuration was almost complete, we had our first big setback. We discovered that it was impossible to proxy repositories which are in the legacy layout of maven 1 (at Atlassian and dev.java.net for example).<br />
To achieve this we need to create virtual repositories which are used by Nexus to convert a repository from one format to another. Tough luck, because two bugs (<a href="https://issues.sonatype.org/browse/NEXUS-1909">NEXUS-1909</a>, <a href="https://issues.sonatype.org/browse/NEXUS-1910">NEXUS-1910</a>) prevented us from doing it.<br />
Fortunately for us, the Nexus team has been very responsive and was able to incorporate the corrections to these bugs in version 1.3.3 which was published the day after our discovery. Otherwise we have to admit that we probably would not have continued our tests on Nexus.<br />
We have updated our server which allowed us to see that the process was very simple since the application, its configuration, and the data were all well separated.</p>
<p>We finalized the configuration of Nexus by creating groups. That is the same concept as in Archiva (which copied it).<br />
The configuration of groups is however relatively poorly designed in terms of ergonomics. We had to select each repository we wanted to add to the group and then put it in the correct order in the list. The order is very important, because Nexus will use it to search for artifacts. We must therefore place  internal repositories prior to external ones. The problem is that this list displays only the name of each repository (and the name is often truncated because of its length). So you should be careful in naming your repositories to be able to easily sort them when you have several dozen in a group.</p>
<p>We followed Nexus recommendations by creating a single group that exposes all releases and all snapshots. (This will help us avoid having to battle the screen for configuring a group twice <img src='http://blog.aheritier.net/wp-includes/images/smilies/icon_smile.gif' alt=':-)' class='wp-smiley' />  ).</p>
<p>From now we were supposed to be able to download all artifacts needed to build our projects with Nexus.</p>
<p>After several successful tests on our desktop we tested the whole system with our continuous integration server.<br />
We deleted its local repository and updated its configuration:</p>
<p>[xml]<br />
<settings><br />
  <mirrors><br />
    <mirror><br />
      <!--This sends everything else to /public --><br />
      <id>nexus</id><br />
      <mirrorof>*</mirrorof><br />
      <url>http://serveur.entreprise.fr/nexus/content/groups/public/ </url><br />
    </mirror><br />
  </mirrors></p>
<profiles>
<profile>
      <id>default</id><br />
      <!--Enable snapshots for the built in central repo to direct --><br />
      <!--all requests to nexus via the mirror --><br />
      <repositories><br />
        <repository><br />
          <id>central</id><br />
          <url>http://central </url><br />
          <releases><enabled>true</enabled></releases><br />
          <snapshots><enabled>true</enabled></snapshots><br />
        </repository><br />
      </repositories></p>
<pluginrepositories>
<pluginrepository>
          <id>central</id><br />
          <url>http://central </url><br />
          <releases><enabled>true</enabled></releases><br />
          <snapshots><enabled>true</enabled></snapshots>
        </pluginrepository>
      </pluginrepositories>
    </profile>
  </profiles>
  <activeprofiles><br />
    <!--make the profile active all the time --><br />
    <activeprofile>default</activeprofile><br />
  </activeprofiles><br />
</settings><br />
[/xml]</p>
<p><strong>Please note:</strong>  I am not at all a fan of using the mirror * which requires us to put releases and snapshots in the same group. However, this is the only solution, as there is no way to tell Maven to find releases on one mirror location and snapshots on another one. I find this dangerous because e.g. when you call a plugin without defining its version (a plugin in command line such as eclipse:eclipse or archetype:generate) you may retrieve a snapshot version of it. Thus you have to take care to follow the recommendation of Maven to define all the versions of plugins that are used in your project descriptor (directly or by inheritance) to avoid surprises. In our context we won&#8217;t have this issue since the recommendation is followed by all projects using a parent POM that is setting all versions for them.</p>
<p>The environment with Nexus and Archiva running in parallel was now ready to go :</p>
<div id="attachment_610" class="wp-caption aligncenter" style="width: 310px"><a href="http://blog.aheritier.net/wp-content/uploads/2009/07/ArchivaNexusWhileMigrating.png"><img class="size-medium wp-image-610" title="The environment while migrating" src="http://blog.aheritier.net/wp-content/uploads/2009/07/ArchivaNexusWhileMigrating-300x153.png" alt="The environment while migrating" width="300" height="153" /></a><p class="wp-caption-text">The environment while migrating</p></div>
<p>Nothing changed for developers who still use Archiva while the continuous integration server retrieves all artifacts from Nexus.</p>
<h2>Tuning</h2>
<p>After testing it a few days we could see that Nexus sometimes had difficulty quickly delivering artifacts. The time has come to look at a few more advanced settings.</p>
<p>Routes allow to restrict the list of repositories that Nexus has to verify when we request an artifact to a group. This can be done via permissions or prohibitions.</p>
<p>The first route we create is the one which tells to Nexus to search for our artifacts (.*/com.mycompany/.*) only in proxy repositories giving access to our internal artifacts on Archiva. <em>When the switch to Nexus will be completely finalized, this route will point only to our internal repositories hosted by Nexus.</em></p>
<p>We also add rules for .*/org/apache/.* and .*/org/codehaus/.* which are heavily used by Maven, so that artifacts are retrieved only from the central repository and snapshots repositories of each community.</p>
<p>This gave a pretty good boost to our Nexus implementation.</p>
<p>After several days of use by the continuous integration server, Nexus was running fine. Therefore we got ready for the second part of our migration: hosting of our internal repositories on Nexus.</p>
<h2>Setting internal repositories and security</h2>
<p>Before we could move internal repositories from Archiva to Nexus we had to create hosted repositories. We created directories for our repositories in a different location from Archiva, as to not let both products access the same data. We reused repository identifiers used in Archiva to easily create rewriting rules on Apache HTTP server.</p>
<p>We spent some time learning the security mechanism in Nexus. Settings are so fine that even the most basic use cases require convoluted settings.</p>
<p>We began by creating privileges (read, write, update) on each hosted repository. We created roles that grouped some privileges on hosted repositories together. In our case, one role to deploy released artifacts on repositories (for projects teams) and another role to deploy snapshots on repositories (for continuous integration server).</p>
<p>We finished by creating users with roles defined above without forgetting the role to download from any repository.</p>
<p>Internal repositories were ready, all was left to do was to move data to Nexus and to stop Archiva.</p>
<h2>The final steps</h2>
<p>To keep the compatibility between Archiva and Nexus we had to do two things.<br />
For each internal repository on which we&#8217;ll have to upload artifacts we explicitly wrote a rule to transform the URL from Archiva to Nexus.<br />
Apache configuration example:<br />
[text]<br />
RewriteRule ^/archiva/repository/internal-releases/(.*) http://localhost/nexus/content/repositories/internal-releases/$1 [P]<br />
RewriteRule ^/archiva/repository/internal-snapshots/(.*) http://localhost/nexus/content/repositories/internal-snapshots/$1 [P]<br />
RewriteRule ^/archiva/repository/third-parties/(.*) http://localhost/nexus/content/repositories/third-parties/$1 [P]<br />
[/text]<br />
For all other types of read access we just created a rule which transfered them to our unique group in Nexus.<br />
Apache configuration example:<br />
[text]<br />
RewriteRule ^/archiva/repository/[a-z\-]+/(.*) http://localhost/nexus/content/groups/public/$1 [P]<br />
[/text]<br />
Now we were ready to migrate:</p>
<ol>
<li>Stop Nexus.</li>
<li>Stop Archiva.</li>
<li>Install rewriting rules on Apache.</li>
<li>Move content of internal repositories from Archiva to Nexus.</li>
<li>Restart Nexus.</li>
</ol>
<p>On D-day we made the switch in less than 10 minutes. Nexus took a few hours to index the hundreds of GB of data, but without taking much of a performance hit.</p>
<div id="attachment_611" class="wp-caption aligncenter" style="width: 310px"><a href="http://blog.aheritier.net/wp-content/uploads/2009/07/ArchivaNexusAfterMigration.png"><img class="size-medium wp-image-611" title="The final environment" src="http://blog.aheritier.net/wp-content/uploads/2009/07/ArchivaNexusAfterMigration-300x182.png" alt="The final environment" width="300" height="182" /></a><p class="wp-caption-text">The final environment</p></div>
<p>Despite some pitfalls we encountered, the migration wasn&#8217;t technically really complex. We did it in 2 weeks and we spent less than half that time actually working on it.</p>
<p>Now we are studying how to configure scheduled services. <a href="http://www.sonatype.com">Sonatype</a> made a major effort on <a href="http://www.sonatype.com/books/nexus-book/reference/">product documentation</a>. It allows us to quickly discover all its features. However, we are disappointed when we want to go further than the reference guide. Some best practices about the usage of the tool in a corporate environment are still missing:</p>
<ul>
<li>What scheduled tasks should be used?</li>
<li>Under what circumstances?</li>
<li>When?</li>
<li>Why should we repair metadata?</li>
<li>Why should we delete caches?</li>
<li>How are we supposed to use the trash?</li>
</ul>
<h1>Results</h1>
<p>Two weeks after the migration we drew a first conclusion of our Nexus experience. </p>
<p>Let&#8217;s begin by changes on issues we previously had with Archiva and which led us to attempt the Nexus adventure.</p>
<h2>The number of file descriptors simultaneously opened</h2>
<p>It&#8217;s a little bit early to declare victory, however after running for two weeks we can see that our problem on the number of file descriptors opened simultaneously disappeared. <strong>Whereas Archiva easily exceeded the 1024 descriptors opened, Nexus uses only 400 which enormously reduces the load on the server.</strong></p>
<div id="attachment_392" class="wp-caption alignnone" style="width: 310px"><a href="http://blog.aheritier.net/wp-content/uploads/2009/05/archiva-open-files.png"><img class="size-medium wp-image-392" title="archiva-open-files" src="http://blog.aheritier.net/wp-content/uploads/2009/05/archiva-open-files-300x65.png" alt="Number of file descriptors simultaneously opened by Archiva" width="300" height="65" /></a><p class="wp-caption-text">Number of file descriptors simultaneously opened by Archiva</p></div>
<div id="attachment_394" class="wp-caption alignnone" style="width: 310px"><a href="http://blog.aheritier.net/wp-content/uploads/2009/05/nexus-open-files.png"><img class="size-medium wp-image-394" title="nexus-open-files" src="http://blog.aheritier.net/wp-content/uploads/2009/05/nexus-open-files-300x65.png" alt="Number of file descriptors simultaneously opened by Nexus" width="300" height="65" /></a><p class="wp-caption-text">Number of file descriptors simultaneously opened by Nexus</p></div>
<h2>Memory consumption</h2>
<p>Even if we had enough RAM, Archiva is a big consumer of memory. <strong>Archiva took an average of 1.3 GB to run. Nexus requires many less and works with 400MB (Even my <a href="http://www.eclipse.org">Eclipse</a> requires more  <img src='http://blog.aheritier.net/wp-includes/images/smilies/icon_smile.gif' alt=':-)' class='wp-smiley' />  ). It saves almost 1GB that we can now allocate to our builds.</strong></p>
<div id="attachment_391" class="wp-caption alignnone" style="width: 310px"><a href="http://blog.aheritier.net/wp-content/uploads/2009/05/archiva-memory.png"><img class="size-medium wp-image-391" title="archiva-memory" src="http://blog.aheritier.net/wp-content/uploads/2009/05/archiva-memory-300x65.png" alt="Memory consumption by Archiva" width="300" height="65" /></a><p class="wp-caption-text">Memory consumption by Archiva</p></div>
<div id="attachment_393" class="wp-caption alignnone" style="width: 310px"><a href="http://blog.aheritier.net/wp-content/uploads/2009/05/nexus-memory.png"><img class="size-medium wp-image-393" title="nexus-memory" src="http://blog.aheritier.net/wp-content/uploads/2009/05/nexus-memory-300x70.png" alt="Memory consumption by Nexus" width="300" height="70" /></a><p class="wp-caption-text">Memory consumption by Nexus</p></div>
<h2>Not found snapshots</h2>
<p>Sadly this problems always persists. Because migration to Nexus hasn&#8217;t fixed it, we investigated a little bit more and discovered two causes for it :</p>
<ul>
<li>The first one is a bug in Maven (<a href="http://jira.codehaus.org/browse/MNG-4142">MNG-4142</a>) : It&#8217;s a subtle problem halfway between the use of artifacts with classifiers and a corruption of metadata in the local repository.</li>
<li>The second one is a set of bugs in Nexus (<a href="https://issues.sonatype.org/browse/NEXUS-1333">NEXUS-1333</a>, <a href="https://issues.sonatype.org/browse/NEXUS-2036">NEXUS-2036</a>): The scheduled service used to repair metadata deletes them if it cannot read it. The problem is that it doesn&#8217;t succeed to read them if you are using some deprecated properties like {parent.*} (replaced by ${project.parent.*}) or ${pom.*} (replaced by ${project.*}). <em>Note that <a href="https://issues.sonatype.org/browse/NEXUS-2036">NEXUS-2036</a> is marked as fixed on version 1.3.4.</em></li>
</ul>
<h2>Nothing is perfect</h2>
<p>A bug we didn&#8217;t have before appeared with the usage of Nexus. Because of our usage of rewriting rules in apache, Maven now complains that cookies are rejected when we upload artifacts on an internal repository (<a href="https://issues.sonatype.org/browse/NEXUS-1967">NEXUS-1967</a>). This is a minor issue which doesn&#8217;t alter our system, but is annoying because it pollutes our Maven logs on the integration server.</p>
<h2>But we had a good surprise</h2>
<p>Resource savings on the server (IO, RAM) and the quality of Nexus on the speed to upload artifacts (whatever their size) lead to an important improvement of quality of service and stability of the continuous integration server. As you can see below on some graphs taken from different builds in Bamboo there&#8217;s a big difference between before and after Nexus. <strong>Build times decreased and are consistent like never before.</strong></p>
<p><a href="http://blog.aheritier.net/wp-content/uploads/2009/05/chart4.png"><img class="size-medium wp-image-379" title="chart4" src="http://blog.aheritier.net/wp-content/uploads/2009/05/chart4-300x240.png" alt="chart4" width="300" height="240" /></a></p>
<p><a href="http://blog.aheritier.net/wp-content/uploads/2009/05/chart3.png"><img class="size-medium wp-image-378" title="chart3" src="http://blog.aheritier.net/wp-content/uploads/2009/05/chart3-300x240.png" alt="chart3" width="300" height="240" /></a></p>
<p><a href="http://blog.aheritier.net/wp-content/uploads/2009/05/chart2.png"><img class="size-medium wp-image-377" title="chart2" src="http://blog.aheritier.net/wp-content/uploads/2009/05/chart2-300x240.png" alt="chart2" width="300" height="240" /></a></p>
<p><a href="http://blog.aheritier.net/wp-content/uploads/2009/05/chart1.png"><img class="size-medium wp-image-376" title="chart1" src="http://blog.aheritier.net/wp-content/uploads/2009/05/chart1-300x240.png" alt="chart1" width="300" height="240" /></a></p>
<h2>Conclusion</h2>
<p>Did we find the silver bullet ? Of course, no. I have already listed some constraints and problems we had and there are probably many others to discover (the team already has a <a href="https://issues.sonatype.org/secure/IssueNavigator.jspa?reset=true&#038;mode=hide&#038;pid=10001&#038;resolution=-1&#038;sorter/field=updated&#038;sorter/order=DESC">good backlog</a>). Any product can be improved. Despite all that, how could I say something other than&#8230; migrate! It&#8217;s unfortunate for me to have to admit this as a member of the Archiva team, but my own research proves it. Nexus is a product of great quality, which delivers the service you need for your development projects very well. Furthermore, developed by full-time employees (thank you <a href="http://www.sonatype.com">Sonatype</a>), it enjoys an easily accessible and responsive support (I recommend the channel #nexus on #irc.codehaus.org). Archiva itself is governed by the laws of open source, suffers from the lack of time of its maintainers (even if they are doing as much as they can) which doesn&#8217;t help it to stay in the competition. </p>
<p>So, enjoy and benefit from service and quality by adopting Nexus!</p>
<br /><div><img src="http://blog.aheritier.net/wp-content/plugins/gd-star-rating/gfx.php?value=10.0" /></div><div>Rating: 10.0/<strong>10</strong> (2 votes cast)</div><br />]]></content:encoded>
			<wfw:commentRss>http://blog.aheritier.net/from-apache-archiva-to-sonatype-nexus/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>D&#8217;Apache Archiva à Sonatype Nexus &#8211; Conclusion</title>
		<link>http://blog.aheritier.net/dapache-archiva-a-sonatype-nexus-le-bilan/</link>
		<comments>http://blog.aheritier.net/dapache-archiva-a-sonatype-nexus-le-bilan/#comments</comments>
		<pubDate>Thu, 14 May 2009 04:00:52 +0000</pubDate>
		<dc:creator>Arnaud Héritier</dc:creator>
				<category><![CDATA[Technologie]]></category>
		<category><![CDATA[Apache Archiva]]></category>
		<category><![CDATA[Apache Maven]]></category>
		<category><![CDATA[Java]]></category>
		<category><![CDATA[Sonatype Nexus]]></category>

		<guid isPermaLink="false">http://blog.aheritier.net/?p=357</guid>
		<description><![CDATA[Dernière partie consacrée à la migration d&#8217;Archiva vers Nexus avec le bilan. Tout d&#8217;abord revenons sur les problèmes que nous avions avec Archiva et qui nous ont poussés à tenter l&#8217;aventure Nexus. Le nombre de descripteurs de fichiers ouverts par &#8230; <a href="http://blog.aheritier.net/dapache-archiva-a-sonatype-nexus-le-bilan/">Continue reading <span class="meta-nav">&#8594;</span></a><br /><div><img src="http://blog.aheritier.net/wp-content/plugins/gd-star-rating/gfx.php?value=9.7" /></div><div>Rating: 9.7/<strong>10</strong> (7 votes cast)</div><br />]]></description>
			<content:encoded><![CDATA[<p>Dernière partie consacrée à la migration d&#8217;Archiva vers Nexus avec le bilan.</p>
<p><span id="more-357"></span></p>
<p><em>Tout d&#8217;abord revenons sur les problèmes que nous avions avec Archiva et qui nous ont poussés à tenter l&#8217;aventure Nexus.<br />
</em></p>
<h2>Le nombre de descripteurs de fichiers ouverts par le produit</h2>
<p>Il est encore un peu tôt pour crier victoire cependant après plus de deux semaines d&#8217;exploitation nous pouvons constater que notre problème sur le nombre de descripteurs de fichiers ouverts simultanément a disparu.<strong>Là où Archiva dépassait facilement les 1024 descripteurs ouverts, Nexus se contente d&#8217;environ 400 ce qui soulage énormément la machine.</strong></p>
<div id="attachment_392" class="wp-caption alignnone" style="width: 310px"><a href="http://blog.aheritier.net/wp-content/uploads/2009/05/archiva-open-files.png"><img src="http://blog.aheritier.net/wp-content/uploads/2009/05/archiva-open-files-300x65.png" alt="Nombre de &quot;file descriptors&quot; ouverts par Archiva" title="archiva-open-files" width="300" height="65" class="size-medium wp-image-392" /></a><p class="wp-caption-text">Nombre de 'file descriptors' ouverts par Archiva</p></div>
<div id="attachment_394" class="wp-caption alignnone" style="width: 310px"><a href="http://blog.aheritier.net/wp-content/uploads/2009/05/nexus-open-files.png"><img src="http://blog.aheritier.net/wp-content/uploads/2009/05/nexus-open-files-300x65.png" alt="Nombre de &quot;file descriptors&quot; ouverts par Nexus" title="nexus-open-files" width="300" height="65" class="size-medium wp-image-394" /></a><p class="wp-caption-text">Nombre de 'file descriptors' ouverts par Nexus</p></div>
<h2>La consommation mémoire</h2>
<p>Même si cela n&#8217;était pas très grave puisque nous avions les ressources nécessaire Archiva était très consommateur de mémoire. Il en prennait en moyenne 1,3Go.<strong> Nexus est beaucoup moins gourmand et tourne avec moins de 400Mo</strong> (Même mon eclipse consomme plus <img src='http://blog.aheritier.net/wp-includes/images/smilies/icon_smile.gif' alt=':-)' class='wp-smiley' />  ).</p>
<div id="attachment_391" class="wp-caption alignnone" style="width: 310px"><a href="http://blog.aheritier.net/wp-content/uploads/2009/05/archiva-memory.png"><img src="http://blog.aheritier.net/wp-content/uploads/2009/05/archiva-memory-300x65.png" alt="Mémoire consommée par Archiva" title="archiva-memory" width="300" height="65" class="size-medium wp-image-391" /></a><p class="wp-caption-text">Mémoire consommée par Archiva</p></div>
<div id="attachment_393" class="wp-caption alignnone" style="width: 310px"><a href="http://blog.aheritier.net/wp-content/uploads/2009/05/nexus-memory.png"><img src="http://blog.aheritier.net/wp-content/uploads/2009/05/nexus-memory-300x70.png" alt="Mémoire consommée par Nexus" title="nexus-memory" width="300" height="70" class="size-medium wp-image-393" /></a><p class="wp-caption-text">Mémoire consommée par Nexus</p></div>
<h2>Les problèmes de snapshots non trouvés</h2>
<p>Malheureusement à ce niveau là, le problème perdure. Mais le fait que le changement de serveur ne résolve pas le problème nous avons investigué un peu plus.<br />
Nous avons découvert aujourd&#8217;hui deux causes plus précises du problème :</p>
<ul>
<li>La première est un bug Maven (<a href="http://jira.codehaus.org/browse/MNG-4142">MNG-4142</a>) qui est un subtil problème à moitié chemin entre l&#8217;utilisation d&#8217;artifacts avec des classifiers et une corruption des metadonnées du repository local.</li>
<li>La seconde cause est liée à des bugs NEXUS (<a href="https://issues.sonatype.org/browse/NEXUS-1333">NEXUS-1333</a>, <a href="https://issues.sonatype.org/browse/NEXUS-2036">NEXUS-2036</a>) qui font que le processus de correction des metadonnées les supprime dans un répertoire si il n&#8217;arrive pas à comprendre un POM. Cas qui semble arriver fréquemment en utilisant par exemple des propriétés maven &#8220;deprecated&#8221; comme ${parent.*} (à remplacer par ${project.parent.*}) ou ${pom.*} (à remplacer par ${project.*}).</li>
</ul>
<p><em>A ces problèmes vient s&#8217;en greffer un nouveau spécifique à Nexus.</em></p>
<h2>Les cookies rejetés</h2>
<p>Un problème est apparu avec Nexus. Nous avons un soucis avec les règles de réécriture qui font que Maven se plaint lorsqu&#8217;il fait un déploiement que les cookies sont rejetés (<a href="https://issues.sonatype.org/browse/NEXUS-1967">NEXUS-1967</a>). Ca n&#8217;est pas grave, mais cela crée du bruit dans les logs Maven ce qui ne facilite pas le diagnostic des erreurs. </p>
<p><em>Mais au final le jeu en valait bien la chandelle !!</em></p>
<h2>La cerise sur le gâteau</h2>
<p>Au final toutes les économies de ressources sur le serveur mais aussi la meilleure qualité de Nexus sur la rapidité de l&#8217;upload des artifacts (quelque soit leur taille) font que le serveur d&#8217;intégration continue est beaucoup plus stable et beaucoup plus régulier. Comme on peut le voir sur les quelques graphiques ci-dessous tirés de différents builds sur Bamboo il y a une nette fracture lors de la mise en production de Nexus. <strong>On note une régularité sans commune mesure sur les temps des builds et surtout une grande diminution de ceux-ci.</strong></p>
<p><a href="http://blog.aheritier.net/wp-content/uploads/2009/05/chart4.png"><img src="http://blog.aheritier.net/wp-content/uploads/2009/05/chart4-300x240.png" alt="chart4" title="chart4" width="300" height="240" class="size-medium wp-image-379" /></a><a href="http://blog.aheritier.net/wp-content/uploads/2009/05/chart3.png"><img src="http://blog.aheritier.net/wp-content/uploads/2009/05/chart3-300x240.png" alt="chart3" title="chart3" width="300" height="240" class="size-medium wp-image-378" /></a></p>
<p><a href="http://blog.aheritier.net/wp-content/uploads/2009/05/chart2.png"><img src="http://blog.aheritier.net/wp-content/uploads/2009/05/chart2-300x240.png" alt="chart2" title="chart2" width="300" height="240" class="size-medium wp-image-377" /></a><a href="http://blog.aheritier.net/wp-content/uploads/2009/05/chart1.png"><img src="http://blog.aheritier.net/wp-content/uploads/2009/05/chart1-300x240.png" alt="chart1" title="chart1" width="300" height="240" class="size-medium wp-image-376" /></a></p>
<h2>Conclusion</h2>
<p>Avons-nous trouvé la silver bullet ? Bien sur que non. J&#8217;ai déjà listé quelques contraintes ou problèmes rencontrés et il y en a d&#8217;autres à découvrir. Tout produit est perfectible. Malgré cela comment dire autre chose que &#8230;. migrez !!! C&#8217;est malheureux pour moi de l&#8217;avouer en tant que membre de l&#8217;équipe Archiva mais je dois me ranger aux résultats. Ils sont édifiants. Nexus est un produit de qualité qui rend très bien le service qu&#8217;on lui demande. De plus, développé par des personnes à temps plein (merci Sonatype), il bénéficie d&#8217;un support réactif et facilement accessible (je vous conseille le channel #nexus sur irc.codehaus.org). Archiva, lui, régit par les lois de l&#8217;open-source, doit se contenter du maigre temps libre de ses committeurs ce qui ne suffit plus pour rester dans la compétition.<br />
Alors, faites-vous plaisir et profitez d&#8217;un service à la hauteur de vos demandes, adoptez Nexus !</p>
<br /><div><img src="http://blog.aheritier.net/wp-content/plugins/gd-star-rating/gfx.php?value=9.7" /></div><div>Rating: 9.7/<strong>10</strong> (7 votes cast)</div><br />]]></content:encoded>
			<wfw:commentRss>http://blog.aheritier.net/dapache-archiva-a-sonatype-nexus-le-bilan/feed/</wfw:commentRss>
		<slash:comments>4</slash:comments>
		</item>
		<item>
		<title>D&#8217;Apache Archiva à Sonatype Nexus &#8211; La migration</title>
		<link>http://blog.aheritier.net/dapache-archiva-a-sonatype-nexus-la-migration/</link>
		<comments>http://blog.aheritier.net/dapache-archiva-a-sonatype-nexus-la-migration/#comments</comments>
		<pubDate>Wed, 13 May 2009 16:00:39 +0000</pubDate>
		<dc:creator>Arnaud Héritier</dc:creator>
				<category><![CDATA[Technologie]]></category>
		<category><![CDATA[Apache Archiva]]></category>
		<category><![CDATA[Apache Maven]]></category>
		<category><![CDATA[Java]]></category>
		<category><![CDATA[Sonatype Nexus]]></category>

		<guid isPermaLink="false">http://blog.aheritier.net/?p=433</guid>
		<description><![CDATA[Passons à l&#8217;action aujourd&#8217;hui avec la migration en elle même. Comment avons-nous fait ? A quoi faut-il faire attention ? Avant de migrer &#8230; Petit topo sur la solution existante. Avant la migration, notre environnement ressemble à peu de choses &#8230; <a href="http://blog.aheritier.net/dapache-archiva-a-sonatype-nexus-la-migration/">Continue reading <span class="meta-nav">&#8594;</span></a><br /><div><img src="http://blog.aheritier.net/wp-content/plugins/gd-star-rating/gfx.php?value=8.6" /></div><div>Rating: 8.6/<strong>10</strong> (8 votes cast)</div><br />]]></description>
			<content:encoded><![CDATA[<p>Passons à l&#8217;action aujourd&#8217;hui avec la migration en elle même. Comment avons-nous fait ? A quoi faut-il faire attention ?</p>
<p><span id="more-433"></span></p>
<h3>Avant de migrer &#8230;</h3>
<p>Petit topo sur la solution existante. Avant la migration, notre environnement ressemble à peu de choses près à ceci :</p>
<div id="attachment_516" class="wp-caption aligncenter" style="width: 310px"><a href="http://blog.aheritier.net/wp-content/uploads/2009/05/archivanexusavantmigration.png"><img src="http://blog.aheritier.net/wp-content/uploads/2009/05/archivanexusavantmigration-300x227.png" alt="L&#039;environnement avant migration" title="L&#039;environnement avant migration" width="300" height="227" class="size-medium wp-image-516" /></a><p class="wp-caption-text">L'environnement avant migration</p></div>
<p>Nous hébergeons nos référentiels internes dans ce que Archiva appelle des <em>managed repositories</em>. On en retrouve un pour les <em>releases</em>, un pour les <em>snapshots</em> et un dernier pour les librairies tierces (celles des éditeurs en général).<br />
Pour gérer le cache des référentiels externes (déclarés en tant que <em>&#8220;remote repositories&#8221;</em>) nous utilisons deux autres référentiels internes ( <em>releases</em> et <em>snapshots</em>).</p>
<p>Archiva expose deux groupes : L&#8217;un pour accéder à toutes les <em>releases</em>, l&#8217;autre pour les <em>snapshots</em>. Nous n&#8217;avons jamais mis en place de groupe qui expose les deux types d&#8217;artifacts ensembles car Archiva a souvent eu des problèmes pour fusionner les descripteurs présents sur les référentiels (<em>maven-metadata.xml</em>).</p>
<p>Les groupes permettent de simplifier énormément la configuration de Maven en évitant de déclarer tous les référentiels. Encore plus important, les groupes optimisent grandement les performances de Maven car pour un artifact manquant celui-ci ne fait qu&#8217;une requête vers le groupe qui la distribue sur tous les référentiels qu&#8217;il masque. Interroger individuellement chaque référentiel est une perte de temps inexorable.</p>
<p>Les clients des référentiels (utilisateurs et intégration continue) y accèdent en configurant ainsi Maven :<br />
[xml]<br />
<settings></p>
<profiles>
<profile>
      <id>default</id><br />
      <repositories><br />
        <repository><br />
          <id>central</id><br />
          <url>http://serveur.entreprise.fr/archiva/repository/releases/ </url><br />
          <releases><enabled>true</enabled></releases><br />
          <snapshots><enabled>false</enabled></snapshots><br />
        </repository><br />
        <repository><br />
          <id>snapshots</id><br />
          <url>http://serveur.entreprise.fr/archiva/repository/snapshots/ </url><br />
          <releases><enabled>false</enabled></releases><br />
          <snapshots><enabled>true</enabled></snapshots><br />
        </repository><br />
      </repositories></p>
<pluginrepositories>
<pluginrepository>
          <id>central</id><br />
          <url>http://serveur.entreprise.fr/archiva/repository/releases/ </url><br />
          <releases><enabled>true</enabled></releases><br />
          <snapshots><enabled>false</enabled></snapshots>
        </pluginrepository>
<pluginrepository>
          <id>snapshots</id><br />
          <url>http://serveur.entreprise.fr/archiva/repository/snapshots/ </url><br />
          <releases><enabled>false</enabled></releases><br />
          <snapshots><enabled>true</enabled></snapshots>
        </pluginrepository>
      </pluginrepositories>
    </profile>
  </profiles>
  <activeprofiles><br />
    <activeprofile>default</activeprofile><br />
  </activeprofiles><br />
</settings><br />
[/xml]</p>
<p>En redéfinissant l&#8217;adresse du serveur central (normalement situé ici : <a href="http://repo1.maven.org/maven2/">http://repo1.maven.org/maven2/</a>) Maven recherche les artifacts de type <em>release</em> dans notre groupe dédié sur archiva. Cela nous donne alors accès autant aux <em>releases</em> internes qu&#8217;externes. De la même manière le référentiel additionnel <em>snapshots</em> nous permet d&#8217;obtenir les versions en cours de développement.</p>
<h3>Les contraintes</h3>
<p>La migration n&#8217;est pas aisée lorsque l&#8217;on a 200 développeurs qui utilisent le serveur au quotidien. </p>
<p>Premièrement, il faut s&#8217;assurer de stopper le gestionnaire d&#8217;artifacts un minimum de temps (ou alors venir le faire en dehors des heures de travail &#8230; gloups !!!). Arrêter l&#8217;intégration continue temporairement n&#8217;est pas un problème majeur. Par contre, demander aux équipes d&#8217;utiliser Maven en mode offline et de ne plus utiliser les référentiels est plus difficile. En général, Il ne faut pas longtemps avant qu&#8217;une personne ait besoin de télécharger une librairie ou qu&#8217;un projet doive faire une <em>release</em>. </p>
<p>Deuxièmement, il est impératif de garder la compatibilité avec les paramétrages Maven actuels. Compte tenu du nombre de projets et de développeurs il est impossible de reconfigurer tous les références aux référentiels dans le paramétrage Maven. Il faudrait impacter tous les projets pour modifier les urls d&#8217;upload (<em>distributionManagement</em>) et tous les développeurs pour les paramètres de téléchargement (<em>repositories</em>).</p>
<h3>La démarche</h3>
<p>Pour limiter les coûts nous avons décidé de ne pas faire tous nos tests sur un environnement de recette. Il aurait fallu dupliquer tout l&#8217;environnement d&#8217;intégration continue aujourd&#8217;hui en production afin d&#8217;avoir des résultats probants.<br />
Une fois les quelques tests de base effectués sur l&#8217;outil, la véritable épreuve du feu se joue sur la volumétrie et la montée en charge du serveur.<br />
Comme nous changeons de produit, nous pouvons facilement faire tourner les deux serveurs en parallèle (tant que les ressources système nous le permettent).  Nous sommes donc partis sur la stratégie de faire un &#8220;parallel run&#8221; Archiva / Nexus pour ensuite basculer les services les uns après les autres (en gardant la possibilité de revenir en arrière au cas où).<br />
Nous avons assez de place pour recréer les caches des référentiels externes (cela ne représente que quelques Go). Il n&#8217;y a que les référentiels internes que nous ne pouvons pas dupliquer (ils sont trop gros, et cela poserait un problème de cohérence). Nous ne voulons pas non plus partager ces référentiels internes entre les deux produits afin de ne pas risquer d&#8217;avoir des accès concurrents. Nous commencerons donc notre migration en laissant les repositories internes sur Archiva puis nous les migrerons à la dernière minute sur Nexus lors de la bascule finale.</p>
<p>Pour la compatibilité des urls nous allons utiliser des règles de réécritures (<em>rewriting rules</em>) sur le serveur Apache que nous avons en frontal. Il fera le passage entre les anciennes url et les nouvelles de manière transparente.</p>
<h3>Installation de Nexus</h3>
<p>Nous effectuons une installation classique de Nexus 1.3.2 en version opensource standalone en adaptant uniquement quelques paramètres comme le port HTTP, les chemins des répertoires des données et des logs pour se conformer à l&#8217;organisation de notre serveur. Tout cela se fait en très très peu de temps puisque contrairement à Archiva nous n&#8217;avons pas à créer de base de données. Notre serveur Nexus est rapidement en route et prêt à être configuré.</p>
<h3>Configuration des groupes et référentiels externes</h3>
<p>Nous commençons la configuration de Nexus par les référentiels externes (<em>proxy repositories</em>). Nous rajoutons aussi pour les besoins de la migration les caches vers nos référentiels internes toujours hébergés sur Archiva.  </p>
<p>L&#8217;IHM est assez bien faite ce qui rend la saisie des 20 référentiels externes supportable. Merci à <a href="http://extjs.com/">ExtJS</a> !</p>
<p>Contrairement à Archiva qui propose de stocker les artifacts de plusieurs référentiels externes dans un même référentiel local, Nexus stocke le contenu de chacun dans un répertoire dédié. </p>
<p>Concernant le paramétrage des référentiels externes, il faut noter que l&#8217;on perd la possibilité offerte par Archiva de gérer des listes blanches ou noires des <em>artifacts</em> à récupérer sur les référentiels externes. C&#8217;est la notion de <em>&#8220;routes&#8221;</em> qui est utilisée dans Nexus pour faire ce type de filtrage. Malheureusement elle ne s&#8217;applique aujourd&#8217;hui qu&#8217;au niveau d&#8217;un groupe et non pas au niveau d&#8217;un référentiel.<br />
Puisque les quelques listes que nous avons dans Archiva ne sont là que pour des questions de performance (ne pas interroger un référentiel dans lequel on sait qu&#8217;un <em>artifact</em> n&#8217;est pas), nous avons décidé de ne pas dupliquer cette configuration sur Nexus en attendant de voir si cela posait de réels problèmes.</p>
<p>Lors de notre paramétrage nous faisons face à une autre déconvenue. Comme nous devons faire proxy pour des référentiels hébergés en interne (pour le référentiel exposé par le serveur sonar et pour Archiva pendant la migration) nous avons été obligés de déclarer le proxy web de l&#8217;entreprise sur chaque référentiel externe. Il est impossible en définissant le proxy web dans la configuration globale de Nexus de la désactiver sur un référentiel donné.</p>
<p>Alors que notre configuration des référentiels externes était quasiment terminée, nous trébuchons sur un os de taille. Nous découvrons qu&#8217;il est impossible de faire proxy de référentiels qui sont au format maven 1 (chez atlassian et dev.java.net par exemple).<br />
Pour y parvenir nous devons créer des référentiels virtuels (<em>virtual repository</em>) qui servent à Nexus pour convertir un référentiel d&#8217;un format vers un autre. Manque de chance deux bugs (<a href="https://issues.sonatype.org/browse/NEXUS-1909">NEXUS-1909</a>, <a href="https://issues.sonatype.org/browse/NEXUS-1910">NEXUS-1910</a>) nous empêchent de le faire.<br />
Heureusement pour nous, l&#8217;équipe Nexus a su être très réactive et elle a pu incorporer les corrections à ces bugs dans la version 1.3.3 qu&#8217;elle publiait le lendemain de notre découverte. Sans cela il fallait bien avouer que l&#8217;on n&#8217;aurait probablement pas continué nos tests sur Nexus.<br />
Nous avons donc mis à jour notre installation ce qui en passant nous a permis de voir que l&#8217;opération était très aisée puisque l&#8217;application, sa configuration et ses données sont très bien séparées.</p>
<p>Nous finalisons la configuration de Nexus par la création des groupes. Cette la même notion que celle d&#8217;Archiva (qui a d&#8217;ailleurs copié dessus).<br />
La gestion d&#8217;un groupe est par contre assez mal faite en terme d&#8217;ergonomie. Il nous faut sélectionner les référentiels à rajouter au groupe puis l&#8217;ordonner dans une liste. L&#8217;ordre est très important car Nexus l&#8217;utilisera pour rechercher les <em>artifacts</em>. Il faut donc placer les référentiels avec des <em>releases</em> avant des <em>snapshots</em> et les référentiels locaux avant les référentiels externes. Le problème c&#8217;est que cette liste n&#8217;affiche que le nom de chaque référentiel (et encore ce nom est souvent tronqué faute de place). Vous avez donc intérêt à faire très attention au nommage des référentiels pour vous y retrouver lorsqu&#8217;il faut en classer plusieurs dizaines dans un groupe. </p>
<p>Nous suivons les recommandations de Nexus en créant un groupe unique qui expose toutes les releases et tous les snapshots. (Ce qui nous évitera en plus de nous battre deux fois avec l&#8217;écran de configuration d&#8217;un groupe).</p>
<p>A partir de ce moment là nous sommes censés être en mesure de récupérer tous les artifacts nécessaires à la construction de nos projets depuis Nexus. </p>
<p>Après quelques tests unitaires concluants nous validons l&#8217;ensemble avec notre serveur d&#8217;intégration continue.<br />
Nous supprimons son référentiel local et mettons à jour sa configuration :<br />
[xml]<br />
<settings><br />
  <mirrors><br />
    <mirror><br />
      <!--This sends everything else to /public --><br />
      <id>nexus</id><br />
      <mirrorof>*</mirrorof><br />
      <url>http://serveur.entreprise.fr/nexus/content/groups/public/ </url><br />
    </mirror><br />
  </mirrors></p>
<profiles>
<profile>
      <id>default</id><br />
      <!--Enable snapshots for the built in central repo to direct --><br />
      <!--all requests to nexus via the mirror --><br />
      <repositories><br />
        <repository><br />
          <id>central</id><br />
          <url>http://central </url><br />
          <releases><enabled>true</enabled></releases><br />
          <snapshots><enabled>true</enabled></snapshots><br />
        </repository><br />
      </repositories></p>
<pluginrepositories>
<pluginrepository>
          <id>central</id><br />
          <url>http://central </url><br />
          <releases><enabled>true</enabled></releases><br />
          <snapshots><enabled>true</enabled></snapshots>
        </pluginrepository>
      </pluginrepositories>
    </profile>
  </profiles>
  <activeprofiles><br />
    <!--make the profile active all the time --><br />
    <activeprofile>default</activeprofile><br />
  </activeprofiles><br />
</settings><br />
[/xml]</p>
<p><strong>A noter :</strong> Je ne suis pas du tout fan de l&#8217;utilisation du mirroir * qui oblige à mettre dans le même groupe les releases et les snapshots. C&#8217;est cependant la seule solution aujourd&#8217;hui puisqu&#8217;il n&#8217;y a pas la possibilité avec les miroirs de dire à Maven de rechercher les releases à un emplacement et les snapshots à un autre. Je trouve cette utilisation dangereuse car, par exemple, lorsque vous demandez un plugin sans définir sa version (un plugin en ligne de commande par exemple comme eclipse:eclipse ou archetype:generate) vous risquez de récupérer une version snapshot. Il faut donc prendre à la lettre la recommandation de Maven qui est de <strong>définir dans son POM (ou par héritage) toutes les versions des plugins que l&#8217;on utilise</strong> pour s&#8217;éviter des surprises (ce qui ne me gène pas dans notre contexte puisque la recommandation est suivie par tous les projets en utilisant un pom parent qui fait cette définition pour eux).</p>
<p>L&#8217;environnement Archiva et Nexus en parallèle est opérationnel. </p>
<div id="attachment_517" class="wp-caption aligncenter" style="width: 310px"><a href="http://blog.aheritier.net/wp-content/uploads/2009/05/archivanexuspendantmigration.png"><img src="http://blog.aheritier.net/wp-content/uploads/2009/05/archivanexuspendantmigration-300x153.png" alt="Nexus / Archiva en parallèle" title="Double Run" width="300" height="153" class="size-medium wp-image-517" /></a><p class="wp-caption-text">Nexus / Archiva en parallèle</p></div>
<p>Rien ne changent pour les développeurs qui continuent d&#8217;utiliser Archiva. Le serveur d&#8217;intégration continue récupère par contre tous les artifacts nécessaires depuis Nexus.</p>
<h3>Tuning</h3>
<p>Au bout de quelques jours de tests on remarque que Nexus a parfois du mal à servir rapidement les artifacts. On s&#8217;intéresse donc aux paramétrages un peu plus avancés.</p>
<p>Les routes permettent lorsque l&#8217;on demande un artifact à un groupe de restreindre la liste des référentiels que Nexus doit consulter dans le groupe donné. Cela peut se faire via des autorisations ou des interdictions.</p>
<p>La route que nous créons en premier est celle qui concerne les artifacts de nos projets (.*/fr/monentreprise/.*) pour lesquels Nexus doit renvoyer automatiquement vers les proxy des référentiels gérés pour l&#8217;instant par Archiva. <em>Une fois la mise en production finale effectuée, celui-ci pointe uniquement vers les référentiels locaux.</em></p>
<p>Nous ajoutons aussi des règles pour .*/org/apache/.* et .*/org/codehaus/.* qui sont massivement utilisées par Maven afin que les artifacts ne soient recherchés que sur le référentiel central et sur les référentiels des snapshots de chaque communauté.</p>
<p>Tout cela donne déjà un bon coup de boost à notre Nexus.<br />
Après plusieurs jours d&#8217;utilisation pour les téléchargements de l&#8217;intégration continue, le serveur Nexus tourne parfaitement. Nous préparons donc la deuxième partie de la migration : La mise en place des référentiels internes sur Nexus.</p>
<h3>Configuration des référentiels internes et de la sécurité</h3>
<p>Pour reprendre les référentiels internes hébergés par Archiva sur Nexus il nous faut commencer par créer les référentiels internes <em>(hosted repositories</em>). Nous plaçons les répertoires de stockage des artifacts à un emplacement différent de celui d&#8217;Archiva pour ne pas laisser les deux produits accéder aux même données. Nous reprenons les identifiants de référentiels utilisés dans Archiva afin de pouvoir facilement créer des règles de réécriture sur notre frontal Apache. </p>
<p>Nous passons un peu de temps pour comprendre le mécanisme de sécurité de Nexus. Ce dernier est tellement fin que les paramétrages basiques sont vite compliqués.</p>
<p>Nous commençons par créer des privilèges sur les référentiels internes (lecture, écriture, mis à jour). Nous créons des rôles qui regroupent un certain nombre de privilèges sur certains référentiels. Dans notre cas un rôle pour déployer sur les référentiels des releases (pour les équipes projets) et un rôle pour déployer sur les référentiels de snapshots (pour l&#8217;intégration continue).<br />
Nous terminons en créant les utilisateurs avec les rôles définis ci-dessus sans oublier le rôle pour lire sur tous les référentiels.</p>
<p>Les référentiels internes étant prêts il ne nous reste plus qu&#8217;à les basculer sur Nexus et éteindre Archiva.</p>
<h3>La bascule finale</h3>
<p>Pour conserver la compatibilité des urls entre Archiva et Nexus nous faisons deux choses.<br />
Pour les accès en écriture sur les référentiels nous définissons une à une la règle qui transforme l&#8217;adresse d&#8217;Archiva vers Nexus.<br />
Exemple de configuration Apache :<br />
[text]<br />
####<br />
# Compatibilité ARCHIVA<br />
####<br />
RewriteRule ^/archiva/repository/internal-releases/(.*) http://localhost/nexus/content/repositories/internal-releases/$1 [P]<br />
RewriteRule ^/archiva/repository/internal-snapshots/(.*) http://localhost/nexus/content/repositories/internal-snapshots/$1 [P]<br />
RewriteRule ^/archiva/repository/third-parties/(.*) http://localhost/nexus/content/repositories/third-parties/$1 [P]<br />
&#8230;<br />
[/text]<br />
Pour les accès en lecture qui se faisaient sur archiva avec des groupes nous transférons la demande vers le groupe unique que nous avons sur Nexus.<br />
Exemple de configuration Apache :<br />
[text]<br />
####<br />
# Accès aux groupes<br />
####<br />
RewriteRule ^/archiva/repository/[a-z\-]+/(.*) http://localhost/nexus/content/groups/public/$1 [P]<br />
[/text]<br />
La bascule est prête :</p>
<ol>
<li>Arrêt de Nexus,</li>
<li>Arrêt d&#8217;Archiva,</li>
<li>Installation des règles de réécriture sur le frontal Apache,</li>
<li>Déplacement du contenu des référentiels internes depuis Archiva vers Nexus,</li>
<li>Redémarrage de Nexus.</li>
</ol>
<p>Le jour J nous avons fait la bascule en moins de 10 minutes. Nexus a pris quelques heures à digérer nos centaines de Go de données mais sans pour autant que cela diminue énormément ses performances.</p>
<div id="attachment_520" class="wp-caption aligncenter" style="width: 310px"><a href="http://blog.aheritier.net/wp-content/uploads/2009/05/archivanexusapresmigration.png"><img src="http://blog.aheritier.net/wp-content/uploads/2009/05/archivanexusapresmigration-300x182.png" alt="Environnement après migration" title="Environnement après migration" width="300" height="182" class="size-medium wp-image-520" /></a><p class="wp-caption-text">Environnement après migration</p></div>
<p>Malgré les quelques écueils rencontrés, la migration n&#8217;aura pas été d&#8217;une grande complexité technique. Elle s&#8217;est déroulée sur deux semaines et nous en a coûté moins de la moitié en temps consommé. </p>
<p>Nous étudions aujourd&#8217;hui comment régler les taches en arrière plan. <a href="http://www.sonatype.com">Sonatype</a> a fait un très gros effort sur la <a href="http://www.sonatype.com/books/nexus-book/reference/">documentation du produit</a>. Celle-ci permet de découvrir rapidement l&#8217;ensemble de ses fonctionnalités. Cependant on reste vite sur notre faim lorsque l&#8217;on veut dépasser le cadre du guide de référence. Il manque encore quelques bons conseils sur la mise en œuvre de l&#8217;outil dans un environnement d&#8217;entreprise : </p>
<ul>
<li>Quelles tâches planifiées faut-il utiliser ?</li>
<li>Dans quels cas ? </li>
<li>Quand ? </li>
<li>Pourquoi réparer les metadonnées ? </li>
<li>Pourquoi supprimer les caches ? </li>
<li>Comment gère-t&#8217;on la poubelle ?</li>
</ul>
<p>Je n&#8217;hésiterai pas à remonter ces manques à l&#8217;équipe Nexus pour qu&#8217;elle enrichisse la documentation ( C&#8217;est Tim qui va être content <img src='http://blog.aheritier.net/wp-includes/images/smilies/icon_smile.gif' alt=':-)' class='wp-smiley' />  ).</p>
<p>Ainsi se termine ce retour d&#8217;expérience les mains dans le cambouis pour migrer d&#8217;Archiva vers Nexus. Sur le prochain et dernier article sur le sujet, à découvrir dès demain, vous verrez quel est notre bilan un peu plus de deux semaines après la migration.</p>
<br /><div><img src="http://blog.aheritier.net/wp-content/plugins/gd-star-rating/gfx.php?value=8.6" /></div><div>Rating: 8.6/<strong>10</strong> (8 votes cast)</div><br />]]></content:encoded>
			<wfw:commentRss>http://blog.aheritier.net/dapache-archiva-a-sonatype-nexus-la-migration/feed/</wfw:commentRss>
		<slash:comments>11</slash:comments>
		</item>
		<item>
		<title>D&#8217;Apache Archiva à Sonatype Nexus &#8211; Introduction</title>
		<link>http://blog.aheritier.net/dapache-archiva-a-sonatype-nexus-introduction/</link>
		<comments>http://blog.aheritier.net/dapache-archiva-a-sonatype-nexus-introduction/#comments</comments>
		<pubDate>Tue, 12 May 2009 05:00:39 +0000</pubDate>
		<dc:creator>Arnaud Héritier</dc:creator>
				<category><![CDATA[Technologie]]></category>
		<category><![CDATA[Apache Archiva]]></category>
		<category><![CDATA[Apache Maven]]></category>
		<category><![CDATA[Java]]></category>
		<category><![CDATA[Sonatype Nexus]]></category>

		<guid isPermaLink="false">http://blog.aheritier.net/?p=431</guid>
		<description><![CDATA[Venant de réaliser une migration d&#8217;Apache Archiva vers Sonatype Nexus, sur un environnement significatif, je vous livre la démarche utilisée, les astuces et écueils rencontrés. L&#8217;article étant un peu long il est découpé en 3 parties. Aujourd&#8217;hui je vous présente &#8230; <a href="http://blog.aheritier.net/dapache-archiva-a-sonatype-nexus-introduction/">Continue reading <span class="meta-nav">&#8594;</span></a><br /><div><img src="http://blog.aheritier.net/wp-content/plugins/gd-star-rating/gfx.php?value=10.0" /></div><div>Rating: 10.0/<strong>10</strong> (1 vote cast)</div><br />]]></description>
			<content:encoded><![CDATA[<p>Venant de réaliser une migration d&#8217;<a href="http://archiva.apache.org/">Apache Archiva</a> vers <a href="http://nexus.sonatype.org/">Sonatype Nexus</a>, sur un environnement significatif, je vous livre la démarche utilisée, les astuces et écueils rencontrés. <a href="http://blog.aheritier.net/wp-content/uploads/2009/05/nexus-real-logo.png"><img src="http://blog.aheritier.net/wp-content/uploads/2009/05/nexus-real-logo-300x99.png" alt="nexus-real-logo" title="nexus-real-logo" width="300" height="99" class="alignright size-medium wp-image-458" /></a><br />
L&#8217;article étant un peu long il est découpé en 3 parties. Aujourd&#8217;hui je vous présente le contexte pour vous mettre l&#8217;eau à la bouche. Demain vous pourrez découvrir la migration, les mains dans le cambouis. Je terminerai jeudi sur le bilan et les gains pour les projets qui l&#8217;utilisent.<br />
Merci à <a href="http://www.tarpoon.org/">Tarpoon</a>, <a href="http://www.cestpasdur.com/">C&#8217;est pas dur</a> et toute l&#8217;équipe pour leur aide.<br />
<strong>&lt;Disclaimer&gt; Etant membre de l&#8217;équipe du projet Archiva (rarement actif il faut bien l&#8217;avouer) je devrais essayer de le défendre becs et ongles tout au long de l&#8217;article. Etant consultant avant tout, j&#8217;espère garder une grande objectivité. Je vous laisse juger &#8230;&lt;/Disclaimer&gt;</strong><br />
<span id="more-431"></span></p>
<h2>Le contexte</h2>
<p>Le contexte de la migration est le suivant : une grande entreprise, avec plusieurs dizaines de projets JEE de toutes tailles (de la petite souris au gros paquebot &#8212; NON ! je n&#8217;ai pas parlé du Titanic !! <img src='http://blog.aheritier.net/wp-includes/images/smilies/icon_wink.gif' alt=';-)' class='wp-smiley' />  ), et au moins 200 développeurs actifs simultanément en pleine journée.</p>
<p>La majeure partie des projets utilise Maven. Pour aider les équipes des études à faire mieux et plus vite nous offrons toute une infrastructure dédiée à l&#8217;intégration continue. Un serveur du genre Mister Muscles (Bi-Xeon QuadCore avec 16Go RAM sous RedHat Enterprise Linux 5.1), héberge un serveur d&#8217;intégration continue <a href="http://www.atlassian.com/software/bamboo/">Atlassian Bamboo</a> avec à son bord (environ) : 110 builds d&#8217;intégration continue, 40 builds de sites maven (quotidien), 20 builds <a href="http://sonar.codehaus.org/">Sonar</a> (quotidien). Il héberge aussi un gestionnaire de référentiels d&#8217;artifacts Maven (Archiva 1.1.1 avant la migration) qui abrite un peu moins d&#8217;une dizaine de référentiels locaux et qui fait proxy-cache d&#8217;une vingtaine de référentiels externes. Ces référentiels représentent tout de même 400Go de données. La majeure partie est utilisée par le référentiel des snapshots (200Go) et par le référentiel des releases (150Go). Pour comprendre ces tailles il faut savoir que certains projets produisent (pour de bonnes ou de mauvaises raisons) des EARs pouvant faire jusqu&#8217;à 100Mo. En rajoutant la taille des WARs et JARs qui composent ces EARs, un projet occupent rapidement beaucoup de place à chaque déploiement.</p>
<h2>Pourquoi changer ?</h2>
<p>Cela faisait plusieurs mois que la stabilité de notre environnement d&#8217;intégration ne nous satisfaisait pas. Nous avions des temps d&#8217;exécution très variables d&#8217;un build à un autre, et par intermittence nous avions des erreurs qui n&#8217;étaient pas liées aux projets mais à l&#8217;infrastructure mise en place : </p>
<ul>
<li>Erreurs 500 ou 502 sur des uploads sur Archiva sans raison apparente (j&#8217;ai cherché sans succès la cause),</li>
<li>Plantage complet d&#8217;Archiva ou d&#8217;un autre soft après avoir dépassé le nombre maximum de descripteurs de fichiers ouverts pour l&#8217;utilisateur. Il faut concéder que ces outils manipulent beaucoup de fichiers (téléchargements, uploads, et autres manipulations sur un grand nombre d&#8217;artifacts). Archiva dépasse allègrement la limite par défaut des 1024 descripteurs ce qui nous avait forcé à l&#8217;augmenter. Mais même à 2048 il lui arrive encore occasionnellement de la dépasser.</li>
<li>Récupération de snapshots impossible si le référentiel local utilisé par Bamboo avait été vidé juste avant. Cela entraînait régulièrement l&#8217;échec des builds de sites Maven ou Sonar.</li>
</ul>
<p>A tout cela il faut rajouter le récent bug d&#8217;Archiva (<a href="http://jira.codehaus.org/browse/MRM-1136">MRM-1136</a>) sur lequel j&#8217;ai passé plusieurs heures en diagnostic (problème sur la gestion des meta-données émises par Maven 2.1.0) et qui allait nous obliger à upgrader rapidement vers une version 1.1.4 ou 1.2.</p>
<p>Tous ces problèmes même s&#8217;ils n&#8217;étaient que ponctuels, dévalorisaient fortement l&#8217;intégration continue. Comment reprocher à un projet de ne plus en tenir compte si cette dernière vous envoie des faux négatifs ? Ils ont déjà bien assez de travail pour traiter les véritables erreurs. <strong>L&#8217;environnement d&#8217;intégration continue doit être aussi fiable qu&#8217;une horloge suisse.</strong></p>
<p>Il était donc temps pour nous de réagir. </p>
<p>Soit nous mettions à jour Archiva, ce qui représentait un coût non négligeable en recette mais qui n&#8217;apporterait pas beaucoup d&#8217;améliorations. En dehors de l&#8217;incompatibilité avec Maven 2.1.0, rien ne nous laissait penser que les nouvelles versions corrigeraient certains autres de nos problèmes. Et du coté des évolutions, ces dernières se font rares sur Archiva en ce moment (faute de moyen).</p>
<p>Soit nous faisions le pari de prendre un autre outil avec le risque de rencontrer de nouveaux écueils.</p>
<p>Les retours de la communauté à propos de Nexus sont très encourageants. De plus, celui-ci en version pro ouvre de nouvelles possibilités à l&#8217;avenir avec ses fonctionnalités novatrices :</p>
<ul>
<li>Référentiels de recette (staging repository) pour mettre dans un sas les artifacts en cours de validation avant leur livraison,</li>
<li>Possibilité de faire proxy pour les updates sites eclipse. Actuellement nous le faisons à la main cependant cela est coûteux, compliqué (je déteste P2), et inintéressant.</li>
</ul>
<p>Puisque le jeu semblait en valoir la chandelle, nous avons décidé de tenter notre chance avec Nexus&#8230;</p>
<br /><div><img src="http://blog.aheritier.net/wp-content/plugins/gd-star-rating/gfx.php?value=10.0" /></div><div>Rating: 10.0/<strong>10</strong> (1 vote cast)</div><br />]]></content:encoded>
			<wfw:commentRss>http://blog.aheritier.net/dapache-archiva-a-sonatype-nexus-introduction/feed/</wfw:commentRss>
		<slash:comments>3</slash:comments>
		</item>
	</channel>
</rss>

