My favorites | Sign in
Project Logo
                
Search
for
Updated Feb 16, 2009 by clement.escoffier
Labels: Featured
ExampleApplications  

Introduction

ModuleFusion currently contains 5 example applications. Each of these examples show how to use e.g. Guice, JPA and web applications within the OSGi Service Platform. The example build is based on Maven. Download: modulefusion-examples-1.1.0.zip

iPOJO Examples are described on iPOJOExampleApplications.

Hello World Example: org.modulefusion.example.servlet.helloworld

This bundle creates a simple "Hello World" servlet and exposes it at http://server:port/helloworld. The servlet code is:

public class HelloWorldServlet extends HttpServlet {
    protected void doGet(HttpServletRequest req, HttpServletResponse resp)
          throws ServletException, IOException {

	ServletOutputStream out = resp.getOutputStream();
	out.println("Hello World!");
	out.close();
    }
}

To actually "expose" this servlet, the bundle uses its BundleActivator to register the Servlet in the OSGi service registry:

public class Activator implements BundleActivator {
    public void start(final BundleContext context) {
        Servlet helloWorld = new HelloWorldServlet();
	Properties p = new Properties();
	p.put("alias", "/helloworld");
	context.registerService(Servlet.class.getName(), helloWorld, p);
    }
    public void stop(BundleContext context) throws Exception {
    }
}

Of course, you can register any Servlet you like and this also could be e.g. the Struts or "_insert_ _a_ _random_ _web_ _framework_ _here_" servlet.

This is all you need to do to export a Servlet. ModuleFusion contains Jetty v6 and the glue code to do the rest.

Guice Example: org.modulefusion.example.guice.simple

This bundle shows how to use the Guice IoC framework within the OSGi framework. ModuleFusion relies on the Peaberry extension for the OSGi/Guice integration. The following code snippets shows a Guice Module "importing" an OSGi service:

Module module = new AbstractModule() {
    protected void configure() {
        // Use the Guice Peaberry extension
        install(Peaberry.osgiModule(context));

        // Bind a service reference to the PackageAdmin
        bind(PackageAdmin.class).toProvider(Peaberry.service(PackageAdmin.class).single());

	// Class using an OSGi service
	bind(UsingAService.class).asEagerSingleton();

	// Class beeing exported as a OSGi service
	bind(Runnable.class).to(ExportedAsAService.class);
    }
};
Injector injector = Guice.createInjector(module);

Here, the PackageAdmin, registered in the OSGi service registry, is now available for classes configured in this module. The Class UsingAService uses the standard @Inject annotation just like it would use it for any other dependency:

public class UsingAService {	
    @Inject
    public UsingAService(PackageAdmin packageAdmin) {
        ExportedPackage[] packages = packageAdmin.getExportedPackages((Bundle) null);
	System.out.println("----------------------");
	System.out.println("Simple Guice Examples");
	System.out.println("----------------------");
	System.out.println("Number of exported packages in the framework: " + packages.length);
	System.out.println("----------------------");
    }
}

To create a service registration, the bundle activator gets an instance from the Guice injector to register it with the normal OSGi API:

Runnable instance = injector.getInstance(Runnable.class);
context.registerService(Runnable.class.getName(), instance, null);

JPA Introduction

When building Java enterprise applications, programmers normally use an O/R mapper to persist their objects in the database and probably the one mostly used is Hibernate. Hibernate provides a JPA frontend to its API so that code is not coupled to Hibernate's proprietary API.

OSGi introduces a new deployment format (bundles) and brings a new application model with services and the dynamic life cycle of bundles. Unfortunately, it is not always straightforward to map JPA elements to the OSGi model. E.g. entity classes can be split accross several bundles. Therefore, ModuleFusion contains the necessary glue code to make the use of Hibernate JPA as simple as possible.

In ModuleFusion, each bundle containing entity classes, simply lists those classes in a text file inside the bundle's jar file. ModuleFusion will read these files and the database configuration (section below), and combine them to provide a valid javax.persistence.EntityManager. This EntityManager is then available in the OSGi service registry.

Important: The registered service is a proxy that delegates to a thread local EntityManager. Therefore, each thread will automatically have its own instance.

Additionally, a javax.persistence.EntityManagerFactory gets registered. Clients can use this service directly if they need more control over the creation of the entity managers.

Database Connection Configuration

The database and Hibernate configuration can be changed in the file "load/configs/org.modulefusion.hibernate.jpaservicehibernate.cfg":

hibernate.connection.driver_class=org.hsqldb.jdbcDriver
hibernate.connection.url=jdbc:hsqldb:file:data/database
hibernate.connection.username=sa
hibernate.connection.password=
hibernate.dialect=org.hibernate.dialect.HSQLDialect
hibernate.current_session_context_class=thread
hibernate.cache.provider_class=org.hibernate.cache.NoCacheProvider
hibernate.show_sql=false
hibernate.hbm2ddl.auto=update

The HSQLDB RDBMS is included in the ModuleFusion distribution. The default JPA configuration (listing above) of ModuleFusion uses HSQLDB in the embedded mode. You don't need to change the configuration to use JPA applications in ModuleFusion. The default one will do just fine. Later, you still can change to e.g. MySQL, PostgreSQL, etc.

JPA Examples

ModuleFusion contains two bundles showing how to use JPA in OSGi:

  • The first bundle contains the entity Person and the PersonService service providing the CRUD operations (create, read, update, delete).
  • The second bundle simply uses the PersonService and does not depend on JPA directly.

JPA Example 1/2: org.modulefusion.example.jpa.personprovider

This bundle provides the entity class Person:

@Entity
public class Person implements Serializable {
	
    @Id
    @GeneratedValue(strategy = GenerationType.TABLE)
    private Long id;

    private String firstname;
    private String lastname;

    // getter/setter
    // for firstname and lastname
    // ...
}

As described above, the bundle has to inform ModuleFusion about this entity class. This is done by listing the class in the file OSGI-INF/jpa/classes. Each line consists of the fully-qualified class name (package name + class name):

org.modulefusion.example.jpa.personprovider.Person

This file and the configuration explained above is enough for ModuleFusion to create and register the entity manager. This bundle now uses the entity manager to implement a person service other bundles can use. The bundle uses Guice to reference the service:

// Bind OSGi service reference in this module
bind(EntityManager.class).toProvider(service(EntityManager.class).single());

// Bind the PersonService
bind(PersonService.class).to(PersonServiceImpl.class);

Within the PersonService class, the entity manager gets injected using the constructor and can be used just like in a non-OSGi environment:

public class PersonServiceImpl implements PersonService {
    private EntityManager entityManager;
	
    @Inject
    public PersonServiceImpl(EntityManager entityManager) {
        this.entityManager = entityManager;
    }
	
    public Person savePerson(Person person) {
        entityManager.getTransaction().begin();
        Person newP = entityManager.merge(person);
        entityManager.getTransaction().commit();
        return newP;
    }

    // ...
}

Again, this entity manager is a proxy delegating to a thread local instance and is therefore thread save.

The next step is to register the PersonService in the OSGi service registry so that the second bundle can use it:

// Get the PersonService out of the injector and register it in
// the OSGi service registry
PersonService instance = injector.getInstance(PersonService.class);
context.registerService(PersonService.class.getName(), instance, null);

JPA Example 2/2: org.modulefusion.example.jpa.personclient

The person client bundle simply uses the person service that was registered by the first bundle. It does not use the JPA API directly and is not specific to OSGi, Guice, etc. Please check the source code for more information.


Comment by dias.rodolfo, Nov 16, 2008

Hi,

Congratulations, I like modulefusion, but i have question about hibernate integration. How I use orm.xml with hibernate of modulefusion?

Thanks.


Sign in to add a comment
Hosted by Google Code