views:

388

answers:

4

What I want to do is to create source code distribution of my application with all dependencies and burn it on DVD. So that I could build it in 100 years (well, ok, you know what I mean...). No online dependencies on libraries or maven plugins!

I know that Ant would be better for this, but I'm using maven in my project. I'm not going to switch to Ant just for that, I'm asking how to do this with maven. Or, if there is a way how to generate self sustainable Ant build that I could put on DVD that would be great too. (there is ant:ant plugin but it just generates Ant build.xml that points dependencies to local maven repo)

The approach I've taken is that I wanted to create special local repository that I can put on DVD and then build project with mvn -o -Dmaven.repo.local=repo/on/dvd. I was trying to make such repository with dependency:copy-dependencies anduseRepositoryLayout param set to true. But it doesn't copy freaking maven plugins that my build depends on...

+1  A: 

The only way I can think of to include the plugins is to specify a different local repository for the build on the command line and ensure all the dependency sources etc are downloaded, then create an archive including the project's contents and the custom repository.

Here is a pom that downloads the sources and javadocs (it downloads them to the project's target directory, which we exclude from the archive because they will also be in the local repository). The assembly descriptor bundles the project's contents and the local repository into a single (pretty large) archive.

Note the processing is all in a profile because you really don't want this running on every build. If temporary local repository is in the target directory you can easily clean the mess up afterwards with a mvn clean. To activate the profile do something like the following:

mvn package -Parchive -Dmaven.repo.local=.\target\repo

Here's the pom:

<?xml version="1.0" encoding="UTF-8"?>
<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/maven-v4_0_0.xsd"&gt;
  <modelVersion>4.0.0</modelVersion>
  <groupId>name.seller.rich</groupId>
  <artifactId>test-archive</artifactId>
  <version>0.0.1</version>
  <dependencies>
    <dependency>
      <groupId>junit</groupId>
      <artifactId>junit</artifactId>
      <version>4.5</version>
      <scope>test</scope>
    </dependency>
  </dependencies>
  <profiles>
    <profile>
      <id>archive</id>
      <build>
        <plugins>
          <plugin>
            <groupId>org.apache.maven.plugins</groupId>
            <artifactId>maven-dependency-plugin</artifactId>
            <executions>
              <execution>
                <id>sources</id>
                <phase>pre-package</phase>
                <goals>
                  <goal>copy-dependencies</goal>
                </goals>
                <configuration>
                  <classifier>sources</classifier>
                  <failOnMissingClassifierArtifact>false</failOnMissingClassifierArtifact>
                  <!--the target directory won't be included, but the sources will be in the repository-->
                  <outputDirectory>${project.build.directory}/sources</outputDirectory>
                </configuration>
              </execution>
              <execution>
                <id>javadocs</id>
                <phase>pre-package</phase>
                <goals>
                  <goal>copy-dependencies</goal>
                </goals>
                <configuration>
                  <classifier>javadoc</classifier>                      <failOnMissingClassifierArtifact>false</failOnMissingClassifierArtifact>
                  <outputDirectory>${project.build.directory}/javadocs</outputDirectory>
                </configuration>
              </execution>
            </executions>
          </plugin>
          <plugin>
            <artifactId>maven-assembly-plugin</artifactId>
            <version>2.2-beta-4</version>
            <executions>
              <execution>
                <phase>package</phase>
                <goals>
                  <goal>single</goal>
                </goals>
                <configuration>
                  <descriptors>
                    <descriptor>src/main/assembly/archive.xml</descriptor>
                  </descriptors>
                </configuration>
              </execution>
            </executions>
          </plugin>    
        </plugins>
      </build>
    </profile>
  </profiles>
</project>

And here's the assembly:

<assembly>
  <id>archive</id>
  <formats>
    <format>zip</format>
  </formats>
  <fileSets>
    <fileSet>
     <directory>${project.basedir}</directory>
     <outputDirectory>/</outputDirectory>
      <excludes>
        <exclude>target/**</exclude>
      </excludes>
    </fileSet>
    <fileSet>
     <directory>${maven.repo.local}</directory>
     <outputDirectory>repo</outputDirectory>
    </fileSet>
  </fileSets>
</assembly>
Rich Seller
+1 for interesting answer. I might need it some time...
KLE
A: 

I don't have a complete answer. Last time I looked at this, I thought that cleaning out the localRepository at the start of the build (or using a separate one) and the running mvn dependency:go-offline.

If you're really keen, you'll also want to bundle maven itself and a JDK into the distribution. This likely takes it out of scope of a pure maven build.

Dominic Mitchell
A: 

Watch this: Maven Assembly Plugin

Quote from the homepage:

Do you want to create a binary distribution from a Maven project that includes supporting scripts, configuration files, and all runtime dependencies? You need to use the Assembly Plugin to create a distribution for your project.

It's well configurable. I used it especially for making self-running demo versions of web-applications with an embedded jetty server and user documentation.

pcjuzer
A: 

I have been struggling with this task for several months. I have multi-module Maven project and I am filtering out some items from end-result distribution (also using special pom for that distribution). I have used local Maven repo configuration and assembly descriptors. There really is no good instructions for this case in web. I cannot make it working so that it would work like... forever. Still needs some manual work.

jim