# Problem mit Maven Assembly ...



## tuxedo (2. Mai 2010)

Hallo zusammen,

bin gerade kurz davor an Maven und dem Assembly-Plugin zu verzweifeln...

Es geht um folgendes:

Ich habe ein Serverprojekt. Das besteht zur Zeit aus einem Core und einer Library. Der Core hat diverse Dependencies (MINA, Scannotation, ...). Die Library hat eine Dependency zum Core (LibA von von Core zur Laufzeit dynamisch geladen)

Ich habe beide "Projekte" als "Module" geplant und ein "Mutterprojekt" als zusammenführung beider Projekte gedacht.

Die Pfade sind wie folgt:


```
Mutterprojekt
|
+--- pom.xml
|
+---+ src
|   |
|   +--+ distribution
|   |  |
|   |  + <files die später in ein Distributionsarchiv sollen>
|   |
|   +---+ assemble
|       |
|       + assemble.xml
|
+---+ Core
|   |
|   +--- pom.xml
|
+---+ LibA
    |
    +--- pom.xml
```


Nach einem "mvn package" soll dann im target Verzeichnis folgendes liegen:



```
+---+ lib
|   |
|   +--- Core.....jar
|   +--- <weitere dependencies von Core>
|
+---+ deploy
|   |
|   +--- LibA.....jar
|
+--- <weitere files/ordner aus oben genannten "distribution Verzeichnis">
```


So, die pom.xml im Mutterprojekt sieht wie folgt aus:


```
<project>
    <modelVersion>4.0.0</modelVersion>
    <groupId>com.mydomain</groupId>
    <artifactId>Mutter</artifactId>
    <version>1.0.0-SNAPSHOT</version>
    <name>Mutterprojekt</name>
    <packaging>pom</packaging>

    <modules>
        <module>Core</module>
        <module>LibA</module>
    </modules>

    <build>
        <plugins>
            <plugin>
                <artifactId>maven-assembly-plugin</artifactId>
                <version>2.2-beta-5</version>
                <executions>
                    <execution>
                        <id>distribution</id>
                        <goals>
                            <goal>directory-single</goal>
                        </goals>
                        <phase>package</phase>
                    </execution>
                </executions>

                <configuration>
                    <descriptors>
                        <descriptor>src/assemble/assemble.xml</descriptor>
                    </descriptors>
                </configuration>
            </plugin>

            <plugin>
                <groupId>org.apache.maven.plugins</groupId>
                <artifactId>maven-compiler-plugin</artifactId>
                <version>2.0.2</version>
                <configuration>
                    <encoding>${project.build.sourceEncoding}</encoding>
                    <source>1.6</source>
                    <target>1.6</target>
                </configuration>
            </plugin>
            <plugin>
                <groupId>org.apache.maven.plugins</groupId>
                <artifactId>maven-resources-plugin</artifactId>
                <version>2.2</version>
                <configuration>
                    <encoding>${project.build.sourceEncoding}</encoding>
                </configuration>
            </plugin>
        </plugins>
    </build>




    <dependencies>
        <dependency>
            <groupId>com.mydomain.mp</groupId>
            <artifactId>Core</artifactId>
            <version>1.0.0-SNAPSHOT</version>
        </dependency>

        <dependency>
            <groupId>com.mydomain.mp</groupId>
            <artifactId>LibA</artifactId>
            <version>1.0.0-SNAPSHOT</version>
        </dependency>
    </dependencies>

    <properties>
        <project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
    </properties>
</project>
```

Der Assembly-Descriptor sieht so aus:


```
<assembly xmlns="http://maven.apache.org/plugins/maven-assembly-plugin/assembly/1.1.0"
          xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
          xsi:schemaLocation="http://maven.apache.org/plugins/maven-assembly-plugin/assembly/1.1.0 http://maven.apache.org/xsd/assembly-1.1.0.xsd">
    <id>distribution</id>
    <formats>
        <format>zip</format>
    </formats>
    <includeBaseDirectory>false</includeBaseDirectory>

    <fileSets>
        <fileSet>
            <directory>${basedir}</directory>
            <includes>
                <include>*.bat</include>
                <include>*.sh</include>
            </includes>
            <excludes>
                <exclude>README.txt</exclude>
                <exclude>NOTICE.txt</exclude>
            </excludes>
            <outputDirectory>/</outputDirectory>
        </fileSet>

        <fileSet>
            <directory>${basedir}/src/distribution</directory>
            <outputDirectory>/</outputDirectory>
        </fileSet>

    </fileSets>

    <dependencySets>
        <dependencySet>
            <includes>
                <include>com.mydomain.mp:Core</include>
            </includes>
            <outputDirectory>lib</outputDirectory>
        </dependencySet>

        <dependencySet>
            <includes>
                <include>com.mydomain.mp:LibA</include>
            </includes>
            <outputDirectory>deploy</outputDirectory>
        </dependencySet>

    </dependencySets>

</assembly>
```

Aktuell landet auch alles da wo's hin soll. Nur hab ich eine Fehlermeldung in der Maven-Console:



> [INFO] [assembly:directory-single {execution: distribution}]
> [INFO] Reading assembly descriptor: src/assemble/assemble.xml
> [WARNING] Cannot include project artifact: com.mydomain:Mutterom:1.0.0-SNAPSHOT; it doesn't have an associated file or directory.
> [WARNING] Cannot include project artifact: com.mydomain:Mutterom:1.0.0-SNAPSHOT; it doesn't have an associated file or directory.



Wieso? 

Hab es auch schon anders versucht: Hab versucht den Core nach wie vor über "dependencyset" abzufahren und "LibA" als "moduleset". Aber sobald ich mit ModuleSet anfange bekomme ich zahlreiche Meldungen dass LibA doch schon ins Zielverzeichnis kopiert/ bzw. dort schon existient wäre.

Mache ich hier etwas Grundlegend falsch?
Hintergrund dieser Konstellation ist, dass ich in einem späteren Ausbau noch weitere Libs haben werde die dann alle in das deploy Verzeichnis müssen, ich aber mit "Mutter" ein Basisprojekt haben will das mit die Konstellation der Libs definiert.

- Alex


----------



## kama (6. Mai 2010)

Hallo,

Du solltest den Descriptor um einen Eintrag ergänzen


```
<dependencySet>
  <useProjectArtifact>false</useProjectArtifact>
  ....
   
</dependencySet>
```
zu einen....

und warum gibst Du zwei <dependencySet> an? Warum nicht nur einen?
wie folgt?


```
<dependencySets>
        <dependencySet>
            <includes>
                <include>com.mydomain.mp:Core</include>
                <include>com.mydomain.mp:LibA</include>
            </includes>
            <outputDirectory>lib</outputDirectory>
        </dependencySet>
    </dependencySets>
```

Das Warum ist recht einfach. Wenn Du ein Assembly erzeugst aus einem Project dann sollte das üblicherweise kein POM-Type Projekt sein. Das sagt ja auch die Warning:


```
[WARNING] Cannot include project artifact: com.mydomain:Mutter:pom:1.0.0-SNAPSHOT; it doesn't have an associated file or directory.
```

Das Projekt das zusammenpackt solltest Du als eigenes Modul auslagern und nicht mit dem Root-POM zusammen legen...das wiederspricht ein wenig dem Konzept von Maven. Das geht derzeit noch aber später wird dich das irgendwann beissen...

EDIT: Was mir noch einfällt...Das Verzeichniss distribution solltest Du nochmal überdenken. Was liegen da überhaupt für Dateien ? (ansonsten src/main/resources) dann wird das automatisch mit verpackt.
Gruß
Karl Heinz Marbaise


----------



## tuxedo (6. Mai 2010)

kama hat gesagt.:


> Hallo,
> 
> Du solltest den Descriptor um einen Eintrag ergänzen
> 
> ...



Okay, schlag ich gleich mal nach was das exakt bewirkt...



> und warum gibst Du zwei <dependencySet> an? Warum nicht nur einen?
> wie folgt?
> 
> 
> ...



Naja, ich hatte/habe deshalb zwei, weil ich zwei verschiedene Output-Folder habe. Dein Beispiel bedient nur einen (den lib ...).



> Das Warum ist recht einfach. Wenn Du ein Assembly erzeugst aus einem Project dann sollte das üblicherweise kein POM-Type Projekt sein. Das sagt ja auch die Warning:
> 
> 
> ```
> ...



Ja, da bin ich dann noch einigem googeln auch drauf gekommen. Dass das mit dem Root-POM nicht funktionieren kann konnte ich mir dann so erklären: 

Dieses Root-POM definiert ja nur: Da gibts Module. Wenn irgendwelche Goals ausgeführt werden, dann bei diesen Modulen.
Das Root-POM hat keinen Plan welches Modul in welcher Version erstellt wird.
Und wenn ich jetzt den Assemble-Vorgang auch noch direkt in das Root-POM stecke wird's natürlich nicht besser.

Werde jetzt ein weiteres Module (ein "foobar-dist" Modul) anlegen welches die dependencies zu den anderen Modulen hat und somit, zusammen mit dem Assembly-Plugin, genau weiß welches Modul in welcher Version wie zusammengebaut wird.



> EDIT: Was mir noch einfällt...Das Verzeichniss distribution solltest Du nochmal überdenken. Was liegen da überhaupt für Dateien ? (ansonsten src/main/resources) dann wird das automatisch mit verpackt.
> Gruß
> Karl Heinz Marbaise



Ja, so ganz gefallen hat's mir nicht. Hätte es auch gern im Modul gehabt. Wusste aber nicht genau wo. Werde das mal versuchen in den Resource-Ordner des Core-Moduls zu packen.

Danke soweit für die Tipps.


- Alex


----------



## kama (6. Mai 2010)

Hallo,



tuxedo hat gesagt.:


> Naja, ich hatte/habe deshalb zwei, weil ich zwei verschiedene Output-Folder habe. Dein Beispiel bedient nur einen (den lib ...).


Käse nicht aufgepasst sorry.

Gruß
Karl Heinz Marbaise


----------



## tuxedo (6. Mai 2010)

So, hab mal angefangen das ganze umzubauen. Aber so richtig will es noch nicht klappen. Einen Fehler hab ich auf der Console nun nicht mehr. Aber das Ergebnis ist noch weit entfernt von zufriedenstellend:

1) Ich hab nun folgende kostellation:

* Mutter
** Core
** LibA
** Mutter-Dist

Das POM File von Mutter sieht nun wie folgt aus:


```
<project>
    <modelVersion>4.0.0</modelVersion>
    <groupId>com.mydomain</groupId>
    <artifactId>Mutter</artifactId>
    <version>1.0.0-SNAPSHOT</version>
    <name>Mutterprojekt</name>
    <packaging>pom</packaging>

    <modules>
        <module>Core</module>
        <module>LibA</module>
        <module>Mutter-Dist</module>
    </modules>  

    <properties>
        <project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
    </properties>
</project>
```

Soweit so gut. 

Nun aber zum "Dist" Projekt...

Wie bereits erwähnt, hätte ich gerne aus "Output" einen Ordner der folgendes enthält:


```
+---+ lib
|     |
|     +--- Core.....jar
|     +--- <alle weiteren Dependencies von Core>
|
+---+ deploy
|     |
|     +--- LibA.....jar
|
+--- <weitere files/ordner>
```

Das "distribution" Verzeichnis habe ich nun verschoben. Es liegt nun hier:

Mutter/Core/src/main/resource/<weitere files/ordner>

Wenn ich Core baue, dann hab ich die Files im JAR drin. Gebrauchen kann ich sie da gar nicht. Denn die bringen eine Ordner-Struktur mit, in der der Server-Core dann später arbeiten soll: Sprich Log-Config, Log Ordner, andere Configs die der User anpassen kann/darf, ...

Packe ich die Files nach

Mutter/Mutter-Dist/src/main/resource/<weitere files/ordner>

dann sieht das schon logischer aus. Aber "von haus aus" landet das in keinem Output-Ordner, aber dafür wieder im JAR, welches ich so nicht gebrauchen kann: Brauche kein META-INF und Co. Einfach ein Ordner mit oben beschriebenem Inhalt und dazu noch das gleiche als ZIP ... Mehr nicht.

Mit dem Dependency-Set im Assembly-Descriptor kann ich die Dependencies (Core, LibA), bzw. die einzelnen JARs prima in einen Ziel-Ordner packen. Aber wie ich da das kopieren der Resourcen (<weitere files/ordner>) veranlasse: Keinen Schimmer. Hier mal meine aktuelle  Baustelle:

pom.xml

```
<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">
    <modelVersion>4.0.0</modelVersion>

    <groupId>com.mydomain.mp</groupId>
    <artifactId>Mutter-Dist</artifactId>
    <version>1.0.0-SNAPSHOT</version>

  
    <name>Mutter-Dist</name>
    <packaging>jar</packaging>

    <build>
        <plugins>
            <plugin>
                <artifactId>maven-assembly-plugin</artifactId>
                <version>2.2-beta-5</version>
                <executions>
                    <execution>
                        <id>distribution</id>
                        <goals>
                            <goal>directory</goal>
                        </goals>
                        <phase>package</phase>
                    </execution>
                </executions>

                <configuration>
                    <descriptors>
                        <descriptor>src/assemble/bin.xml</descriptor>
                    </descriptors>
                </configuration>
            </plugin>
            
            <plugin>
                <groupId>org.apache.maven.plugins</groupId>
                <artifactId>maven-compiler-plugin</artifactId>
                <version>2.0.2</version>
                <configuration>
                    <source>1.6</source>
                    <target>1.6</target>
                    <encoding>${project.build.sourceEncoding}</encoding>
                </configuration>
            </plugin>
            <plugin>
                <groupId>org.apache.maven.plugins</groupId>
                <artifactId>maven-resources-plugin</artifactId>
                <version>2.2</version>
                <configuration>
                    <encoding>${project.build.sourceEncoding}</encoding>
                </configuration>
            </plugin>		
        </plugins>
    </build>

    <dependencies>
        
        <dependency>
            <groupId>com.mydomain.mp</groupId>
            <artifactId>Core</artifactId>
            <version>1.0.0-SNAPSHOT</version>
            <type>jar</type>
        </dependency>

        <dependency>
            <groupId>com.mydomain.mp</groupId>
            <artifactId>LibA</artifactId>
            <version>1.0.0-SNAPSHOT</version>
            <type>jar</type>
        </dependency>

    </dependencies>
    
    <properties>
        <project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
    </properties>
</project>
```

bin.xml

```
<assembly xmlns="http://maven.apache.org/plugins/maven-assembly-plugin/assembly/1.1.0"
          xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
          xsi:schemaLocation="http://maven.apache.org/plugins/maven-assembly-plugin/assembly/1.1.0 http://maven.apache.org/xsd/assembly-1.1.0.xsd">
    <id>distribution</id>
    <formats>
        <format>zip</format>
    </formats>
    <includeBaseDirectory>false</includeBaseDirectory>

<!--

Das hatte ich früher, geht aber jetzt wohl nicht mehr?!
    <fileSets>
        <fileSet>
            <directory>${basedir}</directory>
            <includes>
                <include>*.bat</include>
                <include>*.sh</include>
            </includes>
            <excludes>
                <exclude>README.txt</exclude>
                <exclude>NOTICE.txt</exclude>
            </excludes>
            <outputDirectory>/</outputDirectory>
        </fileSet>

        <fileSet>
            <directory>${basedir}/src/assemble/distribution</directory>
            <outputDirectory>/</outputDirectory>
        </fileSet>

    </fileSets>
-->


    <dependencySets>
        <dependencySet>
            <includes>
                <include>com.mydomain.mp:Core</include>
                <include>com.mydomain.mp:LibA</include>
            </includes>
            <outputDirectory>lib</outputDirectory>
        </dependencySet>

        <dependencySet>
            <includes>
                <include>com.mydomain.mp:LibA</include>
            </includes>
            <outputDirectory>deploy</outputDirectory>
        </dependencySet>

    </dependencySets>

</assembly>
```

Wenn ich das so ausführe, bekomme ich folgenden Output:

target/Mutter-Dist-1.0.0-SNAPSHOT-distribution/lib/Core-1.0.0-SNAPSHOT.jar
target/Mutter-Dist-1.0.0-SNAPSHOT-distribution/lib/LibA-1.0.0-SNAPSHOT.jar
target/Mutter-Dist-1.0.0-SNAPSHOT-distribution/deploy/LibA-1.0.0-SNAPSHOT.jar

Haben würde ich gerne (fehlende Teile hervorgehoben):

target/Mutter-Dist-1.0.0-SNAPSHOT-distribution/lib/Core-1.0.0-SNAPSHOT.jar
*target/Mutter-Dist-1.0.0-SNAPSHOT-distribution/lib/<alle Dependencies die Core benötigt>*
target/Mutter-Dist-1.0.0-SNAPSHOT-distribution/lib/LibA-1.0.0-SNAPSHOT.jar
target/Mutter-Dist-1.0.0-SNAPSHOT-distribution/deploy/LibA-1.0.0-SNAPSHOT.jar
*target/Mutter-Dist-1.0.0-SNAPSHOT-distribution/<weitere files/ordner>*

Steh jetzt mal wieder wie der Ochs vorm Berg: Kein Plan wie's weiter geht. Werde - bis hier antworten kommen - mal derweil die Assembly-Plugin-Doku weiter wälzen ...


- Alex



[update]

Okay, einen Punkt konnte ich selbst lösen:

Die Sache mit den weiteren Files und Ordnern geht so:

Im bin.xml bei den DependencySets folgendes einbauen:

```
<!-- include the required files/folder resources for the server runtime environment-->
        <dependencySet>
            <includes>
                <include>com.mydomain.mp:Mutter-Dist</include>
            </includes>
            <outputDirectory></outputDirectory>
            <unpack>true</unpack>
            <unpackOptions>
                <excludes>
                    <exclude>META-INF/**</exclude> <!-- but exclude the ugly META-INF folder -->
                </excludes>
            </unpackOptions>
        </dependencySet>
```

Fehlen nur die die Libs des Core-Moduls in den Lib-Ordner zu packen ... 

Aktueller IST Zustand:

target/Mutter-Dist-1.0.0-SNAPSHOT-distribution/lib/Core-1.0.0-SNAPSHOT.jar
target/Mutter-Dist-1.0.0-SNAPSHOT-distribution/lib/LibA-1.0.0-SNAPSHOT.jar
target/Mutter-Dist-1.0.0-SNAPSHOT-distribution/deploy/LibA-1.0.0-SNAPSHOT.jar
target/Mutter-Dist-1.0.0-SNAPSHOT-distribution/<weitere files/ordner>

Soll-Zustand (fehlende Teile hervorgehoben):

target/Mutter-Dist-1.0.0-SNAPSHOT-distribution/lib/Core-1.0.0-SNAPSHOT.jar
*target/Mutter-Dist-1.0.0-SNAPSHOT-distribution/lib/<alle Dependencies die Core benötigt>*
target/Mutter-Dist-1.0.0-SNAPSHOT-distribution/lib/LibA-1.0.0-SNAPSHOT.jar
target/Mutter-Dist-1.0.0-SNAPSHOT-distribution/deploy/LibA-1.0.0-SNAPSHOT.jar
target/Mutter-Dist-1.0.0-SNAPSHOT-distribution/<weitere files/ordner>

Any ideas?


----------



## tuxedo (6. Mai 2010)

Oh man, bin ich doof...  :-(

Statt


```
<dependencySet>
            <includes>
                <include>com.mydomain.mp:Core</include>
                <include>com.mydomain.mp:LibA</include>
            </includes>
            <outputDirectory>lib</outputDirectory>
        </dependencySet>
```

einfach ein


```
<dependencySet>
            <includes>
                <include>com.mydomain.mp:Core</include>
                <include>com.mydomain.mp:LibA</include>
            </includes>
            <outputDirectory>lib</outputDirectory>
        </dependencySet>
```

benutzen und schon landen _alle_ Dependencies alle Module im Lib Ordner... 

Drauf gekommen bin ich weil ich mal maven im Debug-Mode benutzt habe und der dann fleissig meldet was er alles aufgrund des "include" filters weglässt.... ;-)

Soweit so gut. Problem gelöst.

- Alex


----------



## kama (6. Mai 2010)

Hallo,

habe noch ein bischen rumgespielt...

Gruß
Karl Heinz Marbaise


----------

