dev@glassfish.java.net

[Fwd: Re: [blocking] Comet integration]

From: Kohsuke Kawaguchi <Kohsuke.Kawaguchi_at_Sun.COM>
Date: Mon, 03 Mar 2008 14:25:05 -0800

Sending this to dev mainly so that we have a record to point to from
elsewhere.

-- 
Kohsuke Kawaguchi
Sun Microsystems                   kohsuke.kawaguchi_at_sun.com

attached mail follows:




OK, I think I understand what's going on now.

The grizzly-module POM (distributions/external/grizzly-http) is written
to use the property value as the build version:

> <project>
> <parent>
   ...
> <artifactId>grizzly-module</artifactId>
> <packaging>hk2-jar</packaging>
> <version>${grizzly.version}</version>

When we install/deploy these modules, this POM is deployed as-is to the
remote repository or your local repository. So for example, if you look
at our GFv3 repository, all the POMs have this "${grizzly.version}" in
its version field. See [1] for example.

Another fact. The gf-jruby-connector module (extras/rails) is written to
refer to 1.7-SNAPSHOT version of grizzly-module, like this:

> <dependency>
> <groupId>org.glassfish.external</groupId>
> <artifactId>grizzly-jruby-module</artifactId>
> <version>1.7-SNAPSHOT</version>
> </dependency>
> <dependency>
> <groupId>org.glassfish.external</groupId>
> <artifactId>grizzly-module</artifactId>
> <version>1.7-SNAPSHOT</version>
> <scope>compile</scope>
> </dependency>

This is probably just an oversight --- it should have used
${grizzly.version}, but this by itself should have been a rather
harmless mistake, because the version resolution mechanism in Maven
favors 1.7.2 instead of 1.7-SNAPSHOT because it's newer.


But when these two things are combined, unexpected things happen.
While working, Maven parses a lot of POMs, and as it parses a POM and
builds in-memory model, it caches it so that multiple attempt to parse
POMs would reuse the previous parsed value.

The key of this cache is groupId:artifactId:version, so it is capable of
parsing multiple versions of the same artifact. This is necessary, as
the way Maven works is it parses grizzly-module:1.7-SNAPSHOT as well as
1.7.2, before determining that 1.7.2 is newer and that it should be used.

Indeed even before the actual distribution assembly processing happens
(to be precise, as a part of the dependency resolution for the
maven-antrun-extended-plugin mojo execution), Maven parses
grizzly-module:1.7-SNAPSHOT POM, because this is referenced in
gf-jruby-connector, which is a transitive dependency of the distribution
build.

Now, remember the fact 1 that this POM uses "${grizzly.version}" in the
version field. The variable resolutions in loading POM is always done by
using the current values, not by using the values when the POM was
originally deployed (in fact such values are not kept anywhere) --- so
what ends up happening here is that the parsed POM would have version
1.7.2, even though this POM was supposed to be 1.7-SNAPSHOT.

Maven isn't written to gracefully handle this, so the rest of the code
gets very confused about whether this is a 1.7-SNAPSHOT POM or 1.7.2 POM.

Some of the rest of the code decides to think that this POM is actually
for 1.7.2. In grizzly-module:1.7-SNAPSHOT, it was depending on
grizzly-http:1.7-SNAPSHOT, so this is why the distribution assembly
process ends up placing grizzly-http and not grizzly-comet.

So in the end, the fix was very easy --- I committed rev.18322 in
extras/rails/pom.xml to use ${grizzly.version} and this fixed the problem.


I think the problem like this can happen in elsewhere in the future,
too, and debugging this kind of problem is very expensive. So we need to
generalize this lesson a bit to make sure we won't have to do this
again. So here is my suggestion:

1. don't use property expansion in the version, groupId, and artifactId
of POMs. These are key properties and therefore their interpretations
shouldn't change depending on where these POMs are loaded. This is a
relatively simple rule to enforce.

2. grizzly-jruby-module and grizzly-module builds should be split out
from the main build tree and built/released separately. These two
modules appear to only depend on com.sun.grizzly, so in fact it would be
  even easier to just move them into the grizzly project. In this way,
single "mvn release:prepare release:perform" would rev them correctly.

If we don't move them to the grizzly project, at least they should get a
top-level directory in the v3 build and shouldn't be a part of the
glassfish-parent super POM.

Splitting builds to smaller pieces helps stabilizing our builds, too.





[1]
http://maven.dyndns.org/glassfish/org/glassfish/external/grizzly-module/1.7.0/grizzly-module-1.7.0.pom

Jeanfrancois Arcand wrote:
> Thanks.
>
> Sorry for pushing, but Sridatta/Rajiv really wanted Comet sooner than
> later :-) Let me know if I can be of any help.
>
> -- Jeanfrancois
>
> Kohsuke Kawaguchi wrote:
>>
>> I'll look into this now.
>>
>> Jeanfrancois Arcand wrote:
>>> Hi,
>>>
>>> Jerome is already aware, but maybe Kohsuke can fix the problem
>>> :-)...sorry for pushing but Comet is suddenly important to Sun and I'm
>>> getting a lot of requests to turn it on by docs, sqe, etc. This is not
>>> complicated to integrate at the servlet level, except there is a
>>> build/packaging issue. Adding:
>>>
>>>
>>> >
>>> > Index: distributions/external/grizzly-http/pom.xml
>>> > ===================================================================
>>> > --- distributions/external/grizzly-http/pom.xml (revision 18229)
>>> > +++ distributions/external/grizzly-http/pom.xml (working copy)
>>> > @@ -73,7 +73,7 @@
>>> > <dependencies>
>>> > <dependency>
>>> > <groupId>com.sun.grizzly</groupId>
>>> > - <artifactId>grizzly-http</artifactId>
>>> > + <artifactId>grizzly-comet</artifactId>
>>> > <version>${grizzly.version}</version>
>>> > </dependency>
>>> > </dependencies>
>>>
>>> should brings up comet into v3, but the grizzly-comet-1.7.2.jar is
>>> never added to the distribution. Jerome proposed a workaround:
>>>
>>>
>>>> <dependency>
>>>> <groupId>com.sun.grizzly</groupId>
>>>> <artifactId>grizzly-comet</artifactId>
>>>> <version>${grizzly.version}</version>
>>>> </dependency>
>>>
>>> in distribution/web and distribution/glassfish for now, but I would
>>> like to make sure we all agree I should go with the hack or wait for a
>>> complete fix. So I hack or should I wait?
>>>
>>> Just let me know :-)
>>>
>>> A+
>>>
>>> -- Jeanfrancois
>>>
>>
>>
>


-- 
Kohsuke Kawaguchi
Sun Microsystems                   kohsuke.kawaguchi_at_sun.com