multiproject build with external linkage doesn't find linked classes

Maxime Cowez's Avatar

Maxime Cowez

22 Feb, 2012 11:51 AM

Suppose I have a multiproject setup with these projects:

include 'lib-a', 'lib-b'

"lib-a" doesn't have any dependencies; "lib-b" depends on "lib-a". When I compile it with the project dependency set to 'merged', everything works fine.
When using 'external' on the other hand the compiler complains about a base class from "lib-a" it can't find, as if I hadn't included the dependency at all. "lib-a" was compiled correctly in the process.

dependencies {    
    external project(':lib-a')
}

I have the exact same setup in FlashBuilder which compiles just fine and I have also done this lots of times with ANT and compc.
I should add that I'm also linking the Flex framework externally on both projects.

Is it my mistake or is ther something missing in GradleFx?
Thanks,
Max

  1. Support Staff 1 Posted by Maxime Cowez on 22 Feb, 2012 01:04 PM

    Maxime Cowez's Avatar

    I fixed the issue by manually adding the external linkage to the compiler options, somewhat like this:

    dependencies {    
        external project(':lib-a')
    }
    
    additionalCompilerOptions = [
        "-external-library-path+=${project(':lib-a').buildDir}/lib-a.swc"
    ]
    

    I assumed this would be done automatically. What does the 'external' keyword do otherwise?

  2. Support Staff 2 Posted by Yennick Trevels on 22 Feb, 2012 07:39 PM

    Yennick Trevels's Avatar

    Hi Maxime,

    This is exactly what GradleFx does, so it's weird that this isn't working for you.
    I just tried this scenario (with static-link-runtime-shared- libraries=false) with one of the GradleFx example projects and it worked fine, so can you check your project build files with those at https://github.com/GradleFx/GradleFx-Examples/tree/master/multiproj...

    If you can't find a difference, let me know and I'll try to find something else we can try out.

  3. Support Staff 3 Posted by Maxime Cowez on 23 Feb, 2012 11:07 AM

    Maxime Cowez's Avatar

    Hey Yennick,

    I built the entire script up from the ground to see where it started going wrong and I eventually found the issue. As I briefly mentioned in my original post, I was trying to link the framework externally too. If I leave the defaults my compiled library will contain the entire Flex framework and weigh around 1Mb. I did so by adding the Flex libraries to the external classpath through 'additionalCompilerOptions':

    additionalCompilerOptions = [
        "-external-library-path+=${flexHome}frameworks/libs/player/${player}/playerglobal.swc",
        "-external-library-path+=${flexHome}frameworks/libs/textLayout.swc",
        "-external-library-path+=${flexHome}frameworks/libs/framework.swc",
        "-external-library-path+=${flexHome}frameworks/libs/osmf.swc",
        "-external-library-path+=${flexHome}frameworks/libs/charts.swc",
        "-external-library-path+=${flexHome}frameworks/libs/mx/mx.swc",
        "-external-library-path+=${flexHome}frameworks/libs/rpc.swc",
        "-external-library-path+=${flexHome}frameworks/libs/flash-integration.swc",
        "-external-library-path+=${flexHome}frameworks/libs/spark.swc",
        "-external-library-path+=${flexHome}frameworks/libs/advancedgrids.swc",
        "-external-library-path+=${flexHome}frameworks/libs/authoringsupport.swc",
        "-external-library-path+=${flexHome}frameworks/libs/sparkskins.swc",
        "-external-library-path+=${flexHome}frameworks/libs/spark_dmv.swc"
    ]
    

    What went wrong was this: I had copy/pasted this list from an old ANT task and the first line did not contain the + sign. So apparently GradleFx added the external library paths first and then I overrode those with the ones for the Flex framework libs. Adding the + sign fixed the issue.

    Perhaps there is a better way to link the framework externally? If not, I'd like to make it a feature request ;)

    Maybe you could also make GradleFx parse the 'additionalCompilerOptions' and issue a warning or an error when one overrides compiler options that GradleFx sets internally.


    One more thing: while tracking down the issue I often got the following error message:

    Execution failed for task ':fx-users:compile'.
    Cause: Could not resolve all dependencies for configuration ':fx-users:external'.
    Cause: org.gradle.api.internal.artifacts.dependencies.DefaultProjectDependency_Decorated cannot be cast to org.gradle.api.artifacts.ExternalModuleDependency
    

    I cannot tell you exactly how or when it is triggered, because the same script will sometimes throw this error and sometimes it won't. I suppose this behaviour has something to do with script caching.

  4. Support Staff 4 Posted by Yennick Trevels on 25 Feb, 2012 01:45 PM

    Yennick Trevels's Avatar

    Currently there's no better way to link the framework externally, I'll create an issue on the github issuetracker. I'll see what I can do.

    Good idea about those warning, actually this is something that could be improved in general because in a lot of cases the errors you get aren't that descriptive right now (like when you haven't specified the FLEX_HOME, which throws some rather weird error). I'll create an issue on the Github issuetracker for it.

    Concerning your last problem, can you try Gradle milestone 8a (latest release), apparently it got fixed in this release according to this jira issue: http://issues.gradle.org/browse/GRADLE-2010

  5. Support Staff 5 Posted by Yennick Trevels on 25 Feb, 2012 01:57 PM

    Yennick Trevels's Avatar

    Now I think about it, I think there is a better way, declare them as file based dependencies:

    dependencies {

    external fileTree(dir: '${flexHome}frameworks/libs', includes: [
         "${player}/playerglobal.swc",
         "textLayout.swc",
        "framework.swc",
        "osmf.swc",
        "charts.swc",
        "mx/mx.swc",
        "rpc.swc",
        "flash-integration.swc",
        "spark.swc",
        "advancedgrids.swc",
        "authoringsupport.swc",
        "sparkskins.swc",
        "spark_dmv.swc"
    ])
    

    }

    I haven't tested this piece of code, but something like this should work. For more info on file-based dependencies see: http://gradle.org/docs/0.8/userguide/dependency_management.html
    Not going to create an issue for this anymore as I think this is quite ok.

  6. Support Staff 6 Posted by Maxime Cowez on 27 Feb, 2012 11:12 AM

    Maxime Cowez's Avatar

    Tested and confirmed: works like a charm! An even more concise notation might be:

    dependencies {
        external fileTree(
            dir: "${flexHome}frameworks/libs", 
            includes: ['*.swc']
        )
    }
    

    which will simply include all the framework swcs it can find. Since they are linked externally it doesn't really matter whether they're being used or not. Mind you, I don't know what would happen if there were multiple 'playerglobal' swcs in the SDK (e.g. one for 10.2 and one for 11.1).

    Come to think of it: it would be a nice feature to add a project property with which you can choose the framework linkage (like you can do in FlashBuilder). Something along the lines of:

    frameworkLinkage = 'external'
    frameworkLinkage = 'rsl'
    frameworkLinkage = 'merged'
    

    Note that in FlashBuilder the default setting for this is 'external'.


    As for milestone 8a: I updated my gradle installation to this version, but then I got the following error in one of my library projects:

    Execution failed for task ':fx-components:compile'.
    > Could not find matching constructor for:
    org.gradle.api.internal.file.BaseDirFileResolver(java.io.File)
    

    I've attached the full stacktrace (which is somewhat opaque to me). I have other projects that have the exact same build script and do not throw this error.

    (Should I start a new discussion for this one?)

  7. Support Staff 7 Posted by Yennick Trevels on 27 Feb, 2012 11:21 AM

    Yennick Trevels's Avatar

    Such a property would indeed be a nice addition. Can you create a feature request for it on the Github issuetracker? https://github.com/GradleFx/GradleFx/issues

    Regarding the error, looks like GradleFx isn't compatible with milestone 8a. Please log a bug for this on the issuetracker. I'll try to keep GradleFx up to date with the latest Gradle versions.

  8. Yennick Trevels closed this discussion on 04 Mar, 2012 10:35 AM.

Comments are currently closed for this discussion. You can start a new one.

Keyboard shortcuts

Generic

? Show this help
ESC Blurs the current field

Comment Form

r Focus the comment reply box
^ + ↩ Submit the comment

You can use Command ⌘ instead of Control ^ on Mac