In addition to the modelVersion evolution problem, there are some other
issues that I think we need to address for Maven 4.0+

* Platform specific builds

* Architecture specific builds

* Native build flavours (e.g. debug vs non-debug)

You could see this as the "side-artifact" dilemma.

Here are some issues as I see it.... in no specific order

* You may have a Java artifact that works on Java 1.5+ and Android. How
would you express that?

  One idea I have had is to have a "platform" descriptor... this could be a
simple dependency type or it could be an explicit model object... there are
swings and roundabouts to both.

    - A "platform" dependency type is perhaps even doable in Maven 2.x,
3.x... just needs somebody to do all the work for everyone... You would
have e.g. java:standard-edition:1.4:platform,
java:standard-edition:1.5:platform, java:standard-edition:1.6:platform,
java:standard-edition:1.7:platform, etc... they could have dependencies on
the additional libraries and apis that those platforms provide... which
would let you collapse the dependency tree somewhat... the question is how
do we express android into that set?

    - A "platforms" element in the model would allow for a list of
platforms against which the artifact is compatible... perhaps even allowing
for expressing different dependency lists on each platform (if we go the
.dml route) so you might have

      <platforms>
        <platform gav="java:standard-edition:1.5+">
          <dependencies>
            <dependency gav="..."/>
          </dependencies>
        </platform>
        <platform gav="java:standard-edition:1.6+">
          <dependencies>
            <dependency gav="..."/>
          </dependencies>
        </platform>
        <platform gav="google:android:4.2+">
          <dependencies>
            <dependency gav="..."/>
          </dependencies>
        </platform>
      </platforms>

      In such a scheme, you'd pick the best match platform, so JavaSE 1.7
would have a best match against the 1.6 platform dependency list... but
from the platform descriptor you may already have resolved some of the
required dependencies...

    - Another approach is to list the platforms like scopes in
dependencies...

    - In any case, this would be a consumer side information store... the
build side descriptor would be responsible for constructing the
information... and I presume some sort of tooling could end up being
required to validate artifacts against the platform(s) they target.

    - Do not assume all target platforms are JVM based... we could have
people with NodeJS as a target platform... or .Net or Ruby On Rails (if
they don't like Gem... or perhaps we get this right and Gem adopts our
repo's new .dml descriptor!... don't worry that will never happen)

    - If we get this right there would be a multitude of platforms... e.g.
Tomcat 7 could be seen as a valid platform for running on... similarly
TomEE and Jetty. Each of these provide additional classes on the
classpath... some classes are container specific and some not... plus
people can run with different JVMs... could get messy real fast... [that
may be a legitimate excuse as to why we have not tackled this problem until
now... does not make a valid excuse for continuing to dodge it though]

* You may not be able to build all flavours of an artifact on the same
machine at the same time. Need to support differential publishing.

    - Publish the OS-X built artifact day 1
    - Publish the x86 linux artifact day 2
    - Publish the Windows artifact day 3
    - Publish the debug ARM linux artifact that has additional runtime
dependencies day 4

    - This is calling out for tweaks in the repository format... we cannot
leverage classifiers for this without risk of some sort of hell... perhaps
we add platform/arch/build-type as a path layer in the repo... risks
alienating existing clients... but as existing clients cannot handle this
currently... so what... and as long as we let them construct a GAVCT that
can retrieve the specific artifact they want... do we care?

    - So G:A:V:P can be mapped to G.A:V:P or to put it a different way,
legacy clients could access the osx-x86_64-debug build of
org.manchu:foobar:1.0:dylib as org.manchu.foobar:1.0:osx-x86_64-debug:dylib
the downside with that mapping is -SNAPSHOT symantics are lost, e.g.
org.manchu.foobar:1.0-SNAPSHOT:osx-x86_64-debug:dylib would not be
considered a -SNAPSHOT version

    - An alternative is to append P to A... letting us keep the G and V, so
we'd have org.manchu:foobar-osx-x86_64-debug:1.0:dylib and
org.manchu:foobar-osx-x86_64-debug:1.0-SNAPSHOT:dylib

      This one actually doesn't feel too bad... ok, so people may have fun
excluding transitive dependencies on other P's... but then again you may
want to bundle the different native binaries in the same jar file, so this
affords the option and retains a lot of the feel you'd expect... but is
this just a hack?

What do people think on this set of hard problems?

-Stephen

Reply via email to