tag:support.gradlefx.org,2011-05-23:/discussions/problems/12-multiproject-build-with-external-linkage-doesnt-find-linked-classesGradleFx: Discussion 2012-03-04T10:35:21Ztag:support.gradlefx.org,2011-05-23:Comment/138922592012-02-22T11:51:16Z2012-02-24T15:14:20Zmultiproject build with external linkage doesn't find linked classes<div><p>Suppose I have a multiproject setup with these projects:</p>
<pre>
<code>include 'lib-a', 'lib-b'</code>
</pre>
<p>"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.<br>
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.</p>
<pre>
<code>dependencies {
external project(':lib-a')
}</code>
</pre>
<p>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.<br>
I should add that I'm also linking the Flex framework externally on
both projects.</p>
<p>Is it my mistake or is ther something missing in GradleFx?<br>
Thanks,<br>
Max</p></div>Maxime Coweztag:support.gradlefx.org,2011-05-23:Comment/138922592012-02-22T13:04:03Z2012-02-24T15:14:20Zmultiproject build with external linkage doesn't find linked classes<div><p>I fixed the issue by manually adding the external linkage to the
compiler options, somewhat like this:</p>
<pre>
<code>dependencies {
external project(':lib-a')
}
additionalCompilerOptions = [
"-external-library-path+=${project(':lib-a').buildDir}/lib-a.swc"
]</code>
</pre>
<p>I assumed this would be done automatically. What does the
'external' keyword do otherwise?</p></div>Maxime Coweztag:support.gradlefx.org,2011-05-23:Comment/138922592012-02-22T19:39:16Z2012-02-22T19:39:16Zmultiproject build with external linkage doesn't find linked classes<div><p>Hi Maxime,</p>
<p>This is exactly what GradleFx does, so it's weird that this
isn't working for you.<br>
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 <a href=
"https://github.com/GradleFx/GradleFx-Examples/tree/master/multiproject-all-conventions">
https://github.com/GradleFx/GradleFx-Examples/tree/master/multiproj...</a></p>
<p>If you can't find a difference, let me know and I'll try to find
something else we can try out.</p></div>Yennick Trevelstag:support.gradlefx.org,2011-05-23:Comment/138922592012-02-23T11:07:37Z2012-02-24T15:14:21Zmultiproject build with external linkage doesn't find linked classes<div><p>Hey Yennick,</p>
<p>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':</p>
<pre>
<code>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"
]</code>
</pre>
<p>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.</p>
<p>Perhaps there is a better way to link the framework externally?
If not, I'd like to make it a feature request ;)</p>
<p>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.</p>
<hr>
<p>One more thing: while tracking down the issue I often got the
following error message:</p>
<pre>
<code>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</code>
</pre>
<p>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.</p></div>Maxime Coweztag:support.gradlefx.org,2011-05-23:Comment/138922592012-02-25T13:45:24Z2012-02-25T13:45:24Zmultiproject build with external linkage doesn't find linked classes<div><p>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.</p>
<p>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.</p>
<p>Concerning your last problem, can you try Gradle milestone 8a
(latest release), apparently it got fixed in this release according
to this jira issue: <a href=
"http://issues.gradle.org/browse/GRADLE-2010">http://issues.gradle.org/browse/GRADLE-2010</a></p></div>Yennick Trevelstag:support.gradlefx.org,2011-05-23:Comment/138922592012-02-25T13:57:06Z2012-02-25T13:57:06Zmultiproject build with external linkage doesn't find linked classes<div><p>Now I think about it, I think there is a better way, declare
them as file based dependencies:</p>
<p>dependencies {</p>
<pre>
<code>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"
])</code>
</pre>
<p>}</p>
<p>I haven't tested this piece of code, but something like this
should work. For more info on file-based dependencies see: <a href=
"http://gradle.org/docs/0.8/userguide/dependency_management.html">http://gradle.org/docs/0.8/userguide/dependency_management.html</a><br>
Not going to create an issue for this anymore as I think this is
quite ok.</p></div>Yennick Trevelstag:support.gradlefx.org,2011-05-23:Comment/138922592012-02-27T11:12:57Z2012-02-27T11:12:57Zmultiproject build with external linkage doesn't find linked classes<div><p>Tested and confirmed: works like a charm! An even more concise
notation might be:</p>
<pre>
<code>dependencies {
external fileTree(
dir: "${flexHome}frameworks/libs",
includes: ['*.swc']
)
}</code>
</pre>
<p>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).</p>
<p>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:</p>
<pre>
<code>frameworkLinkage = 'external'
frameworkLinkage = 'rsl'
frameworkLinkage = 'merged'</code>
</pre>
<p>Note that in FlashBuilder the default setting for this is
'external'.</p>
<hr>
<p>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:</p>
<pre>
<code>Execution failed for task ':fx-components:compile'.
> Could not find matching constructor for:
org.gradle.api.internal.file.BaseDirFileResolver(java.io.File)</code>
</pre>
<p>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.</p>
<p>(Should I start a new discussion for this one?)</p></div>Maxime Coweztag:support.gradlefx.org,2011-05-23:Comment/138922592012-02-27T11:21:06Z2012-02-27T11:21:06Zmultiproject build with external linkage doesn't find linked classes<div><p>Such a property would indeed be a nice addition. Can you create
a feature request for it on the Github issuetracker? <a href=
"https://github.com/GradleFx/GradleFx/issues">https://github.com/GradleFx/GradleFx/issues</a></p>
<p>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.</p></div>Yennick Trevels