Skip to main content


Eclipse Community Forums
Forum Search:

Search      Help    Register    Login    Home
Home » Archived » Buckminster » Accessing transitive dependencies in an ant actor
Accessing transitive dependencies in an ant actor [message #487451] Wed, 23 September 2009 10:01 Go to next message
Johannes Utzig is currently offline Johannes UtzigFriend
Messages: 329
Registered: July 2009
Senior Member
Hi,

sorry if I'm asking too many questions here, but I couldn't find any
hint for an elegant solution for this in the bucky book or the wiki.

This is a bit hard to describe, that's why I'll give you a short
overview of my project setup.
I'm working on a textual DSL with XText. There are several plugins that
contain the EMF model, the XText based parser, the XText based editor
for the language,...
There is also one special plugin that is responible for executing one of
the DSL files in a separate VM (just like the JDT would do for a
java/class file).
Since it is a separate VM, this plugin requires all involved bundles to
parse the DSL file in a standalone fashion.
What I am currently doing is adding a cspecx in that 'launch'-bundle
that has a fetch.dependency.jars action with an ant actor that copies
all required jars into the bundle's lib folder. These jars are not part
of the bundles classpath, instead it invokes a java process with the
classpath set to all jars contained in this folder.

Now my problem is, it does not only need the 'engine' and the parser for
that DSL file, but also everything these two bundles depend on (XText,
ANTLR, EMF,...).
Now what I have to do is to specifiy all transitive dependencies of my
two included bundles as extra dependencies and action prerequisites.
This works fine, but I'm not really happy about it, because I'm just
duplicating information that is already available. The parser for
example knows that it requires EMF and the headless portion of XText.
These two bundles know what they themself depend on, and so on.
Buckminster has all this information since it's done correctly during
the resolution, that's why I would really like to avoid going back to
manual dependency resolution for this task.
This approach also requires me to manually update the cspecx every time
XText (or another external bundle) changes its dependencies.
Now I was wondering, is there any way to access the complete tree of
known transitive dependencies and pass that to my ant actor?
If not, would it be possible if I'd write my own actor?


Thanks for any help and best regards,
Johannes

This is what the cspecx currently looks like:

<?xml version="1.0" encoding="UTF-8"?>
<cspecExtension
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xmlns:bc="http://www.eclipse.org/buckminster/Common-1.0"
xmlns="http://www.eclipse.org/buckminster/CSpec-1.0"
xmlns:cs="http://www.eclipse.org/buckminster/CSpec-1.0">
<dependencies>
<!-- Place your Dependencies here -->
<dependency name="org.apache.commons.logging"
componentType="osgi.bundle" versionDesignator="1.0.4" versionType="OSGi"/>
<dependency name="org.eclipse.xtext.log4j" componentType="osgi.bundle"
versionType="OSGi"/>
<dependency name="org.eclipse.core.resources"
componentType="osgi.bundle"/>
<dependency name="org.eclipse.emf.common" componentType="osgi.bundle"/>
<dependency name="org.eclipse.emf.ecore" componentType="osgi.bundle"/>
<dependency name="org.eclipse.emf.ecore.xmi" componentType="osgi.bundle"/>
<dependency name="org.eclipse.equinox.common"
componentType="osgi.bundle"/>
<dependency name="org.eclipse.xtext" componentType="osgi.bundle"/>
<dependency name="org.eclipse.xtext.util" componentType="osgi.bundle"/>
<dependency name="de.itemis.xtext.antlr" componentType="osgi.bundle"/>
<dependency name="com.google.guice" componentType="osgi.bundle"/>
<dependency name="com.google.collect" componentType="osgi.bundle"/>
<dependency name="org.antlr.runtime" componentType="osgi.bundle"/>
<dependency name="org.apache.ant" componentType="osgi.bundle"/>

<dependency name="org.example.engine" componentType="osgi.bundle" />
<dependency name="org.example.emf" componentType="osgi.bundle" />
</dependencies>
<generators>
<!-- Place your Generators here -->
</generators>
<artifacts>
<!-- Place your Artifacts here -->
</artifacts>
<actions>
<cs:public name="fetch.dependency.jars" actor="ant">
<cs:actorProperties>
<cs:property key="buildFile" value="build/copyJars.xml"/>
<cs:property key="targets" value="copy"/>
</cs:actorProperties>
<cs:prerequisites alias="copyJars.prerequisites">
<cs:attribute name="bundle.jar"
alias="org.apache.commons.logging" component="org.apache.commons.logging"/>
<cs:attribute name="bundle.jar"
alias="org.eclipse.xtext.log4j" component="org.eclipse.xtext.log4j"/>
<cs:attribute name="bundle.jar"
component="org.antlr.runtime"/>
<cs:attribute name="java.binaries"
component="org.apache.ant"/>
<cs:attribute name="bundle.jar"
component="org.eclipse.emf.common"/>
<cs:attribute name="bundle.jar"
component="org.eclipse.emf.ecore"/>
<cs:attribute name="bundle.jar"
component="org.eclipse.emf.ecore.xmi"/>
<cs:attribute name="bundle.jar"
component="org.eclipse.core.resources"/>
<cs:attribute name="bundle.jar"
component="org.eclipse.xtext"/>
<cs:attribute name="bundle.jar"
component="org.eclipse.xtext.util"/>
<cs:attribute name="bundle.jar"
component="de.itemis.xtext.antlr"/>
<cs:attribute name="bundle.jar"
component="com.google.collect"/>
<cs:attribute name="java.binaries"
component="com.google.collect"/>
<cs:attribute name="java.binaries"
component="com.google.guice"/>
<cs:attribute name="bundle.jar" component="org.eclipse.equinox.common"/>

<cs:attribute name="bundle.jar"
component="org.example.engine"/>
<cs:attribute name="bundle.jar"
component="org.example.emf"/>
</cs:prerequisites>
</cs:public>

</actions>
<groups>
<cs:private name="buckminster.prebind" >
<cs:attribute name="fetch.dependency.jars"
alias="action.requirements"/>
</cs:private>
</groups>
<alterDependencies>
<!-- Place your Dependency alterations here -->
</alterDependencies>
<alterArtifacts>
<!-- Place your Artifact alterations here -->
</alterArtifacts>
<alterActions>
<!-- Place your Action alterations here -->
</alterActions>
<alterGroups>
<!-- Place your Group alterations here -->
</alterGroups>
</cspecExtension>
Re: Accessing transitive dependencies in an ant actor [message #487486 is a reply to message #487451] Wed, 23 September 2009 12:23 Go to previous messageGo to next message
Thomas Hallgren is currently offline Thomas HallgrenFriend
Messages: 3240
Registered: July 2009
Senior Member
Hi Johannes,
Perhaps you can use the 'jdt.ant' actor. It does exactly what the 'ant' actor does but it also sets the
'project.classpath' property to the classpath known to the Eclipse builder.

Another option might be to use the classpath emitter (an Eclipse build command). We designed that to be able to compile
ant-tasks etc. in a separate JVM but still gain access to the full classpath used when compiling a bundle.

If you add this to the .project file:

<buildCommand>
<name>org.eclipse.buckminster.jdt.classpathEmitter</name>
<arguments>
<dictionary>
<key>full.printstream</key>
<value>false</value>
</dictionary>
<dictionary>
<key>file</key>
<value>make/bm.properties</value>
</dictionary>
</arguments>
</buildCommand>

Include the generated file in your ant script with

<property file="bm.properties"/>

and then compile using:

<javac ...>
<classpath>
<pathelement path="${bm.classpath}"/>
...

HTH,
- thomas


On 09/23/2009 12:01 PM, Johannes Utzig wrote:
> Hi,
>
> sorry if I'm asking too many questions here, but I couldn't find any
> hint for an elegant solution for this in the bucky book or the wiki.
>
> This is a bit hard to describe, that's why I'll give you a short
> overview of my project setup.
> I'm working on a textual DSL with XText. There are several plugins that
> contain the EMF model, the XText based parser, the XText based editor
> for the language,...
> There is also one special plugin that is responible for executing one of
> the DSL files in a separate VM (just like the JDT would do for a
> java/class file).
> Since it is a separate VM, this plugin requires all involved bundles to
> parse the DSL file in a standalone fashion.
> What I am currently doing is adding a cspecx in that 'launch'-bundle
> that has a fetch.dependency.jars action with an ant actor that copies
> all required jars into the bundle's lib folder. These jars are not part
> of the bundles classpath, instead it invokes a java process with the
> classpath set to all jars contained in this folder.
>
> Now my problem is, it does not only need the 'engine' and the parser for
> that DSL file, but also everything these two bundles depend on (XText,
> ANTLR, EMF,...).
> Now what I have to do is to specifiy all transitive dependencies of my
> two included bundles as extra dependencies and action prerequisites.
> This works fine, but I'm not really happy about it, because I'm just
> duplicating information that is already available. The parser for
> example knows that it requires EMF and the headless portion of XText.
> These two bundles know what they themself depend on, and so on.
> Buckminster has all this information since it's done correctly during
> the resolution, that's why I would really like to avoid going back to
> manual dependency resolution for this task.
> This approach also requires me to manually update the cspecx every time
> XText (or another external bundle) changes its dependencies.
> Now I was wondering, is there any way to access the complete tree of
> known transitive dependencies and pass that to my ant actor?
> If not, would it be possible if I'd write my own actor?
>
>
> Thanks for any help and best regards,
> Johannes
>
> This is what the cspecx currently looks like:
>
> <?xml version="1.0" encoding="UTF-8"?>
> <cspecExtension
> xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
> xmlns:bc="http://www.eclipse.org/buckminster/Common-1.0"
> xmlns="http://www.eclipse.org/buckminster/CSpec-1.0"
> xmlns:cs="http://www.eclipse.org/buckminster/CSpec-1.0">
> <dependencies>
> <!-- Place your Dependencies here -->
> <dependency name="org.apache.commons.logging"
> componentType="osgi.bundle" versionDesignator="1.0.4" versionType="OSGi"/>
> <dependency name="org.eclipse.xtext.log4j" componentType="osgi.bundle"
> versionType="OSGi"/>
> <dependency name="org.eclipse.core.resources" componentType="osgi.bundle"/>
> <dependency name="org.eclipse.emf.common" componentType="osgi.bundle"/>
> <dependency name="org.eclipse.emf.ecore" componentType="osgi.bundle"/>
> <dependency name="org.eclipse.emf.ecore.xmi" componentType="osgi.bundle"/>
> <dependency name="org.eclipse.equinox.common" componentType="osgi.bundle"/>
> <dependency name="org.eclipse.xtext" componentType="osgi.bundle"/>
> <dependency name="org.eclipse.xtext.util" componentType="osgi.bundle"/>
> <dependency name="de.itemis.xtext.antlr" componentType="osgi.bundle"/>
> <dependency name="com.google.guice" componentType="osgi.bundle"/>
> <dependency name="com.google.collect" componentType="osgi.bundle"/>
> <dependency name="org.antlr.runtime" componentType="osgi.bundle"/>
> <dependency name="org.apache.ant" componentType="osgi.bundle"/>
>
> <dependency name="org.example.engine" componentType="osgi.bundle" />
> <dependency name="org.example.emf" componentType="osgi.bundle" />
> </dependencies>
> <generators>
> <!-- Place your Generators here -->
> </generators>
> <artifacts>
> <!-- Place your Artifacts here -->
> </artifacts>
> <actions>
> <cs:public name="fetch.dependency.jars" actor="ant">
> <cs:actorProperties>
> <cs:property key="buildFile" value="build/copyJars.xml"/>
> <cs:property key="targets" value="copy"/>
> </cs:actorProperties>
> <cs:prerequisites alias="copyJars.prerequisites">
> <cs:attribute name="bundle.jar" alias="org.apache.commons.logging"
> component="org.apache.commons.logging"/>
> <cs:attribute name="bundle.jar" alias="org.eclipse.xtext.log4j"
> component="org.eclipse.xtext.log4j"/>
> <cs:attribute name="bundle.jar" component="org.antlr.runtime"/>
> <cs:attribute name="java.binaries" component="org.apache.ant"/>
> <cs:attribute name="bundle.jar" component="org.eclipse.emf.common"/>
> <cs:attribute name="bundle.jar" component="org.eclipse.emf.ecore"/>
> <cs:attribute name="bundle.jar" component="org.eclipse.emf.ecore.xmi"/>
> <cs:attribute name="bundle.jar" component="org.eclipse.core.resources"/>
> <cs:attribute name="bundle.jar" component="org.eclipse.xtext"/>
> <cs:attribute name="bundle.jar" component="org.eclipse.xtext.util"/>
> <cs:attribute name="bundle.jar" component="de.itemis.xtext.antlr"/>
> <cs:attribute name="bundle.jar" component="com.google.collect"/>
> <cs:attribute name="java.binaries" component="com.google.collect"/>
> <cs:attribute name="java.binaries" component="com.google.guice"/>
> <cs:attribute name="bundle.jar" component="org.eclipse.equinox.common"/>
>
> <cs:attribute name="bundle.jar" component="org.example.engine"/>
> <cs:attribute name="bundle.jar" component="org.example.emf"/>
> </cs:prerequisites>
> </cs:public>
>
> </actions>
> <groups>
> <cs:private name="buckminster.prebind" >
> <cs:attribute name="fetch.dependency.jars" alias="action.requirements"/>
> </cs:private>
> </groups>
> <alterDependencies>
> <!-- Place your Dependency alterations here -->
> </alterDependencies>
> <alterArtifacts>
> <!-- Place your Artifact alterations here -->
> </alterArtifacts>
> <alterActions>
> <!-- Place your Action alterations here -->
> </alterActions>
> <alterGroups>
> <!-- Place your Group alterations here -->
> </alterGroups>
> </cspecExtension>
Re: Accessing transitive dependencies in an ant actor [message #487510 is a reply to message #487486] Wed, 23 September 2009 13:28 Go to previous messageGo to next message
Johannes Utzig is currently offline Johannes UtzigFriend
Messages: 329
Registered: July 2009
Senior Member
Hi Thomas,

this is indeed a cool feature and I had no clue such a thing exists, but
I don't think that works in my scenario.
I do not need to compile anything, that is done by buckminster just
fine. What I am trying to achive is to reuse some existing bundles
(eclipse plugins) for standalone usage. The code that's going to be
executed at runtime is a main method in a bundle X (outside of an OSGi
framework). I know bundle X, have it declared as a dependency and
buckminster builds it for me.
I can easily get the bundle with:
<cs:attribute name="bundle.jar" component="X"/>
and pass that to an ant actor that copies the jar into a target directory.
The catch is, the main method of this bundle needs all the bundle's
dependencies in the classpath. And these dependencies need their
dependencies respectively. This information is there and buckminster
knows about it, but how can I tell buckminster that I want X plus all
direct and transitive dependencies of X to appear as nicely packaged
jars in a target folder?

Your approach will reveal the direct dependencies of the project because
they are necessary for compilation, but not the transitive depencenies.
Another problem would be that the classpath would point to dependency
Y's bin/ folder instead of Y's bundle.jar attribute.

The end result I would like to see is an output directory that contains
X.jar, all the jars this X.jar depends on (org.eclipse.xtext.jar,
org.eclipse.emf.jar,....) and all jars these dependencies depend on
(com.google.guice, de.itemis.xtext.antlr,...)

Once I have this output folder, I can invoke the 'engine' just by
java -cp ALL_JARS_IN_OUTPUT_FOLDER -jar X.jar program arguments

It's very similar to for example an EMF model that runs both in eclipse
and standalone. It's easy to deploy that in eclipse, but to run it
standalone you need some emf and some eclipse jars in the classpath.
While this is still easy going to do manually for EMF because there are
not many dependencies, it gets harder with complicated projects like
XText. So what I was hoping for is a way to reuse the dependency tree
already known to buckminster to fetch all the bundles I need to make
them standalone usable without eclipse.
Staying with the emf example, I do know for example that my.model needs
org.eclipse.emf.ecore to run standalone. I also know that
org.eclipse.emf.ecore depends on org.eclipse.core.runtime and so on.
Since this information is also available to buckminster, I'm wondering
if there is a way to say 'copy my.model + it's dependencies (e.g.
org.eclipse.emf.ecore) + the dependencies of my dependencies (e.g.
org.eclipse.core.runtime) to a target folder'.


Best regards and thank you for your time,
Johannes


Thomas Hallgren schrieb:
> Hi Johannes,
> Perhaps you can use the 'jdt.ant' actor. It does exactly what the 'ant'
> actor does but it also sets the 'project.classpath' property to the
> classpath known to the Eclipse builder.
>
> Another option might be to use the classpath emitter (an Eclipse build
> command). We designed that to be able to compile ant-tasks etc. in a
> separate JVM but still gain access to the full classpath used when
> compiling a bundle.
>
> If you add this to the .project file:
>
> <buildCommand>
> <name>org.eclipse.buckminster.jdt.classpathEmitter</name>
> <arguments>
> <dictionary>
> <key>full.printstream</key>
> <value>false</value>
> </dictionary>
> <dictionary>
> <key>file</key>
> <value>make/bm.properties</value>
> </dictionary>
> </arguments>
> </buildCommand>
>
> Include the generated file in your ant script with
>
> <property file="bm.properties"/>
>
> and then compile using:
>
> <javac ...>
> <classpath>
> <pathelement path="${bm.classpath}"/>
> ...
>
> HTH,
> - thomas
>
>
Re: Accessing transitive dependencies in an ant actor [message #487519 is a reply to message #487510] Wed, 23 September 2009 13:58 Go to previous messageGo to next message
Thomas Hallgren is currently offline Thomas HallgrenFriend
Messages: 3240
Registered: July 2009
Senior Member
On 09/23/2009 03:28 PM, Johannes Utzig wrote:
> Hi Thomas,
>
> this is indeed a cool feature and I had no clue such a thing exists, but
> I don't think that works in my scenario.
> I do not need to compile anything, that is done by buckminster just
> fine. What I am trying to achive is to reuse some existing bundles
> (eclipse plugins) for standalone usage. The code that's going to be
> executed at runtime is a main method in a bundle X (outside of an OSGi
> framework). I know bundle X, have it declared as a dependency and
> buckminster builds it for me.
> I can easily get the bundle with:
> <cs:attribute name="bundle.jar" component="X"/>
> and pass that to an ant actor that copies the jar into a target directory.
> The catch is, the main method of this bundle needs all the bundle's
> dependencies in the classpath. And these dependencies need their
> dependencies respectively. This information is there and buckminster
> knows about it, but how can I tell buckminster that I want X plus all
> direct and transitive dependencies of X to appear as nicely packaged
> jars in a target folder?
>
Ah, then I misunderstood. I think the 'bundle.jars' attribute will give you what you need. It's the 'bundle.jar'
together with all 'bundle.jars' from all dependent bundles.

- thomas
Re: Accessing transitive dependencies in an ant actor [message #487524 is a reply to message #487519] Wed, 23 September 2009 14:15 Go to previous message
Johannes Utzig is currently offline Johannes UtzigFriend
Messages: 329
Registered: July 2009
Senior Member
How could I not see that? That's exactly what I wanted.
Now all I need to do is filter out the bad ones, fantastic!


Best regards and thank you very much,
Johannes
Previous Topic:Problems resolving some jackrabbit components from maven central
Next Topic:Spaces in path on Windows with Hudson
Goto Forum:
  


Current Time: Tue Apr 23 12:58:13 GMT 2024

Powered by FUDForum. Page generated in 0.03995 seconds
.:: Contact :: Home ::.

Powered by: FUDforum 3.0.2.
Copyright ©2001-2010 FUDforum Bulletin Board Software

Back to the top