Skip to main content

Notice: this Wiki will be going read only early in 2024 and edits will no longer be possible. Please see: for the plan.

Jump to: navigation, search

Eclipse b3/proposals/Extending Meta Data Translation

This information is dated. Please visit the b3 website for the latest information

What's the issue

In b3, units are translated into the common b3 model via meta data translators. These translators look at available meta data and translates it into the common form. There are situations where this is not enough:

  • There may be no meta data at all in the original unit
  • There may not be enough meta data in the original unit
  • The original meta data is wrong
  • The meta data translator does not make use of all available information
  • Custom translation is needed - there is nothing wrong with the original transformation, but more is wanted

How can it be solved?

Extending the translation can be done in several ways:

  • Replacing the meta data translator for a namespace with a custom translator
  • Using advice in b3 build files (internal or external, that add the advice when the b3 build file is used)
  • Embedding advice in the unit that translators pick up and use
  • Providing proxy units that provide the original as a capability - the extension is done on the proxy

Replacing a translator

This is quite straight forward - a new translator is created (it can extend an existing translator), and the new translator is used for a particular namespace instead of the original. The extended translator simply provides build units in the new required shape.

Using Advice in b3 build files

This is straight forward. Simply author a build file and advice the units that should be different than the standard translation. It is even possible to create new units this way.

The pros are:

  • useful for ad hoc work - experimentation
  • easy to understand - other systems work like this (inject dependencies, are more task oriented).

The cons are:

  • the b3 build file is separate from the original unit, and users would have to include the advice in their b3 build file (either reference some other build file, or restate the advice).
  • makes refactoring the build more difficult - functionality may move between build unit parts and the build files, they are used in different ways.
  • a large system is difficult to maintain as separation of concerns can be an issue (i.e. have to deal with all downstream advice)

This is not described further in this proposal - it is what it is, and can be used.

Embedding Advice

Embedding the advice means placing new meta data inside the original unit that is picked up by the meta data translators after they have done their original work.

The pros are:

  • The advice is an integral part - everyone gets the same translation
  • Shares the life-cycle with the original unit

The cons are:

  • requires write access to the original component

Proxy Advisor

Instead of embedding the advice, a proxy is created that contains the advice (or has meta data in a translatable form, e.g. a feature that describes dependencies).

The pros are:

  • The proxy can be referenced - everyone gets the same
  • No write access needed to original component

The cons are:

  • If users have to refer to the proxy instead of the original
  • Other units depending on the unit we try to extend have requirements on the original - if the proxy must be known to them, it does not work.
  • if users have to know that they must include the proxies in a configuration even if they don't have to reference the proxies instead of the originals (i.e. some fragment based solution). Users could just as well include the advice in their build files - this is just replacing a difficulty with another.
  • It is difficult to detect proxies/fragments in a source code repository

Embedding Advice

Embedding advice could be done by placing a build file with a special name in the original unit. The meta data translators would pick this up and apply the advice. A better solution is perhaps to have a variation on the syntax. The b3 build file has the context as its root, and as the extension of a component has no business providing advice outside of the build unit itself, it just becomes a chore to restate the path from a context to the unit.


advice {
/units:last = new BuildUnit {

If instead, the root is the created unit:

advice {
/ {
name = "x.y.z";

Which seems silly, and a new top level keyword is better - allowing the user to write:

unit {

Or indeed, since the only thing that makes sense is advice on the actual unit, the advice itself could be at the root of the document:


Although simple, it makes it more difficult to extend, and there is an issue with using import statements. The best solution is probably to have a section called "unit", "self" or "this". Or possibly "advice self", or "advice this", to make it clear that it is advice that follows.

Special name of file

The file would need to have a special name to be picked up by the meta data translators. In Buckminster, this file is called buckminster.cspec (if there is not other meta data available), and buckminster.cspex (if there is other meta data available). In b3, we could call this file "this.b3", but as we probably want a variation on the syntax, it could be a .b3x file. The name of the file does perhaps not matter, but it is probably cleaner if the name is fixed.

Suggest "this.b3x"

Proxy Unit

We decided that proxy units as described here is just trading one difficulty for another. It is just as easy to repackage an original unit with embedded meta data, or organize the build files with advice.

But maybe someone has a different opinion? Here are some ideas anyway...

The key issue is how to find the proxies instead of the requested. This could be done by having the proxy expose the original as a capability. Thus, dependencies to the original can be kept as original.

a -> x, org.braids;

i.e. a requires the capability x in the org.braids namespace.

But, this is very difficult to find in a source code management system. Which of all the files (and versions thereof) in the SCM should be investigated to see if it can be turned into a build unit that provides the requested capability? Something else must resolve to the proxy to make its provided capabilities detected. A special kind of repository could also be used for this, and the user must publish the proxies to this repository.

I can imagine that the resolvers are set up with a "provide proxies for requests matching this pattern...". A very simple way of solving this is to impose a directory/filename standard on a repository of proxies:


I.e. when looking for a proxy for "org.myorg.nemo" in namespace "java.jar" it first finds the actual real unit using the normal resolvers. This determines its original version. The resolver could have been informed that it should look for proxies (as opposed to always looking for proxies for everything being resolved). It then searches for the proxy to the original. A proxy handler finds files called "org.myorg.nemo_1_2_3" (using some established standard for name/version encoding), "org.myorg.nemo_2_0_0", and reads and applies the advice on the original.

  • It is of value to be able to configure the use of proxy to give an error if a proxy is not found.
  • proxies should perhaps use a range instead of a version, as there could otherwise be a proliferation of files with the exact same content.

Copyright © Eclipse Foundation, Inc. All Rights Reserved.