Shorcut issue with Apache on Windows

I usually use Linux, but a few days ago my wireless driver stopped working. I don’t know why, anyway, no time to figure it out. So I have to use Windows when developing websites with Apache.

I’ve already installed Zend Server (which has a built-in Apache) but I found my site running more slowly than usual. So I decided to install XAMPP as a replacement. The problem here is, when I tried to create a shortcut in the XAMPP’s htdocs folder pointing to the Zend Server’s htdocs folder, which contains my old site, Apache didn’t “follow” them, even if the FollowSymLinks option is enabled. Then after a quick search, I’ve found the solutions: Use the Alias!

Yeah, using Alias is very easy. You can find its documentation here: http://httpd.apache.org/docs/2.0/mod/mod_alias.html

All you have to do is insert a single line in the http.conf:
Alias /old-site /full/path/to/your/folder

This will tell Apache to treat (in my case) http://localhost/old-site as an alias for the full path to your external folder (outside the your document root) .The full path is the actual file path, in my case: C:\….\Zend\Apache2\htdocs\…

And last but not least, remember to permit access to the external folder, like this:

<Directory /path/to/your/folder> –>Use ‘/’ instead of ‘\’ for path separator!

Order allow,deny

Allow from all

</Directory>

Posted in Tips | Tagged , , , | Leave a comment

Remove all dependency lookups in Spring application

Dependency lookup is a call to any method on a Spring Container’s bean factory in your app. It is used for retrieving a bean from another bean. It may be of use in a circumstance where a bean needs to collaborate with another bean having different scope (or lifecycle). specifically, between a singleton and a prototype bean.

To make use of dependency lookup, just simply make your bean (typically the singleton bean) implement the ApplicationContextAware, which will let your bean access the ApplicationContext. After that, you can make a call to the getBean() method of the ApplicationContext to retrieve the bean you need, as shown below:

Listing 1. Using Dependency Lookup in business code

protected Foo createBean() {
    return this.applicationContext.getBean("foo", Foo.class);
}

This approach is, however,  not recommended. Because your business code is coupled to the Spring Framework, and it breaks the Inversion of Control principle.

As far as I know, there are two solutions to this.

1. Lookup Injection: First, you can make use of the so-called lookup injection feature of Spring Framework. To get things done, simply make the method createBean() above abstract, as shown below:

Listing 2. Modified createBean() method

protected abstract Foo createBean();

But where is the implementation? Well, Spring will take care of that. All you have to do is registering this method as a lookup method in your configuration metadata, and Spring will automatically implement it at runtime.

Listing 3. Register the lookup method


<bean id="foo" class="x.y.Foo" scope="prototype">
</bean>
<bean id="bar" class="x.y.Bar">
<lookup-method name="createBean" bean="foo"/>
</bean>

2. Employ the ServiceLocatorFactory: The second approach is to use the ServiceLocatorFactoryBean class. To make use of it, create a new interface FooCreator:

Listing 4. The FooCreator interface

public interface FooCreator {
    Foo createFoo(String fooId);
}

As you can see, this approach this similar to the previous.  Again, where’s the implementation? And yet again, all you have to do is registering a few things at your configuration metadata, as shown below:

Listing 5. Register your bean factory

<bean id="myFooCreator" class="org.springframework.beans.factory.config.ServiceLocatorFactoryBean">
    <property name="serviceLocatorInterface" value="x.y.FooCreator">
</bean>

To retrieve the foo bean (the one with a prototype scope) in another bean, just make a call:

Foo f = myFooCreator.createFoo("foo");

Bear in mind that the myFooCreator bean above is just a dynamic proxy created by Spring at runtime, and Spring requires the CGLIB library to handle that, so make sure you have the CGLIB in your classpath.

Conclusion

You should not use dependency lookup in your business code, as it forgo the Dependency Injection, which is the core principle of Spring Framework, and it couple your business code to the Spring Framework. Instead, you should use the Lookup Injection feature of Spring, or make use of the ServiceLocatorFactoryBean, which allows you to create a custom locator.

P/S: You should consult this article: http://java-x.blogspot.com/2007/01/spring-prototype-beans-with-singletons.html, as I see it very useful.

Posted in Tips | Tagged , , , | 2 Comments

Building a simple EJB application

Enterprise JavaBeans (EJB) technology is the server-side component architecture for Java Platform, Enterprise Edition (Java EE). EJB technology enables rapid and simplified development of distributed, transactional, secure and portable applications based on Java technology.

In this tutorial, I will show you how to build a very simple application using the EJB Technology: the ‘notorious’ Hello World application

Before getting into work, you should prepare some materials, they are:

J2EE Application Server of your choice. There are plenty application servers that you can use, opensource, closed source, commercial, community, etc. However, in this tutorial I will only mention Sun Java System Application Server PE 8.2. For others, the recipe is similar.

Ok, that’s all about preparation. Now let’s get our hand into work.
Our recipe contains 6 steps:

  1. Installing & Configuring
  2. Creating Project
  3. Implementing
  4. Creating Deployment Descriptor
  5. Packaging & Deploying
  6. Implementing Client

Remember that you can implement the client for your EJB-based application in any language of your choice, but I prefer Java for convenient.

Ok, let’s see what we have to do in our 6-step recipe.

Step 1: Installing and configuring

There’s not much to say in this step. Seemingly, you don’t have to do anything after installing the J2EE Application Server (AS). But there is an issue that almost AS use their own JDK. So if the JDK of the AS has a different version from the JDK you use to compile your EJB application, a “Bad version number” exception will be thrown when deploying (step 5).

To remedy this, you need to point the JDK of the AS to a proper one (the one that you use to compile your app).

For example, with SJSAS you have to:

  1. Open <install_dir>/config/asenv.bat (<install_dir> refers to the directory where you install the SJSAS)
  2. Search for “AS_JAVA” (without the quotes) and change its value to the path of your JDK, for example:
  3. set AS_JAVA=C:\Program Files\Java\jdk1.6.0_12
  4. Restart the application server, if needed

Step 2: Creating Project in Eclipse

Again, not much to say in this step. Change the Target Runtime to your AS. Choose “J2EE Runtime Library” if you install SJSAS. Pay attention when choosing the JRE. Anyway, the JDK when compiling must have the same version as that of the AS.

Step 3: Implementing

Let say we are going to build a EJB application that return the String “Hello World” to a (local/remote) client on demand.

You need 3 classes for your EJB application:

  • EJB Home/EJB Home Local: Client uses this class to retrieve the EJB instance from your server. It is similiar to a factory class.
  • EJB Remote/EJB Local: Client uses this class to interfacing with the actual EJB object (which is hidden from the client).
  • EJB Class: The main class, containing your actual business code and is hidden from clients.

First, create the EJB Home class (well in fact, it is an interface). Every home classes must extend the EJBHome class, and contain create() method, as shown in Listing 1.

Listing 1. HelloworldHome.java

package com.griever.simpleejb;
import java.rmi.RemoteException;

import javax.ejb.CreateException;
import javax.ejb.EJBHome;

public interface HelloworldHome extends EJBHome {

    public HelloworldEJBRemote create() throws CreateException, RemoteException;
}

If you create your EJB as a remote EJB (which is typically in most cases), you must declare the throws RemoteException, as example above.

Second, create the HelloworldEJBRemote class, which contain the abstract business method (in this tutorial, the sayHello() method).

Listing 2. HelloworldEJBRemote.java

package com.griever.simpleejb;
import java.rmi.Remote;
import java.rmi.RemoteException;

import javax.ejb.EJBObject;

public interface HelloworldEJBRemote extends EJBObject, Remote {

    public String sayHello() throws RemoteException;
}

If your EJB is remote, you must extends the Remote class, as well as declare the throws RemoteException.

Finally, create our main class, HelloworldEJB, which contains our actual business code (in this case, return the String “Helloworld”)

This class must implement one of the three types of EJB, these are: Session Bean (which is divided into Stateful and Stateless), Message-driven Bean or Entity Bean.

The session bean is used for performing some tasks for a client. This type of bean is the most appropriate in this tutorial.

The entity bean represents a business entity object that exists in persistent storage. IMHO, this type of bean is similar to the Model in the MVC architecture, although sometimes the Model may not has access to the persistent storage (database).

The message bean acts as a listener for the Java Message Service (JMS) API, processing messages asynchronously.

For more info, consult the following tutorial: http://java.sun.com/j2ee/tutorial/1_3-fcs/doc/EJBConcepts2.html

Ok, let our EJB class extends the SessionBean, as described above.

Listing 3. HelloworldEJB.java

package com.griever.simpleejb;

import java.rmi.RemoteException;

import javax.ejb.EJBException;
import javax.ejb.SessionBean;
import javax.ejb.SessionContext;

/**
 * Session Bean implementation class HelloworldEJB
 */
public class HelloworldEJB implements SessionBean    {

    /**
     * Default constructor.
     */
    public HelloworldEJB() {
        // TODO Auto-generated constructor stub
    }

    public String sayHello()    {
        // TODO Auto-generated method stub
        return "helloworld";
    }

    //some life-cycle callback method
    ...
}

Well, it is very simple, containing only one method, which returns the string “helloworld”. And pay attention to the last comment. This class must implements the life-cycle callback methods. These methods are automatically called by EJB container, i.e the Application Server (that’s why it’s named callback methods) at specific time. You should consult this tutorial for detailed instructions of all lifecycle callback method: http://java.sun.com/j2ee/tutorial/1_3-fcs/doc/EJBConcepts9.html

Well, that’s all for this step, phew.

Step 4: Creating deployment descriptors

A deployment descriptor is an XML file that specifies information about the bean such as its persistence type and transaction attributes.

In this step we need 2 descriptors:

  • One for the EJB itself, put in ejb-jar.xml. This descriptor specifies the structure of the EJB (the home class, the home interface, and the concrete class). The schema of this descriptor is EJB version-specific
  • One for the Application Server, depending on the Application Server, in SJSAS it is put in sun-ejb-jar.xml. The schema of this descriptor is Application Server-specific

Let’s look at the ejb-jar.xml:

Listing 4. ejb-jar.xml

<?xml version=”1.0″ encoding=”UTF-8″?>
<ejb-jar xmlns=”http://java.sun.com/xml/ns/j2ee&#8221; xmlns:ejb=”http://java.sun.com/xml/ns/javaee/ejb-jar_3_0.xsd&#8221; xmlns:xsi=”http://www.w3.org/2001/XMLSchema-instance&#8221; version=”2.1″ xsi:schemaLocation=”http://java.sun.com/xml/ns/j2eehttp://java.sun.com/xml/ns/j2ee/ejb-jar_2_1.xsd Java EE : XML Schemas for Java EE Deployment Descriptorshttp://java.sun.com/xml/ns/javaee/ejb-jar_3_0.xsd”&gt;
<display-name>SimpleEJB</display-name>
<enterprise-beans>
<session>
<description>Helloworld EJB</description>
<display-name>Helloworld EJB</display-name>
<ejb-name>Helloworld</ejb-name>

<home>com.griever.simpleejb.HelloworldHome</home>
<remote>com.griever.simpleejb.HelloworldEJBRemot e</remote>
<ejb-class>com.griever.simpleejb.HelloworldEJB</ejb-class>
<session-type>Stateless</session-type>
<transaction-type>Container</transaction-type>
</session>
</enterprise-beans>
</ejb-jar>

Let’s take a closer look at the meaning of each tag:

  • display-name: The name displayed in the EJB container of our application.
  • enterprise-beans: This is where we put all EJBs descriptions.
  • session: A session EJB.
  • description: Description of our EJB.
  • display-name: The name displayed in the EJB container of our EJB.
  • ejb-name: The name of our EJB. Which differentiate it from other EJBs.
  • home: The home class, in this case, HelloworldHome.
  • remote: The bean interface, interacting with client.
  • ejb-class: The actual EJB class, containing our business method.
  • session-type: Type of session bean, which can be Stateful or Stateless.
  • transaction-type: Type of transaction, which can be container-managed or bean-managed.
  • […]

Then, the sun-ejb-jar.xml:

Listing 5. sun-ejb-jar.xml

<?xml version=”1.0″ encoding=”UTF-8″?>
<!DOCTYPE sun-ejb-jar PUBLIC “-//Sun Microsystems, Inc.//DTD Application Server 8.1 EJB 2.1//EN” “http://www.sun.com/software/appserver/dtds/sun-ejb-jar_2_1-1.dtd”><sun-ejb-jar&gt;
<enterprise-beans>
<name>SimpleEJB</name>
<ejb>
<ejb-name>Helloworld</ejb-name>
<jndi-name>Helloworld</jndi-name>
</ejb>
</enterprise-beans>
</sun-ejb-jar>

Pay attention to the following tags:

  • ejb-name: The name of the ejb, as specified in ejb-jar.xml
  • jndi-name: The JNDI name. JNDI naming services will look up our EJB (or any other resources) via JNDI name. So, in our example, clients can retrieve our EJB using a JNDI naming service via its JNDI name “Helloworld”.

Step 5. Packaging and Deploying

First, package our application into a JAR file. Very easy, huh?

Second, deploy it in our AS. If you use SJSAS, you can use the asadmin tool (CLI) or the Admin Console (Web-based). To use the Admin Console, point your browser to the Admin Console address, typically http://localhost:48484. After logging in, there is an EJB section in the left panel. This section allows you to view all deployed EJBs, their states, and to deploy new EJBs. You can do the rest yourself, it is very easy.

Step 6. Implementing the Client

The client of an EJB is anything using the services provided by that EJB. It may be another EJB, a web client, an application client, a standalone client or a program in other languages.

In this tutorial, we will create a standalone client. Well, it is very simple, just have a main method (the entry-point of every applications, you know), doing the following steps:

  1. Use JNDI naming service to retrieve the Home class.
  2. Retrieve the EJB interface via Home class.
  3. Call the method sayHello() to get the “helloworld” String.

Let’s look into it!

package com.griever.simpleejb;

import javax.naming.Context;
import javax.naming.InitialContext;
import javax.rmi.PortableRemoteObject;

public class Client {

    public static void main(String []args)    {
        new Client();
    }

    public Client()    {
        try    {
            Context ctx = new InitialContext();
            Object obj = ctx.lookup("Helloworld");
            HelloworldHome home = (HelloworldHome) PortableRemoteObject.narrow(obj, HelloworldHome.class);
            HelloworldEJBRemote remoteEJB = home.create();
            System.out.println(remoteEJB.sayHello());
        } catch (Exception ex)    {
            ex.printStackTrace();
        }
    }
}

Pay attention to the first line: it creates a new instance of the InitialContext. This will invoke a JNDI naming service so that the client can lookup for remote resources via JNDI name. But where’s the location of the JNDI naming service? Well, for a flexible application, you should not specify that location explicitly in the application (or in other word, you should not hardcode the location of the JNDI naming service). You should specify them via environment properties when starting the client, which will be described as below:

  • java.naming.factory.initial: The context factory.
  • java.naming.provider.url: The provider url, that means the url of the JNDI naming service.
  • […]

Refers to the document of your AS for detailed instructions.

All remaining lines are straight-forward and easy to understand (I hope :D).

Well, that’s all for our “simple stupid” application. This is EJB 2.1-compliant. I will post another tutorial for EJB 3.0 in the next tutorial. Phew.

Posted in My Tuts | Tagged , | 3 Comments

Hello World! Using OSGi Framework – Part V

Previous: Hello World! Using OSGi Framework – Part IV

Creating a service factory

In the last section you learned how to use the OSGi framework to create a Java object and register it as service to be consumed by any other bundle. If you look at the HelloServiceActivator.start()method you will notice that we created an object of theHelloServiceImpl class in the start method and registered it under the name of HelloService interface. Thereafter, whenever any bundle asks for the HelloService service, the OSGi container will return the same object.

This implementation will work for most common use cases. But let’s say you want to return a different object of the HelloServiceImplclass for every consumer bundle. Alternately, let’s say your service object needs to open a connection to a database and you don’t want to open the connection unless someone really needs the service.

In either case, the solution is to create a class implementing theServiceFactory interface and register its object, instead of the actual service object, as a service. Once you do that, yourServiceFactory class will take control whenever any bundle requests the service. ServiceFactory will create a new object ofService for every bundle, and will also delay creation of the actual service until someone really needs it.

Follow these steps to change the implementation of thecom.javaworld.sample.HelloService bundle developed in the last section to use a ServiceFactory:

  1. Create the factory classHelloServiceFactory.java, as shown in Listing 9.

    Listing 9. Create HelloServiceFactory.java

  2. public class HelloServiceFactory implements ServiceFactory{
        private int usageCounter = 0;
        public Object getService(Bundle bundle, ServiceRegistration registration) {
            System.out.println("Create object of HelloService for " + bundle.getSymbolicName());
            usageCounter++;
            System.out.println("Number of bundles using service " + usageCounter);
            HelloService helloService = new HelloServiceImpl();
            return helloService;
        }
        public void ungetService(Bundle bundle, ServiceRegistration registration, Object service) {
            System.out.println("Release object of HelloService for " + bundle.getSymbolicName());
            usageCounter--;
            System.out.println("Number of bundles using service " + usageCounter);
        }
    }
  3. The ServiceFactory interface defines two methods:
    • getService(): The OSGi framework invokes this method the first time the specified bundle requests a service object using theBundleContext.getService(ServiceReference) method. In Listing 9, we use this method to create a different object ofHelloServiceImpl for every bundle, and we return that object. The OSGi framework caches the value returned (unless it is null), and will return the same service object on any future calls to BundleContext.getService() from the same bundle.
    • ungetService(): The OSGi container invokes this method when a service has been released by a bundle. The service object may then be destroyed. In Listing 9, we use this method to reduce the usageCount of the service and print the number of clients for the service.
  4. Change HelloServiceActivator.java and modify the start() method of your activator so that it will register objects ofServiceFactory instead of HelloService, as shown in Listing 10:

    Listing 10. Changes to HelloServiceActivator.java

public class HelloServiceActivator implements BundleActivator  {
    ServiceRegistration helloServiceRegistration;
    public void start(BundleContext context) throws Exception {
        HelloServiceFactory helloServiceFactory = new HelloServiceFactory();
        helloServiceRegistration =context.registerService(HelloService.class.getName(), helloServiceFactory, null);
    }
    public void stop(BundleContext context) throws Exception {
        helloServiceRegistration.unregister();
    }
}

Now try running this sample code. You should notice that it prints the service usage count as one (1) when HelloWorldbundle is started and zero (0) when the HelloWorld bundle is stopped.

Tracking services

In the “OSGi services” section you learned how to search for a service using its interface name. But what happens if more than one bundle registers a service under the same interface name? In that case the OSGi container will return the service with the highest ranking — that is, the service that is registered with the highest valued SERVICE_RANKING property. If more than one service has an equally valued SERVICE_RANKING property, then the OSGi container will return the service with the lowest PID.

But let’s say that you are creating a consumer that needs to know whenever an object is registered or unregistered under a particular interface. In this situation, you should use the ServiceTracker class. Let’s see what happens when we change the sample code to utilize a service tracker, as described below.

  1. Change the MANIFEST.MF for your HelloWorld bundle to import the org.osgi.util.tracker package.
  2. Create HelloServiceTracker.java as shown in Listing 11.

    Listing 11. HelloServiceTracker.java

  3. public class HelloServiceTracker extends ServiceTracker {
        public HelloServiceTracker(BundleContext context) {
            super(context, HelloService.class.getName(),null);
        }
        public Object addingService(ServiceReference reference) {
            System.out.println("Inside HelloServiceTracker.addingService " + reference.getBundle());
            return super.addingService(reference);
        }
        public void removedService(ServiceReference reference, Object service) {
            System.out.println("Inside HelloServiceTracker.removedService " + reference.getBundle());
            super.removedService(reference, service);
        }
    }
  4. As you can see in the constructor of the HelloServiceTracker class, we are passing the name of the HelloService interface to its super class, which is the equivalent of saying that HelloServiceTracker should track services registered under theHelloService interface name. The HelloServiceTracker class extends the ServiceTracker class and implements two methods:
    • addingService() is called when a bundle registers a service under the given interface name.
    • removedService() is called when a bundle unregisters a service under the given interface name.
  5. Change Activator.java so that it starts using the HelloServiceTracker class to manage services instead of looking them up directly, as shown in Listing 12.

    Listing 12. Activator.java uses HelloServiceTracker

  6. public class Activator implements BundleActivator {
        HelloServiceTracker helloServiceTracker;
        public void start(BundleContext context) throws Exception {
            System.out.println("Hello World!!");
            helloServiceTracker= new HelloServiceTracker(context);
            helloServiceTracker.open();
            HelloService helloService = (HelloService)helloServiceTracker.getService();
            System.out.println(helloService.sayHello());
    
        }
        public void stop(BundleContext context) throws Exception {
            System.out.println("Goodbye World!!");
            helloServiceTracker.close();
        }
    }
  7. In the initial start() method we first create a HelloServiceTracker object, then we ask HelloServiceTracker to start tracking the underlying service. A call to getService() will now get the HelloService object.

If you try executing this sample you will notice that whenever you start or stop the HelloService bundle it will result in a call to either the addingService() or removedService() method of the HelloServiceTracker object.

In conclusion

In this first article in the three-part Hello, OSGi series, I’ve introduced you to the basic concepts of modular application development with OSGi. You’ve learned about the three currently available open source OSGi containers and walked through the steps to develop a simple component bundle using Equinox, the fully OSGi-compliant Eclipse container. You’ve also learned how bundles can interact by importing and exporting each other’s packages and services.

In this article you may have noticed one of the challenges of developing OSGi bundles: that each of your bundles needs to be aware of OSGi AP. In some development scenarios this could mean writing a lot of infrastructure code. In the next article in the Hello, OSGi series I’ll introduce you to the Spring Dynamic Modules for OSGi Service Platforms project, which simplifies development of Spring-based OSGi bundles. See the Resources section in the meantime, to learn more about OSGi.

Source: http://www.javaworld.com/javaworld/jw-03-2008/jw-03-osgi1.html

Posted in Archives | 1 Comment

Hello World! Using OSGi Framework – Part IV

Previous: Hello World! Using OSGi Framework – Part III

Class-level scope

If you try running the sample service package now it will print “Hello World” on your Eclipse console. If you try running Activator.java to access HelloServiceImpl.java and compile it with the normal javaccomplier, it will compile. If you try to execute this bundle in an OSGi container, however, it will throw an exception.

How is the OSGi container able to hide a few classes from the .jar file while others are visible? The answer is that the OSGi container uses the Java class loader to manage class visibility. The OSGi container creates a different class loader for every bundle. The bundle can therefore access classes from

  • Boot classpath: Contains the java.* packages.
  • Framework classpath: Usually has a separate class loader for the framework implementation classes as well as key service interface classes.
  • Bundle space: Consists of the JAR file that is associated with the bundle plus any additional JARs that are closely tied to the bundle, like fragments.
  • Imported packages: For instance, the HelloWorld bundle imports thecom.javaworld.sample.service package so it can access classes from that package.

The bundle-level scope is a powerful feature allowing you (for instance) to safely change the HelloServiceImpl.java class without worrying that dependent code might break.

OSGi services

As previously mentioned, the OSGi architecture is a very good candidate for implementing service-oriented applications. It allows bundles to export services that can be consumed by other bundles without knowing anything about the exporting bundle. Taken with the ability to hide the actual service implementation class, OSGi provides a perfect combination for service-oriented applications.

In OSGi, a source bundle registers a POJO (you don’t have to implement any interfaces or extend from any superclass) with the OSGi container as a service under one or more interfaces. The target bundle can then ask the OSGi container for services registered under a particular interface. Once the service is found, the target bundle binds with it and can start calling its methods. As with other OSGi concepts, a sample application will make all of this more clear.

Exporting services

In this section we will change the HelloService bundle so that it exports objects of the HelloServiceImpl.java class as a service. Here are the steps to set up the sample application:

  1. Change the MANIFEST.MF for com.javaworld.sample.HelloService to import the org.osgi.framework package.
  2. Create the com.javaworld.sample.service.impl.HelloServiceActivator.java as shown in Listing 7.

    Listing 7. Create HelloServiceActivator.java

  3. public class HelloServiceActivator implements BundleActivator  {
        ServiceRegistration helloServiceRegistration;
        public void start(BundleContext context) throws Exception {
            HelloService helloService = new HelloServiceImpl();
            helloServiceRegistration =context.registerService(HelloService.class.getName(), helloService, null);
        }
        public void stop(BundleContext context) throws Exception {
            helloServiceRegistration.unregister();
        }
    }
  4. Note that the source bundle should use the BundleContext.registerService() method to export the service. It takes three parameters:
    • The name of the interface under which you want to register the service. If you want to register the service under multiple interfaces then you should create a String array of interface names and pass it as your first argument. In the sample code we want to export the service under the name of HelloService interface.
    • The actual Java object that you want to register as a service. In our sample code we are exporting objects of theHelloServiceImpl class as the service.
    • Properties of the service, in this case a Dictionary object. If more than one bundle exports a service under the same interface name then the target object can use these properties to filter out the service that it is interested in.
  5. The last step is to change the MANIFEST.MF file of the HelloService bundle to declare HelloServiceActivator as the bundle’s activator class. To do that, simply add com.javaworld.sample.service.impl.HelloServiceActivator as the value of theBundle-Activator header in your MANIFEST.MF file.

Now the HelloService bundle is ready to export objects of the HelloServiceImpl class. When the OSGi container starts theHelloService bundle it will pass control to HelloServiceActivator.java, which will register an object of HelloServiceImpl as a service. The next step is to create the service consumer.

Importing the service

In this section we will change the HelloWorld bundle developed in the last section so that it acts as a consumer of theHelloService service. The main thing you need to do is change the Activator.java for the HelloWorld bundle as shown in Listing 8.

Listing 8. HelloWorldActivator.java

public class Activator implements BundleActivator {
    ServiceReference helloServiceReference;
    public void start(BundleContext context) throws Exception {
        System.out.println("Hello World!!");
        helloServiceReference= context.getServiceReference(HelloService.class.getName());
        HelloService helloService =(HelloService)context.getService(helloServiceReference);
        System.out.println(helloService.sayHello());

    }
    public void stop(BundleContext context) throws Exception {
        System.out.println("Goodbye World!!");
        context.ungetService(helloServiceReference);
    }
}

The BundleContext.getServiceReference() method returns a ServiceReference object for a service registered under theHelloService interface. If multiple such services exist, the service with the highest ranking (as specified in itsConstants.SERVICE_RANKING property) is returned. Once you have the object of ServiceReference you can call itsBundleContext.getService() method to get the actual service object.

You can run this sample the same way you would execute any bundle, by clicking Run –> Run Simply make sure that both the HelloWorld and HelloService bundles are checked in as plugins. When you start the HelloService bundle, you will see the message “Inside HelloServiceImple.sayHello()” printed from the HelloServiceImpl.sayHello() method.

Next: Hello World! Using OSGi Framework – Part V

Source: http://www.javaworld.com/javaworld/jw-03-2008/jw-03-osgi1.html

Posted in Archives | 2 Comments

Hello World! Using OSGi Framework – Part III

Previous: Hello World! Using OSGi Framework – Part II

The OSGi console

The OSGi console is a command-line interface to the OSGi container. It allows you to do things like start, stop, install bundles, and update or delete bundles. In your Eclipse IDE, click the console view to give focus to that view, then click Enter and you will get an OSGi prompt like the one shown in Figure 2 (click to enlarge).

A screenshot of the OSGi console.
Figure 2. HelloWorldActivator.java in the OSGi console


Here are some of the commonly used OSGi commands that you can use to interact with your OSGi container:

  • ss displays a list of installed bundles with the status of each bundle. It will display the bundle ID, short name, and status of the bundle.
  • start <bundleid> starts a bundle.
  • stop <bundleid> stops a bundle.
  • update <bundleid> updates a bundle with a new JAR file.
  • install <bundleURL> installs a new bundle into the OSGi container.
  • uninstall <bundleid> uninstalls already installed bundles from the OSGi container.

Note that these commands are defined in the OSGi specification so you can use them to interact with any of the OSGi containers.

Dependency management

The OSGi specification allows you to break your application into multiple modules and then manage their dependencies on each other. It does this by adding a bundle scope. By default, none of the classes in a bundle are visible from any other bundle; inside bundles they follow the normal rules of the Java language. So, what do you do if you want to access the classes of one bundle from another bundle? The solution is to export packages from the source bundle and then import them into the target bundle. In this section we’ll walk through a sample application that demonstrates this concept.

First, we will create a com.javaworld.sample.HelloService bundle, which will export a package. Then we will import the package into our com.javaworld.sample.HelloWorld bundle.

Exporting a package

We’ll start by creating the com.javaworld.sample.HelloService bundle and exporting a package from it. Follow these steps to create the bundle and export the package:

  • Create the com.javaworld.sample.HelloService bundle by following the same steps used to create thecom.javaworld.sample.HelloWorld bundle in the previous section.
  • Inside the HelloService bundle, create a com.javaworld.sample.service.HelloService.java interface, as shown in Listing 3

Listing 3. HelloService.java

public interface HelloService {
    public String sayHello();
}

  • Now create a com.javaworld.sample.service.impl.HelloServiceImpl.java class implementing the HelloServiceinterface, as shown in Listing 4.

Listing 4. HelloServiceImpl.java

public class HelloServiceImpl implements HelloService{
    public String sayHello() {
        System.out.println("Inside HelloServiceImple.sayHello()");
        return "Say Hello";
    }
}
  • Open the MANIFEST.MF for the HelloService package in your Eclipse Manifest editor and go to the Runtime tab. In the Exported Packages section, click Add and select the com.javaworld.sample.service package. The MANIFEST.MF file for theHelloService bundle should look like the one in Listing 5.

Listing 5. Manifest for HelloService bundle

Manifest-Version: 1.0
 Bundle-ManifestVersion: 2
 Bundle-Name: HelloService Plug-in
 Bundle-SymbolicName: com.javaworld.sample.HelloService
 Bundle-Version: 1.0.0
 Bundle-Vendor: JAVAWORLD
 Bundle-Localization: plugin
 Export-Package: com.javaworld.sample.service
 Import-Package: org.osgi.framework;version="1.3.0"

As you can see, the MANIFEST.MF file for the HelloService bundle looks very similar to that of the HelloWorld bundle. The only difference is that this MANIFEST.MF file has one Export-Package manifest header, whose value iscom.javaworld.simple.service.

The Export-Package manifest header informs the OSGi container that classes in the com.javaworld.sample.service package from the HelloService bundle can be accessed from outside. Note that in the sample code we have exposed a HelloServiceinterface but not the HelloServiceImpl implementation class.

Importing a package

The next step is to update the HelloWorld bundle to import the com.javaworld.simple.service package. Here are the steps to import the package:

  • In the com.javaworld.sample.HelloWorld bundle, open the MANIFEST.MF file in the Plug-in Manifest editor. Now go to the Dependencies tab, and then to Imported Packages. Add com.javaworld.sample.service as the value of Imported Packages. The MANIFEST.MF file for your HelloWorld bundle should look like the one in Listing 6.

Listing 6. Manifest for the updated HelloWorld bundle

Manifest-Version: 1.0
Bundle-ManifestVersion: 2
Bundle-Name: HelloWorld Plug-in
Bundle-SymbolicName: com.javaworld.sample.HelloWorld
Bundle-Version: 1.0.0
Bundle-Activator: com.javaworld.sample.helloworld.Activator
Bundle-Vendor: JAVAWORLD
Bundle-Localization: plugin
Import-Package: com.javaworld.sample.service,
 org.osgi.framework;version="1.3.0"
  • As you can see, the value of the Import-Package header is a comma-separated list of packages that this bundle wants to import. In the sample code the HelloWorld bundle imports two packages: com.javaworld.sample.service and org.osgi.framework.
  • The org.osgi.framework package contains OSGi framework classes such as BundleContext and BundleActivator, which are used by the Activator.java class of the HelloWorld bundle.
  • Next, open com.javaworld.sample.helloworld.Activator.java in the Eclipse Java editor. You will notice that you are now able to access the HelloService interface but not the HelloServiceImpl class. This is because the HelloService package exports (and the HelloWorld package imports) the com.javaworld.sample.service package. HelloServiceImpl is an internal class for the HelloService bundle and no other bundle can access it.

Next: Hello World! Using OSGi Framework – Part IV

Source: http://www.javaworld.com/javaworld/jw-03-2008/jw-03-osgi1.html

Posted in Archives | 2 Comments

Hello World! Using OSGi Framework – Part II

Developing a Hello World bundle

Previous: Hello World! Using OSGi Framework – Part I

In OSGi, software is distributed in the form of a bundle. A bundle consists of Java classes and other resources that deliver functions to device owners, as well as providing services and packages to other bundles. Eclipse offers excellent support for developing OSGi bundles. Not only does it provide wizards for creating OSGi bundles, it also has an embedded Equinox OSGi container that you can use to execute and debug OSGi plugins. Note that every Eclipse plug-in is essentially an OSGi bundle with some additional Eclipse-specific code. Eclipse also allows you to build standard-compliant OSGi bundles without code specific to Eclipse. In this section you’ll learn how to develop a Hello World OSGi bundle using the Eclipse IDE.

Creating the bundle

Follow the steps below to create a Hello World bundle using OSGi and Eclipse.

  1. In Eclipse, click on File –> New –> Project. A New Project dialog will open.
  2. In the New Project dialog, select Plug-in Project and click Next. The Plug-in Project dialog will open.
  3. In the Plug-in Project dialog, enter the following values:
    • Project Name: com.javaworld.sample.HelloWorld
    • Target Platform: OSGi framework –> Standard
  4. Use default values for the remaining input and click Next. The Plug-in Context dialog will open.
  5. Select the default values for the Plug-in Context dialog and click Next.
  6. In the Templates dialog you’ll find only one entry in Available Templates: Hello OSGi Bundle. Select it and click Finish.

Eclipse will take few seconds to generate template code for the Hello World bundle. It will create two files: Activator.java andMANIFEST.MF. We’ll take a closer look at them both.

Activator.java

Your Activator.java file should look as shown in Listing 1.

Listing 1. Activator.java


package com.javaworld.sample.helloworld;
import org.osgi.framework.BundleActivator;
import org.osgi.framework.BundleContext;
public class Activator implements BundleActivator {
    public void start(BundleContext context) throws Exception {
        System.out.println("Hello world");
    }
    public void stop(BundleContext context) throws Exception {
        System.out.println("Goodbye World");
    }
}

If your bundle needs to be notified at the time of bundle startup or shutdown then you should create a class implementing theBundleActivator interface. Follow these rules when creating the class:

  • The BundleActivator class must have a public constructor that takes no parameters. The OSGi framework can create aBundleActivator object by calling Class.newInstance().
  • The container will call the start() method of your Activator class to start the bundle. The bundle can take this opportunity to perform resource initialization such as getting a database connection for future use. The start() method takes one argument, the BundleContextobject. This object allows bundles to interact with the framework by providing access to OSGi-container-related information. If an exception is thrown for a particular bundle the container will mark that bundle as stopped and will not put it into service.
  • The container will call the stop() method of your Activator class to report that it is shutting down a bundle. You can use this opportunity to perform cleanup tasks such as releasing the database connection.

Once your Activator class is ready you should relay its fully qualified name to the container using your MANIFEST.MF file.

MANIFEST.MF

The MANIFEST.MF file acts as deployment descriptor for your bundle. The format for this file is the same as that of a normal JAR file, so it consists of a set of headers with values. The OSGi specification defines a set of headers that you can use to describe your bundle to the OSGi container. The MANIFEST.MF file for your Hello World bundle should look as shown in Listing 2.

Listing 2. Manifest for the Hello World bundle


Manifest-Version: 1.0
Bundle-ManifestVersion: 2
Bundle-Name: HelloWorld Plug-in
Bundle-SymbolicName: com.javaworld.sample.HelloWorld
Bundle-Version: 1.0.0
Bundle-Activator: com.javaworld.sample.helloworld.Activator
Bundle-Vendor: JAVAWORLD
Bundle-Localization: plugin
Import-Package: org.osgi.framework;version="1.3.0"

Let’s take a closer look at what each of these headers is used for:

Bundle-ManifestVersion
The Bundle-ManifestVersion header tells the OSGi container that this bundle follows the rules of the OSGi specification. A value of 2means that the bundle is compliant with OSGi specification Release 4; a value of 1 means that it is compliant with Release 3 or earlier.
Bundle-Name
The Bundle-Name header defines a short, human-readable name for the bundle.
Bundle-SymbolicName
The Bundle-SymbolicName header specifies a unique, non-localizable name for the bundle. This is the name you will use while referring a given bundle from other bundles.
Bundle-Version
The Bundle-Version header specifies the version of the bundle.
Bundle-Activator
The Bundle-Activator header specifies the name of the optional listener class to be notified of bundle start and stop events. In Listing 2 the value of this header is com.javaworld.sample.helloworld.Activator.
Bundle-Vendor
The Bundle-Vendor header contains a human-readable description of the bundle vendor.
Bundle-Localization
The Bundle-Localization header contains the location in the bundle where localization files can be found. The Hello World bundle doesn’t contain any locale-specific files, but the eclipse IDE still generates this header.
Import-Package
The Import-Package header defines imported packages for the bundle. You’ll learn more about this when I discuss dependency management, later in the article.

The Hello World bundle is ready, so let’s execute it to see the output.

Executing a bundle

As I mentioned earlier, the Eclipse IDE has an embedded Equinox OSGi container that you can use to execute or debug OSGi bundles. Follow these steps to execute the Hello World bundle:

  1. Click on Run –> Run.
  2. Eclipse will open the dialog called “Create, manage and run configuration.” In that dialog, double-click the Equinox OSGi Framework button and it will open a runtime configuration dialog box.
  3. In that dialog, change the value of the Name field to Hello World Bundle.
  4. You will notice that in the Plug-ins section under the Workspace plug-in there is an entry for thecom.javaworld.sample.HelloWorld plugin, which is checked. Under Target Platform, make sure that the checkbox next to theorg.eclipse.osgi plugin is also checked.Your Run dialog should look like the screenshot in Figure 1 (click to enlarge).A screenshot of the Equinox Run dialog in Eclipse.
  5. Now click the Run button. You should see a “Hello world” message in the IDE’s console view. Note that Eclipse actually opens the OSGi console in its console view.

Next: Hello World! Using OSGi Framework – Part III

Source: http://www.javaworld.com/javaworld/jw-03-2008/jw-03-osgi1.html

Posted in Archives | 2 Comments

Hello world! Using OSGi framework – Part I

The Open Services Gateway Initiative (OSGi) defines an architecture for developing and deploying modular applications and libraries. In this first article in a three-part introduction to OSGi, Sunil Patil gets you started with OSGi development concepts and shows you how to build a simple Hello World application using the Eclipse OSGi container implementation, Equinox. He also touches briefly on building service-oriented applications using OSGi and introduces OSGi’s ServiceFactory and ServiceTracker classes.

The Open Services Gateway Initiative (OSGi), also known as theDynamic Module System for Java, defines an architecture for modular application development. OSGi container implementations such as KnopflerfishEquinox, and Apache Felix allow you to break your application into multiple modules and thus more easily manage cross-dependencies between them.

Similar to the Java Servlet and EJB specifications, the OSGi specification defines two things: a set of services that an OSGi container must implement and a contract between the container and your application. Developing on the OSGi platform means first building your application using OSGi APIs, then deploying it in an OSGi container. From a developer’s perspective, OSGi offers the following advantages:

  • You can install, uninstall, start, and stop different modules of your application dynamically without restarting the container.
  • Your application can have more than one version of a particular module running at the same time.
  • OSGi provides very good infrastructure for developing service-oriented applications, as well as embedded, mobile, and rich internet apps.

Given that you use servlet containers for building Web applications and EJB containers for building transactional applications, you may be wondering why you need yet another type of container. The short answer is that OSGi containers are intended specifically for developing complex Java applications that you want to break up into modules. I’ll expand on that short answer throughout this series.

OSGi in enterprise applications

Work on the OSGi specification was started by the OSGi Alliance in March 1999. Its main goal was to create an open specification for delivering managed services to local networks and devices. The basic idea is that once you add an OSGi Service Platform to a networked device (embedded as well as servers), you should be able to manage the lifecycle of software components in that device from anywhere in the network. Software components can be installed, updated, or removed on the fly without ever having to disrupt the operation of the device.

For years, OSGi technology has flourished in the embedded systems and network devices market. Now, thanks in part to Eclipse, OSGi is emerging as a viable and valuable technology for enterprise development.

Growing support for OSGi

In 2003, the Eclipse development team began looking for ways to make Eclipse a more dynamic rich client platform and increase the toolset’s modularity. Eventually, the team settled on using the OSGi framework as a runtime component model. Eclipse 3.0, released in June of 2004, was the first version of Eclipse based on OSGi.

Almost all enterprise application servers support or plan to support OSGi. The Spring framework also supports OSGi, via theSpring Dynamic Modules for OSGi Service Platforms project, which provides an infrastructure layer to make it easier to use OSGi in Spring-based Java enterprise application development.

Open source OSGi containers

From an enterprise developer’s point of view, the OSGi container has such a low footprint that you can easily embed it into an enterprise application. For example, let’s say you’re developing a complex Web application. You want to break the application into multiple modules: one module for the view layer, another for the DAO layer, and a third module for the data access layer. Using an embedded OSGi container to manage the cross-dependencies of these modules would enable you to update your DAO layer (say from slow DAO to fast DAO) without restarting your application.

As long as your application is compliant with the OSGi specification it should be able to run in any OSGi-compliant container. Currently, there are three popular open source OSGi containers:

  • Equinox is the reference implementation for the framework portion of the OSGi Service Platform Release 4. It is the modular Java runtime at the heart of the Eclipse IDE, and implements all of the mandatory and most of the optional features of the OSGi R4 specification.
  • Knopflerfish is an open source implementation of the OSGi R3 and OSGi R4 specifications. Knopflerfish 2 implements all the mandatory features and some of the optional features defined in the R4 specification.
  • Apache Felix is the open source OSGi container from the Apache Software Foundation. At the time of writing this container is not fully compliant with the OSGI R4 specification.

In this article we will use Equinox as our OSGi container. See the Resources section for more information about Apache Felixand Knopflerfish.

Next: Hello World! Using OSGi framework – Part II

Source: http://www.javaworld.com/javaworld/jw-03-2008/jw-03-osgi1.html

Posted in Archives | Leave a comment