Saturday, November 8, 2008

OSGi - Why do we need it?

I heard this question many times. I usually reply quickly in a few sentences, but I agree that OSGi deserves a more detailed answer.
Let's start with the basics. The Java Language Specification does not mention higher-level abstractions, like components. It follows the OO concepts, in which the highest level of abstraction is the class. Why is it important? There is a difference between a class and a component. A component specifies its provided and required interfaces, while a class is not able to do it. Of course, a class can contain public members that implicitly form a provided interface together (and we can extract them into a Java interface to make things more clear), but it is not a formal specification of a provided interface. Specifying the required interface is more problematic, it can only be extracted from the class using static analysis. It is far from being a formal specification, too.
This 'minor' weakness of the language makes real component-based development impossible without building an additional abstraction level at the top of classes and interfaces. We can call it a component model.
At the very beginning, Sun specified one called JavaBeans, but it was too simplistic and it was intended for building graphical user interfaces, not complex systems.
As Java became a mainstream language, complex tasks required sophisticated component models. It was the time when EJB was born. At the same time, many projects (Spring, PicoContainer, etc.) tried to address the same need in a lightweight fashion, but they all have two common problems: handling versioning and dynamic loading at component-level.
As the internet-boom was over, EJB lost popularity because of its complexity and price (application servers were very expensive at this time), and lightweight frameworks became more popular. OSGi was created at this time to address the same need, but it treated components as first-class entities (they called them bundles). This resulted in a complete component model that made component-based development possible. Furthermore, OSGi defines standard services, like logging, package management, etc. that simplifies the job of developers not wanting to reinvent the wheel.
There are some important consequences of having a good component model. First, a well-written component is reusable. With the introduction of component versioning, runtime library conflicts (JAR hell) can be eliminated. Second, component instances can provide services and this, together with dynamic component loading and component-level dependency management makes service composition possible.
To wrap it up: OSGi is a natural extension of Java, because of the nice component model and its dynamic nature. We really needed it for years when we were forced to manually handle all of the problems solved by OSGi in each and every project.

Monday, October 27, 2008

GITEX impressions


GITEX was finished last week. We were there as exhibitors to make our company's NFC-based products more popular. I think we were quite successful in it, but it's not what I want to say. I want to talk about a few interesting observations I made.
Perhaps the most important of these is related to the way we do presentations.
I had to get experienced that conventional demos are not very effective in exhibitions where we only have few seconds to raise interest. Forget about slides filled with textual information. Present an idea that can be visualized; a picture, a movie or a diagram, with only a few words. Remember the old saying "A picture is worth a thousand words."
My second thought is about documentation and brochures. Very few people want to read long descriptions, no matter how useful they are. Prepare a very short overview section in which you write about the most important things you want to express. In case you have more to say, the next section can contain more details. Then, at the end of the document, you may summarize the most important things once again in a separate section.

Tuesday, April 15, 2008

Architecture diagrams, once again

A few months before, I wrote a blog entry about architecture diagrams. I mentioned that UML can be used for describing architectural concepts, but I didn't write too much about that. Perhaps it was a mistake, because you might think, that UML is a good choice for these kind of tasks. Bu it's not.
To describe an architecture, we need a way to describe entire systems, not just components and connections. UML has deployment diagram, of course, but it lacks well-defined semantic meaning behind diagram elements. It means, that a deployment diagram is not an unambiguous description of a system, since different people assign different meaning to the elements of a diagram.
There are some more formal approaches, like FMC (Fundamental Modeling Concepts). Its concepts are nice and well-founded, but only a few people use it, unfortunately.

Saturday, March 29, 2008

Textual DSLs and diagrams

While it seems fairly trivial to generate the graphical representation of a model built using a textual DSL, many people (including me, until now) do these two steps (modeling and diagramming) separately. Perhaps they don't know about tools that can greatly simplify this task like Graphwiz. It is really a very nice tool. Using a simple textual DSL provided by the tool for diagramming, wide range of graphs can be generated, even very complex ones. Lets see a concrete example:

digraph Components {
Container [shape="box"];
Component [shape="box"];
Port [shape="box"];
Service [shape="box"];
RequiredService [shape="box"];
ProvidedService [shape="box"];
Interface [shape="box"];
Container -> Component [label="manages", headlabel="*", arrowhead="open"];
Component -> Port [label="has", headlabel="*", arrowhead="open"];
Component -> ProvidedService [label="provides", headlabel="*", arrowhead="open"];
Component -> RequiredService [label="requires", headlabel="*", arrowhead="open"];
ProvidedService -> Service [arrowhead="empty"];
RequiredService -> Service [arrowhead="empty"];
Port -> RequiredService [label="points to", headlabel="*", arrowhead="open"];
Service -> Interface [label="defined by", arrowhead="open"];
}


and here is the generated diagram.
So my point is, that (with minor modifications on the templates used for code generation) nice diagrams can be generated; there is no need to use a separate diagramming tool for these kind of tasks.

Thursday, March 27, 2008

Components and Java classes

People often misuse words that have a well-defined meaning. This is the case with the word "component" which is often used as a synonym for a Java class. In reality, these artifacts are very different. Component is an architectural concept whereas the Java class is an implementation artifact that can be part of the programming model, but might not be used in the conceptual architecture. Moreover, the Java language has no notion of component, so components can poorly be represented using only the elements of the language, without annotations or external configuration (but remember, these are not part of the language, only extensions to it).
Let me explain that briefly. Components should express their inter-dependencies, so every component has to declare its provided interface and required interface (these are not Java interfaces, only architectural level concepts).
In Java, a class can declare its provided interfaces (these are the implemented interfaces), but can't declare its required interfaces explicitly, since there is no language element for it. Only implicit declaration is possible, but it may not be enough if we want to express component dependencies in the programming model.

Thursday, March 20, 2008

JUM 6

The 6th JUM meeting has been held yesterday. There were two presentation about appservers and Flex, and I gave a talk about Java component models. I talked briefly about the basics (component, component model, component framework, Dependency Injection, Dependency Lookup) and about some concrete component models and frameworks (SCA, Spring, OSGi, Guice, JSR277) and their interoperability (Spring-DM, Guice-OSGi, Guice-Spring). Here are the slides (only in Hungarian).

Wednesday, March 12, 2008

Dumb value objects

What sometimes really bothers me is that many programmers overuse value objects. They do it despite the fact that this concept is over-simplified for many tasks. And they even implement the accessors as dumb wrappers around the values, leave the checking of values for the callers, which is mostly a silly thing.
My point is that we should talk more about this kind of design. My 10 cents:
  • Read about domain objects and try to understand the concept. It's easy.
  • If you need value objects, implement their accessors in a way to check the accessed values and throw exceptions (in Java, I prefer runtime exceptions such as IllegalArgumentException or IllegalStateException) if the pre-defined constraints are not satisfied.
  • Think about concepts at higher abstraction level than data (objects, components etc), before you implement things.

Friday, March 7, 2008

Podcast about software components

The guys at Software Engineering Radio have recorded a very good podcast about software components and component-based architectures. It's worth to listen to.

Saturday, March 1, 2008

Architecture, again

Last time I blogged about architectural diagrams. Now, a very good article appeared on InfoQ from Markus Völter. In the article he is focusing on the creation of a language used to describe a conceptual architecture and provides an overview about DSLs.

Wednesday, January 30, 2008

Bad style - Architecture Diagrams

Plain boxes linked with each other using lines; these kind of diagrams are fine to explain many things - until they are called "architecture". It is a wide-spread misconception, they are just plain diagrams, until they meet the requirements of an architecture diagram. But wait a minute. What are these requirements?
There are many definitions of software architecture. I don't want to go into the details of software architectures, many people did this before (read the POSA books or this, this and this). Instead, I'd like to discuss some of the most important properties of good architecture diagrams.
The first is an unambiguous language (in this case, graphical notations, but the architecture description can be textual as well) the architecture is expressed in. Completeness (remember: component, interface, connector, configuration) is also important. This language should be well-defined with respect to its syntax (the set of notations used) and semantics (the meaning of the notations and language constructs).
It can be very helpful if the graphical notations of the language are based on well-known graphical notations, such as the elements of UML component or class diagrams.
The diagrams must reflect the architectural decisions (which are based on requirements, of course) and they should be organized around architectural aspects and/or viewpoints. This is the most important thing.
The layout of diagrams should emphasize the architectural configuration. Position and connections of each element in every diagram should be in sync with the architecture. For example, a diagram should not show layers or partitions where they don't exist.
And that's enough for start. If a diagram is made with these things in mind, it is an architecture diagram.

Thursday, January 24, 2008

OSGi and DynamicImport-Package

Last week I refactored an old Spring-based application to be OSGi-based. First I created some bundles of it. It was a pleasure, I really like the Eclipse plug-in development tools, but it's not what I want to talk about.
One of the classes from the legacy app used dynamic class loading via Class.forName(). This class was a factory used to load other classes reside in many bundles. It is perfectly legal, but in order to load a class, the class loader of the bundle must be able to find it. This can be done nicely with "Import-Package: package.of.the.class.to.be.loaded". Of course, someone must export this package using Export-Package. But what happens when the factory class is referenced from the bundle exported that package? The answer is simple: circular dependency. You may say that it is a non-issue and can be solved easily using DynamicImport-Package, but lets think about that for a moment. What are the architectural consequences of such a decision?
Importing a package means you are about to create dependency to the bundle exporting that package. So even if your importing bundle works perfectly fine without the other (exporter) bundle, the exporter must also be deployed in order to satisfy the dependency.
Moreover, exporting means that you expose internals of the exporter bundle that are not part of the service's API provided by this bundle. By doing this, you may experience compatibility issues when you change the internals of this bundle in the future, even if the service API remains the same.
With the above in mind, I decided to refactor the affected bundles to eliminate circular dependency instead of just "work around" the problem using DynamicImport-Package.
To wrap it up: I suggest you to think about the architecture first and use DynamicImport-Package if you really need it.

Monday, January 14, 2008

OSGi and the infamous class loading problems

I just fought my fight with OSGi and JCL (Jakarta Commons Logging). I was porting an old Spring-based app to OSGi+Spring-DM, so I tried to use commons logging in my bundles. This ended up getting a nice exception:

org.apache.commons.logging.LogConfigurationException:
java.lang.NoClassDefFoundError (Caused by
java.lang.NoClassDefFoundError)
...

So I refactored all of my bundles to use the OSGi LogService instead of JCL. Re-deploy, start ... and no change. After some googling I found an interesting article which explained that JCL uses a custom class loading scheme which does not cause problems in standalone applications, but shows this weird behaviour under an OSGi environment. The article pointed to another logging framework (SLF4J) which provided a nice solution for the problem. A few lines from my config.ini:

jcl104-over-slf4j-1.4.3.jar@start,\
slf4j-simple-1.4.3.jar@start,\
slf4j-api-1.4.3.jar@start,\

And that's all. So please do not use JCL unless you want to bang your head against the wall.

(This madness drove me to an OSGi-related rule of thumb: if something looks suspicious around your bundles and you have no idea what's wrong, you may have a class loading issue.)