JavaScript is required to for searching.
Skip Navigation Links
Exit Print View
Oracle GlassFish Server 3.1 Application Development Guide
search filter icon
search icon

Document Information

Preface

Part I Development Tasks and Tools

1.  Setting Up a Development Environment

2.  Class Loaders

3.  Debugging Applications

Part II Developing Applications and Application Components

4.  Securing Applications

5.  Developing Web Services

6.  Using the Java Persistence API

7.  Developing Web Applications

8.  Using Enterprise JavaBeans Technology

9.  Using Container-Managed Persistence

10.  Developing Java Clients

11.  Developing Connectors

12.  Developing Lifecycle Listeners

13.  Developing OSGi-enabled Java EE Applications

Overview of OSGi Application and GlassFish Server

Benefits of Using OSGi in Enterprise Java Applications

Developing OSGi Application Bundles for GlassFish Server

Developing Plain OSGi Bundles

HTTP Service

Transaction Service

JDBC Data Source Service

JMS Resource Service

Developing Web Application Bundles

Required WAB Metadata

How WABs Consume OSGi Services

OSGi CDI Extension for WABs

Developing EJB Application Bundles

Required EJB Metadata

How EJB Bundles Consume OSGi Services

Using the OSGi CDI Extension With EJB Bundles

Deploying OSGi Bundles in GlassFish Server

Part III Using Services and APIs

14.  Using the JDBC API for Database Access

15.  Using the Transaction Service

16.  Using the Java Naming and Directory Interface

17.  Using the Java Message Service

18.  Using the JavaMail API

Index

Developing OSGi Application Bundles for GlassFish Server

GlassFish Server enables interaction between OSGi components and Java EE components. OSGi services managed by the OSGi framework can invoke Java EE components managed by the Java EE container and vice versa. For example, developers can declaratively export EJBs as OSGi services without having to write any OSGi code. This allows any plain OSGi component, which is running without the Java EE context, to discover the EJB and invoke it. Similarly, Java EE components can locate OSGi services provided by plain OSGi bundles and use them as well. GlassFish Server extends the Java EE Context and Dependency Injection (CDI) framework to make it easier for Java EE components to consume dynamic OSGi services in a type-safe manner.

Developing Plain OSGi Bundles

Java EE components (like an EJB or Servlet) can look up Java EE platform services using JNDI names in the associated Java EE naming context. Such code can rely on the Java EE container to inject the required services as well. Unfortunately, neither of them works when the code runs outside a Java EE context. An example of such code is the BundleActivator of an OSGi bundle. For such code to access Java EE platform services, GlassFish Server makes key services and resources of the underlying Java EE platform available as OSGi services. Thus, an OSGi bundle deployed in GlassFish Server can access these services using OSGi Service look-up APIs or by using a white board pattern. The following Java EE services are available as OSGi services:

HTTP Service

The GlassFish Server web container is made available as a service for OSGi users who do not use OSGi Web Application Bundles (WABs). This service is made available using the standard OSGi/HTTP service specification, which is a light API that predates the concept of a web application as we know it today. This simple API allows users to register servlets and static resources dynamically and draw a boundary around them in the form of a HttpContext. This simple API can be used to build feature–rich web application, such as the Felix Web Console for example.

The GlassFish Server web container has one or more virtual servers. A virtual server has one or more web application deployed in it. Each web application has a distinct context path. Each virtual server has a set of HTTP listeners. Each HTTP listener listens on a particular port. When multiple virtual servers are present, one of them is treated as the default virtual server. Every virtual server comes configured with a default web application. The default web application is used to serve static content from the docroot of GlassFish Server. This default web application uses / as the context path. A web application contains static and dynamic resources. Each virtual server is mapped to an org.osgi.services.http.HttpService instance. When there are multiple virtual servers present, there will be multiple occurrences of HttpService registered in the service registry. In order to distinguish one service from another, each service is registered with a service property named VirtualServer, whose value is the name of the virtual server. The service corresponding to default virtual server has the highest ranking, so when looking up a service of type HttpService without any additional criteria returns the HttpService corresponding to the default virtual server. In a typical GlassFish Server installation, the default virtual server is configured to listen on port 8080 for the HTTP protocol and port 8181 for the HTTPS protocol.

The context path / is reserved for the default web application. Every resource and servlet registered using the registerResource() and registerServlet() methods of HttpService are made available under a special context path named /osgi in the virtual server. The /osgi context path can be changed to some other value by setting an appropriate value in the OSGi configuration property or in a system property called org.glassfish.osgihttp.ContextPath.

For example, HelloWorldServlet will be available at http://localhost:8080/osgi/helloworld when the following code is executed:

HttpService httpService = getHttpService(); // Obtain HttpService
httpService.registerServlet(httpService.registerServlet("/helloworld", 
new HelloWorldServlet(), null, ctx);

Transaction Service

The Java Transaction API (JTA) defines three interfaces to interact with the transaction management system: UserTransaction, TransactionManager, and TransactionSynchronizationRegistry. They all belong to the javax.transaction package. TransactionManagerand TransactionSynchronizationRegistry are intended for system level code, such as a persistence provider. Whereas, UserTransaction is the entity that you should use to control transactions. All the objects of the underlying JTA layer are made available in the OSGi service registry using the following service interfaces:

There is no additional service property associated with them. Although UserTransaction appears to be a singleton, in reality any call to it gets rerouted to the actual transaction associated with the calling thread. Code that runs in the context of a Java EE component typically gets a handle on UserTransaction by doing a JNDI lookup in the component naming context or by using injection, as shown here:

(UserTransaction)(new InitialContext().lookup("java:comp/UserTransaction")); 

or

@Resource UserTransaction utx;

When certain code (such as an OSGi Bundle Activator), which does not have a Java EE component context, wants to get hold of UserTransaction, or any of the other JTA artifacts, then they can look it up in the service registry. Here is an example of such code:

BundleContext context;
ServiceReference txRef =
    context.getServiceReference(UserTransaction.class.getName());
UserTransaction utx = (UserTransaction);
context.getService(txRef);

JDBC Data Source Service

Any JDBC data source created in GlassFish Server is automatically made available as an OSGi Service; therefore, OSGi bundles can track availability of JDBC data sources using the ServiceTracking facility of the OSGi platform. The life of the OSGi service matches that of the underlying data source created in GlassFish Server. For instructions on administering JDBC resources in GlassFish Server, see the Oracle GlassFish Server 3.1 Administration Guide.

GlassFish Server registers each JDBC data source as an OSGi service with objectClass = ”javax.sql.DataSource” and a service property called jndi-name, which is set to the JNDI name of the data source. Here is a code sample that looks up a data source service:

  @Inject
  @OSGiService(true,
         "(jndi-name=jdbc/MyDS)") 
  private DataSource ds;

JMS Resource Service

Like JDBC data sources, JMS administered objects, such as destinations and connection factories, are also automatically made available as OSGi services. Their service mappings are as follows.

JMS Object
Service Interface
Service Properties
Comments
JMS Queue destination
javax.jms.Queue
jndi-name
jndi-name is set to the JNDI name of the queue
JMS Topic destination
javax.jms.Topic
jndi-name
jndi-name is set to the JNDI name of the topic
JMS connection factory
javax.jms.QueueConnectionFactory or javax.jms.TopicConnectionFactory or javax.jms.ConnectionFactory
jndi-name
jndi-name is set to the JNDI name of the topic.

The actual service interface depends on which type of connection factory was created.

Developing Web Application Bundles

When a web application is packaged and deployed as an OSGi bundle, it is called a Web Application Bundle (WAB). WAB support is based on the OSGi Web Application specification , which is part of the OSGi Service Platform, Enterprise Specification, Release 4, Version 4.2. A WAB is packaged as an OSGi bundle, so all the OSGi packaging rules apply to WAB packaging. When a WAB is not packaged like a WAR, the OSGi Web Container of GlassFish Server maps the WAB to the hierarchical structure of web application using the following rules:

The simplest way to avoid knowing these mapping rules is to avoid the problem in the first place. Moreover, there are many packaging tools and development time tools that understand WAR structure. Therefore, we strongly recommend that you package the WAB exactly like a WAR, with only additional OSGi metadata.

Required WAB Metadata

In addition to the standard OSGi metadata, the main attributes of META-INF/MANIFEST.MF of the WAB must have an additional attribute called Web-ContextPath. The Web-ContextPath attribute specifies the value of the context path of the web application. Since the root of a WAB is mapped to the docroot of the web application, it should not be used in the Bundle-ClassPath. Moreover, WEB-INF/classes/ should be specified ahead of WEB-INF/lib/ in the Bundle-ClassPath in order to be compliant with the search order used for traditional WAR files.

Assuming the WAB is structured as follows:

  foo.war/
       index.html
       foo.jsp
       WEB-INF/classes/
                      foo/BarServlet.class
       WEB-INF/lib/lib1.jar
       WEB-INF/lib/lib2.jar

Then the OSGi metadata for the WAB as specified in META-INF/MANIFEST.MF of the WAB would appear as follows:

  MANIFEST.MF:Manifest-Version: 1.0 
  Bundle-ManifestVersion: 2
  Bundle-SymbolicName: com.acme.foo
  Bundle-Version: 1.0
  Bundle-Name: Foo Web Application Bundle Version 1.0
  Import-Package: javax.servlet; javax.servlet.http, version=[3.0, 4.0)
  Bundle-ClassPath: WEB-INF/classes, WEB-INF/lib/lib1.jar, WEB-INF/lib/lib2.jar
  Web-ContextPath: /foo

How WABs Consume OSGi Services

Since a WAB has a valid Bundle-Context, it can consume OSGi services. Although you are free to use any OSGi API to locate OSGi services, GlassFish Server makes it easy for WAB users to use OSGi services by virtue of extending the Context and Dependency Injection (CDI) framework. Here's an example of the injection of an OSGi Service into a Servlet:

  @WebServlet 
  public class MyServlet extends HttpServlet {   
    @Inject @OSGiService(dynamic=true)
    FooService fooService; 
  }

To learn more about this feature, refer to OSGi CDI Extension for WABs.

OSGi CDI Extension for WABs

GlassFish Server includes a CDI extension that enables web applications, such as servlets, that are part of WABs to express a type-safe dependency on an OSGi service using CDI APIs. An OSGi service can be provided by any OSGi bundle without any knowledge of Java EE/CDI, and they are allowed to be injected transparently in a type-safe manner into a web application.

A custom CDI Qualifier, @org.glassfish.osgicdi.OSGiService, is used by the component to represent dependency on an OSGi service. The qualifier has additional metadata to customize the service discovery and injection behavior. The following @OsgiService attributes are currently available:

Example 13-1 Example of a WAB Using CDI

In this example, Bundle B0 defines a service contract called com.acme.Foo and exports the com.acme package for use by other bundles. Bundle B1 in turn provides a service implementation, FooImpl, of the com.acme.Foo interface. It then registers the service FooImpl service with the OSGi service registry with com.acme.Foo as the service interface.

Bundle B2 is a hybrid application bundle that imports the com.acme package. It has a component called BarServlet that expresses a dependency to com.acme.Foo by adding a field/setter method and qualifies that injection point with @OsgiService. For instance, BarServlet could look like:

  @Servlet
  public void BarServlet extends HttpServlet{
      @Inject @OSGiService(dynamic=true)
      private com.acme.Foo f;
  }

Developing EJB Application Bundles

Another type of hybrid application bundle is the EJB Application Bundle. When an EJB Jar is packaged with additional OSGi metadata and deployed as an OSGi bundle it is called an EJB Application Bundle. GlassFish Serversupports only packaging the OSGi bundle as a simple JAR file with required OSGi metadata, just as you would package an ejb-jar file.

Required EJB Metadata

An EJB Application Bundle must have a manifest metadata called Export-EJB in order to be considered as an EJB Bundle. For syntax of Export-EJB header, please refer to the Publishing EJB as OSGi Service section. Here's an example of an EJB Application Bundle with its metadata:

  myEjb.jar/
           com/acme/Foo
           com/acme/impl/FooEJB
           META-INF/MANIFEST.MF
  MANIFEST.MF: 
  Manifest-Version: 1.0 
  Bundle-ManifestVersion: 2 
  Bundle-SymbolicName: com.acme.foo EJB bundle 
  Bundle-Version: 1.0.0.BETA 
  Bundle-Name: com.acme.foo EJB bundle version 1.0.0.BETA 
  Export-EJB: ALL 
  Export-Package: com.acme; version=1.0 
  Import-Package: javax.ejb; version=[3.0, 4.0), com.acme; version=[1.0, 1.1)

How EJB Bundles Consume OSGi Services

Since an EJB has a valid Bundle-Context, it can consume OSGi services. Although you are free to use any OSGi API to locate OSGi services, GlassFish Server makes it easy to use OSGi services by virtue of extending the Context and Dependency Injection (CDI) framework. Here's an example of injection of an OSGi Service into a servlet:

  @Stateless 
  public class MyEJB {   
    @Inject @OSGiService(dynamic=true)
    Foo foo;
    ...
  }

To learn more about this feature, refer to Using the OSGi CDI Extension With EJB Bundles.

Using the OSGi CDI Extension With EJB Bundles

GlassFish Server includes a CDI extension that enables EJB application bundles to express a type-safe dependency on an OSGi Service using CDI APIs. An OSGi service can be provided by any OSGi bundle without any knowledge of Java EE/CDI, and they are allowed to be injected transparently in a type-safe manner into an EJB bundle.

A custom CDI Qualifier, @org.glassfish.osgicdi.OSGiService, is used by the component to represent dependency on an OSGi service. The qualifier has additional metadata to customize the service discovery and injection behavior. The following @OsgiService attributes are currently available: