Thursday, December 18, 2008

EclipseCON 2009 Riena - EMF - oAW and more

This time I'll not only visit the eclipseCON - one of my submissions was accepted:



I'm very happy about this. This was the second really good news last time - first was at german W-Jax where I became a member of the oAW Team.

redView (Riena - EMF - Dynamic View) is a sub-project of my model-driven OSGI Enterprise Application. redView  will be Open Source (EPL). Dynamic views from redView can be used stand-alone or in combination with openArchitectureWare (oAW).  ... I'll talk more about this next weeks 

This week was a heavy update - week: 

  • OSX 10.5.6
  • MagicDraw 16.0
  • openArchitectureWare 4.3.1RC3 und RC4
  • Riena M6
  • EasyBeans 1.1.0 Snapshots
Thanks to EasyBeans - Team (they added some properties for Declarative Services) I can continue my work to switch from ServiceTracker to Declarative Servics (DS) and there'll be new blogs also coming soon.

stay tuned...

ekke
BTW: dont wonder if my submission 391 has no author. I tried to add my assistant as co-author, got an error and now the submissions has lost author and assistant. reported a bugzilla...

Wednesday, December 10, 2008

Logging in OSGI Enterprise Applications, Part 6

This part of my blog series "Logging in OSGI Enterprise Applications" will talk about openArchitectureWare 



...and logging with SLF4J / LogBack.


The previous blog entries from this series described logging from the Runtime of an OSGI Enterprise Application. The whole Client / Server Project is model-driven based on Eclipse Modeling Project: EMF, UML2 and as engine the generator framework openArchitectureWare. 


The MDSD - aspects of the application will be part of another blog series.

Now we want to take a look at logging with SLF4J / LogBack while working with openArchitectureWare.

openArchitectureWare (oAW) in Target Platforms

If you want to use oAW in a Target Platform with SLF4J / LogBack as Logging Framework together with bridges to Commons Logging and Log4J, you'll notice some problems: Many of the oAW bundles are using Require - Bundles instead of Import - Packages as dependency to logging bundles.



I opened a Bugzilla, but it seems its too late for 4.3.1.

If you need it now, thanks to PDE its easy: Import Bundles in your Workspace, change Dependencies to Import Package, then export the Bundle als Plug-In again.

openArchitectureWare (oAW) Workflows

There's an own Launcher for oAW Workflows (Run Configurations | oAW Workflow) - we have to change the Classpath:


Click on User Entries and then Add Projects...


...choose the Logging - Projekts from workspace


...and save changes with Apply.

You have to put the logback.xml (or logback-test.xml) directly under src/ into the project which starts the oAWworkflow. In this xml file we configure the logging from the workflow - doesn't matter if the logoutput was originally sent to Log4J, Commons-Logging or OSGI LogServices.

To control please start a Workflow with debug="true" in your logback.xml.



If all is configured right, then the Console will list at first the logback - configuration and then all log - output from the Workflow sent to our configured Appender (Console, Socket, usw)


Blog Series "Logging in OSGI Enterprise Applications":

Part 1: An overview
Part 6: Logging and openArchitectureWare Workflows
Part 7: ... follows (Stay tuned...)

Perhaps some of my older blogs about Logging und OSGI are also interesting:




Comparing Files And Folders After Codegeneration

Eclipse has great possibilities to compare files and folders with each other or history.
But I'm also using external tools: 

Some time ago I blogged how to use NameChanger (Freeware) under OSX to rename files where the bundle names aren't named like eclipse bundles (plug-ins) using "name_version".

Also for creating of target platform - locations I'm using a tool to get unique sets of bundles. My blog „Avoid Duplicate Bundles“ desribes the use of FileMerge (under OSX part of XCode Tools).

Now I was looking for an intelligent tool to see if generated code is identical to an older version. This generated code is not checked into a sourcecode repository, because its always regenerated. Before starting the generation those directories werde cleared, so there's also no local history in Eclipse.

While testing 4.3.1RC2 of openArchitectureWare I was interestd to see if the generated code is identical to version 4.3.0.

Its not so easy because there are some allowed differences like:

* generation started at: 9. Dezember 2008 08:04:13 CET

Those generation timestamps should be "identical" to lines with another timestamp. FileMerge from OSX was no help, because these files are reported as different.

Next try: Compare Folders compares the size of files and also reports added or missing files. If the generation timestamp hase same length, then the files are identical otherwise not: 



... I also dont know if the other content is identical - I need the compare more detailed. I found DeltaWalker where I can do waht I want. But the best of all is:

DeltaWalker is an Eclipse RCP Application :-)

...and available for OSX, Windows, Linux. Now it was easy to see if the generated code is the same as before:

Create a File - Filter, where lines of different generation timestamps are identical:



Create a Folder- Filter ignoring OSX-specific .DS_Store Files:



Then hitting Compare::



All the same :-)

congratulations openArchitectureWare 


- in all my projects no differences found between 4.3.0 and 4.3.1RC2 after re - generation.

Without the File - Filter DeltaWalker lists the differences:



...think that DeltaWalker will be a good helper and a great example for RCP Apps.

Thursday, December 4, 2008

Properties in OSGI Declarative Services and ServiceTracker

As proposed in my last blog "Dependencies and Services in OSGI Enterprise Applications" it seems that a new blog series was started ;-)

ServiceTracker vs Declarative Services

There was only a short statement last time - now some tips follow how to use properties in ServiceTracker vs Declarative Services (DS).

A ServiceTracker from my OSGI Server project was opened with this Filter: 

final String filterPool = "("
+Constants.OBJECTCLASS
+ "="
+ JDBCPoolComponent.class.getName()
+")";

So the ServiceTracker will get Services of Type JDBCPoolComponent - we are interested into the attribut JndiName:

private void processDataSources(JDBCPoolComponent service) {
  if (service.getJndiName().equals("foo_entity_data_source_hsql")) {
  // do something
  }
}

How could this be done using Declarative Services (equinox.ds): 

We're defining a reference to get exactly one specific service of type JDBCPoolComponent to know that a DataSource is ready. 

A first idea to declare this reference could be:


Launching the OSGI application, but the reference wasn't resolved. 

How could we find the reason ? At first we should test if the Filter is correct and there's no typo in the Interface.

Tip: Use of Equinox OSGI Console to test the Filter !

Try this command:

services (&(objectclass=org.ow2.easybeans.component.jdbcpool.JDBCPoolComponent)
(jndiName=foo_entity_data_source_hsql))

But no Service was found: No registered Services.

As next we try only to look for Services of Interface JDBCPoolComponent. Now our command looks like: 

services (objectclass=org.ow2.easybeans.component.jdbcpool.JDBCPoolComponent)

Some Services were listet - we also see the one we're looking for:

{org.ow2.easybeans.component.jdbcpool.JDBCPoolComponent}={classname=org.ow2.easybeans.component.jdbcpo......, xmlconfig=
  Registered by bundle: .../easybeans-component-jdbcpool_1.1.0-M3-SNAPSHOT.jar/

Analyzing the printed text we found: jndiName="foo_entity_data_source_hsql"
But there's a small difference: its the Property xmlconfig containing the informations. Thats the solution:

services (&(objectclass=org.ow2.easybeans.component.jdbcpool.JDBCPoolComponent)
(xmlconfig=*foo_entity_data_source_hsql*))

The Service we want to reference will be found and we know how to declare the reference inside the Service Component:



Why can the ServiceTracker use  getJndiName(), but the target Filter can't ?
getJndiName() is a Methode of JDBCPoolComponent, but JndiName isn't registered as Service Property ! 

Target Filter cannot access methods of implementation - only Service Properties. 

You maybe run into this using 3rdParty bundles where you have to live with their services as-is. If you're in luck its Open Source, you write a Bugzilla or JIRA and get it fixed in hours :-)

Remark:
You can take a look at my blog series about "OSGI Enterprise Applications" - the index is in the column right beside this blog.
There are also some submissions for EclipseCon 2009 - if you want to hear more about: comments are welcome ;-)


blog in german

Tuesday, December 2, 2008

Dependencies and Services in OSGI Enterprise Applications

A busy week has started again:
  • Refactoring my OSGI Enterprise Server: Using Declarative Services instead of ServiceTracker where possible. (I'll report soon in my other blog series)
  • openArchitectureWare 4.3.1RC1 is published and has to be tested against my many modeling templates
  • Some more tests using Eclipse 3.5M3: PDE - supporting Declarative Services and  Cycles in 3rd Party Bundles
  • Development of a new soon-coming project: redView (Riena - EMF - Dynamic Views) and integration of these dynamic view models into my modeling workflow

But now lets start and report some of my experiences of:

Dependencies and Services in OSGI Enterprise Applications

If you follow my blog series „HowTo Build an OSGI Enterprise Server“, you probably have read in the last entry that its difficult to use a ServiceTracker with much logic and dependencies inside. Its not so hard to make it run, but hard to manage all the dynamic of an OSGI application. So the next task is to use Declarative Services instead as possible to solve the requirements. While working in this area I noticed some points I want to blog about.

PDE Tooling

This is really the first what happens: you'll miss the comfortable PDE tooling.
You have to describe the service components in a XML file without support:


... and also an entry in the MANIFEST.MF as reference to this file:


Good news: Dopwnload and test Eclipse 3.5M3: PDE Tooling supports now Declarative Services :-)



Managing Dependencies

Under OSGI the management of dependencies is very important and fundamental to get a well structured application achitecture.

We already know dependencies using Import-Package or Require-Bundle. We can also look at these dependencies from inside eclipse.

The classic way as Plug-In - Dependencies:



or the easy to understand visuell way:

(here's the Updatesite from Graph Visualization Plug-In)

But bundle - dependencies are only one part - we're missing the service - dependencies

If you look at the DataSource example from above:


There are no more bundle dependencies ? Indirectly we have dependencies from Declarative Services: The DataSourceService will only be provided if exactly one service of Type Ejb3ServerComponentsService and one service of type JDBCPoolComponent is available. These two referenced services are declared in two other bundles.

If our declarative Service Component would include bind / unbind methods, then we would have Import-Package dependencies.

Till now I couldn't find a tool displaying service - dependencies in a visual graph.

And if you think more about service - dependencies: there are some different strategies to use services and you can even mix them in one application:


As an Software Architekt I like to get an overview of used Bundles, Services and dependencies. Because there's no tool to show the existing dependencies I'll come the way from another direction: my server project is model-driven, so I can model service - dependencies and -strategies :-)


using openArchitectureWare I'll then generate service - components in XML - files or Javacode for ServiceTracker or Riena - Injection ...

This will be part of another blog ;-)


debug - trace - log Declarative Services

While refactoring my project of course from time to time I reached a point asking why a specific declarative service reference is not resolved from eqinox.ds ;-)

With the help from Equinox - Newsgroup and some searches I learned some important System Properties I didn't found in the Eclipse Help or Equinox Wiki:

  • equinox.ds.debug=true switch debugmode on 
  • equinox.ds.print=true prints the trace-logs on the console. I dont need it because I catch the OSGI LogServices and log them by myself.(s.a. blog series Logging)
  • equinox.ds.perf=true logs the execution times in ms
  • equinox.scr.waitTimeOnBlock=10000 how many ms should equinox.ds wait until a service component is ready. Was very helpful because 10000 ms is default and some  3rdParty components need more then 50000 ms in DEBUG log - mode.


ServiceTracker vs Declarative Services

Can a Service Tracker completely be replaced by Declarative Services ? No - this isn't always possible. 
One example: Using a ServiceTracker you can get access to all methods of a service - using Declarative Services instead you can only use service properties in target - filters.


...enough for the first blog about Declarative Services - there are so many things to talk about in this context, so I can imagine to start a blog series about this - but at first I have to finish the already started blog series ;-)

You can take a look at my blog series about OSGI Enterprise Applications - the index is in the column right beside this blog.

There are also some submissions for EclipseCon 2009 - if you want to hear more about: comments are welcome ;-)


blog in german

Friday, November 21, 2008

HowTo Build an OSGI Enterprise Server: EasybeansServiceTracker

We've seen that its not easy to use EasyBeans OSGI - you have to be very carefully how to start bundles, watch many dependencies etc. So we created a „Server - Agent“ - bundle to control and manage these tasks.

This „Server - Agent“ - bundle contains an EasybeansServiceTracker we'll discuss now. 

At first we must be sure that all EasyBeans Components are started - there's an easybeans.agent bundle controlling this. EasyBeans Components are:


Which of these EasyBeans Components you need depends from your reqirements - in this blog series we'll only look at the EJB3 Container.

One component is important in our use case: JDBCPool registers data sources as JNDI names and this must be done before EasyBeans can manage the "EJB - bundles".


If we're sure that all EZB Components are registered and also the JDBCPool Component has registered all data sources, then we can start our  „PersistenceContext - Bundles“ and „EJB - Bundles“. 

While creating an EJB3 - Container for each of our „PersistenceContext - Bundles“ and each of our „EJB - Bundles“ EasyBeans registers for each Business - Interface (@Local, @Remote) a ManagedService. The EasybeansServiceTracker tracks all Remote - Business - Interfaces and registers them as Riena Remote Endpoints.

When the EJB3 Container is completed from EasyBeans - an EZBContainerService will be registered. After checking that EZBContainerServices are registered for all of our EJB - Bundles we can register the RienaEasyBeansServerService: our Server it ready.



EasybeansServiceTracker

You'll have some logic like this in your Tracker:



Is the use of a ServiceTracker the best solution ?

At first it looks good to have all the logic around the EasyBeans EJB3Container at a central point in our EasybeansServiceTracker - and it works well.

Analyzing it in more detail you'll find out that its very complex and difficult to manage - even thinking on multi-threading. Also: does it look like the nature of a dynamic and flexible OSGI solution ? How to react if bundles or services are stopped and started again ?

But there's an alternative way: we'll look again how to solve the EJB3 - Container in our OSGI Enterprise Application using Declarative Services. Then you can decide what you prefer to use: ServiceTracker or Declarative Services.

There's an this index of this blog series in the column right beside the blog entries.


blog in german.

Monday, November 17, 2008

Going to Eclipse Summit

Same procedure as every year going to Eclipse Summit or EclipseCon:

Because my OSGI Enterprise solution needs it all:
Equinox, OSGI, Riena, RCP, Modeling (oAW, EMF, UML), UI, PDE, P2, ....

...its so hard to decide which of the sessions to choose ;-)

I'll arrive Tuesday evening - so I can't go to the e4 and RT Symposium

Hope to see some of you in Ludwigsburg

ekke

HowTo Build an OSGI Enterprise Server: EJB3 Container

This entry of my blog series „HowTo build an OSGI Enterprise Server“ will talk about the „EJB3 Container“ managed by EasyBeans. EasyBeans uses by default Felix as OSGI Framework - this blog series describes how to use it all under Eclipse Equinox together with Eclipse Riena.

You have to follow some rules how to start the OSGI application: start - levels, start - order, automatic-start ... Please read important instructions in chapter „Server starten“. A short overview:



Our OSGI Enterprise application automatically starts a „Server Agent - Bundle“ - this agent contains an OSGI Service Tracker watching if EasyBeans initializes all EJB3 Container to see when all is ready.

We also start our domain-specific „Server Bundles“ which are tracking to see if our ServerService is registered from „Server Agent“ Bundle.


Server - Agent - Bundle and Server - Bundles




Our (domain-specific) „Server - Bundles“ and the „Server - Agent - Bundle“ are started automatically using Default - Start - Level (in our example Level 3).

The „Server - Bundles“ are waiting until a RienaEasyBeansServerService signals, that our Server with Riena- and EasyBeans - Functionality is available.

The most important dependencies of our „Server - Agent“ - Bundle:



The „Server - Agent
  • tracks Services from EasyBeans using an EasybeansServiceTracker
  • registers Remote - „Business - Interfaces“ for Riena - Remoting
  • registers RienaEasyBeansServerService when or server is available

EasybeansServiceTracker - Filter

An OSGI ServiceTracker should only track needed Services - so we have to define a Filter used as Parameter creating a new ServiceTracker. The Filter:

(|(objectClass=org.osgi.service.cm.ManagedServiceFactory)(objectClass=org.ow2.easybeans.api.EZBContainer)(objectClass=org.ow2.easybeans.component.jdbcpool.JDBCPoolComponent)(service.pid=*RemoteManagerI*Bean))

What kind of OSGI Services we'll get using this Filter ?


ManagedServiceFactory:

EasyBeans registers for each EasyBeans Component a Service of Type ManagedServiceFactory:

{org.osgi.service.cm.ManagedServiceFactory}=
{service.pid=org.ow2.easybeans.component.carol.carolcomponent,..
Registered by bundle:
...easyBeans/bundles/easybeans-component-carol_1.1.0-...jar
Bundles using service:
.../org.eclipse.equinox.cm_1.0.0.v20080509-1800.jar
.../org.ekkehard.server.agent_1.0.0.jar

Tracking these Services we can test if all EasyBeans Components are correct initialized.

EZBContainer:

After successfully processing our „EJB - Bundles“ and „PersistenceContext - Bundles“ from EasyBeans a Service of Type EZBContainer is registered:

{org.ow2.easybeans.api.EZBContainer}={service.id=103}
Registered by bundle: .../org.ekkehard.foo.datamanager.bean_1.0.0.jar
Bundles using service:
.../easybeans-core_1.1.0-M3-SNAPSHOT.jar
.../org.ekkehard.server.agent_1.0.0.jar

Tracking these Services we know, that EasyBeans has created an EJB3Container for our Bundle - and if its a „PersistenceContext - Bundle“ then we also know, that Hibernate has done all the Mapping and Binding.

JDBCPoolComponent:

EasyBeans JDBCPoolComponent registers always after initializing a DataSource an OSGI Service of Type JDBCPoolComponent:

{org.ow2.easybeans.component.api.EZBComponent,
org.ow2.easybeans.component.jdbcpool.JDBCPoolComponent}=
{... jndiName="foo_data_source_hsql"....

Using the Property jndiName we can test if our DataSource is available.

service.pid:

We also filter Services containing a service.pid of our pattern for Remote - Business - Interfaces: „*RemoteManagerI*Bean“. The pattern depends from your naming schema.

Tracking those Services will give us OSGI Services of Type ManagedService. The we do some additional testing to see if some Properties are set from EasyBeans. If true, we know that its a ManagedService created by EasyBeans for one of our @Remote - „Business - Interfaces“.



Now we can register this @Remote - „Business - Interface“ for Riena Remoting, to provide a Riena Published Endpoint for our Rich Clients.

This is also the reason why the „Server - Agent - Bundle“ needs Package-Import-Dependencies to our „Business - Interface - Bundles“ - if you dont use Riena, then you dont need these dependencies.


RienaEasyBeansServerService

If all tracking was successfully, then our „Server - Agent - Bundle“ registers an RienaEasyBeansServerService as OSGI Service. Because this Service will also be registered as Riena Remote Endpoint, our „Server - Bundles“ and also our „Rich Client - Bundles“ can track if the Server of a specific domain is live and ready-to-go.

When knows the „Server - Agent“ that all was successfully processed ?
  • All EasyBeans Components are initialized
  • All DataSources are avilable
  • All EJB Container are available
There are some special tricks how to track and test and start bundles - but this will be part of the next blog.

There's an this index of this blog series in the column right beside the blog entries.

blog in german

Wednesday, November 12, 2008

HowTo Build an OSGI Enterprise Server: Entity- and EJB- Bundles

This part of the blog series „HowTo build an OSGI Enterprise Server“ will take a look at the different types of bundles we provide to the EJB3 container. The next chapter „EJB3 Container“ will show you how to use an OSGI ServiceTracker to start and initialize all the right way.


How to divide Entities and EJBs in Bundles

BTW: you should have knowledge about EJB3 and Annotations. The structure used in this server is only an example and your implementation perhaps is different. We can talk about these issues later after publishing source code. Also you can use Eclipse Link as JPA provider instead of Hibernate - EasyBeans can work with both.

We're using following types of bundles:

  • Entity - Bundles
  • EJB - Bundles
  • PersistenceContext - Bundles 
  • Business Interface - Bundles 


Entity - Bundles

@Entity, @Embeddable
You can use as much Entity - Bundles as you want - perhaps structured vertical for your different domains. These Entity - Bundles will also be used from our Rich Client, so - if you have bundle dependencies only used at server-side, make them optional.


EJB - Bundles

@Stateless and  @Stateful Beans, implementing Business - Interfaces (@Local, @Remote) depending from your requirements. 
These Bundles have dependencies to your Entity - Bundles and to the Business - Interfaces. 
Other EJBs from your PersistenceContext - Bundles can be injected like:
@EJB(mappedName) Business - Interface
The EJB - Bundles will not be used from Rich Client.

Remark: mappedName must be used at the moment, EZB cannot found the corresponding Business - Interfaces, if they are in different bundles (JIRA EZB-322)


PersistenceContext - Bundles

@Stateless Beans, containing a PersistenceContext (EntityManager) and - depending from your use-cases - implementing Business - Interfaces (@Local, @Remote).
@PersistenceContext(unit-name) points to your Persistence - Unit.
Each PersistenceContext - Bundle has a persistence.xml with attributes for the persistence-unit and also jta-data-source.
PersistenceContext - Bundles need package-imports of the used Entities and  implemented Business - Interfaces.
PersistenceContext - Bundles will not be used at Client-Side.

Remarks: 
  1. All EJBs, belonging to a peristence-unit, must be in ONE bundle at the moment. (JIRA EZB-294)
  2. The Beans must have an EJB3.mappedName attribute: @Stateless(mappedName), otherwise because of a bug from EasyBeans (JIRA EZB-322) injected @EJB won't found them.
  3. Inside the persistence.xml all Entity- and Embeddable must be listed as class entries. EasyBeans should found the classes itself because of Annotations, but there's a bug if Entities and EJBs are in different Bundles.


Business Interface - Bundles

@Local, @Remote
The Business - Interface - Bundles can be structured and separated as you want - perhaps for different sub-applications or domains or...
These Bundles will also be used from your Rich Client.


EasyBeans Configuration

EasyBeans needs some configuration - data. If you're using an OSGI Framework Configuration you can add a VM argument: 
-Dorg.ow2.easybeans.osgi.conf.dir=${workspace_loc}/config/easybeans/config 
In this config folder you must store the easybeans.xml.
This easybeans.xml contains jdbcpool jndiName entries for each of your  Data - Sources. These values are identical with the jta-data-source, described at your  Persistence Unit inside persistence.xml of our PersistenceContext - Bundles.


Remark: The EasyBeans JDBCPool - Component must register first all Data - Sources, before you can start your PersistenceContext - Bundles. s.a. chapter „EJB3 Container“ for details on this.


openArchitectureWare - always can help if you're in trouble

This project is model-driven - details about it will be described in another blog series. Here are some small examples showing you, why I never will miss  openArchitectureWare in a project lead by me.


EasyBeans should recognize @Entity and @Embeddable automagically because of annotations - but it doesnt work through borders of bundles, so all @Entity and @Embeddable - classes have to be listed in your persistence.xml - in my ERP project this means more then 800 classen - and the data model isn't static and grows or changes depending from new use-cases and requirements.

But thanks to openArchitectureWare (oAW) we only need some lines in a template to get the needed output into the persistence.xml:

automatically all was generated from oAW and is in sync with your entity data model:

Another example: EasyBeans should be able to inject @EJB MyBusinessInterface correctly. But because of a bug this isn't possible if Business Interfaces are in another bundle and so we need the @EJB.mappedName attribute.

But with oAW its also easy: insert some text into a XPand - Template to add this attribute:

... and in your Business Interface:

Now all Beans get the mappedName attribute, the Business Interfaces get a Constant with this mappedName so you can inject easy:
@EJB(mappedName = MyInterface.EZB_MAPPED_NAME) MyInterface mi = null;

These are positive side-effects of model-driven development: developing of workarounds in hundredrs of classes are funny ;-)

BTW: my whole complex ERP - project would not be possible to be realized from me alone without oAW. You'll hear more about this in another blog series - and of course its your decision if you work model-driven or not - I only can show you my way of working.

 
 blog in german.

Tuesday, November 11, 2008

HowTo Build An OSGI Enterprise Server: Introduction

If you followed my blog series „Logging in OSGI Enterprise Applications“, you probably know that logging is only one small but important aspect of an OSGI Enterprise Server.

This new blog series „HowTo Build An OSGI Enterprise Server“ will give you tips from my experiences how to build and configure an OSGI server, how to structure your project and bundles and how to make it all run.

Main parts of the server are:

  • Equinox (OSGI Framework)
  • Riena (OSGI RemoteServices, ObjectTransactions)
  • EasyBeans (OSGI EJB3 Container, Hibernate JPA)

There will also be a rich client:

  • Equinox (OSGI Framework)
  • Eclipse RCP
  • Riena (OSGI RemoteServices, ObjectTransactions, UI: Ridgets) 

(Clients for mobile devices and web will follow.)

Not only the Runtime Platform is important - the whole project is model-driven:

  • Eclipse Modeling (EMF, UML2)
  • openArchitectureWare - oAW (Workflow, XPand, Xtend)
  • Magicdraw (UML, DSL, oAW Integration)

Server, Client, oAW Templates, MagicDraw Custom DSL Editor will be published as Open Source (EPL) and are used as core of an ERP - Business Solution.

Before giving an overview of the project and then start with chapter „Installation“ I'll jump to chapter „EasyBeans as OSGI EJB3 Container integrated with Equinox“ because I know some are waiting for this.

From readers of my last blog series I learned that its not always easy to read the entries in right order - to help you I'll always update an index of the blog series. You'll find this index in the column right beside the blog entries.

I hope to help some others with this new blog series and I'm always thankful for your feedback.

Later on blog series will follow "HowTo build an OSGI Rich Client" and also "Modeling OSGI Client - Server Applications". 


 blog in german.

Friday, October 31, 2008

Index BlogSeries Logging in OSGI Enterprise Applications

I got responses that its not easy to read the blog series
"Logging in OSGI Enterprise Applications" in chronological order.

So here's the index:

Logging in OSGI Enterprise Applications, Part 5

This (fifth) part of my blog series "Logging in OSGI Enterprise Applications" will show you some important elements of configuring the logging framework LOGBack we use as SLF4J implementation:


I dont want to talk about the configuration of a logging framework itself - you should be familiar with this. If you're using LOGBack inside an OSGI Enterprise Application there are some special things to watch and problems to solve.

If we're logging in a non-OSGI Java Application we normaly want to know which class logs the event. Logging from an OSGI Enterprise Application its also important to know which bundle causes the LogEvent. Using OSGI LogServices you also have this information from BundleContext..

Its a good practice to name the Logger with the class name - normaly as static Logger defined in each class. This works with all logging frameworks like Log4J, Commons-Logging, java.util.logging or SLF4J.

Using SLF4J as Logging API you can also describe the source of the Log Event more detailed with:
  • MDC (Mapped Diagnostic Contexts)
  • Marker 

MDC is implemented by Log4J and LOGBack. MDC is great to store informations from a client user session: per ex. Username, IP etc. Its a Map and you're free to store what you like. To  access these informations in the Layout of an Appender is easy: 
    ...N:%X{username}... 
produces
   ...N:JohnDoe...
The LOGBack User Manual chapter 7 (here) explains it in detail and gives you some examples.

Marker and Bundles

Marker are part of the SLF4J API and they mark (as the name says ;-) Log Messages. At the moment only LOGBack implements Marker.  
From the MarkerFactory for a given String we always get the same Marker: 
    Marker marker = MarkerFactory.getMarker("MyMarker");

Marker can reference other Marker - so you can build an object graph of Marker:
    Marker special = MarkerFactory.getMarker("special");
   special.add(MarkerFactory.getMarker("init"))

In our OSGI Enterprise Application we're using Marker to log the Name of the bundle.


For each bundle we define once (per ex. in the Activator):

    private static final Logger logger = LoggerFactory.getLogger(MyActivator.class);
    public static final String ID = "my.bundle.symbolic.name";
    public static final Marker bundleMarker = createBundleMarker();
    private static final Marker createBundleMarker() {
        Marker bundleMarker = MarkerFactory.getMarker(ID);
bundleMarker.add(MarkerFactory.getMarker("IS_MARKER"));
return bundleMarker;
    }

In all the other classes of a bundle we define:

    import static MyActivator.bundleMarker;
    private static final Logger logger = LoggerFactory.getLogger(Foo.class);

Then the logging statements are looking like:

    logger.debug(bundleMarker,"This is my {} message",xyz);

Remark: LOGBack replaces {} with xyz. toString(). More details later.

To get the marker in the logging - output we can simply use
    ... %marker ... 
in the Layout of an Appender. 

In our application we want to test if a Marker is a BundleMarker and then handle formatting the output different, per ex.: 
    ... - [B:my.symbolic.bundle.name] ...

To do this we have to extend ch.qos.logback.classic.pattern.ClassicConverter and overwrite the methode public String convert(LoggingEvent le).

In our LOGBack configuration (logback.xml or logback-test.xml) we have to insert a new ConversionRule:


then we can use it in the Layout of an Appender:
    ... %bundle ...
and we get as output
   ... - [B:my.symbolic.bundle.name] ...
or an empty String if the Marker is no BundleMarker.


Fragment Bundles

But thats not all - because the logback.classic Bundle doesnt know our BundleConverter class we need a Fragment-Bundle:


You remember: We already use another Fragment to use our configuration file from Logback Core Bundle:



Remark: perhaps you have noticed that the Manifest files above are using logback Version 0.9.11: there are new versions of SLF4J (Download Version 1.5.5) and LOGBack (Download Version 0.9.11). Because at the moment they are not found from SpringSource EnterpriseBundleRepository we have to build them by ourself. How to do this is explained in part 2 of this blog series.

Logoutput twice

It looks so good: we catch all LogEvents from all Logging Frameworks used from other Bundles and also from OSGI LogServices. But it can happen that you found some messages twice in your log output. What happens ? If you're using per ex. Eclipse Riena M4 you got messages twice:

Riena uses Listener to catch OSGI Logservices and logs them using Log4J. Log4J will found the way to our SLF4J / LOGBack implementation. So long so good.
But our own Logging Bundle org.ekkehard.osgi.over.slf4j also catches OSGI Logservices and loggs them using SLF4J / LOGBack.
And now we got some messages twice.

The good news first: in some days Riena will publish Milestone M5 and then you should be able to switch these Listeners from Riena-Logging off.
Because it can happen every day again using other 3rdParty bundles, here's the solution. We need an entry in our LOGBack configuration file logback.xml:


This will hide those output from org.eclipse.riena

Riena uses Equinox Extended OSGI Logservices, which contain an own Logger. We catch those ExtendedLogEvents and log the message using the Loggername from ExtendedLogEntry. To distinguish Logging - Output from our Listeners we add a prefix:


Now we know where the Logging - Output comes from and as a side-effect its easy to log all LogEvents originally logged from Equinox ExtendedLogServices per ex. at DEBUG Level:


Here's an example logging output catched by our Listener and logged to LOGBack:

23:25:41.846 DEBUG [X.o.e.r.c.publisher.ServicePublishBinder] - [B:org.eclipse.riena.core] service endpoints count: 792

ExtendedLogEntry uses this as Loggername:
    org.eclipse.riena.communication.publisher.ServicePublishBinder
We add the prefix "X."
You also see a Bundlename (from our BundleConverter)
    org.eclipse.riena.core
We got the name from Context of the catched ExtendedLogEntry: 
    getBundle().getSymbolicName()

Using Marker from LOGBack is an easy way to get the information of the Bundle logging the event and also not to loose the Bundlename if rooting LogEvents from OSGI LogServices to SLF4J/LOGBack.

What happens next ?

This blog series isn't finished, but we already talked about the most important informations about Logging in OSGI Enterprise Applications. Of course I'll continue this series next months because there are some more aspects to look at in detail. But expect next blog entries in a time-frame of 2-3 weeks for each.

Blog Series "Logging in OSGI Enterprise Applications":

Perhaps some of my older blogs about Logging und OSGI are also interesting:


New blog series coming soon

Now I'll also starting a new  blog series :

HowTo build an Equinox-Riena-EasyBeans-OSGI-Server“. 

After working through that blog series you'll get a complete server as Open Source (EPL) to try it out by yourself. This server of course also contains all of the logging aspects I talked about.


this blog in german