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.