3

I have a new library, called Codelet. It depends on two other libraries I've created, called Template Featherweight and XBN-Java. But the primary library--the one I'm trying to get other people to use!--is Codelet. The other two are secondary. Both are required, but they are only directly used when advanced features are needed.

I build all aspects of all three of these projects with Ant. I use Maven for one reason only: To sign the jars

  • codelet-0.1.0.jar
  • codelet-0.1.0-sources.jar
  • codelet-0.1.0-javadoc.jar

and push them to Maven Central. After shedding significant blood, sweat, tears, and soul in the past week, as evidenced by these four questions

  1. How to use Maven to only sign three jars and push them to Maven Central?
  2. Followup questions: Using Maven to only sign and deploy jars to Maven Central. Build and compilation is done entirely with Ant
  3. Followup part 2 -- Using Maven to only sign and deploy jars to Maven Central. Build and compilation is done entirely with Ant
  4. Why am I getting a "401 Unauthorized" error in Maven?

I have finally gotten the jars to upload to Maven Central via mvn deploy, at least once anyway, so that's big progress.

I'm realizing, however, that in order for other people to actually use Codelet, they need the entire dependency tree to be mapped out in Codelet's POM. I believe this is correct.

I am concerned that mapping this three-project dependency tree, in their three POMs, will essentially require that I duplicate much of my Ant build process in Maven. I am hoping with all hope that I don't need to do this, as Ant works well for me, and Maven and I do not get along.

Here are the dependency trees:

Dependencies for compilation of core library classes and example code, only

All items are listed by Maven groupId / artifactId / version.

XBN-Java 0.1.3 depends on

  • org.apache.commons / commons-collections4 / 4.0
  • org.apache.commons / commons-io / 2.4
  • org.apache.commons / commons-lang3 / 3.3.2
  • com.google.guava / guava / 16.0

Template Featherweight 0.1.0 depends on

  • com.github.aliteralmind / xbnjava / 0.1.3 (and its dependencies)

Codelet 0.1.0 depends on

  • com.github.aliteralmind / templatefeather / 0.1.0 (and its dependencies)
  • ${java.home}/../lib/tools.jar (This is considered "provided", since it's part of the JDK and not on Maven Central)

Dependencies for compilation and execution of unit tests, only

These are in addition to those needed for core-compilation.

For all projects: junit / junit / 4.11 (and its dependency: hamcrest core)


For compilation of "Codelets" (which are used only by javadoc.exe), and execution of javadoc.exe

These are in addition to those needed for core-compilation.

For all projects: com.github.aliteralmind / codelet / 0.1.0 (and all its "core-compilation" dependencies)

(Some background: Codelet automates the insertion of example code into JavaDoc, using inline taglets like

{@.codelet.and.out com.github.mylibrary.examples.AGoodExample}

These optional "Codelet classes", called "customizers", are compiled before running javadoc.exe. They are used to customize how example code is displayed. Once compiled, Codelet is executed automatically, as are all inline taglets, via javadoc.exe.)


For core-compilation it's pretty much linear:

  1. XBN-Java is the root
  2. Template Feather depends on XBN-Java, and
  3. Codelet depends on Template Feather

But for "javadoc", all three projects depend on Codelet. So even XBN-Java depends on Codelet...which depends on Template Feather...which depends on XBN-Java.


The POMs in all three projects are working, although this is only as far as it concerns signing and pushing the jars to Maven Central.

After reading Maven's dependency Mechanism documentation, it seems that all three projects could have the same flat dependency tree

<dependencies>
    <dependency>
        <groupId>com.github.aliteralmind</groupId>
        <artifactId>templatefeather</artifactId>
        <version>0.1.0</version>
    </dependency>
    <dependency>
        <groupId>com.github.aliteralmind</groupId>
        <artifactId>codelet</artifactId>
        <version>0.1.0</version>
    </dependency>
    <dependency>
        <groupId>org.apache.commons</groupId>
        <artifactId>commons-collections4</artifactId>
        <version>4.0</version>
    </dependency>
    <dependency>
        <groupId>org.apache.commons</groupId>
        <artifactId>commons-io</artifactId>
        <version>2.4</version>
    </dependency>
    <dependency>
        <groupId>org.apache.commons</groupId>
        <artifactId>commons-lang3</artifactId>
        <version>3.3.2</version>
    </dependency>
    <dependency>
        <groupId>com.google.guava</groupId>
        <artifactId>guava</artifactId>
        <version>16.0</version>
    </dependency>
    <dependency>
        <groupId>junit</groupId>
        <artifactId>junit</artifactId>
        <version>4.11</version>
        <scope>test</scope>
    </dependency>
</dependencies>

But the right way is to have a parent project, which is inherited by the other two. It seems that XBN-Java should be the parent, but given the recursive nature of the dependencies, I'm not sure.

I am not getting the difference between dependencies and dependencyManagement (why some dependencies blocks can go right into the project proper, and others are sub-blocks in dependencyManagement...although it seems related to parent-child), and I also don't understand how "javadoc" fits into the "scope" attribute. While compile and test are explicitely listed, the word "doc" doesn't even exist on the page.


I would appreciate some advice. Thank you.

Community
  • 1
  • 1
aliteralmind
  • 19,847
  • 17
  • 77
  • 108
  • I think if you want such specific requirements to an exported POM it might be OK to have a POM designed to describe the dependencies but not use it for the actual build (not even the signing). – eckes Jul 19 '14 at 02:49
  • 2
    Looking at the `build.xml` for codelet, I don't see anything super-complex that would make Maven unusable, so I would say that *the right way* is "re-do your build in Maven (or Gradle or something else with better support for Maven artifacts)". – Nathaniel Waisbrot Jul 19 '14 at 02:50
  • After reading these comments and @EdwinBuck's answer, I'm realizing that the only reason for this dependency-tree POM is for projects that want to *use* Codelet. Even the "sign and push the jar to Maven Central" part is useless to anyone but me (or someone wanting to develop or change Codelet). So in addition to the three jars, the only thing that needs to be sent to maven central is this "using Codelet" POM. And the only thing I can think of being in it is the "using Codelet" dependency tree. – aliteralmind Jul 19 '14 at 04:12
  • I'm still not sure quite what this means, or how to best implement it, but it does seem that the scope of my problem has narrowed a bit. (For anyone wanting to do anything except just *using Codelet* will have to download the source code jar, which contains all build files.) – aliteralmind Jul 19 '14 at 04:13

1 Answers1

2

If your code needs something, but not for compile-time (just for run-time) then declare the dependency, but add a runtime scope.

Now if you want to provide a "starter parent" pom.xml, then release a "starter parent" pom.xml but don't use it in your actual build chain.

Edwin Buck
  • 69,361
  • 7
  • 100
  • 138