2

I'm currently building an application and I have a maven project structured like so:

|-> root
|
|-------> ui
|       |---> pom.xml
|
|-------> core
|       |---> pom.xml
|
|
|-------> pom.xml
  • ui depends on core
  • core has no internal dependencies
  • root/pom.xml is an aggregator which specifies as it's modules ui and core

Now I'm planning to mvn release this piece of software and I only want to expose a central artifact say myapp which should be a jar containing all the code from ui and core (ie. I don't want ui, core, and the aggregator to all be released separately) so that anyone who adds myapp as a dependency can access both com.somepackage.ui as well as com.somepackage.core.

Questions:

  • How do I handle the ui -> core dependency? Can I make it point to a relative pom ../core/pom.xml?
  • How do I bundle the generated sources from ui and core into a ${rootartifactname}.jar
  • Running mvn deploy on root deploys all three poms to the repository, so right now anyone can reference my ui artifact and I don't want that, how do I expose only the root pom artifact
ᴘᴀɴᴀʏɪᴏᴛɪs
  • 7,169
  • 9
  • 50
  • 81
  • I think it's not trivial. The easiest way to achieve all goals is to have only a single Maven project and rely on packages for structuring. – mm759 Sep 12 '16 at 17:27
  • "How do I handle the ui -> core dependency? Can I make it point to a relative pom../core/pom.xml?" You can use a regular dependency. – mm759 Sep 12 '16 at 17:28
  • "How do I bundle the generated sources from uiand core into a ${rootartifactname}.jar" The maven-assembly-plugin can bundle Jars in a Zip file. This might be an alternative option. And there is an izpack-plugin for creating installers. – mm759 Sep 12 '16 at 17:31
  • The maven-dependency-plugin could be used for extracting files from Jars for packaging in a common Jar. – mm759 Sep 12 '16 at 17:33
  • Creating the final artifact can be done in a separate Maven project next to ui and core. – mm759 Sep 12 '16 at 17:34

1 Answers1

2

You can create another module, myapp, that will specifically package your application including ui and core. This new module will depend on both the ui and core modules, and Maven will take care of the build order itself. Then, you can configure your build only to deploy / release the myapp module.

Although it isn't something would generally be recommended, it is possible to configure certain modules of a multi-module Maven project to not be released by the maven-release-plugin. For that, you need to tell the maven-deploy-plugin to skip its default execution.

A simple implementation of the myapp module would be the following:

<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/xsd/maven-4.0.0.xsd">
  <modelVersion>4.0.0</modelVersion>
  <parent>
    <groupId>my.groupId</groupId>
    <artifactId>root</artifactId>
    <version>0.0.1-SNAPSHOT</version>
  </parent>
  <artifactId>myapp</artifactId>
  <dependencies>
    <dependency>
      <groupId>my.groupId</groupId>
      <artifactId>ui</artifactId> <!-- brings core transitively -->
      <version>${project.version}</version>
    </dependency>
  </dependencies>
  <build>
    <plugins>
      <plugin>
        <artifactId>maven-deploy-plugin</artifactId>
        <configuration>
          <skip>false</skip>
        </configuration>
      </plugin>
    </plugins>
  </build>
</project>

Then, in the parent module, called root, you would have a default

<plugin>
  <artifactId>maven-deploy-plugin</artifactId>
  <version>2.8.2</version>
  <configuration>
    <skip>true</skip>
  </configuration>
</plugin>

When you run mvn clean deploy or when you perform a release with the Release Plugin, only the module configured to be deployed will actually be deployed or released. In this case, it would only be the myapp module: ui, core and even the parent POM, won't be deployed.

For your real use-case, myapp could create an uber jar, but this sketch is enough to show that it is possible.

Community
  • 1
  • 1
Tunaki
  • 132,869
  • 46
  • 340
  • 423
  • Thanks for the post. I have tried to do what you described and deployed the `myapp` jar to the repository but users can't use because it references a parent and the parent is not uploaded. Then probably parent will not be able to be used because `ui` and `core` won't be there either. Any way around this? – ᴘᴀɴᴀʏɪᴏᴛɪs Sep 13 '16 at 11:13
  • @ᴘᴀɴᴀʏɪᴏᴛɪs Well I thought you only wanted to deploy `myapp` so that users would download just that. You'd need the parent if you're going to have a dependency on it, yes, in which case you can skip the deployment of `ui` and `core`, and not the parent. It shouldn't cause trouble with the two modules not being deployed. – Tunaki Sep 13 '16 at 12:00
  • Yes I only wanted to deploy `myapp` and on your sample pom you added a `` tag which I thought was needed, I removed it and republished `myapp` and everything works great, thanks again! – ᴘᴀɴᴀʏɪᴏᴛɪs Sep 13 '16 at 13:42