2

I know this is not recommended practice and I have read:

http://www.sonatype.com/people/2010/01/how-to-create-two-jars-from-one-project-and-why-you-shouldnt/

which I agree upon. But currently I need to solve the following issue:

I have a project with multiple src folders A and B (using the build-helper-maven-plugin). I need to create two corresponding jars A (the default jar) and B. Jar A contains the classes from src folder A and jar B contains the classes from src folder B.

First I create the default jar A and try to exclude all classes from src folder B:

        <plugin>
            <groupId>org.apache.maven.plugins</groupId>
            <artifactId>maven-jar-plugin</artifactId>
            <executions>
                <execution>
                    <id>default-jar</id>
                    <goals>
                        <goal>jar</goal>
                    </goals>
                    <configuration>
                        <excludes>
                            <exclude>**/B*</exclude>
                        </excludes>
                    </configuration>
                </execution> 

But when I inspect the A jar it contains classes from packages in source folder B. Is my reqex exclude notation wrong/does it only work on packages?

Based on the below answers I now do:

<properties>
    <artifactId.model>${project.artifactId}-model-${project.version}</artifactId.model>
    <artifactId.default>${project.artifactId}-${project.version}</artifactId.default>
</properties>

        <plugin>
            <artifactId>maven-assembly-plugin</artifactId>
            <version>2.3</version>
            <executions>
                <execution>
                    <id>make-model-assembly</id>
                    <phase>package</phase>
                    <goals>
                        <goal>single</goal>
                    </goals>
                    <configuration>
                        <appendAssemblyId>false</appendAssemblyId>
                        <finalName>${artifactId.model}</finalName>
                        <descriptors>
                            <descriptor>src/main/assembly/model.xml</descriptor>
                        </descriptors>
                        <attach>true</attach>
                    </configuration>
                </execution>
                <execution>
                    <id>make-default-assembly</id>
                    <phase>package</phase>
                    <goals>
                        <goal>single</goal>
                    </goals>
                    <configuration>
                        <appendAssemblyId>false</appendAssemblyId>
                        <finalName>${artifactId.default}</finalName>
                        <descriptors>
                            <descriptor>src/main/assembly/default.xml</descriptor>
                        </descriptors>
                        <attach>true</attach>
                    </configuration>
                </execution>
            </executions>
        </plugin>

where the descriptor for the model is:

<assembly>
    <id>model</id>
    <formats>
        <format>jar</format>
    </formats>
    <baseDirectory>target</baseDirectory>
    <includeBaseDirectory>false</includeBaseDirectory>

    <fileSets>
        <fileSet>
            <directory>${basedir}/model_a</directory>
            <includes>
                <include>**/**</include>
            </includes>
        </fileSet>
        <fileSet>
            <directory>${basedir}/model_b</directory>
            <includes>
                <include>**/**</include>
            </includes>
        </fileSet>
    </fileSets>
</assembly>

I then attach the jars using the build-helper. THe problem with the above is obviously that I get the .java files and not the compiled .class files. Since all .class files are located in the same target/classes folder for all source folders (see noahz comment) I need to manually specify each include/exclude for the relevant packages - so this approach is a no go :-( I think the best approach is to create a sub-project.

u123
  • 15,603
  • 58
  • 186
  • 303

2 Answers2

0

Yes, the include / exclude of the Jar plugin is for packages, which don't take physical location of the original source files into account.

Consider splitting this project into two child modules.

Alternative Approach

As I frequently say: for 90% of build requirements, there's Maven. For everything else, there's Antrun Plugin.

You are going to have to generate your jars using the Ant Jar Task, leveraging the includesfile parameter. This file can be hard-coded, or generated from a script that you execute at build time (i.e. find all the files under each source directory and output to your includes file).

Not the best solution, but it should accomplish your goal (two child modules would be easier though).

noahlz
  • 10,202
  • 7
  • 56
  • 75
  • That is currently not an option :-( So is there no way to accomplish this without splitting into separate modules - I am aware that its a hack? – u123 Oct 08 '12 at 15:05
  • Updated with an answer: use AntRun Plugin and multiple executions of the `` task using the `includesfile` parameter. – noahlz Oct 08 '12 at 15:30
  • Yeah I guess that would probably be the closes to an "automated" solution as possible - without having tried it. Unless there is someway of specifying in maven that it should group the class files in the target folder based on their originating source folders. – u123 Oct 08 '12 at 18:46
  • No, there is not a way of doing that in "standard" Maven. That's why we have Antrun Plugin, etc. – noahlz Oct 08 '12 at 19:21
0

This is nearly a copy of an answer I gave:

You can use different executions of the assembly plugin and then attach the resulting assembly to the build. Of course you have to configure different final names for the artifacts in the assembly plugin configuration. In the assembly descriptor you will have to configure what to include.

Community
  • 1
  • 1
SpaceTrucker
  • 13,377
  • 6
  • 60
  • 99
  • How can this work, given that the compiled class files are all co-mingled together under `target/classes`? – noahlz Oct 08 '12 at 15:12
  • You will have to configure the `includes` and `excludes` of the assembly in a very fine grained way. This is probably not a very sophisticated solution, but one where you will have two separate jars. I suspect that the classes don't depend tightly on each other in the project. – SpaceTrucker Oct 08 '12 at 15:15
  • Packaging a Jar file using Assembly Plugin is very non-standard. That's what Jar Plugin is for. If you are going to go through the trouble listing every class file to `include`, then just use the Jar Plugin (or use my solution, Antrun Plugin + Ant Jar Task, which supports an `includesfile`) – noahlz Oct 08 '12 at 19:23