Ivy succeeds to publish in Java6 but fails in Java5
---------------------------------------------------
Key: IVY-1124
URL: https://issues.apache.org/jira/browse/IVY-1124
Project: Ivy
Issue Type: Bug
Components: Core
Affects Versions: 2.1.0-RC2
Environment: Linux
Reporter: Flavio Coutinho da Costa
Fix For: trunk
IBiblioResolver has a small bug due to a change in the behaviour between Java5
and Java6.
After spending quite a lot of time debugging this I finally found where the
problem is.
I've added some debugging messages to the following methods so that I could
keep track of what is happening behind the scenes.
* setM2compatible
* setUsepoms
* setPattern
* setRoot
All the debug does it print the name of the method that's getting called and
print the hash code of the instance (just for the sake of identifying in which
repository the call happened)
>From the documentation and from the code we can see that the 'usepoms'
>property defaults to 'true'.
Now let's take a look the following snippet of code extracted from
IBiblioResolver:
private void updateWholePattern() {
if (isM2compatible() && isUsepoms()) {
setIvyPatterns(Collections.singletonList(getWholePattern()));
}
setArtifactPatterns(Collections.singletonList(getWholePattern()));
}
Assuming that setM2compatible(true) happens before a setUsepoms(false) Ivy
would end up calling setIvyPatterns(...) and therefore setting an invalid Ivy
pattern (actually it's not invalid but a default one like this:
http://repo1.maven.org/maven2/). After this happens Ivy won't have a chance to
ever "unset/reset" the Ivy patterns list and because of that any artifact which
type equals to "ivy" will (try) to be uploaded to Maven Central repository as
this code extracted from RepositoryResolver highlights:
public void publish(Artifact artifact, File src, boolean overwrite)
throws IOException {
String destPattern;
if ("ivy".equals(artifact.getType()) &&
!getIvyPatterns().isEmpty()) {
destPattern = (String) getIvyPatterns().get(0);
} else if (!getArtifactPatterns().isEmpty()) {
destPattern = (String) getArtifactPatterns().get(0);
}
...
}
Instead of falling back to getArtifactPatterns (as desired and expected), Ivy
sees that the List returned by getIvyPatterns() is not empty (due to the bug
mentioned above) and tries to upload the ivy.xml file to Maven Central (where,
most of the mortals, can't HTTP PUT) resulting on the following:
/home/flavio/workspace/IvyTestCase/build.xml:16: impossible to publish
artifacts for my.test.case#ivy-test;1.0: java.io.IOException: PUT operation to
URL http://repo1.maven.org/maven2/my/test/case/ivy-test/1.0/ivy-1.0.xml failed
with status code 405
Enough of side effects, let's get back to the actual bug.
Like I said before this bug happens due to a difference in behaviour between
Java5 and Java6. The following ant output shows that:
--- Running Java(TM) SE Runtime Environment - 1.6.0_16-b01
[ivy:configure] :: Ivy 2.2.x-local-20090917003317 - 20090917003317 ::
http://ant.apache.org/ivy/ ::
[ivy:configure] :: loading settings :: file =
/home/flavio/workspace/IvyTestCase/ivysettings.xml
[ivy:configure] setM2compatible called for repo: 9740137
[ivy:configure] setUsepoms called for repo: 13228332
[ivy:configure] setPattern called for repo: 13228332
[ivy:configure] setRoot called for repo: 13228332
[ivy:configure] setM2compatible called for repo: 13228332
setUsepoms(false) is called before setM2compatible(true) so the bug is never
triggered because the condition in IBiblioResolver.updateWholePattern()
evaluates to false and setIvyPatterns(...) is NEVER called thus resulting on
getIvyPatterns() returning an empty List later on and because of that
RepositoryResolver falls back to getArtifactPatterns(). Everything works just
fine.
--- Running Java(TM) 2 Runtime Environment, Standard Edition - 1.5.0_21-b01
[ivy:configure] :: Ivy 2.2.x-local-20090917003317 - 20090917003317 ::
http://ant.apache.org/ivy/ ::
[ivy:configure] :: loading settings :: file =
/home/flavio/workspace/IvyTestCase/ivysettings.xml
[ivy:configure] setM2compatible called for repo: 18923308
[ivy:configure] setM2compatible called for repo: 13078969
[ivy:configure] setUsepoms called for repo: 13078969
[ivy:configure] setRoot called for repo: 13078969
[ivy:configure] setPattern called for repo: 13078969
setM2compatible(true) is called before setUsepoms(false) and the condition
inside IBiblioResolver.updateWholePattern() evaluates to true causing a cascade
effect (setIvyPatterns() is called and can't be reseted/unseted,
RepositoryResolver never falls back to getArtifactPatterns(), etc, etc...).
Everything falls apart!
So the fact of the XML parser interpreting the arguments in a different order
totally screw up the logic.
I found a way around this by change the IBiblioResolver.updateWholePattern() to
this:
private void updateWholePattern() {
if (isM2compatible() && isUsepoms()) {
setIvyPatterns(Collections.singletonList(getWholePattern()));
} else {
setIvyPatterns(Collections.EMPTY_LIST);
}
setArtifactPatterns(Collections.singletonList(getWholePattern()));
}
Basically resetting the list whenever the condition doesn't evaluates to true,
giving Ivy the chance to "recover" from the wrong state it was set. Not sure if
that's the right way but it did fix the problem since the IvyPatterns List is
actually empty when it should, not counting on a weird behaviour of a specific
JVM version.
I'll be attaching the diff of IBiblioRepository.java and also a sample project
that can trigger this bug.
--
This message is automatically generated by JIRA.
-
You can reply to this email to add a comment to the issue online.