Gradle
  1. Gradle
  2. GRADLE-1583

Gradle doesn't support ivy configuration expression

    Details

    • Type: Bug Bug
    • Status: Resolved Resolved
    • Resolution: Fixed
    • Affects Version/s: 1.0-milestone-3
    • Fix Version/s: 1.7-rc-1

      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(*)

        Activity

        Hide
        Sky Ao
        added a comment -

        the is that "( * )"

        Show
        Sky Ao
        added a comment - the is that "( * )"
        Hide
        Sky Ao
        added a comment -

        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(","));".

        Show
        Sky Ao
        added a comment - 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(","));".
        Show
        Luke Daley
        added a comment - Related forum post: http://forums.gradle.org/gradle/topics/ivy_configuration_mapping_problem
        Hide
        James Poli
        added a comment -

        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

        Show
        James Poli
        added a comment - 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
        Hide
        Daz DeBoer
        added a comment -

        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

        Show
        Daz DeBoer
        added a comment - 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
        Hide
        James Poli
        added a comment -

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

        Show
        James Poli
        added a comment - Test use case for non-compile artifacts included on javac classpath.
        Hide
        James Poli
        added a comment - - edited

        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

        Show
        James Poli
        added a comment - - edited 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
        Hide
        Adam Murdoch
        added a comment -

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

        Show
        Adam Murdoch
        added a comment - @James, I've created a new issue for the problem you're seeing: GRADLE-2866
        Hide
        James Poli
        added a comment -

        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

        Show
        James Poli
        added a comment - 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

          People

          • Assignee:
            Unassigned
            Reporter:
            Sky Ao
          • Votes:
            5 Vote for this issue
            Watchers:
            11 Start watching this issue

            Dates

            • Created:
              Updated:
              Resolved: