Wicket, Spring 3, JPA2 & Hibernate OSGi Application on Apache Karaf

Wicket, Spring 3, JPA2 & Hibernate OSGi Application on Apache Karaf

EDIT: Hibernate is now OSGi ready so most of those stuff are now completely outdated.

The full source for this post has been move to github.

Recently I attempted to modify an existing crud web application for OSGi deployment. During the process I encountered a lot of issues such as

  • Lack of OSGi bundles.
  • Troubles wiring the tiers of the application together.
  • Issues on the OSGi container configuration.
  • Lack of detailed examples on the web.

 So, I decided to create such a guide & provide full source for a working example (A very simple person crud application).

The first part of this guide is Creating custom Hibernate 3.5 OSGi bundles. This part provides an example project (which includes the bundles source) that describes how to use the custom hibernate bundles in order to build a wicket, spring 3, hibernate 3.5 jpa 2 and deploy it to Karaf.

Among others it describes:

  • How to wire database and web tier using the OSGi blueprint.
  • How to deploy web applications to Karaf 1.6.0.
  • A small wicket crud application.

Note: This demo application does not make use OSGi Enterprise Spec, since its an OSGi-fication of an existing application. The use of the spec will be a subject for future posts.


Environment Preparation
The OSGi run-time that will be used in this post is Felix/Karaf version 1.6.0.
This section describes the required configuration for deploying web applications.

Once, karaf is downloaded and extracted, it can be started by typing


from inside the karaf root folder.

Now, we are going to install karaf webconsole and war deployer that will allow us to deploy web applications to karaf.

features:install webconsole
features:install war

Note: In the background karaf fetches all the required bundles from maven repositories. You are going to need internet access for this. Moreover, if you are behind a proxy you will need to set up your jvm net.properties accordingly. Having the proxy configured in maven settings.xml is not enough.

Custom Bundles
Most of the bundles required for this project are available either in public maven repositories or inside Spring Enterprise Bundle Repository. However, hibernate 3.5.x which is one of the key dependencies for this project is not available as OSGi bundle (note: earlier version of hibernate can be found in Spring EBR). More details on OSGi-fying Hibernate 3.5.x in the previous part of the guide “Creating custom Hibernate 3.5 OSGi bundles“.

Creating the application itself
The actual demo application will be the simplest possible wicket crud for persons (a killer application that stores/delete/updates a persons first name and last name to the database).

The create schema script of such application in mysql would look like this:


Database Tier
For the database tier we are going to create a simple bundle that will contain the entity, the dao interface and the dao implementation. The bundle will contain the necessary persistence descriptor for JPA 2.0 with hibernate as persistence provider. Finally it will use spring to create the data source, entity manager factory & JPA transaction manager. This bundle will export the dao as a service to the OSGi Registry using Spring dynamic modules.

The Person entity for the example can look like:

package net.iocanel.database.entities;

import java.io.Serializable;
import javax.persistence.Basic;
import javax.persistence.Column;
import javax.persistence.Entity;
import javax.persistence.GeneratedValue;
import javax.persistence.GenerationType;
import javax.persistence.Id;
import javax.persistence.NamedQueries;
import javax.persistence.NamedQuery;
import javax.persistence.Table;

* @author iocanel
@Table(name = "Person")
@NamedQuery(name = "Person.findAll", query = "SELECT p FROM Person p"),
@NamedQuery(name = "Person.findById", query = "SELECT p FROM Person p WHERE p.id = :id"),
@NamedQuery(name = "Person.findByFirstName", query = "SELECT p FROM Person p WHERE p.firstName = :firstName"),
@NamedQuery(name = "Person.findByLastName", query = "SELECT p FROM Person p WHERE p.lastName = :lastName")})
public class Person implements Serializable {

private static final long serialVersionUID = 1L;
@GeneratedValue(strategy = GenerationType.AUTO)
@Basic(optional = false)
@Column(name = "ID")
private Integer id;
@Column(name = "FIRST_NAME")
private String firstName;
@Column(name = "LAST_NAME")
private String lastName;

public Person() {

public Person(Integer id) {
this.id = id;

public Integer getId() {
return id;

public void setId(Integer id) {
this.id = id;

public String getFirstName() {
return firstName;

public void setFirstName(String firstName) {
this.firstName = firstName;

public String getLastName() {
return lastName;

public void setLastName(String lastName) {
this.lastName = lastName;

public int hashCode() {
int hash = 0;
hash += (id != null ? id.hashCode() : 0);
return hash;

public boolean equals(Object object) {
// TODO: Warning - this method won't work in the case the id fields are not set
if (!(object instanceof Person)) {
return false;
Person other = (Person) object;
if ((this.id == null && other.id != null) || (this.id != null && !this.id.equals(other.id))) {
return false;
return true;

public String toString() {
return "net.iocanel.database.entities.Person[id=" + id + "]";

For this entity we will create a dao interface, through which the rest of the bundles in the container can track/lookup the dao service (the actual implementation).

We want the dao service to provide simple crud operations such as, create, delete, find & findAll, so the dao interface can be something like:

package net.iocanel.database.dao;

import java.util.List;
import net.iocanel.database.entities.Person;

* @author iocanel
public interface PersonDAO {

public void create(Person person) throws Exception;
public void edit(Person person) throws Exception;
public void destroy(Integer id) throws Exception;
public Person findPerson(Integer id);
public List findAllPersons();

The actual jpa implementation of the dao will obtain the EntityManager via Spring (it will be injected by Spring) and for transaction demarcation will use Spring’s Transactional annotation:

package net.iocanel.database.dao;

import java.util.List;
import javax.persistence.EntityManager;
import javax.persistence.Query;
import javax.persistence.PersistenceContext;
import net.iocanel.database.entities.Person;
import org.springframework.transaction.annotation.Transactional;

* @author iocanel
public class PersonJpaDAO implements PersonDAO {

private EntityManager entityManager;

public void create(Person person) throws Exception {

public void edit(Person person) throws Exception {

public void destroy(Integer id) throws Exception {

public List findPersonEntities(int maxResults, int firstResult) {
return findPersonEntities(false, maxResults, firstResult);

private List findPersonEntities(boolean all, int maxResults, int firstResult) {
Query q = entityManager.createQuery("select object(o) from Person as o");
if (!all) {
return q.getResultList();

public Person findPerson(Integer id) {
return entityManager.find(Person.class, id);

public int getPersonCount() {
Query q = entityManager.createQuery("select count(o) from Person as o");
return ((Long) q.getSingleResult()).intValue();

public List findAllPersons() {
Query q = entityManager.createNamedQuery("Person.findAll");
return q.getResultList();

For the EntityManager injection and Spring Transactions, we need need a spring context. Since we are going to use Spring Dynamic Modules, the spring context needs to be placed under META-INF/spring/.

For the creation of the EntityManagerFactory Spring will need a persistence.xml file located under META-INF:


So far in the database tier we did what we would do in a typical application. Now we will add OSGi flavor to our module.

Creating the DAO OSGi Service
As mentioned above for the creation of the dao service we will use spring dynamic modules. So all we need is to add a descriptor under META-INF/spring that will instruct Spring’s OSGi exporter to export bean personDAO as OSGi service:

Finally, we need to perform a small hack. In the previous part of this guide, we created an OSGi fragment for Hibernate Validator. This fragment is attached on the validation api host, so that the validation api can find the classes of hibernate validator. However, we still need to instruct the validation api, to look for Hibernate Validator classes. In an non-OSGi world the validation api will lookup in the classpath for the following file META-INF/services/javax.validation.spi.ValidationProvider and read the actual validation provider class name from this file.

Passing the Validation Provider to Validation API
In the OSGi world the validation api, will delegate that call to the calling bundle (in our case the database tier bundle) so we are going to make sure that it finds it. How we are going to do so? We are going to copy it from Hibernate Validator and add it in our bundle. This approach might not seem that elegant, however it has two great advantages:

  • Its simple
  • It works

If you are aware of more elegant alternative feel free to communicate them.

The final obstacle is creating the bundle itself.The bundle will be created using maven-bundle-plugin. As maven dependencies it will contain only whatever it requires for the compile scope and its run-time dependencies(hibernate,spring,jpa spec, cglib etc) will be declared as OSGi Import-Packages.






Presentation/Web Tier
For the presentation tier we are going to be a Wicket OSGi application. This application will be integrated with Spring using @SpringBean annotation (more details on this on Wicket/Spring Wiki).

Since we are interested in taking advantage of Spring Dynamic Modules, we are going to instruct to load its context from OsgiBundleXmlWebApplicationContext inside the web.xml.


So the full web deployment descriptor for Wicket/Spring/OSGi could look like this(yes I know I am starting to sound like Bob Ross):









The Spring context file (/WEB-INF/applicationContext.xml)that will be loaded needs to define two simple things:

  • The Wicket Application Object.
  • The PersonDAO OSGi service.

The PersonDAO service will be looked up using Spring Dynamic Modules. Inside the wicket application the PersonDAO service will be injected as if it was a normal spring bean using the @SpringBean annotation.

We are almost there. All that’s left is the coding of the actual crud. I will not go into much detail, since its beyond the scope of this blog post. However, I am going to list the key points of the crud.

The C.R.U.D.
For the CRUD part we will create a single ajax page that will display:

  • A list of all persons in the database.
  • A small form to insert/edit person details.
  • Buttons for each record to edit/remove persons in the database.

The List Component that will be used is PropertyListView, and the model attached to list will be a LoadableDetachableModel that will load all persons from the database. Finally the person details form will consist of 2 text fields First Name & Last Name.


The full source for this example (including the custom bundles) can be found at my github repository. Once you unpack it you can mvn clean install and it will package the project bundles, the custom bundles and all the required bundles under target/wicket-osgi.dir/deploy folder. Just copy the contents of this folder to $KARAF_HOME/deploy and you are ready launch the application at http://localhost:8181/web-tier/.

Final thoughts
I hope you find this useful.
Once my schedule allows, I will blog on how to add JTA transactions on the example above, so stay tuned(The Hibernate bundle is JTA ready, however we need a JTA transaction manager bundle).
Feel free to send comments or suggestions.

Comments (35)

  1. Jamie Goodyear

    Thanks for sharing this demo! I look forward to seeing what additions you make to this example 🙂

  2. Nima

    Hi, thanks for sharing. I tried to build it but I faced this error, please advice:

    1) org.hibernate:net.iocanel.hibernate.all:jar:3.5.2-Final

  3. iocanel

    The problem is that the actual artifact required by the database-tier is org.hibernate:net.iocanel.hibernate.all:jar:3.5.2.Final. So there is a typo here. I'll have it fixed and reuploaded later today.

  4. Ilya Tepikin

    Strange. I made it work under Apache Karaf, but under Apache ServiceMix 4.2 (and FUSE ESB), that based on Apache Karaf, still having problem.
    May be it's because of incompatibility of bundle(s).

    Anyway Ioannis thank you!

  5. iocanel

    @Ilya Tepikin: There are a couple of bundles used in this post, that are drawn from Spring EBR. ServiceMix 4.2 provides some of these bundles by default (e.g. antlr). So you will have to resolve these conflicts in order to get it working on ServiceMix.

  6. iocanel

    @Ilya Tepikin: Regarding the second message you sent me. I am sorry but I accidentally deleted it. I am more than willing to help you, however I would need a full stack trace. Please sent me an email with it.

  7. Ilya Tepikin

    Thank you very much, Ioannis, but I partically solved the problem. Conflict was in Spring: FUSE contents 2.5.6.SEC01 (used by ActiveMQ ver. <= 5.3), Hibernate from your bundles uses 3.0.2.
    I took last snapshot of ActiveMQ(5.4) and your bundles started successfully.

  8. Marcelo Marmol

    I am trying to use you bundles, everything looks great, but for some reason validation is not getting attached..

    69 ACTIVE com.springsource.javax.validation_1.0.0.GA
    70 INSTALLED org.hibernate.net.iocanel.hibernate.validator_4.0.2.GA

    Any idea of what can be the problem? I am using Equinox.


  9. iocanel

    @Marcelo Marmol: Can you please try to refresh the host bundle?

  10. Marcelo Marmol

    sorry i forgot all about the javax.validation.spi.ValidationProvider, I am having other problems now, but will see..
    Thanks a lot for this post.

  11. Marcelo Marmol

    well I got it working, i had a dependency missing. But my new problem is that i have the following exception:
    javax.validation.ValidationException: Unable to find a default provider
    And the jars are resolved and activated in the osgi equinox context

    69 ACTIVE com.springsource.javax.validation_1.0.0.GA
    70 ACTIVE com.springsource.com.googlecode.jtype_0.1.0
    71 RESOLVED org.hibernate.net.iocanel.hibernate.validator_4.0.2.GA

    Any idea?

  12. iocanel

    @Marcelo Marmol: Thanks Marcelo for your feedback. Its good to know that its working on Equinox too.

  13. Marcelo Marmol

    Hey… finally is running, i see that the entities are found and tables are created in the data base, but i am having the following exception:

    12:53:06.168 [DEBUG] org.hibernate.ejb.Ejb3Configuration:822 – Detect class: true; detect hbm: true
    12:53:06.176 [DEBUG] org.hibernate.ejb.packaging.AbstractJarVisitor:123 – Searching mapped entities in jar/par: bundleresource://88.fwk19627754/
    12:53:06.177 [WARN] org.hibernate.ejb.packaging.InputStreamZippedJarVisitor:61 – Unable to find file (ignored): bundleresource://88.fwk19627754/
    java.lang.NullPointerException: in is null
    at java.util.zip.ZipInputStream.(ZipInputStream.java:64)
    at java.util.jar.JarInputStream.(JarInputStream.java:57)
    at java.util.jar.JarInputStream.(JarInputStream.java:43)
    at org.hibernate.ejb.packaging.InputStreamZippedJarVisitor.doProcessElements(InputStreamZippedJarVisitor.java:57)
    at org.hibernate.ejb.packaging.AbstractJarVisitor.getMatchingEntries(AbstractJarVisitor.java:146)
    at org.hibernate.ejb.packaging.NativeScanner.getFilesInJar(NativeScanner.java:192)
    at org.hibernate.ejb.Ejb3Configuration.addScannedEntries(Ejb3Configuration.java:490)
    at org.hibernate.ejb.Ejb3Configuration.scanForClasses(Ejb3Configuration.java:832)
    at org.hibernate.ejb.Ejb3Configuration.configure(Ejb3Configuration.java:586)

    My application is not a war inside osgi, is a jar, so i am not sure if this is the problem… The bundle 88 that is trying to access is the one that contains the entities and the persistence.xml file.
    Any idea?

  14. iocanel

    @Marcelo Marmol:It seems that the entity manager can't read the entities. I think that it has to do with your environment. Maybe a debug would shed some light into it.

  15. ialex

    It is always nice to find out developers whose's geographical proximity to you is near ( especially if working in Greece 😛 ),
    and are active and working on new technologies (commiters are even rarer hehe).

    Looking around about servicemix 4.x, JPA 2.0, transactions (JTA too), etc i stumbled upon this blog a couple of days ago and it was really helpful.

    @Marcelo Marmol : (if you are still monitoring the blog and/or haven't found the solution)
    that problem occurred to me too, even though it is a warning, it could not process entities in another bundle.
    If the entities were in the same bundle, everything would work (even though the exception would still occur).

    I found an explanation and solution here : http://stackoverflow.com/questions/1190518/equinox-osgi-and-jpa-hibernate-finding-entities
    (tested Rich Seller 's solution and it actually works). Otherwise, putting them in the same bundle would suffice (if you don't have
    a problem with packaging it in the same bundle and the aesthetics of the exception)

  16. iocanel

    @ialex: Thanks for your kind words.

    It is indeed rare find such links in Greece. However, I think that you have the pleasure to work with the BEST (I think we have a friend in common).

  17. Anonymous


    Great post. I have a quick question. Do you think that it is possible to add a service layer where transaction will he handled and keep it separate from the DAO ?


    Charles M. (Apache Camel Committer)

  18. iocanel

    @Charles M.: Thanks for you kind words.

    Yes, Its possible. In fact I have tried it successfully.

  19. Anonymous

    Hi, thanks for the detailed post.
    Can it run on tomcat?

  20. iocanel

    If you exclude the OSGi stuff I guess it could.

  21. Stream

    i've tried you pom.xml, and then depoly the jar to karaf.
    but there is a problem that
    Error executing command: Unresolved constraint in bundle org.hibernate.net.iocanel.hibernate.all [231]: Unable to resolve 231.1: missing requirement [
    231.1] package; (package=bitronix.tm)

    could you help me thanks…

  22. iocanel

    @Stream: It seems that hibernate.all bundle is requesting the bitronix transaction manager. You could edit the pom.xml and mark that package as optional.

  23. stacciaburatta

    Nice post, I've tried to build the bundles but I got an error

    [ERROR] The build could not read 3 projects -> [Help 1]
    [ERROR] The project net.iocanel:bundles:1.0-SNAPSHOT (/Users/stacciaburatta/sviluppo/Hibernate OSGi/wicket-spring-jpa2-hibernate-karaf/bundles/pom.xml) has 1 error
    [ERROR] Non-resolvable parent POM: Could not find artifact net.iocanel:parent:pom:1.0-SNAPSHOT and 'parent.relativePath' points at wrong local POM @ line 4, column 10 -> [Help 2]
    [ERROR] The project net.iocanel:database-tier:1.0-SNAPSHOT (/Users/stacciaburatta/sviluppo/Hibernate OSGi/wicket-spring-jpa2-hibernate-karaf/database-tier/pom.xml) has 1 error
    [ERROR] Non-resolvable parent POM: Could not find artifact net.iocanel:parent:pom:1.0-SNAPSHOT and 'parent.relativePath' points at wrong local POM @ line 5, column 10 -> [Help 2]
    [ERROR] The project net.iocanel:web-tier:1.0-SNAPSHOT (/Users/stacciaburatta/sviluppo/Hibernate OSGi/wicket-spring-jpa2-hibernate-karaf/web-tier/pom.xml) has 1 error
    [ERROR] Non-resolvable parent POM: Could not find artifact net.iocanel:parent:pom:1.0-SNAPSHOT and 'parent.relativePath' points at wrong local POM @ line 5, column 10 -> [Help 2]

    could you help me, thanks

  24. iocanel

    @stacciaburatta and everyone else that had issues with the code sample:

    I made some fixes on the code and uploaded to github. You can find it at: https://github.com/iocanel/blog/tree/master/wicket-spring-jpa2-hibernate-karaf

  25. Anonymous

    I have download your sample from the github and try to run it using karaf 2.2.2. i am new starter for karaf, i just follow your guide to start the karaf.exe and install the webconsole and war.
    after that i copy the content inside wicket-osgi/deploy folder which are web-tier-1.0-SNAPSHOT.war and database-tier-1.0-SNAPSHOT.jar, and put them into the deploy folder of karaf.. i can see these two bundles are installed. but when i start db-tier, it says====> Error executing command: Unresolved constraint in bundle net.iocanel.database-tier [130]: Unable to resolve 130.0: missing requirement [130.0] package; (pac
    kage=com.mysql.jdbc) <===

    then i start war file, it says rror executing command: Unresolved constraint in bundle net.iocanel.web-tier [131]: Unable to resolve 131.0: missing requirement [131.0] package; (&(packag

  26. iocanel

    This comment has been removed by the author.

  27. iocanel

    The errors you have indicate that mysql & jpa api are missing. Maybe you could try to install the manually and I will have a look on why they are missing.

  28. Google android apps development

    Thanks for the post. I liked it. Keep going I follow you.
    IPhone App Development| Android apps developer|

  29. Borut Bolčina

    I am looking forward for an updated example of how to use Hibernate JPA inside OSGi, especially how a Camel route persists some JPA anotated entity to a MySql database. Can't find a tutorial on this.

    Or should I back off the Hibernate and use OpenJPA? That would be a tough decision, as we already have the models annotated.

  30. iocanel

    I can send you a sample project of using camel + blueprint + jpa + openjpa, if you can't find any.

    OpenJPA will definitely give you a smoother OSGi experience, than hibernate as it is OSGi ready.

    I am not sure when I'll find the time to do an update on this post.

  31. SMX

    Everyones posts have been interesting however, I cannot get the JbOss Hibernate Entity Manager to START and does not display any errors when the START command is executed for that bundle (i.e. start 657). Can anyone give me an idea ? It is always at RESOLVED.

    I'm attempting to start Hibernate 4.0.1 within ServiceMix 4.5 with Karaf 3.2.2.

    I've installed Hibernate (bundles from SpringSource ) using a feature file as shown in the below listing:




    Once the feature file is installed the following listing is displayed as follows:

    [ 277] [Active ] [ ] [ ] [ 50] Apache ServiceMix :: Bundles :: commons-csv (1.0.0.r706900_3)
    [ 278] [Active ] [ ] [ ] [ 50] camel-csv (2.10.3)
    [ 340] [Active ] [ ] [ ] [ 80] ANTLR (2.7.7)
    [ 407] [Active ] [ ] [ ] [ 30] Commons Collections (3.2.1)
    [ 583] [Active ] [ ] [ ] [ 80] Apache Log4J (1.2.16)
    [ 630] [Active ] [ ] [ ] [ 30] Spring JDBC (3.0.7.RELEASE)
    [ 665] [Active ] [ ] [ ] [ 20] FasterXML ClassMate (0.5.4)
    [ 666] [Active ] [ ] [ ] [ 20] SERP (1.13.1)
    [ 667] [Active ] [ ] [ ] [ 20] Apache ANT (1.8.3)
    [ 668] [Active ] [ ] [ ] [ 20] Javassist Java Programming Assistant (3.15.0.GA)
    [ 669] [Active ] [ ] [ ] [ 20] ClassMate (0.5.4)
    [ 670] [Active ] [ ] [ ] [ 20] JBoss Logging 3 (3.1.0.GA)
    [ 671] [Active ] [ ] [ ] [ 20] JBoss Jandex (1.0.3.Final)
    [ 672] [Active ] [ ] [ ] [ 25] JBoss Hibernate Common Annotations (4.0.1.Final)
    [ 673] [Active ] [ ] [ ] [ 25] Java Bean Validation API (1.0.0.GA)
    [ 674] [Active ] [ ] [ ] [ 25] JBoss Hibernate Object-Relational Mapper (4.0.1.Final)
    Fragments: 675
    [ 675] [Resolved ] [ ] [ ] [ 25] JBoss Hibernate Entity Manager (4.0.1.Final)
    Hosts: 674

    I really would appreciate any help.

  32. iocanel

    The last couple of Hibernate version are OSGi ready and it has become quite trivial to deploy them to Karaf.
    All you need to do is to wrap jandex and classmate and you are good to go.
    If you need to use Hibernate + Aries JPA, you'll need to start hibernate before installing the jpa feature.

  33. joseph audry njangang

    I download the last of this projet.I've run mvn clean install bu this errors happpen and the build don't cannot achieve
    Failed to execute goal on project net.iocanel.jacc: Could not resolve de
    pendencies for project javax.security:net.iocanel.jacc:bundle:1.0: Could not
    transfer artifact javax.security:jacc:jar:1.0 from/to Jboss Maven2 Repository (http
    ://repository.jboss.org/maven2/): Access denied to: http://repository.jboss.org/
    maven2/javax/security/jacc/1.0/jacc-1.0.jar , ReasonPhrase:Forbidden.

  34. iocanel

    The project is at least 3 year old and is really obsolete!

    Hibernate now ships proper OSGi bundles and there is no need to go through all these.

  35. pega training

    Thanks iocanel You saved my life after 3 hours intensive debugging 🙂

Comments are closed.