1

I have a group of projects that have (a) generated beans, and (b) code to work with those beans. I'd like each such project to create two different artifacts: a regular jar artifact that contains all classes, and a custom beans artifact that contains only the generated types.

I put together a quick plugin that creates a second beans artifact using artifact attachments and the "beans" classifier, but it doesn't work well in m2e. For this reason, I think creating a custom packaging type (e.g., "test-jar") is The Right Thing.

To be totally clear about what I'm imagining, this pom would works today and creates two different artifacts with two different packaging types:

<project>
  <groupId>${groupId}</groupId>
  <artifactId>${artifactId}</artifactId>
  <version>${version}</version>

  <build>
    <plugins>
      <plugin>
        <groupId>org.apache.maven.plugins</groupId>
        <artifactId>maven-jar-plugin</artifactId>
        <executions>
          <execution>
            <goals>
              <goal>test-jar</goal>
            </goals>
          </execution>
        </executions>
      </plugin>  
    </plugins>
  </build>
</project>

which you could import with either of the following:

<dependency>
  <groupId>${groupId}</groupId>
  <artifactId>${artifactId}</artifactId>
  <version>${version}</version>
  <!-- <type>jar</type> -->
</dependency>

<dependency>
  <groupId>${groupId}</groupId>
  <artifactId>${artifactId}</artifactId>
  <version>${version}</version>
  <type>test-jar</type>
</dependency>

I'd like to create a plugin that will let me use (for example) beans instead of test-jar to create a similar "paired" artifact.

I've poked around in the maven source code, and you can create custom types. However, "test-jar" seems to be "baked in" to maven, so I can't tell if it has some special features and I can't duplicate this behavior with my own plugin.

Of course, if there's another way to handle this kind of behavior without custom types that m2e understands -- for example, but getting m2e to understand my classifier, although that seems hard -- I'm all ears! :)

How can I make a similar paired packaging type? I've seen this answer regarding how to create custom types, but it only seems to create one artifact from a pom with the given custom packaging type.

Community
  • 1
  • 1
sigpwned
  • 6,957
  • 5
  • 28
  • 48

2 Answers2

2

OK, figured out how to get a custom type working with an additional artifact from the same POM.

You do use attached artifacts to generate the additional artifact. For my example, I used this call in my goal in my plugin (after I was done building my JAR file):

@Mojo(name="goal-name", defaultPhase=LifecyclePhase.PACKAGE)
public class MyMojo
    extends AbstractMojo
{
    @Component
    private MavenProject project;

    @Component
    private MavenProjectHelper projectHelper;

    @Component(role=Archiver.class, hint="jar")
    private JarArchiver archiver;


    public void execute() throws MojoExecutionException {
        // Do work...

        // Create JAR file...
        File jarFile=createJarFile(archiver);

        projectHelper.attachArtifact(project, "beans-jar", jarFile);
    }
}

Note that I specified my custom type beans-jar, and no classifier.

Next, I dropped a components file into my plugin at src/main/resources/plexus/components.xml:

<component-set>
  <components>
    <component>
      <role>org.apache.maven.artifact.handler.ArtifactHandler</role>
      <role-hint>beans-jar</role-hint>
<implementation>org.apache.maven.artifact.handler.DefaultArtifactHandler</implementation>
      <configuration>
        <classifier>beans</classifier>
        <extension>jar</extension>
        <type>beans-jar</type>
        <packaging>jar</packaging>
        <language>java</language>
        <addedToClasspath>true</addedToClasspath>
      </configuration>
    </component>
  </components>
</component-set>

Here, I specify my custom type beans-jar and a classifier, which appears to be used to name the new attribute in the repository.

This file was based on artifact-handlers.xml from the maven-core project in the main maven repository. At the moment, that file is located here. (I found this file by grepping for test-jar in all .xml files in the maven repository.)

To import that dependency, you use:

<dependency>
  <groupId>${groupId}</groupId>
  <artifactId>${artifactId}</artifactId>
  <type>beans-jar</type>
</dependency>

To import the dependency, you don't need to include the custom plugin.

sigpwned
  • 6,957
  • 5
  • 28
  • 48
2

I would suggest to try a simpler way like this:

  <plugin>
    <groupId>org.apache.maven.plugins</groupId>
    <artifactId>maven-jar-plugin</artifactId>
    <executions>
      <execution>
        <id>second-jar</id>
        <goals>
          <goal>jar</goal>
        </goals>
        <configuration>
          <classifier>second</classifier>
          <includes>
            <include>**/service/*</include>
          </includes>
        </configuration>
      </execution>
    </executions>
  </plugin>

Via the <include> you can defined which classes would be packaged into the supplemental jar file.

khmarbaise
  • 92,914
  • 28
  • 189
  • 235
  • 1
    I like that suggestion! Very simple. But I think the resulting artifact can only be imported as a dependency using classifiers, correct? I tried a very similar approach first, then discovered that while maven supports classifiers just fine, m2e does not. The search for m2e support is what caused me to go on this wild goose chase to begin with. The answer I provided allows you to import the resulting artifact using a custom packaging type, which both maven and m2e support well. – sigpwned Jan 20 '14 at 15:22