Archive for the ‘OSGi’ Category

Using the Vaadin (GWT) SuperDevMode in OSGi Environments

July 7, 2015

GWT and Vaadin come with a great feature to debug the client-side widget code in the Chrome browser. Using GWT’s code server, the Java code will be displayed in the Chrome browser, and you can set your breakpoints and do debugging stuff directly in Chrome.

To run the superDevMode some preparations are required:

  1. Enable SuperDevMode in widgetset
  2. Compile your widgetset by a Maven build
  3. Download all dependencies required to run the codeserver (another Maven build)
  4. Create a launch config to run the code server
  5. Enhance the classpath of the code server launch config
    1. Add all downloaded dependencies to the classpath of the code server launch config
    2. Add local client-side code bundles and their source folders to the classpath
    3. Add the widgetset bundle to the classpath
    4. Ensure that 5.2 and 5.3 are at the beginning of the classpath
  6. Start the code server
  7. Start your OSGi Vaadin Application
  8. Open http://localhost:9876/
    1. Bookmark “Dev Mode on” and “Dev Mode off” in the browser
  9. Open your application in Chrome {URL}/?superdevmode
  10. To reload widgetset in 8) click the “Dev Mode on” bookmark
  11. Ensure that Chrome -> Developer tools -> Properties -> Sources -> xyz Sourcemaps are checked
  12. Open the source tab in Chrome and find your java sources there

1 Enable SuperDevMode

To enable the super dev mode, add the following lines to your widgetset.gwt.xml

<set-configuration-property name="devModeRedirectEnabled"
		value="true" />;

<add-linker name="xsiframe" />

2 Compile widgetset

To compile the widgetset properly, we are using a Maven build.

Create a file called pom-compileWidgetset.xml in your widgetset bundle and configure the pom. Therefore just follow Vaaclipse widgetset as a sample.

Following entries in the pom are mandatory:

  1. Add all your maven dependencies required to compile the widgetset
  2. Configure the vaadin-maven-plugin to compile the widgetset. The compiled widgetset will be copied to ${basedir}/resources.

Run the build with “mvn clean verify -f pom-compileWidgetset.xml”

3 Download all dependencies for the CodeServer

To run the code server properly, a lot of jar files are required. The simplest method to collect all dependencies and their transitive dependencies is to use another Maven build.

Create a file called pom-superdev.xml in your widgetset bundle and configure the pom. For this pom, just follow Vaaclipse widgetset as a sample.

The pom contains all required dependencies and a configuration for the maven-dependency-plugin which copies all jar files to a folder under “${project.build.directory}/superDev-lib”. Attention: The superDev-lib folder will be removed, if you call “mvn clean …” on the widgetset bundle. So it might be a good idea to create a folder called superDev-lib directly in the widgetset bundles root and copy the jars from${project.build.directory}/superDev-lib” to this folder manually.

Run the build with “mvn clean verify -f pom-superdev.xml”

4 Create a superDev launch config

The superDev launch config is a simple java launch config.

Settings:

  • Main class: com.google.gwt.dev.codeserver.CodeServer
  • Program arguments: “-logLevel DEBUG org.semanticsoft.vaaclipse.widgetset.DefaultWidgetset”
  • VM arguments: “-Xss8M -Xmx512M -XX:MaxPermSize=512M”

5 Enhance the classpath of the superDev launch config

The jar files downloaded under 3) need to be added to the classpath of the launchconfig.

  • Open the launch config, switch to tab “Classpath”
  • Press “Add JARs”
  • Then add all jar files located in /superDev-lib to the classpath.
  • Then add any “local client-side bundles” contained in the workspace
  • Add the source folder of the “local client-side bundles” too
  • Add the “widgetset bundle”
  • Add the source folder of the “widgetset bundle”
  • Ensure that the “local client-side bundles”, the “widgetset bundle” and their source folders are at the beginning of the classpath.

Follow the launch configs contained in Vaaclipse widgetset as a sample.

superdev-launchconfig

6 Run the superDev launch config

Running the superDev launch config means that the widgetset is compiled.

If the code server could start properly, you will find following lines in the console:

The code server is ready.
Next, visit: http://localhost:9876/

7 Start the application launch config

Now you need to start you application using a launch config. No special configs are required there.

8 Open http://localhost:9876/

superDevURL

Just follow the instructions on the website and bookmark the two links.

9 Open application in superDevMode

To do this, open {URL}/?superdevmode in your Chrome browser.

The browser will tell you that the widgetset is being recompiled. Afterwards, the application opens.

10 and 11

No steps to describe here …

12 Open source code in Chrome browser

Open the developer tools in Chrome. Under the source tab you should find all your client-side Java code.

sourceCodeInChrome

You may set breakpoints to the code and do all the debugging stuff — right in your browser!

OSGi and Vaadin – Using ClassResource

June 18, 2015

Using Vaadin’s ClassResource in OSGi environments is pretty straightforward. But you have to know a few basics about the OSGi class loader:

In OSGi, every bundle has its own classloader. And all resources contained in a certain bundle are loaded by this bundle’s classloader only.


Sample

For instance, we try to load an image based on Vaadin’s ClassResource.

new Image("Bundle2 exported", 
        new ClassResource(org.my.SampleExported.class, 
        "ImageExported.png"))

The ClassResource internally will call

org.my.SampleExported.class.getResourceAsStream(
        "ImageExported.png")

 whenever ClassResource#getStream() is called.


The OSGi classloader takes over

After this, the OSGi classloader comes into play. It uses a defined strategy to look for the resource:

  1. If the package starts with “java”, then the request is forwarded to the parent classloader
  2. If the package is in the list of “boot delegation”, the the request is forwarded to the parent classloader
  3. The request is forwarded to “class loading hooks”
  4. The classloader checks whether there is a “import package” for “org.my”.
    1. If so, then the resource is loaded from this imported package (meaning that the request is forwarded to a different bundle classloader). If a package could be found, the lookup will terminate.
    2. If not, proceed with 5.
  5. The classloader checks all “required bundles” whether the resource can be found there.
  6. The classloader checks the “local” resources contained in the classloaders bundle.
  7. The classloader checks the “fragments classpath” resources contained in the fragments.
  8. The classloader checks for “dynamic imports”.

How not to: Something that will never work

Assume we have two bundles.

Bundle A – contains the Vaadin-Servlet, the resource handler and all that stuff required to run Vaadin in OSGi.

Bundle B – just another bundle. “Bundle A” does not have a dependency to “Bundle B”.

Bundle B contains an image and it should be loaded by a ClassResource. If you prepare a ClassResource for the image contained in “Bundle B”, but you do not pass a class contained in “Bundle B” to the ClassResource, OSGi is not able to load the image.

new Image("", 
        new ClassResource("ImageInBundleB.png"))

The reason is that ClassResource internally will use the classloader of the UI class. And this one does not have a dependency to “Bundle B”. And so the resource can not be loaded because it is not visible to the classloader.


Using a BundleResource

I prepared a BundleResource prototype. It is licensed under the Apache License and is available at the Lunifera github repo.

new Image("", 
        new BundleResource(theBundle, 
        "resources/ImageInBundleB.png"))

The path to the resource is the path relative to the bundle. In this sample, the “ImageInBundleB.png” is located in a folder called “resources”.

Feel free to use the BundleResource for your own projects.


Debugging

If a resource could not be found by the “ClassResource”, one just has to debug the OSGi classloader. If you are using Equinox, take a look at

org.eclipse.osgi.internal.loader.BundleLoader. It is responsible to load the resource.

Hacking OSGi’s bundle resolving

February 19, 2015

Last week, we ran into troubles when deploying our system via Equinox P2: All of a sudden, our DSLs simply didn’t work after the installation of the system into a new Eclipse – the DSL projects didn’t request the Xtext nature, and Eclipse didn’t open the appropriate editor without displaying any error message. Big showstopper!

A look in the log revealed the following:

org.eclipse.e4.core.di.InjectionException: java.lang.LinkageError: 
loader constraint violation: when resolving overridden method
"org.eclipse.xtext.xbase.ui.contentassist.XbaseProposalProvider.getProposalFactory
(Ljava/lang/String;Lorg/eclipse/xtext/ui/editor/contentassist/ContentAssistContext;)
Lcom/google/common/base/Function;" the class loader (instance of
org/eclipse/osgi/internal/loader/EquinoxClassLoader) of the current class,
org/eclipse/xtext/xbase/ui/contentassist/XbaseProposalProvider, and its
superclass loader (instance of org/eclipse/osgi/internal/loader/EquinoxClassLoader),
have different Class objects for the type com/google/common/base/Function
used in the signature ...

So the root of the problem were different versions of Google Guava (that contains com.google.common.base.Function). Of course, OSGi supports running multiple versions of bundles at once – which we do in our system since Sirius uses Guava 15 and Mylyn uses Guava 18. No problem so far!

The problem

The problem arose because Xtext is open to a wide range of Guava versions. Unfortunately, the Xtext bundles were not wired to one Guava version consistently, but randomly to one of the two (depending on the order of resolution). This introduced incompatibilities between Xtext bundles, which prevented the system from working.

Wiring Xtext bundles to different Guava versions prevents Xtext from working.

The problem: Xtext bundles were wired to different Guava versions, causing class loader problems within the Xtext class-space. (Click to enlarge)

Searching for a way

Now what can be done?

One possible solution for this would be employing the OSGi “uses”-directive (good explanation here): This directive in the bundle headers of multi-bundle projects can ensure that the class space is consistent. The problem with this solution was that we would have had to fork Xtext in order to add the “uses”-directives. Since we are not (yet) ready and willing to do that, we reported a bug with Xtext. The good news is that the helpful guys over there reduced the likelihood of inconsistent bundle wiring by removing some reexports. The bad news: There is no waterproof solution at hand that will work in any case.

Maybe – just maybe – upgrading to Xtext 2.8 might have helped. With our complex system, this would have taken two weeks and forced the same migration on our customer. No good!

 

Breakthrough: Hacking OSGi

So back to the planning table: What we want is to make sure that all Xtext bundles end up with the same version of Guava. So if we could influence the OSGi resolving process, we’d be fine! But to do that, the code that influences the resolving process needs to be loaded first – a chicken and egg problem: Who makes sure that the code that determines bundle resolution order is the first to be fired up?

A closer look at the OSGi specification showed us that there is a mechanism in place already: The Resolver Hook Service makes it possible to influence the resover’s decisions by writing a system extension to the OSGi framework.

After some research about the details of the Resolver Hook Service, we came up with a system bundle fragment that is called whenever a bundle wants its dependencies resolved. This fragment is given a list of possible candidates for the bundle wiring. Now we can kick out the older versions if a dependency can be resolved by more than one version of a bundle, so only the newest one remains. And voilà: All of Xtext ended up with Guava 18.

The Resolver Hook Service makes it possible to ensure correct bundle wiring.

Our solution: Using the Resolver Hook Service, we can influence the decisions made by the Resolver and control which bundles are used to satisfy dependencies of other bundles. (Click to enlarge)

 

Deploying the solution

We still were faced with one minor problem: OSGi needs to be made aware of the system extension fragment at startup. Locally, this is no problem: One can either add “osgi.framework.extensions=…” to the $ECLIPSE_HOME/configuration/config.ini, to the vm section in the $ECLIPSE_HOME/eclipse.ini or pass it as an argument to the VM (‑Dosgi.framework.extensions=…).

But how to do this automatically during a P2 installation? Well, as Dennis Hübner put it:

p2.inf is your friend

Using a p2.inf located next to the feature.xml of the feature containing the bundle fragment, it is easy to update the $ECLIPSE_HOME/configuration/config.ini during the installation process. Yayy, it works!

 

Our code

The code we came up with is available under the EPL. It can be found in our lunifera-runtime repo at Github (development branch, relevant folders: org.lunifera.runtime.systemextension and org.lunifera.runtime.feature.resolverhooks).

 

Originally posted at Lunifera.com

 

Vaadin 7.3 – Valo, OSGi and e4

September 2, 2014

I got the chance to see a preview of Vaadin 7.3 some days ago and I am really really impressed about the new features it brings.

Until now, I have worked with the Vaadin Reindeer theme and tried to customize it. But since I am a Java developer, I do not have particularly deep knowledge about CSS3 and had a hard time with it. That’s why I am really looking forward to Vaadin 7.3 and going to upgrade my customer projects in the next days. The new Valo-Theme is exactly what I have been trying to do myself: a responsive and highly customizable theme. There are many different styles and most of them meet my objectives without having to change anything in the CSS.

And the best thing about Vaadin 7.3 is that it comes with a high-end Sass compiler. In the last days I was reading a lot about Sass and it is a perfect match for Java developers. Using this very intuitive styling language, Vaadin 7.3 will compile that information into proper CSS3. Really crazy… For me Sass is something like a DSL for CSS3. Thus, I do not have to schedule my CSS training anymore — I just have to use Sass 😀

 OSGi and Vaaclipse

During the next days, I will “Run a first Vaadin 7.3 OSGi application”. And I am sure right now: it is a perfect match.

Running a Vaadin 7.3 OSGi application is the base for migrating the Vaaclipse-Project to Valo too. The Vaaclipse-Project is a rendering layer to render the e4-workspace with Vaadin. See http://semanticsoft.github.io/vaaclipse/.

For details about Vaadin 7.3 just click here.

I also added two screenshots about the new theme:

Metro-Theme

Valo-1

Dark-Theme

Valo-2

 

Going to keep you informed…

Best, Florian

Something you can’t do with ComponentFactories

May 26, 2011

About 2 weeks ago i started to implement the main architecture of EOS which is a subproject based on redVoodo. The main goal is to provide a very flexible and extendable base implementation for business applications. Based on OSGi DS (declarative services) i started to design my application. I decided to use ComponentFactories to create different instances of the same interface / class. For instance this is necessary to provide web session based classes like an ApplicationContext with application scope. I was suppressed how powerful OSGi services are. But then i recognized, that i have used ComponentFactory a way they are not intended to be used. See http://www.eclipse.org/forums/index.php/t/209483/

This post should explain the problems i faced during the implementation of EOS. Therefore i have prepared a simple example based on “shapes”. A IShapeFactory provides instances of IShapes for different types (circle, square,…). Implementations of IShapes are provided by ComponentFactories. These componenteFactories are required by the shapeFactory.

Class dependencies

This image shows the dependencies between the classes involved and their function.

ShapeFactory

public interface IShapeFactory {

/**
* Creates a new shape for the given type or <code>null</code> if no shape
* is registered for the type.
*
* @param type
* @return
*/
IShape createNewShape(String type);

}

Based on the shape factory several new instances of a shape can be created. Since the architecture of this factory is extendable, the type should be specified by a property (study1.shapeType) in the OSGi component definition of the IShape component factory. The component factories are registered at the shapeFactory by the OSGi DS (declarative service) framework.

If createNewShape is called, the factory tries to find a component factory which is responsible for the given type and uses this factory to create a new instance of IShape.

IShape

public interface IShape {

/**
* Calling this method will paint the
* content of that shape instance.
*/
void paint();

}

Instances of IShape are used to paint the shape defined by the implementation. For instance it paints a circle or a square or something else.
Since each visualized shape is a new instance of the IShape interface, i decided to use a ComponentFactory which provides new instances of that interface. How this works will be described later.

A really nice way, which allows the new instantiated components to use OSGi “declarative services” as well. If we would instantiate the shapes with “new SomeShape()”, that classes can not use DS since they are not defined by a service component definition. But since we are using ComponentFactories the IColorProvider from image above could also be defined as a required service for the class Circle. That’s the BIG advantage using ComponentFactories.

Service dependencies

This image shows the service dependencies.

org.redvoodo.osgi.study1.services

This bundle contains all service interfaces. The ComponentFactory rectangle in the image above is only displayed there to make the visualization much clearer. So it is not really contained in that bundle.

org.redvoodo.osgi.componentfactory.shape

This bundle contains 2 IShape implementations. Square and Circle. Instead of providing the IShape interface, it provides a ComponentFactory service which can be used to create new instances of the IShape implementation.

The really important entries in that service component definition are:

factory="study1.shapesfactory"

Defines the service component as a component factory.

property name="study1.shapeType" type="String" value="circle"

Adds a shape type property to the component definition. The shapeFactory should use this property to identify the type of the shape which is provided by the component factory.

org.redvoodo.osgi.componentfactory.factory

It provides the IShapeFactory service and contains an implementation of ShapeFactory. The ShapeFactory requires 0:n “ComponentFactories providing IShape”.

If a ComponentFactory was added (addShapeComponentFactory), the passed properties will be used to determine the type of the shape that is provided by the component factory. And the component factory is registered in an internal map.

If a ComponentFactory was removed, it will be removed from the internal map by its type.

If createNewShape(String) is called, the factory registered by the given type will be used to create a new instance of the shape. If no registered factory could be found, null will be returned.

public class ShapeFactoryImpl implements IShapeFactory {

private Map<String, ComponentFactory> factories
= new HashMap<String, ComponentFactory>();

/**
* Called by OSGi
*
* @param shapeFactory
* @param properties
*/
protected void addShapeComponentFactory(
     ComponentFactory shapeFactory,
     Map<String, Object> properties) {

     String type = (String)
       properties.get("study1.shapeType");
     factories.put(type, shapeFactory);
}

/**
* Called by OSGi
*
* @param shapeFactory
* @param properties
*/
protected void removeShapeComponentFactory(
     ComponentFactory shapeFactory,
     Map<String, Object> properties) {

     String type = (String)
       properties.get("study1.shapeType");
     factories.remove(type);
}

@Override
public IShape createNewShape(String type) {
     IShape result = null;
     if (factories.containsKey(type)) {
        ComponentFactory factory =
          factories.get(type);
        result = (IShape) factory
          .newInstance(null).getInstance();
        // for normal you should also
       // handle the lifecycle of
       // ComponentInstance
     }
  return result;
}

Conclusion

After finishing this implementation i was really suppressed. Really suppressed that nothing happend! My architecture did not work at all.

But what is the problem? Well, the problem was, that i did not know some issues about ComponentFactories. So i asked at the newsgroup (equinox newsgroup) an got following answer:

BJ Hargrave

DS spec. From 112.2.4 Factory Component:

SCR must register a Component Factory service on behalf of the component as soon as the component factory is satisfied. The service properties must be:

* component.name The name of the component.
* component.factory The factory identifier.

The service properties of the Component Factory service must not include the component properties.

The error

Now i know why this kind of architecture does not work.

I assumed, that the properties specified in the service component definition of the ComponentFactory are passed as properties to the instance of the ComponentFactory. But, as DS spec. about Factory Components describes, only the properties component.name and component.factory are passed to the service. So the ShapeFactory could not determine the type the ComponentFactory is responsible for!

This property is not accessible for the component factory service!

And so the type will always be null.

The solution

Currently i am working on a nested component factory solution. It uses a service which provides some kind of IFactory. Implementations of the IFactory are using nested ComponentFactories to avoid the instantiation by new().

The solution should be probably finished next week. Then i am writing a new post about it.

If you have any suggestions feel free to post a comment. Any input is welcome!