[GRADLE-1583] Gradle doesn't support ivy configuration expression Created: 01/Jun/11  Updated: 13/Aug/13  Resolved: 18/Jun/13

Status: Resolved
Project: Gradle
Affects Version/s: 1.0-milestone-3
Fix Version/s: 1.7-rc-1

Type: Bug
Reporter: Sky Ao Assignee: Unassigned
Resolution: Fixed Votes: 5

Attachments: Zip Archive GRADLE-1583.zip    

 Description   

In ivy's world, the configuration of a dependency is always more complex than a single word and will be a long expression.

The common and widely used one is that :

conf="compile->compile(*),master(*);runtime->runtime(*)"/>

For example, in the ivy file of easymock 3.0:

	<dependencies>
		<dependency org="cglib" name="cglib-nodep" rev="2.2" force="true" conf="compile->compile(*),master(*);runtime->runtime(*)"/>
		<dependency org="org.objenesis" name="objenesis" rev="1.2" force="true" conf="compile->compile(*),master(*);runtime->runtime(*)"/>
		<dependency org="junit" name="junit" rev="4.8.1" force="true" conf="test->runtime(*),master(*)"/>
	</dependencies>

And also testng 6.1

	<dependencies>
		<dependency org="ant" name="ant" rev="1.6.5" force="true" conf="optional->compile(*),master(*)"/>
		<dependency org="junit" name="junit" rev="3.8.1" force="true" conf="compile->compile(*),master(*);runtime->runtime(*)"/>
		<dependency org="org.beanshell" name="bsh" rev="2.0b4" force="true" conf="compile->compile(*),master(*);runtime->runtime(*)"/>
		<dependency org="com.google.inject" name="guice" rev="2.0" force="true" conf="provided->compile(*),provided(*),runtime(*),master(*)"/>
		<dependency org="com.beust" name="jcommander" rev="1.12" force="true" conf="compile->compile(*),master(*);runtime->runtime(*)"/>
		<dependency org="org.yaml" name="snakeyaml" rev="1.6" force="true" conf="compile->compile(*),master(*);runtime->runtime(*)"/>
	</dependencies>

We can see that almost even configuration is not simple like "compile" or "runtime", but a complex expression.This feature is a important, powerful and widely used in ivy's world.

But in gradle's configuration, this configuration expression is not supported!! In gradle, it only supports a single word of configuration like "compile" or "runtime".Otherwise gradle will fail and report that the configuration (like 'compile,runtime') is not a valid configuration!

I checked the code of gradle and found the reason, in class DefaultIvyDependencyResolver :

     private ResolveOptions createResolveOptions(Configuration configuration) {
        ResolveOptions resolveOptions = new ResolveOptions();
        resolveOptions.setDownload(false);
        resolveOptions.setConfs(WrapUtil.toArray(configuration.getName()));
        return resolveOptions;
    }

Be care to this line

resolveOptions.setConfs(WrapUtil.toArray(configuration.getName()));

In this method, the configuration name will be directly passed to ivy resolveOptions by a simply wrap from a String to a String[]. So when the configuration is 'compile,runtime', I expect that the ivy will handle two configurations as String[]

{"compile", "runtime"}

, but in fact gradle will pass a String["compile,runtime"] to ivy.

As a old ivy user, I feel very disappointed and regretful for this issue, because it is really very powerful and important.

I hope in the next release ASAP gradle will support some similar expression like

compile(*),master(*)


 Comments   
Comment by Sky Ao [ 01/Jun/11 ]

the is that "( * )"

Comment by Sky Ao [ 01/Jun/11 ]

If there are something difficult in the implementation of expression 'compile( * )', we can implement the expression 'compile,runtime' at first.

Because this is very simple for gradle : just split the configuration by char ',' and set the result String[] to ivy(trim to get rid of whitespace?).

"resolveOptions.setConfs(configuration.getName().split(","));".

Comment by Luke Daley [ 28/Nov/12 ]

Related forum post: http://forums.gradle.org/gradle/topics/ivy_configuration_mapping_problem

Comment by James Poli [ 15/Jul/13 ]

Hello,
I've tested with Gradle 1.7-rc-1 and the problem described in http://forums.gradle.org/gradle/topics/ivy_configuration_mapping_problem is still not fixed. Can someone point me to the code that handles Ivy configuration mapping so I can take a look at it?
Thanks in advance,
James

Comment by Daz DeBoer [ 15/Jul/13 ]

Hi James
The test coverage for this feature is in https://github.com/gradle/gradle/blob/master/subprojects/core-impl/src/integTest/groovy/org/gradle/integtests/resolve/ivy/IvyModuleResolveIntegrationTest.groovy. In particular the second test case checks a bunch of permutations of configuration mapping. If you can provide a failing test case, that would go a long way toward solving this issue.

Here's a link to one of the recent commits that fixed some problems with handling of ivy configuration mappings: https://github.com/gradle/gradle/commit/b7efd44e068846e804021505c6822a2aa21a909f. Perhaps this will help point you in the right direction to work out how it works internally.
Daz

Comment by James Poli [ 09/Aug/13 ]

Test use case for non-compile artifacts included on javac classpath.

Comment by James Poli [ 09/Aug/13 ]

Hi Daz,
Sorry it’s taken me a while to try and test this again. As a level set, please read the link added by Luke above describing my problem, ivy_configuration_mapping_problem. Essentially it boils down to javac classpath being incorrect, i.e., including non-compile configurations when ivy configuration mapping "SPLAT POINTS TO AT" is used transitively. FWIW, I tried to create a use case of the error by building Gradle 1.7 from sources and modifying IvyModuleResolveIntegrationTest, “correctly handles configuration mapping rule ‘#rule’” with NO luck. So I want back to the drawing board trying to diagnose the error using a build log with debug turned on. This is what I found. Believe it or not it worked the first time I built, i.e., only compile time configuration artifacts where included on the javac classpath! Unfortunately my jubilation was short lived. The second time I ran it the classpath included non-compile configurations. I found by studying the log from the second run it has something to do with the cache? It appears that the configuration mapping is changing from "SPLAT POINTS TO AT" to "SPLAT POINTS TO SPAT" after the ivy.xml(s) have been cached? To show you this I’ve created a standalone test I’ve included as a GRADLE-1583.zip. Copy the repo location to an http server and run gradle in the TEST directly with “clean display” twice. Sorry I had to use SPAT instead of * and AT instead of @ since the text came out dashed through.
Regards,
Jim

Comment by Adam Murdoch [ 12/Aug/13 ]

@James, I've created a new issue for the problem you're seeing: GRADLE-2866

Comment by James Poli [ 13/Aug/13 ]

Thanks Adam, I'll watch the problem and test a fix when it becomes available. Let me know if there's any other way I can help. Jim

Generated at Wed Jun 30 11:59:14 CDT 2021 using Jira 8.4.2#804003-sha1:d21414fc212e3af190e92c2d2ac41299b89402cf.