Mostrando entradas con la etiqueta nexus. Mostrar todas las entradas
Mostrando entradas con la etiqueta nexus. Mostrar todas las entradas

miércoles, 18 de mayo de 2011

What if I want to deploy/upload several files to artifactory or nexus with Maven?

Regardless of the repository you are using to store generated artifacts, the default Maven configuration for, let's say, WAR file, is upload a WAR file.. interesting..

A common configuration commented here also uploads the source code as a jar file, and that is very recommendable for debugging.

Another uploaded or auto-generated file is a "pom.xml" project descriptor file for your artifact.

But we want to go further, we want to upload the sql file needed to generate our initial database, or the pdf with the documentation of this release.. how to get this?

<plugin>   
  <groupId>org.codehaus.mojo</groupId>   
  <artifactId>build-helper-maven-plugin</artifactId>
  <executions>
    <execution>

      <id>attach-artifacts</id>
      <phase>package</phase>
      <goals> 

        <goal>attach-artifact</goal>
      </goals> 
      <configuration>
        <artifacts> 
          <artifact> 
            <file>src\main\sql\initdb.sql</file>
            <type>sql</type>
            <classifier>create</classifier>
          </artifact>
          <artifact>
            <file>target\site\docs\document.pdf</file>   
            <type>pdf</type>
            <classifier>doc</classifier>
          </artifact>
        </artifacts>
      </configuration>
    </execution>
  </executions>
</plugin>


With this plugin, you are associating with the same artifact the "document.pdf" file, the "initdb.sql" file, the war, the sources jar, the pom.xml file... all them with the same version, and with the possibility of declaring any of them as a dependency.

It will be executed in package phase, beware because you may mistake the phases and attach something not yet created, for example, the pdf may be created in pre-site phase instead of .. compile, for example.

In the case of multiple configurations, you can configure it like this:


<plugin>   
  <groupId>org.codehaus.mojo</groupId>   
  <artifactId>build-helper-maven-plugin</artifactId>
  <executions>
    <execution>

      <id>attach-artifacts1</id>
      <phase>package</phase>
      <goals> 

        <goal>attach-artifact</goal>
      </goals> 
      <configuration>
        <artifacts> 
          <artifact> 
            <file>src\main\sql\initdb.sql</file>
            <type>sql</type>
            <classifier>create</classifier>
          </artifact>
        </artifacts>
      </configuration>
    </execution>

    <execution>
      <id>attach-artifacts2</id>
      <phase>site</phase>
      <goals> 

        <goal>attach-artifact</goal>
      </goals> 
      <configuration>
        <artifacts> 
          <artifact>
            <file>target\site\docs\document.pdf</file>   
            <type>pdf</type>
            <classifier>doc</classifier>
          </artifact>
        </artifacts>
      </configuration>
    </execution>

  </executions>
</plugin>

In this case, if we execute "mvn deploy", only "initdb.sql" will be attached, if we execute "mvn site-deploy", it will be only attached "document.pdf" (because it is supposed to be created in pre-site phase, but I am not sure if it will be deployed in "artifactory" or "nexus", because you don't pass through "deploy" phase, I would say it won't.

The best, if you execute "mvn site-deploy deploy", firstly "document.pdf" is attached in "site" phase, then "initbd.sql" is attached in "package" phase, and finally all them are deployed in "deploy" phase. Really useful!

This is the solution for a problem we wanted to solve in my job, the solution was taken here, thanks!

domingo, 20 de marzo de 2011

Managing Maven dependencies with an external dependencies repository

Content:

Maven abstract.
Tunning your Maven proyect
Maven standard folders
Managing dependencies with Maven
Adding a nature in Eclipse
Maven profiles inheritance
Managing Maven dependencies with an external dependencies repository


I have been talking a lot about Maven dependencies for a local machine. It is high time to start talking about remote dependencies.

When you define a dependency in your pom.xml file, that dependency is sought in repo1.maven.org. But your libraries and internal dependencies are not there. Certainly they are in your local repository, but not in your workmate's own.

I do not find necessary to speak in favour of a code repository, the reasons are widely known. Reasons for a dependency repository might be less known because code is always used, but Maven is not (always).
Basic scenario is easy to find nevertheless:
  • You create a library for a project with Maven.
  • You design that library as a dependency for that project.
  • You might want your workmate to compile the project in his/her computer, but...
    • Binaries should never be uploaded to code repository!
    • Shared folders are system dependant and difficult to automatize, trace and export.
    • We are looking for zero specific configuration in a compilation.
If you could only upload to a private repo1.maven.org repository in order to make accessible an internal dependency for your company... You can!

There are two main open-source implementation for this task: Nexus and Artifactory. Both seem alike, but I chose to know deeply the last one, maybe I could find some time for comparing both in installation, configuration and performance. 

If you had in your pom.xml a configuration like this:

    <repositories>
        <repository>
            <snapshots />
            <id>snapshots</id>
            <name>libs-internal</name>
            <url>http://localhost:8080/artifactory/libs-internal</url>
        </repository>
    </repositories>

With this entry in pom.xml, we are asking Maven to search in this URL for any dependency we might need, and, for being in pom.xml, that configuration is project-scoped, being shared with the project itself in code repository.

All we have to keep in mind is that the server MUST be accessible by any of your partners who you are expecting to compile the project. In this example, our partners will find that they do not have Artifactory installed in their localhost, and you will find lots of complains for creating a local-dependant configuration for a department project.

Your second try made it better:

        <repository>
            <snapshots />
            <id>snapshots</id>
            <name>libs-internal</name>
            <url>http://srvmachine:8080/artifactory/libs-internal</url>
        </repository>

and now, if that machine is accessible for all your department, and permissions are well configured, so firewall is, and half a dozen more configurations, your dependencies would be able to download broadly.

However, as you find comfortable to download dependencies, you will find awful to upload your libraries manually through web interface. It is possible as well to improve this.

With the correct Artifactory and Nexus (trying to be neutral by now) settings, you can automatize your system for uploading a library once it is compiled by Maven:

<distributionManagement>
    <repository>
        <id>linux-wdx0</id>
        <name>linux-wdx0-releases</name>
        <url>http://srvmachine:8080/artifactory/libs-release-local</url>
    </repository>
</distributionManagement>


by typing "mvn deploy" instead of "mvn install" in your Maven console or IDE compilation button.

Now you can enjoy of an easy way to share and download department-scoped libraries within your department in a new fashion way of making things work. Your objetive: your project should compile and run only by downloading it in any machine with zero configuration.