Login
Pass
Always remember me
Categories

Archive for the ‘Uncategorized’ Category

Train, Training, Trained

The BonitaSoft training group has been busy lately – training, training, training, and training. (Did you know we have 4 levels of training?)

And in addition, our current calendar of training sessions are in English, French and Spanish.

Here’s a summary of what the BonitaSoft Services group is using to help Bonita Open Solution users get up to speed quickly.

Read the rest of this entry »

Pimp your Intro !

What is the first thing you see when you start an RCP product? The splash screen.

What is the second thing you see when you start an Eclipse RCP product? The intro page. This page is the first interaction that the user has with your product. It deserves real effort to ensure that your users feel comfortable when opening the product. Also, you can leverage this page to add dynamic content, that can be used, for example, for direct communication between your company and your users. Then it can become a tool for both user-friendliness and marketing, with a relatively low effort. It’s worth it!

In this post we will describe how we leverage the intro page extensibility and API to develop a more ergonomic and marketing-friendly intro page. Everything you will read here can be found or taken directly from the Eclipse Help contents, but I’ll try to explain it more practically.
Read the rest of this entry »

Tags: , , , ,

Add your own widgets to your forms, Example 2: leveraging jQuery

In a previous post, I explained how it is possible to add complex widgets made with JavaScript in a Bonita Form Application, and also how this widget can interact with the data in your process. That example widget was a Google Map.

In this post, I’ll start with one of the user requests in the Bonita Community bug tracker, in order to show you how to embed and leverage RIA JavaScript framework, such as jQuery, in your application. We’ll create a dialog box in a form, and as you’ll see, it’s easy.

Add jQuery resources to your application

This is an example of why there is a Resource tab. First get all the necessary resources from jQuery by downloading them from the website, and add all the folders you need in the applications folder.

That’s all!

Tweak your main HTML page to include jQuery

This is a mandatory step that you have to perform whenever you want to add JavaScript to your applocation. First, retrieve the BonitaApplication.html that you can get by hitting Run, and show the source code for the page. This is your main HTML page. Then add the necessary <script…> headers to the head element of the page, in order for jQuery to run.

<!--             -->
<!-- The favicon -->
<!--             -->

<script src="application.nocache.js" type="text/javascript"></script>
 
<!-- jQuery -->
 
 
 
<script src="js/jquery-1.4.4.min.js" type="text/javascript"></script>

<script src="js/jquery-ui-1.8.7.custom.min.js" type="text/javascript"></script>
 
<!-- OPTIONAL: include this if you want history support -->
 
<!-- loading displayed while GWT is not yet ready -->

<div id="loading">
<div id="bottom-right-shadow">
<div id="loading-content"><img src="images/large-loading.gif" alt="" /><!-- Please wait while loading... --></div>

 
</div>

 
</div>

And then, simply add the modified BonitaApplication.html in the application resource folder.

Now, use jQuery!

jQuery is added and enabled in your application. Just do it! Put an HTML widget in your form, and add the content below (copy-pasted from jQuery documentation):

<div id="dialog" title="Basic dialog">This is a dialog "popped-up" from an application generated with Bonita Open Solution!</div>

<script type="text/javascript">// <![CDATA[
    $(function() {
        $( "#dialog" ).dialog();
    });
// ]]></script>

Et voila!

A few more things

  • The example can be downloaded from the Bonita community.
  • In some cases, you can put the script headers wherever you want in the HTML page, and you can put it in other templates for your application, or directly in the HTML widget. However, this is not a good practice for compatibility, and the only way to ensure your scripts are loaded is to put them in BonitaApplication.html.
  • If your jQuery widget has any input fields, use callbacks on them to set the value of the fields defined in your form designed in Bonita Studio. Add “hidden field” for the data handled by the widget, and change the value of the hidden input with a callback. See the Google Maps example in previous post for a more complete example.
  • And while I am writing about dialog boxes, I’m hearing this music. Coincidence? I don’t think so.
    AEED – Dialog Box by AEED

Tags: , , ,

Add your own widgets to your forms, Example 1: Google Maps API

Here is an explanation of how to add your own custom widgets to the applications generated by Bonita Open Solution. This is something a lot of Bonita Open Solution users have been asking for on our forum, and here is one solution!

In this mini-tutorial, I’ll use Bonita Open Solution 5.4 with its new HTML widget in the form designer, but the same method can be applied to older releases of BOS. You’ll simply have to use a Message widget with the “Allow HTML” flag set to true.

Example 1: Using the Google Maps API

Google provides a great JavaScript API for almost all its products. Let’s use the Google Maps API for the interaction between the Forms application of your process and a Google Map. The user will see – instead of 2 text widgets to input longitude and latitude – a Google Map with a marker to drag and drop in order to indicate a location. Let’s start with a simple process with 2 text variables: latitude and longitude.

The process with its data

Your widgets will make your pages nicer!

If you really don’t want to do it yourself, you can find this example process in the community contributions.

Step 1: Reference the API in BonitaEnvironment.html

In order to leverage the API, you need to define a reference to it in your application. In my opinion, that’s the trickiest part, although it’s still quite easy, and we’ll probably make this step even easier to do in a future release.

You need to add the following lines to the header of the BonitaApplication.html file:

<script src="http://maps.google.com/maps/api/js?sensor=false" type="text/javascript">
</script>

Then create a new process and run it, get the source of form page, this is BonitaApplication.html. Add the necessary lines. The result should look like this:

<!--             -->
<!-- The favicon -->
<!--             -->

<script src="application.nocache.js" type="text/javascript"></script>
 
<script src="http://maps.google.com/maps/api/js?sensor=false" type="text/javascript">
 </script>

<!-- OPTIONAL: include this if you want history support -->

<!-- loading displayed while GWT is not yet ready -->
<div id="loading">
<div id="bottom-right-shadow">
<div id="loading-content"><img src="images/large-loading.gif" alt="" /><!-- Please wait while loading... --></div>
</div>
</div>

Then, add it to your Forms resources so that the default BonitaApplication.html is replaced by the one you just tweaked:

Add BonitaApplication.html to your application resources

Step 2: Model your form

Your form will be very simple to model. It is simply made of 2 hidden fields: latitude and longitude. These widgets add 2 input fields you’ll use to store and save the location marked in the Google Map. Since a Google Map is not a basic HTML input, we cannot directly retrieve its values to store them later. Then we’ll make the Google Map widget store the data we want to use later in those fields.

Then add your HTML widget (or Message widget allowing HTML in older versions). Put in the following code as the initial value:

<script type="text/javascript">// <![CDATA[
 var map;

   var myLatlng = new google.maps.LatLng(45.18409395583682,5.703503018447886);
   var myOptions = {
     zoom: 4,
     center: myLatlng,
     mapTypeId: google.maps.MapTypeId.HYBRID
   }
   map = new google.maps.Map(document.getElementById("map_canvas"), myOptions);

   var marker = new google.maps.Marker({
       position: myLatlng,
       map: map,
       title:"Where are you?",
    draggable: true
   });
   google.maps.event.addListener(marker, 'dragend', function() {
    var point = marker.getPosition();
    // Update fields.
    document.getElementById("latitude").getElementsByTagName("input")[0].value = point.lat();
    document.getElementById("longitude").getElementsByTagName("input")[0].value = point.lng();
   });
// ]]></script>

This script adds a map to your page and updates the hidden fields whenever you move the marker. As you can see, this is simply HTML, JavaScript and Google Maps API, nothing more!

Form overview

Step 3: Try and enjoy!

Just hit the “Run” button, and take a look at your application. It works! Wasn’t that easy?

A very cool integration!

Tags: , , , ,

How to test a Bonita connector

We can’t say this enough: tests are important for code quality. When writing a connector for
Bonita Open Solution, it’s useful to create such tests. And it’s easy to do that.

For each connector, create a classical jUnit TestCase. Then, two kind of tests may be done:

  • test if the connector description is well written; and
  • test the connector itself.

The following explains how to do this.

How to test the description of the connector “MyConnector”

The procedure is quite simple. We get the connector class, call the method
Connector.validateConnector() on it, and then get back the errors. If the connector is
valid, no error is encountered.

public void testValidateConnector() throws BonitaException {
Class connectorClass = MyConnector.class;
List errors =
Connector.validateConnector(connectorClass);
assertTrue(errors.isEmpty());
}

How to test the connector itself

public void testCreateSubfolder() throws Exception {
// Connector instanciation
MyConnector connector = new MyConnector();

// Call of each setter to initialize the connector
connector.setConnectorVar1("MyValue");

// Connector execution
connector.execute();

// Get of the return values
Boolean result connector.getBooleanOutputValue();

// Check of return values
assertTrue("Should be true !", result);
}

Tags: , , ,

Release engineer vs dependency management: Basing RCP Product and headless build from plugins to features

A year and a half after the first draft of Bonita Studio, we decided to move our product build from plugins to features, in order to better handle internationalization, and with the hope to better factorize the build of our 2 products: BOS and BOS-SP (which is a set of extensions on top of BOS).

Our build still uses the highly customized headless PDE-build wrapped in a master script responsible for packaging and testing the application as we deliver it. Here are the steps we followed:

Create the feature from the product definition

This was not a trivial task, since there is no tool to transform a product definition to a feature. The solution we chose was to use Run Configuration to  create the feature. This is an intermediate step that is useful to turn a product definition into a feature:

  • Right-click on your *.product, and Run as Eclipse application
  • The Run Configuration matching the definition of your .product (and then the set of plugins that it contains) is created
  • Create a new feature, and use the magic Create from Run Configuration button
  • Remove the launchers (org.eclipse.equinox.launcher*) from this feature

This method is inspired from blog posts written by Manuel Selva.

Redefine your *.product

From there, you can redefine your .product to include only 2 features: the one you just created, and the org.eclipse.rcp feature.

Quickly validate it

You can make a first validation of your product. The steps are easy:

  • Create a launch configuration for your product by clicking on the Run As Eclipse application or the Synchronize entry

    Launch product from product editor

  • Open the launch configuration wizard, and click on the validate button

    The validate button will give you some hints to fix deps

  • It tells you about some static missing dependencies. Correct your feature according to its advices.
  • Be patient and keep retrying when you get errors. I think I needed more than a dozen iterations before getting the happy button telling me all is well.

Add the feature to your map

This step is only mandatory if you have a headless build that uses map files. If you usually build using UI, just skip it.

Happy HEADLESS Halloween !

Everything is in the title: you just created a new feature, and you’ll need it at build time. Simply add an entry for the feature to your map:

!** Features
feature@org.bonitasoft.studio=SVN,url=http://svn.bonitasoft.org/,tag=bonita-studio,path=XXX_TAG_XXX/releng/org.bonitasoft.studio-feature

Try, see and troubleshoot

Once you’ve done all that, try to build your product. Using the UI entry should be enough.

The export product wizard

Fixing startup

After that, you can give a first try to your bundled product. Run it. It may fail to start. In this case, analyze the startup log that you will find in YourProduct/config/[timestamp].log. You’ll probably see some lines such as these:

!ENTRY org.eclipse.osgi 2 0 2010-10-21 09:17:50.299
!MESSAGE One or more bundles are not resolved because the following root constraints are not resolved:
!SUBENTRY 1 org.eclipse.osgi 2 0 2010-10-21 09:17:50.299
!MESSAGE Bundle reference:file:plugins/org.eclipse.jdt.junit.runtime_3.4.200.v20100526-0800.jar was not resolved.
!SUBENTRY 2 org.eclipse.jdt.junit.runtime 2 0 2010-10-21 09:17:50.299
!MESSAGE Missing required bundle org.junit_3.8.2.
!SUBENTRY 1 org.eclipse.osgi 2 0 2010-10-21 09:17:50.299
!MESSAGE Bundle reference:file:plugins/javax.servlet.jsp_2.0.0.v200806031607.jar was not resolved.
!SUBENTRY 2 javax.servlet.jsp 2 0 2010-10-21 09:17:50.299
!MESSAGE Missing imported package javax.servlet.http_2.4.0.
!SUBENTRY 2 javax.servlet.jsp 2 0 2010-10-21 09:17:50.299
!MESSAGE Missing imported package javax.servlet.resources_2.4.0.
!SUBENTRY 2 javax.servlet.jsp 2 0 2010-10-21 09:17:50.299
!MESSAGE Missing imported package javax.servlet_2.4.0.
!SUBENTRY 1 org.eclipse.osgi 2 0 2010-10-21 09:17:50.299
!MESSAGE Bundle reference:file:plugins/org.bonitasoft.studio.common_1.0.0.20101021-0701.jar was not resolved.
!SUBENTRY 2 org.bonitasoft.studio.common 2 0 2010-10-21 09:17:50.299
!MESSAGE Missing required bundle org.codehaus.groovy_1.7.0.
!SUBENTRY 1 org.eclipse.osgi 2 0 2010-10-21 09:17:50.299
!MESSAGE Bundle reference:file:plugins/org.mortbay.jetty.util_6.1.23.v201004211559.jar was not resolved.
!SUBENTRY 2 org.mortbay.jetty.util 2 0 2010-10-21 09:17:50.299
!MESSAGE Missing imported package javax.servlet.http_0.0.0.
!SUBENTRY 2 org.mortbay.jetty.util 2 0 2010-10-21 09:17:50.299
!MESSAGE Missing imported package javax.servlet_0.0.0.
!SUBENTRY 1 org.eclipse.osgi 2 0 2010-10-21 09:17:50.299
!MESSAGE Bundle reference:file:plugins/org.bonitasoft.studio.simulation_1.0.0.20101021-0701.jar was not resolved.
!SUBENTRY 2 org.bonitasoft.studio.simulation 2 0 2010-10-21 09:17:50.299
!MESSAGE Missing required bundle org.codehaus.groovy_1.7.0.
!SUBENTRY 1 org.eclipse.osgi 2 0 2010-10-21 09:17:50.300
!MESSAGE Bundle reference:file:plugins/org.bonitasoft.studio.console.libs_1.0.0.20101021-0701 was not resolved.
!SUBENTRY 2 org.bonitasoft.studio.console.libs 2 0 2010-10-21 09:17:50.300
!MESSAGE Missing required bundle javax.servlet_0.0.0.
!SUBENTRY 1 org.eclipse.osgi 2 0 2010-10-21 09:17:50.300
!MESSAGE Bundle reference:file:plugins/org.eclipse.pde.core_3.6.0.v20100601.jar was not resolved.
!SUBENTRY 2 org.eclipse.pde.core 2 0 2010-10-21 09:17:50.300
!MESSAGE Missing required bundle org.eclipse.equinox.p2.touchpoint.eclipse_[2.0.0,3.0.0).
!SUBENTRY 1 org.eclipse.osgi 2 0 2010-10-21 09:17:50.300
!MESSAGE Bundle reference:file:plugins/org.codehaus.groovy.eclipse.core_2.0.2.e36-special20100412-1500-e36-special.jar was not resolved.
!SUBENTRY 2 org.codehaus.groovy.eclipse.core 2 0 2010-10-21 09:17:50.300
!MESSAGE Missing required bundle org.codehaus.groovy_0.0.0.
!SUBENTRY 1 org.eclipse.osgi 2 0 2010-10-21 09:17:50.300
!MESSAGE Bundle reference:file:plugins/org.eclipse.pde.build_3.6.0.v20100603 was not resolved.
!SUBENTRY 2 org.eclipse.pde.build 2 0 2010-10-21 09:17:50.300
!MESSAGE Missing required bundle org.eclipse.equinox.p2.director.app_1.0.200.
!SUBENTRY 1 org.eclipse.osgi 2 0 2010-10-21 09:17:50.300
!MESSAGE Bundle reference:file:plugins/org.mortbay.jetty.server_6.1.23.v201004211559.jar was not resolved.
!SUBENTRY 2 org.mortbay.jetty.server 2 0 2010-10-21 09:17:50.300
!MESSAGE Missing imported package javax.servlet.http_2.5.0.
!SUBENTRY 2 org.mortbay.jetty.server 2 0 2010-10-21 09:17:50.300
!MESSAGE Missing imported package javax.servlet_2.5.0.
!SUBENTRY 1 org.eclipse.osgi 2 0 2010-10-21 09:17:50.300
!MESSAGE Bundle reference:file:plugins/org.codehaus.groovy.eclipse.refactoring_2.0.2.e36-special20100412-1500-e36-special.jar was not resolved.
!SUBENTRY 2 org.codehaus.groovy.eclipse.refactoring 2 0 2010-10-21 09:17:50.300
!MESSAGE Missing required bundle org.codehaus.groovy_0.0.0.
!SUBENTRY 1 org.eclipse.osgi 2 0 2010-10-21 09:17:50.300
!MESSAGE Bundle reference:file:plugins/org.eclipse.ocl_3.0.0.v201005061704.jar was not resolved.
!SUBENTRY 2 org.eclipse.ocl 2 0 2010-10-21 09:17:50.300
!MESSAGE Missing required bundle lpg.runtime.java_[2.0.17,3.0.0).
...

This simply tells you the missing bundles in your feature. Then, for each Missing required bundle entry, you will need to add it to your feature, take a look at its dependency tree, add some its dependencies if you missed them, and… Retry !

Fixing runtime

It can easily happen that one of your plugins does not start without crashing the whole product. In such case, you silently lose the features provided by the code of your plugin. Then you can use the OSGi console to get insight about what’s going wrong.

In this example, the log tells me that it cannot load the test plugin, but I don’t really know why. So I can try the following:

mistria@mistri-laptop:~/BonitaStudio-20101021$ ./BonitaStudio -console
[... Some more or less useful stuff ...]
osgi&gt; start org.bonitasoft.studio.tests
org.osgi.framework.BundleException: The bundle "org.bonitasoft.studio.tests_1.0.0.20101021-2140 [1449]" could not be resolved. Reason: Missing Constraint: Require-Bundle: org.bonitasoft.studio.repository.test; bundle-version="0.0.0"
at org.eclipse.osgi.framework.internal.core.AbstractBundle.getResolverError(AbstractBundle.java:1317)
at org.eclipse.osgi.framework.internal.core.AbstractBundle.getResolutionFailureException(AbstractBundle.java:1301)
at org.eclipse.osgi.framework.internal.core.BundleHost.startWorker(BundleHost.java:319)
at org.eclipse.osgi.framework.internal.core.AbstractBundle.start(AbstractBundle.java:284)
at org.eclipse.osgi.framework.internal.core.AbstractBundle.start(AbstractBundle.java:276)
at org.eclipse.osgi.framework.internal.core.FrameworkCommandProvider._start(FrameworkCommandProvider.java:252)
at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:39)
at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:25)
at java.lang.reflect.Method.invoke(Method.java:585)
at org.eclipse.osgi.framework.internal.core.FrameworkCommandInterpreter.execute(FrameworkCommandInterpreter.java:155)
at org.eclipse.osgi.framework.internal.core.FrameworkConsole.docommand(FrameworkConsole.java:156)
at org.eclipse.osgi.framework.internal.core.FrameworkConsole.runConsole(FrameworkConsole.java:141)
at org.eclipse.osgi.framework.internal.core.FrameworkConsole.run(FrameworkConsole.java:105)
at java.lang.Thread.run(Thread.java:595)

osgi&gt; start org.bonitasoft.studio.repository.test
org.osgi.framework.BundleException: The bundle "org.bonitasoft.studio.repository.test_1.0.0.20101021-2140 [1340]" could not be resolved. Reason: Missing Constraint: Require-Bundle: org.bonitasoft.studio.util.tests; bundle-version="1.0.0"
at org.eclipse.osgi.framework.internal.core.AbstractBundle.getResolverError(AbstractBundle.java:1317)
at org.eclipse.osgi.framework.internal.core.AbstractBundle.getResolutionFailureException(AbstractBundle.java:1301)
at org.eclipse.osgi.framework.internal.core.BundleHost.startWorker(BundleHost.java:319)
at org.eclipse.osgi.framework.internal.core.AbstractBundle.start(AbstractBundle.java:284)
at org.eclipse.osgi.framework.internal.core.AbstractBundle.start(AbstractBundle.java:276)
at org.eclipse.osgi.framework.internal.core.FrameworkCommandProvider._start(FrameworkCommandProvider.java:252)
at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:39)
at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:25)
at java.lang.reflect.Method.invoke(Method.java:585)
at org.eclipse.osgi.framework.internal.core.FrameworkCommandInterpreter.execute(FrameworkCommandInterpreter.java:155)
at org.eclipse.osgi.framework.internal.core.FrameworkConsole.docommand(FrameworkConsole.java:156)
at org.eclipse.osgi.framework.internal.core.FrameworkConsole.runConsole(FrameworkConsole.java:141)
at org.eclipse.osgi.framework.internal.core.FrameworkConsole.run(FrameworkConsole.java:105)
at java.lang.Thread.run(Thread.java:595)

osgi&gt; start org.bonitasoft.studio.util.tests
org.osgi.framework.BundleException: The bundle "org.bonitasoft.studio.util.tests_1.0.0.20101021-2140 [1371]" could not be resolved. Reason: Missing Constraint: Require-Bundle: org.eclipse.swtbot.eclipse.finder; bundle-version="2.0.0"
at org.eclipse.osgi.framework.internal.core.AbstractBundle.getResolverError(AbstractBundle.java:1317)
at org.eclipse.osgi.framework.internal.core.AbstractBundle.getResolutionFailureException(AbstractBundle.java:1301)
at org.eclipse.osgi.framework.internal.core.BundleHost.startWorker(BundleHost.java:319)
at org.eclipse.osgi.framework.internal.core.AbstractBundle.start(AbstractBundle.java:284)
at org.eclipse.osgi.framework.internal.core.AbstractBundle.start(AbstractBundle.java:276)
at org.eclipse.osgi.framework.internal.core.FrameworkCommandProvider._start(FrameworkCommandProvider.java:252)
at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:39)
at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:25)
at java.lang.reflect.Method.invoke(Method.java:585)
at org.eclipse.osgi.framework.internal.core.FrameworkCommandInterpreter.execute(FrameworkCommandInterpreter.java:155)
at org.eclipse.osgi.framework.internal.core.FrameworkConsole.docommand(FrameworkConsole.java:156)
at org.eclipse.osgi.framework.internal.core.FrameworkConsole.runConsole(FrameworkConsole.java:141)
at org.eclipse.osgi.framework.internal.core.FrameworkConsole.run(FrameworkConsole.java:105)
at java.lang.Thread.run(Thread.java:595)
org.osgi.framework.BundleException: The bundle "org.eclipse.swtbot.eclipse.finder_2.0.0.568-dev-e36 [1301]" could not be resolved. Reason: Missing Constraint: Require-Bundle: org.eclipse.swtbot.swt.finder; bundle-version="2.0.0"
at org.eclipse.osgi.framework.internal.core.AbstractBundle.getResolverError(AbstractBundle.java:1317)
at org.eclipse.osgi.framework.internal.core.AbstractBundle.getResolutionFailureException(AbstractBundle.java:1301)
at org.eclipse.osgi.framework.internal.core.BundleHost.startWorker(BundleHost.java:319)
at org.eclipse.osgi.framework.internal.core.AbstractBundle.start(AbstractBundle.java:284)
at org.eclipse.osgi.framework.internal.core.AbstractBundle.start(AbstractBundle.java:276)
at org.eclipse.osgi.framework.internal.core.FrameworkCommandProvider._start(FrameworkCommandProvider.java:252)
at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:39)
at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:25)
at java.lang.reflect.Method.invoke(Method.java:585)
at org.eclipse.osgi.framework.internal.core.FrameworkCommandInterpreter.execute(FrameworkCommandInterpreter.java:155)
at org.eclipse.osgi.framework.internal.core.FrameworkConsole.docommand(FrameworkConsole.java:156)
at org.eclipse.osgi.framework.internal.core.FrameworkConsole.runConsole(FrameworkConsole.java:141)
at org.eclipse.osgi.framework.internal.core.FrameworkConsole.run(FrameworkConsole.java:105)
at java.lang.Thread.run(Thread.java:595)

[... And so on, until ...]

osgi&gt; start org.hamcrest.library
Cannot find bundle org.hamcrest.library

Thanks to the console, I can figure out that the missing bundle is org.hamcrest library. I just add it to my feature, and everything works better. Using the console is a general method to resolve dependencies issues. The console is often your best friend!

Conclusion

As you can see, switching from a plugins-based product to a feature-based is not immediate. Features do not provide the fantasically useful Add Required Plug-ins button that you can find on a plugin-based product, and so this move will probably lead to errors in dependency management.

The "Add Required Plug-ins" button is only available for plugin-based products

That’s why, once you have your feature, you need to tweak it to get your product working, since you can easily miss a bundle. Moreover, the bundles you ship may have a different version after a feature-based build. You’ll need to test it well to ensure that this move did not break some features of your product because of bundle versioning. I opened bugs 328323 and 319085 to ask for improvments on this topic.

As always, automated non-regression tests are your very best friend for such a move.

Our feature-based build has now been working for a few days, and I can already tell I am quite happy with it. The build of our 2 products is easier to understand and maintain, and now looks like a simple composition of features. Also, adding a language does not require us to modify the .product any more, and it helps us to get closer to the ability to provide “language packs” as extensions of the product.

Next step, moving to p2…but that will be another story!

By the way…

Aurélien and I will be at Eclipse Summit in Ludwigsburg. Aurélien will have the opportunity to present to the Eclipse community how we leverage the Modeling projects in our product.
If you want to have a chat with us, about anything, feel free to drop us an email to plan a meeting, or grab us during the event!

Tags: , , , , , ,