{"id":1066,"date":"2012-04-25T13:00:00","date_gmt":"2012-04-25T13:00:00","guid":{"rendered":"http:\/\/www.javacodegeeks.com\/2012\/10\/osgi-modularizing-your-application.html"},"modified":"2012-10-21T23:25:53","modified_gmt":"2012-10-21T23:25:53","slug":"osgi-modularizing-your-application","status":"publish","type":"post","link":"https:\/\/www.javacodegeeks.com\/2012\/04\/osgi-modularizing-your-application.html","title":{"rendered":"OSGI &#8211; Modularizing your application"},"content":{"rendered":"<div dir=\"ltr\" style=\"text-align: left\">Since I am a big proponent of modularity, low coupling, high cohesion, etc \u2026<br \/>\nI believe that this technology is a breakthrough in how we create applications using the Java platform. With OSGi, it is very simple to create highly extensible applications, see for example the Eclipse IDE. My goal here is not to show in depth how the technology works, but to demonstrate a small example of some of its advantages. The sample consists of a system for sending messages. The user types a message into a TextField and this message can be sent in several ways, such as Email or SMS. However, in this example, we have four modules. The graphical user interface, domain, sender of email messages and the sender via SMS.<\/p>\n<p>Following the nomenclature of OSGi, each module is a Bundle. A Bundle is nothing more than a \u201cjar\u201d with some additional information from MANIFEST.MF. This information is used by the OSGi framework. Like almost everything in Java, OSGi technology is a specification and therefore have different implementations to choose from. Among them are the most famous Equinox (Eclipse Project), Felix (Apache) and Knopflerfish. In this article we will use the Equinox.     <\/p>\n<p>Download the Equinox. For this article we only need the jar. Run the jar to access the console of the Equinox.   <\/p>\n<pre class=\"brush:bash\">\r\nC:\\osgi&gt;java -jar org.eclipse.osgi_3.5.1.R35x_v20090827.jar \u2013console\r\n<\/pre>\n<p>To view Bundles installed, simply type the command ss.   <\/p>\n<pre class=\"brush:bash\">\r\nC:\\osgi&gt;java -jar org.eclipse.osgi_3.5.1.R35x_v20090827.jar \u2013 console\r\nosgi&gt; ss\r\n<\/pre>\n<p>Framework is launched.   <\/p>\n<pre class=\"brush:bash\">\r\nid State Bundle&lt;\r\n0 ACTIVE org.eclipse.osgi_3.5.1.R35x_v20090827\r\nosgi&gt; _\r\n<\/pre>\n<p> As we can see at this point we only have one bundle installed. The bundle of Equinox.<br \/>\nNow we\u2019ll create our bundle and add it to Equinox. Create a bundle is very simple.<br \/>\nCreate a simple project with the following class:  <\/p>\n<pre class=\"brush:java\">package br.com.luiscm.helloworld;\r\n\r\nimport org.osgi.framework.BundleActivator;\r\nimport org.osgi.framework.BundleContext;\r\n\r\npublic class Activator implements BundleActivator {\r\n\r\n    \/*\r\n     * (non-Javadoc)\r\n     * @see org.osgi.framework.BundleActivator#start(org.osgi.framework.BundleContext)\r\n     *\/\r\n    public void start(BundleContext context) throws Exception {\r\n        System.out.println(\"Hello World!\");\r\n    }\r\n\r\n    \/*\r\n     * (non-Javadoc)\r\n     * @see org.osgi.framework.BundleActivator#stop(org.osgi.framework.BundleContext)\r\n     *\/\r\n    public void stop(BundleContext context) throws Exception {\r\n        System.out.println(\"Good Bye World!\");\r\n    }\r\n}\r\n<\/pre>\n<p>This class is the Activator of our bundle. The Activator is used by the OSGi framework to start or stop a bundle. In this first example, the Activator will only print messages when started and stopped. Now we need to modify the MANIFEST of the jar to make it an OSGi bundle.    <\/p>\n<pre class=\"brush:bash\">\r\nManifest-Version: 1.0\r\nBundle-ManifestVersion: 2\r\nBundle-Name: LuisCM Plug-in\r\nBundle-SymbolicName: br.com.luiscm.helloworld\r\nBundle-Version: 1.0.0\r\nBundle-Activator: br.com.luiscm.helloworld.Activator\r\nBundle-ActivationPolicy: lazy\r\nBundle-RequiredExcutionEnvironment: JavaSE-1.6\r\nImport-Package: org.osgi.framework;version=\u201d1.3.0?\r\n <\/pre>\n<p>   See the MANIFEST passed to the OSGi bundle some of our information. Among them the name of the bundle (SymbolicName) and the Activator class. Now let\u2019s install this bundle in Equinox. Generate a jar of the project and to install it in Equinox is simple:    <\/p>\n<pre class=\"brush:bash\">\r\ninstall file:.jar\r\nosgi&gt; install file:bundle.jar\r\nBundle id is 1\r\nosgi&gt;\r\n<\/pre>\n<p>    To verify that the bundle was properly installed, simply run the command ss:   <\/p>\n<pre class=\"brush:bash\">\r\nosgi&gt; ss\r\nFramework is launched.\r\nid State Bundle\r\n0 ACTIVE org.eclipse.osgi_3.5.1.R35x_v20090827\r\n1 INSTALLED br.com.luiscm.helloworld_1.0.0\r\nosgi&gt; _\r\n<\/pre>\n<p>   The bundle is properly installed, you just start it now: <\/p>\n<pre class=\"brush:bash\">\r\nstart\r\nosgi&gt; start 1\r\nHello World!\r\nosgi&gt;\r\n <\/pre>\n<p>  To stop the bundle:  <\/p>\n<pre class=\"brush:bash\">\r\nosgi&gt; stop 1\r\nGoodbye World!\r\nosgi&gt;\r\n<\/pre>\n<p>Now that we know how to create a bundle, let\u2019s start our example. In the example, we have four bundles.     <\/p>\n<p>* Domain: As the name says, it stores the domain classes in our example. We will have two classes: Message and IMessageSender.<br \/>\n* SenderSMS: implementation of IMessageSender that sends messages via SMS.<br \/>\n* SenderEmail: implementation of IMessageSender that sends messages by email.<br \/>\n* UI: GUI example     <\/p>\n<p>Bundle UI     <\/p>\n<p>We\u2019ll start with the UI bundle. The activator will just build the frame for the user to enter the message.     <\/p>\n<pre class=\"brush:java\">package br.com.luiscm.helloworld;\r\n\r\nimport java.awt.BorderLayout;\r\nimport java.awt.event.ActionEvent;\r\nimport java.awt.event.ActionListener;\r\n\r\nimport javax.swing.JButton;\r\nimport javax.swing.JFrame;\r\nimport javax.swing.JTextField;\r\n\r\nimport org.osgi.framework.BundleActivator;\r\nimport org.osgi.framework.BundleContext;\r\n\r\nimport br.com.luiscm.helloworld.core.service.Message;\r\n\r\npublic class Activator implements BundleActivator {\r\n\r\n    private Message message;\r\n    private JFrame frame;\r\n\r\n    \/*\r\n     * (non-Javadoc)\r\n     * @see org.osgi.framework.BundleActivator#start(org.osgi.framework.BundleContext)\r\n     *\/\r\n    public void start(BundleContext context) throws Exception {\r\n        buildInterface();\r\n    }\r\n\r\n    \/*\r\n     * (non-Javadoc)\r\n     * @see org.osgi.framework.BundleActivator#stop(org.osgi.framework.BundleContext)\r\n     *\/\r\n    public void stop(BundleContext context) throws Exception {\r\n        destroyInterface();\r\n    }\r\n\r\n    private void destroyInterface() {\r\n        frame.setVisible(false);\r\n        frame.dispose();\r\n    }\r\n\r\n    private void buildInterface() {\r\n        frame = new JFrame(\"Hello\");\r\n        frame.setSize(200, 80);\r\n        frame.getContentPane().setLayout(new BorderLayout());\r\n        final JTextField textField = new JTextField();\r\n\r\n        final JButton button = new JButton(\"Send\");\r\n        button.addActionListener(new ActionListener() {\r\n            @Override\r\n            public void actionPerformed(ActionEvent event) {\r\n                message.send(textField.getText());\r\n            }\r\n        });\r\n\r\n        frame.getContentPane().add(textField, BorderLayout.NORTH);\r\n        frame.getContentPane().add(button, BorderLayout.SOUTH);\r\n        frame.setVisible(true);\r\n    }\r\n}\r\n<\/pre>\n<p>Note that the bundle depends on a class called Message. This class is our domain, so it is not part of this bundle. Here comes another detail of OSGi. The communication is done through bundles of services. We can consider this model as an SOA within the VM. The services bundle UI will use the bundle core. Let\u2019s look at the MANIFEST bundle UI.   <div style=\"display:inline-block; margin: 15px 0;\"> <div id=\"adngin-JavaCodeGeeks_incontent_video-0\" style=\"display:inline-block;\"><\/div> <\/div><\/p>\n<pre class=\"brush:bash\">\r\n\r\nManifest-Version: 1.0\r\nBundle-ManifestVersion: 2\r\nBundle-Name: UI Plug-in\r\nBundle-SymbolicName: br.com.luiscm.helloworld.ui&lt;\r\nBundle-Version: 1.0.0\r\nBundle-Activator: br.com.luiscm.helloworld.ui.Activator\r\nBundle-ActivationPolicy: lazy\r\nBundle-RequiredExecutionEnvironment: JavaSE-1.6\r\nImport-Package: br.com.luiscm.helloworld.core.service,\r\njavax.swing,\r\norg.osgi.framework;version=\u201d1.3.0?,\r\norg.osgi.util.tracker;version=\u201d1.3.6?\r\n<\/pre>\n<p>See the Import-Package statement. We are importing a package bundle core. In this package are the services that our field is providing. Also import the javax.swing package.     <\/p>\n<p>Now we need to create the service.     <\/p>\n<p>Bundle Core     <\/p>\n<p>The Core Bundle has two domain classes. The interface of the senders and the Message field.     <\/p>\n<p>Interface:     <\/p>\n<pre class=\"brush:java\">package br.com.luiscm.helloworld.core.service;\r\n\r\npublic interface IMessageSender {\r\n    void send(String message);\r\n}\r\n<\/pre>\n<p>Domain:     <\/p>\n<pre class=\"brush:java\">package br.com.luiscm.helloworld.core.service;\r\n\r\nimport java.util.ArrayList;\r\nimport java.util.List;\r\n\r\npublic class Message {\r\n\r\n    private final List services = new ArrayList();\r\n\r\n    public void addService(final IMessageSender messageSender) {\r\n        services.add(messageSender);\r\n    }\r\n\r\n    public void removeService(final IMessageSender messageSender) {\r\n        services.remove(messageSender);\r\n    }\r\n\r\n    public void send(final String message) {\r\n        for (final IMessageSender messageSender : services) {\r\n           messageSender.send(message);\r\n        }\r\n    }\r\n}\r\n<\/pre>\n<p>See the Message class is comprised of a list of services. These services are the senders of messages to be used. Note that the send method only interact on the mailing list message. So far everything is very simple. Now we need to export the Message class as a core service bundle. The UI module will interact directly with this service to send messages.     <\/p>\n<p>First we need to tell it to export OSGi bundle to other bundles. See the MANIFEST:   <\/p>\n<pre class=\"brush:bash\">\r\n\r\nManifest-Version: 1.0\r\nBundle-ManifestVersion: 2\r\nBundle-Name: Helloworld Plugin\r\nBundle-SymbolicName: br.com.luiscm.helloworld.core\r\nBundle-Version: 1.0.0\r\nBundle-Activator: br.com.luiscm.helloworld.core.Activator\r\nBundle-ActivationPolicy: lazy\r\nBundle-RequiredExecutionEnvironment: JavaSE-1.6\r\nImport-Package: org.osgi.framework;version=\u201d1.3.0?,\r\norg.osgi.util.tracker;version=\u201d1.3.6?\r\nExport-Package: br.com.luiscm.helloworld.core.service\r\n<\/pre>\n<p>See information Export-Package. For a class to be visible for another bundle, it must be exported within a package. In our case, the UI needs bundle of the Message class, so we need to export the package where the class is. Remember that the UI imported the bundle package.     <\/p>\n<p>Message To register the component as a service, we need to directly interact with the OSGi API. When the core bundle is started, we will register the service in the context of OSGi. The code is simple:      <\/p>\n<pre class=\"brush:java\">package br.com.luiscm.helloworld.core;\r\n\r\nimport org.osgi.framework.BundleActivator;\r\nimport org.osgi.framework.BundleContext;\r\n\r\npublic class Activator implements BundleActivator {\r\n\r\n    \/*\r\n     * (non-Javadoc)\r\n     * @see org.osgi.framework.BundleActivator#start(org.osgi.framework.BundleContext)\r\n     *\/\r\n    public void start(BundleContext context) throws Exception {\r\n        context.registerService(Message.class.getName(), messageService, null);\r\n    }\r\n\r\n    \/*\r\n     * (non-Javadoc)\r\n     * @see org.osgi.framework.BundleActivator#stop(org.osgi.framework.BundleContext)\r\n     *\/\r\n    public void stop(BundleContext context) throws Exception {\r\n        messageService = null;\r\n    }\r\n}\r\n<\/pre>\n<p>The method registerService expects parameter as the service name (for recommendation is the class name), the service itself and some additional settings.     <\/p>\n<p>Now we need to change the UI to use the bundle Message service. In the bundle activator UI, just do the lookup service using your name (class name):      <\/p>\n<pre class=\"brush:java\">    private Message message;\r\n    private JFrame frame;\r\n    private ServiceTracker serviceTracker;\r\n\r\n    \/*\r\n     * (non-Javadoc)\r\n     * @see org.osgi.framework.BundleActivator#start(org.osgi.framework.BundleContext)\r\n     *\/\r\n    public void start(BundleContext context) throws Exception {\r\n        serviceTracker = new ServiceTracker(context, Message.class.getName(), null);\r\n        serviceTracker.open();\r\n        message = (Message)serviceTracker.getService();\r\n        buildInterface();\r\n    }\r\n\r\n    \/*\r\n     * (non-Javadoc)\r\n     * @see org.osgi.framework.BundleActivator#stop(org.osgi.framework.BundleContext)\r\n     *\/\r\n    public void stop(BundleContext context) throws Exception {\r\n        destroyInterface();\r\n        serviceTracker.close();\r\n    }\r\n}\r\n<\/pre>\n<p>If we add the two bundles in the Equinox, we see that the two bundles are communicating. Now we need to create bundles that actually send the messages.     <\/p>\n<p>Bundle Sender Email and SMS     <\/p>\n<p>Shipping services via email and SMS will be new services from our system. Therefore, we create a bundle for each. This way we can control them separately. For example, we can stop the service by sending SMS and leave only the Email without affecting system operation. The two bundles have virtually the same structure, so I\u2019ll save some lines here.     <\/p>\n<p>The sender will have only one bundle class that implements the interface and class IMessageSender Activator. This interface is at the core bundle, so we need to import the package in the same way we did in the bundle UI.   <\/p>\n<pre class=\"brush:bash\">\r\n\r\nManifest-Version: 1.0\r\nBundle-ManifestVersion: 2\r\nBundle-name: SMS Plug-in\r\nBundle-SymbolicName: br.com.luiscm.helloworld.sms.Activator&lt;\r\nBundle-Version: 1.0.0\r\nBundle-Activator: br.com.luiscm.helloworld.sms.Activator\r\nBundle-ActivationPolicy: lazy\r\nBundle-RequiredExecutionEnvironment: JavaSE-1.6\r\nImport-Package: br.com.luiscm.helloworld.core.service,\r\norg.osgi.framework;version=\u201d1.3.0?\r\n<\/pre>\n<p>The only class Sender implements our interface:     <\/p>\n<pre class=\"brush:java\">package br.com.luiscm.helloworld.sms;\r\n\r\nimport br.com.luiscm.helloworld.core.service.IMessageSender;\r\n\r\npublic class MessageSenderSMS implements IMessageSender {\r\n\r\n    @Override\r\n    public void send(final String message) {\r\n        System.out.println(\"Sending by SMS : \" + message);\r\n    }\r\n}\r\n<\/pre>\n<p>Send by SMS is a service of our system. Therefore, we must register it in the OSGi context:      <\/p>\n<pre class=\"brush:java\">public class Activator implements BundleActivator {\r\n\r\n    private IMessageSender service;\r\n\r\n    \/*\r\n     * (non-Javadoc)\r\n     * @see org.osgi.framework.BundleActivator#start(org.osgi.framework.BundleContext)\r\n     *\/\r\n    public void start(BundleContext context) throws Exception {\r\n        service = new MessageSenderSMS();\r\n        context.registerService(IMessageSender.class.getName(), service, null);\r\n    }\r\n\r\n    \/*\r\n     * (non-Javadoc)\r\n     * @see org.osgi.framework.BundleActivator#stop(org.osgi.framework.BundleContext)\r\n     *\/\r\n    public void stop(BundleContext context) throws Exception {\r\n        service = null;\r\n    }\r\n}\r\n<\/pre>\n<p>The bundle of mail is virtually the same code. The only difference is the message on System.out.     <\/p>\n<p>Note that registered the service with the name of the interface. So now we have two services with the same name. Whenever we ask for the service context with the interface name, he will perform a logical priority to return only one implementation.     <\/p>\n<p>Now we have two services for sending messages, we need to change our bundle core to use them. To achieve this objective, a ServiceTrackerCustomizer.     <\/p>\n<p>ServiceTrackerCustomizer e ServiceTracker     <\/p>\n<p>As we saw, we used to do Servicetrack lookup service. However, in the case of senders, we need to know when a new sender service is available or when a sender is removed. This information is important to feed the list of services within the Message object.     <\/p>\n<p>To access this information, we use a ServiceTrackerCustomizer. The code is simple:      <\/p>\n<pre class=\"brush:java\">package br.com.luiscm.helloworld.core;\r\n\r\nimport org.osgi.framework.BundleContext;\r\n\r\npublic class MessageSenderServiceTracker implements ServiceTrackerCustomizer {\r\n\r\n    private final BundleContext context;\r\n    private final Message message;\r\n\r\n    public MessageSenderServiceTracker(final BundleContext context, final Message message) {\r\n        this.context = context;\r\n        this.message = message;\r\n    }\r\n\r\n    @Override\r\n    public Object addingService(final ServiceReference serviceReference) {\r\n        final IMessageSender sender = (IMessageSender)context.getService(serviceReference);\r\n        message.addService(sender);\r\n        System.out.println(\"tracker : \" + sender.getClass().getName());\r\n        return sender;\r\n    }\r\n\r\n    @Override\r\n    public void removedService(final ServiceReference serviceReference, Object service) {\r\n        final IMessageSender sender = (IMessageSender)context.getService(serviceReference);\r\n        message.removeService(sender);\r\n    }\r\n}\r\n<\/pre>\n<p>Just implement the interface and code ServiceTrackerCustomizer what you want when a service is added, modified or removed. Simple!     <\/p>\n<p>In our case we will add or remove the service from the list of services on our Message object. Also has a message of \u201clog\u201dto help us with testing.     <\/p>\n<p>Now we need to make one more minor change in the bundle core activator. We must register our ServiceTrackerCustomizer as a listener for services such IMessageSender.       <\/p>\n<pre class=\"brush:java\">public class Activator implements BundleActivator {\r\n\r\n    public Message messageService = new Message();\r\n    private ServiceTracker messageSenderServiceTracker;\r\n\r\n    \/*\r\n     * (non-Javadoc)\r\n     * @see org.osgi.framework.BundleActivator#start(org.osgi.framework.BundleContext)\r\n     *\/\r\n    public void start(BundleContext context) throws Exception {\r\n        context.registerService(Message.class.getName(), messageService, null);\r\n        final MessageSenderServiceTracker serviceTracker = new MessageSenderServiceTracker(context, messageService);\r\n        messageSenderServiceTracker = new ServiceTracker(context, IMessageSender.class.getName(), serviceTracker);\r\n        messageSenderServiceTracker.open();\r\n    }\r\n\r\n    \/*\r\n     * (non-Javadoc)\r\n     * @see org.osgi.framework.BundleActivator#stop(org.osgi.framework.BundleContext)\r\n     *\/\r\n    public void stop(BundleContext context) throws Exception {\r\n        messageSenderServiceTracker.close();\r\n        messageService = null;\r\n    }\r\n}\r\n<\/pre>\n<p>We use ServiceTrackerCustomizer along with ServiceTtracker. Where a service is added, modified or removed, our component will be called.     <\/p>\n<p><strong>Testing the application<\/strong>    <\/p>\n<p>Now that we code, we test the application.     <\/p>\n<p>Create four jars:     <\/p>\n<p>* bundleCore.jar<br \/>\n* bundleUI.jar<br \/>\n* bundleSenderEmail.jar<br \/>\n* bundleSenderSMS.jar     <\/p>\n<p>Install the four bundles in the Equinox:     <\/p>\n<p>Framework is launched.   <\/p>\n<pre class=\"brush:bash\">\r\nid State Bundle\r\n0 ACTIVE org.eclipse.osgi_3.5.1.R35x_20090827.jar\r\nosgi&gt; install file:bundleCore.jar\r\nBundle id is 5\r\nosgi&gt; install file:bundleUI.jar\r\nBundle id is 6\r\nosgi&gt; install file:bundleSenderEmail.jar\r\nBundle id is 7\r\nosgi&gt; install file:bundleSenderSMS.jar\r\nBundle id is 8\r\nosgi&gt; ss\r\n<\/pre>\n<p>Framework is launched. <\/p>\n<pre class=\"brush:bash\">\r\n0 ACTIVE org.eclipse.osgi._3.5.1.R35x_v20090827.jar\r\n5 INSTALLED br.com.luiscm.helloworld.core_1.0.0\r\n6 INSTALLED br.com.luiscm.helloworld.ui_1.0.0\r\n7 INSTALLED br.com.luiscm.helloworld.email_1.0.0\r\n8 INSTALLED br.com.luiscm.helloworld.sms_1.0.0\r\n<\/pre>\n<p>Start the bundles and test the application.  <\/p>\n<pre class=\"brush:bash\">\r\nC:\\osgi&gt;java -jar org.eclipse.osgi._3.5.1.R35x_v20090827.jar -console\r\nosgi&gt; tracker: br.com.luiscm.heloworld.sms.SenderSMS\r\n\r\ntracker: br.com.luiscm.helloworld.email.SenderEmail\r\n<\/pre>\n<p>See which messages are sent by email and SMS. In console Equinox, pause the service email:   <\/p>\n<pre class=\"brush:bash\">\r\nstop\r\n<\/pre>\n<p>Try again send a message. Because the service is no longer available, the message was sent only by SMS.     <\/p>\n<p>Stopping power application modules without suffering side effects is sensational. Imagine that you discover a critical error in the SMS module. You need not take all the air is applied to correct this problem. Just pause the SMS module. The rest of the system will continue normal operation. Take the test with this small example. Pause and Start services. This will not affect the core, much less the UI.     <\/p>\n<p>I managed to explain a little of what is OSGi. It is noteworthy that has much more detail on control and classpath configuration bundles that do not pay attention here. It is the task for those interested take a look at other features.     <\/p>\n<p>It\u2019s worth looking at the Spring-DM project. The spring makes it very easy to set up services in addition to providing an excellent IoC container.       <\/p>\n<p><strong><i>Reference: <\/i><\/strong><a href=\"http:\/\/eclipsebrazil.wordpress.com\/2011\/03\/01\/osgi-%E2%80%93-modularizing-your-application\/\">OSGI \u2013 Modularizing your application<\/a> from our <a href=\"http:\/\/www.javacodegeeks.com\/p\/jcg.html\">JCG partner<\/a> Luis Carlos Moreira da Costa at the <a href=\"http:\/\/eclipsebrazil.wordpress.com\/\">Eclipse Brazil<\/a> blog.<\/p>\n<\/div>\n","protected":false},"excerpt":{"rendered":"<p>Since I am a big proponent of modularity, low coupling, high cohesion, etc \u2026 I believe that this technology is a breakthrough in how we create applications using the Java platform. With OSGi, it is very simple to create highly extensible applications, see for example the Eclipse IDE. My goal here is not to show &hellip;<\/p>\n","protected":false},"author":216,"featured_media":211,"comment_status":"open","ping_status":"closed","sticky":false,"template":"","format":"standard","meta":{"footnotes":""},"categories":[8],"tags":[190],"class_list":["post-1066","post","type-post","status-publish","format-standard","has-post-thumbnail","hentry","category-enterprise-java","tag-osgi"],"yoast_head":"<!-- This site is optimized with the Yoast SEO plugin v27.5 - https:\/\/yoast.com\/product\/yoast-seo-wordpress\/ -->\n<title>OSGI - Modularizing your application - Java Code Geeks<\/title>\n<meta name=\"description\" content=\"Since I am a big proponent of modularity, low coupling, high cohesion, etc \u2026 I believe that this technology is a breakthrough in how we create\" \/>\n<meta name=\"robots\" content=\"index, follow, max-snippet:-1, max-image-preview:large, max-video-preview:-1\" \/>\n<link rel=\"canonical\" href=\"https:\/\/www.javacodegeeks.com\/2012\/04\/osgi-modularizing-your-application.html\" \/>\n<meta property=\"og:locale\" content=\"en_US\" \/>\n<meta property=\"og:type\" content=\"article\" \/>\n<meta property=\"og:title\" content=\"OSGI - Modularizing your application - Java Code Geeks\" \/>\n<meta property=\"og:description\" content=\"Since I am a big proponent of modularity, low coupling, high cohesion, etc \u2026 I believe that this technology is a breakthrough in how we create\" \/>\n<meta property=\"og:url\" content=\"https:\/\/www.javacodegeeks.com\/2012\/04\/osgi-modularizing-your-application.html\" \/>\n<meta property=\"og:site_name\" content=\"Java Code Geeks\" \/>\n<meta property=\"article:publisher\" content=\"https:\/\/www.facebook.com\/javacodegeeks\" \/>\n<meta property=\"article:published_time\" content=\"2012-04-25T13:00:00+00:00\" \/>\n<meta property=\"article:modified_time\" content=\"2012-10-21T23:25:53+00:00\" \/>\n<meta property=\"og:image\" content=\"https:\/\/www.javacodegeeks.com\/wp-content\/uploads\/2012\/10\/osgi-alliance-logo.jpg\" \/>\n\t<meta property=\"og:image:width\" content=\"150\" \/>\n\t<meta property=\"og:image:height\" content=\"150\" \/>\n\t<meta property=\"og:image:type\" content=\"image\/jpeg\" \/>\n<meta name=\"author\" content=\"Luis Carlos Moreira da Costa\" \/>\n<meta name=\"twitter:card\" content=\"summary_large_image\" \/>\n<meta name=\"twitter:creator\" content=\"@javacodegeeks\" \/>\n<meta name=\"twitter:site\" content=\"@javacodegeeks\" \/>\n<meta name=\"twitter:label1\" content=\"Written by\" \/>\n\t<meta name=\"twitter:data1\" content=\"Luis Carlos Moreira da Costa\" \/>\n\t<meta name=\"twitter:label2\" content=\"Est. reading time\" \/>\n\t<meta name=\"twitter:data2\" content=\"12 minutes\" \/>\n<script type=\"application\/ld+json\" class=\"yoast-schema-graph\">{\"@context\":\"https:\\\/\\\/schema.org\",\"@graph\":[{\"@type\":\"Article\",\"@id\":\"https:\\\/\\\/www.javacodegeeks.com\\\/2012\\\/04\\\/osgi-modularizing-your-application.html#article\",\"isPartOf\":{\"@id\":\"https:\\\/\\\/www.javacodegeeks.com\\\/2012\\\/04\\\/osgi-modularizing-your-application.html\"},\"author\":{\"name\":\"Luis Carlos Moreira da Costa\",\"@id\":\"https:\\\/\\\/www.javacodegeeks.com\\\/#\\\/schema\\\/person\\\/ad307180cad0aa382e482b6616e245a0\"},\"headline\":\"OSGI &#8211; Modularizing your application\",\"datePublished\":\"2012-04-25T13:00:00+00:00\",\"dateModified\":\"2012-10-21T23:25:53+00:00\",\"mainEntityOfPage\":{\"@id\":\"https:\\\/\\\/www.javacodegeeks.com\\\/2012\\\/04\\\/osgi-modularizing-your-application.html\"},\"wordCount\":1457,\"commentCount\":3,\"publisher\":{\"@id\":\"https:\\\/\\\/www.javacodegeeks.com\\\/#organization\"},\"image\":{\"@id\":\"https:\\\/\\\/www.javacodegeeks.com\\\/2012\\\/04\\\/osgi-modularizing-your-application.html#primaryimage\"},\"thumbnailUrl\":\"https:\\\/\\\/www.javacodegeeks.com\\\/wp-content\\\/uploads\\\/2012\\\/10\\\/osgi-alliance-logo.jpg\",\"keywords\":[\"OSGi\"],\"articleSection\":[\"Enterprise Java\"],\"inLanguage\":\"en-US\",\"potentialAction\":[{\"@type\":\"CommentAction\",\"name\":\"Comment\",\"target\":[\"https:\\\/\\\/www.javacodegeeks.com\\\/2012\\\/04\\\/osgi-modularizing-your-application.html#respond\"]}]},{\"@type\":\"WebPage\",\"@id\":\"https:\\\/\\\/www.javacodegeeks.com\\\/2012\\\/04\\\/osgi-modularizing-your-application.html\",\"url\":\"https:\\\/\\\/www.javacodegeeks.com\\\/2012\\\/04\\\/osgi-modularizing-your-application.html\",\"name\":\"OSGI - Modularizing your application - Java Code Geeks\",\"isPartOf\":{\"@id\":\"https:\\\/\\\/www.javacodegeeks.com\\\/#website\"},\"primaryImageOfPage\":{\"@id\":\"https:\\\/\\\/www.javacodegeeks.com\\\/2012\\\/04\\\/osgi-modularizing-your-application.html#primaryimage\"},\"image\":{\"@id\":\"https:\\\/\\\/www.javacodegeeks.com\\\/2012\\\/04\\\/osgi-modularizing-your-application.html#primaryimage\"},\"thumbnailUrl\":\"https:\\\/\\\/www.javacodegeeks.com\\\/wp-content\\\/uploads\\\/2012\\\/10\\\/osgi-alliance-logo.jpg\",\"datePublished\":\"2012-04-25T13:00:00+00:00\",\"dateModified\":\"2012-10-21T23:25:53+00:00\",\"description\":\"Since I am a big proponent of modularity, low coupling, high cohesion, etc \u2026 I believe that this technology is a breakthrough in how we create\",\"breadcrumb\":{\"@id\":\"https:\\\/\\\/www.javacodegeeks.com\\\/2012\\\/04\\\/osgi-modularizing-your-application.html#breadcrumb\"},\"inLanguage\":\"en-US\",\"potentialAction\":[{\"@type\":\"ReadAction\",\"target\":[\"https:\\\/\\\/www.javacodegeeks.com\\\/2012\\\/04\\\/osgi-modularizing-your-application.html\"]}]},{\"@type\":\"ImageObject\",\"inLanguage\":\"en-US\",\"@id\":\"https:\\\/\\\/www.javacodegeeks.com\\\/2012\\\/04\\\/osgi-modularizing-your-application.html#primaryimage\",\"url\":\"https:\\\/\\\/www.javacodegeeks.com\\\/wp-content\\\/uploads\\\/2012\\\/10\\\/osgi-alliance-logo.jpg\",\"contentUrl\":\"https:\\\/\\\/www.javacodegeeks.com\\\/wp-content\\\/uploads\\\/2012\\\/10\\\/osgi-alliance-logo.jpg\",\"width\":150,\"height\":150},{\"@type\":\"BreadcrumbList\",\"@id\":\"https:\\\/\\\/www.javacodegeeks.com\\\/2012\\\/04\\\/osgi-modularizing-your-application.html#breadcrumb\",\"itemListElement\":[{\"@type\":\"ListItem\",\"position\":1,\"name\":\"Home\",\"item\":\"https:\\\/\\\/www.javacodegeeks.com\\\/\"},{\"@type\":\"ListItem\",\"position\":2,\"name\":\"Java\",\"item\":\"https:\\\/\\\/www.javacodegeeks.com\\\/category\\\/java\"},{\"@type\":\"ListItem\",\"position\":3,\"name\":\"Enterprise Java\",\"item\":\"https:\\\/\\\/www.javacodegeeks.com\\\/category\\\/java\\\/enterprise-java\"},{\"@type\":\"ListItem\",\"position\":4,\"name\":\"OSGI &#8211; Modularizing your application\"}]},{\"@type\":\"WebSite\",\"@id\":\"https:\\\/\\\/www.javacodegeeks.com\\\/#website\",\"url\":\"https:\\\/\\\/www.javacodegeeks.com\\\/\",\"name\":\"Java Code Geeks\",\"description\":\"Java Developers Resource Center\",\"publisher\":{\"@id\":\"https:\\\/\\\/www.javacodegeeks.com\\\/#organization\"},\"alternateName\":\"JCG\",\"potentialAction\":[{\"@type\":\"SearchAction\",\"target\":{\"@type\":\"EntryPoint\",\"urlTemplate\":\"https:\\\/\\\/www.javacodegeeks.com\\\/?s={search_term_string}\"},\"query-input\":{\"@type\":\"PropertyValueSpecification\",\"valueRequired\":true,\"valueName\":\"search_term_string\"}}],\"inLanguage\":\"en-US\"},{\"@type\":\"Organization\",\"@id\":\"https:\\\/\\\/www.javacodegeeks.com\\\/#organization\",\"name\":\"Exelixis Media P.C.\",\"url\":\"https:\\\/\\\/www.javacodegeeks.com\\\/\",\"logo\":{\"@type\":\"ImageObject\",\"inLanguage\":\"en-US\",\"@id\":\"https:\\\/\\\/www.javacodegeeks.com\\\/#\\\/schema\\\/logo\\\/image\\\/\",\"url\":\"https:\\\/\\\/www.javacodegeeks.com\\\/wp-content\\\/uploads\\\/2022\\\/06\\\/exelixis-logo.png\",\"contentUrl\":\"https:\\\/\\\/www.javacodegeeks.com\\\/wp-content\\\/uploads\\\/2022\\\/06\\\/exelixis-logo.png\",\"width\":864,\"height\":246,\"caption\":\"Exelixis Media P.C.\"},\"image\":{\"@id\":\"https:\\\/\\\/www.javacodegeeks.com\\\/#\\\/schema\\\/logo\\\/image\\\/\"},\"sameAs\":[\"https:\\\/\\\/www.facebook.com\\\/javacodegeeks\",\"https:\\\/\\\/x.com\\\/javacodegeeks\"]},{\"@type\":\"Person\",\"@id\":\"https:\\\/\\\/www.javacodegeeks.com\\\/#\\\/schema\\\/person\\\/ad307180cad0aa382e482b6616e245a0\",\"name\":\"Luis Carlos Moreira da Costa\",\"image\":{\"@type\":\"ImageObject\",\"inLanguage\":\"en-US\",\"@id\":\"https:\\\/\\\/secure.gravatar.com\\\/avatar\\\/d9fc88ad847f9b672e7b6bcac18c977c10799ac641d0827a64198bfc574c5226?s=96&d=mm&r=g\",\"url\":\"https:\\\/\\\/secure.gravatar.com\\\/avatar\\\/d9fc88ad847f9b672e7b6bcac18c977c10799ac641d0827a64198bfc574c5226?s=96&d=mm&r=g\",\"contentUrl\":\"https:\\\/\\\/secure.gravatar.com\\\/avatar\\\/d9fc88ad847f9b672e7b6bcac18c977c10799ac641d0827a64198bfc574c5226?s=96&d=mm&r=g\",\"caption\":\"Luis Carlos Moreira da Costa\"},\"description\":\"Architect and Developer. OSGi, Eclipse Platform and various programming languages\u200b\u200b.\",\"sameAs\":[\"http:\\\/\\\/eclipsebrazil.wordpress.com\\\/\"],\"url\":\"https:\\\/\\\/www.javacodegeeks.com\\\/author\\\/luis-carlos-moreira-da-costa\"}]}<\/script>\n<!-- \/ Yoast SEO plugin. -->","yoast_head_json":{"title":"OSGI - Modularizing your application - Java Code Geeks","description":"Since I am a big proponent of modularity, low coupling, high cohesion, etc \u2026 I believe that this technology is a breakthrough in how we create","robots":{"index":"index","follow":"follow","max-snippet":"max-snippet:-1","max-image-preview":"max-image-preview:large","max-video-preview":"max-video-preview:-1"},"canonical":"https:\/\/www.javacodegeeks.com\/2012\/04\/osgi-modularizing-your-application.html","og_locale":"en_US","og_type":"article","og_title":"OSGI - Modularizing your application - Java Code Geeks","og_description":"Since I am a big proponent of modularity, low coupling, high cohesion, etc \u2026 I believe that this technology is a breakthrough in how we create","og_url":"https:\/\/www.javacodegeeks.com\/2012\/04\/osgi-modularizing-your-application.html","og_site_name":"Java Code Geeks","article_publisher":"https:\/\/www.facebook.com\/javacodegeeks","article_published_time":"2012-04-25T13:00:00+00:00","article_modified_time":"2012-10-21T23:25:53+00:00","og_image":[{"width":150,"height":150,"url":"https:\/\/www.javacodegeeks.com\/wp-content\/uploads\/2012\/10\/osgi-alliance-logo.jpg","type":"image\/jpeg"}],"author":"Luis Carlos Moreira da Costa","twitter_card":"summary_large_image","twitter_creator":"@javacodegeeks","twitter_site":"@javacodegeeks","twitter_misc":{"Written by":"Luis Carlos Moreira da Costa","Est. reading time":"12 minutes"},"schema":{"@context":"https:\/\/schema.org","@graph":[{"@type":"Article","@id":"https:\/\/www.javacodegeeks.com\/2012\/04\/osgi-modularizing-your-application.html#article","isPartOf":{"@id":"https:\/\/www.javacodegeeks.com\/2012\/04\/osgi-modularizing-your-application.html"},"author":{"name":"Luis Carlos Moreira da Costa","@id":"https:\/\/www.javacodegeeks.com\/#\/schema\/person\/ad307180cad0aa382e482b6616e245a0"},"headline":"OSGI &#8211; Modularizing your application","datePublished":"2012-04-25T13:00:00+00:00","dateModified":"2012-10-21T23:25:53+00:00","mainEntityOfPage":{"@id":"https:\/\/www.javacodegeeks.com\/2012\/04\/osgi-modularizing-your-application.html"},"wordCount":1457,"commentCount":3,"publisher":{"@id":"https:\/\/www.javacodegeeks.com\/#organization"},"image":{"@id":"https:\/\/www.javacodegeeks.com\/2012\/04\/osgi-modularizing-your-application.html#primaryimage"},"thumbnailUrl":"https:\/\/www.javacodegeeks.com\/wp-content\/uploads\/2012\/10\/osgi-alliance-logo.jpg","keywords":["OSGi"],"articleSection":["Enterprise Java"],"inLanguage":"en-US","potentialAction":[{"@type":"CommentAction","name":"Comment","target":["https:\/\/www.javacodegeeks.com\/2012\/04\/osgi-modularizing-your-application.html#respond"]}]},{"@type":"WebPage","@id":"https:\/\/www.javacodegeeks.com\/2012\/04\/osgi-modularizing-your-application.html","url":"https:\/\/www.javacodegeeks.com\/2012\/04\/osgi-modularizing-your-application.html","name":"OSGI - Modularizing your application - Java Code Geeks","isPartOf":{"@id":"https:\/\/www.javacodegeeks.com\/#website"},"primaryImageOfPage":{"@id":"https:\/\/www.javacodegeeks.com\/2012\/04\/osgi-modularizing-your-application.html#primaryimage"},"image":{"@id":"https:\/\/www.javacodegeeks.com\/2012\/04\/osgi-modularizing-your-application.html#primaryimage"},"thumbnailUrl":"https:\/\/www.javacodegeeks.com\/wp-content\/uploads\/2012\/10\/osgi-alliance-logo.jpg","datePublished":"2012-04-25T13:00:00+00:00","dateModified":"2012-10-21T23:25:53+00:00","description":"Since I am a big proponent of modularity, low coupling, high cohesion, etc \u2026 I believe that this technology is a breakthrough in how we create","breadcrumb":{"@id":"https:\/\/www.javacodegeeks.com\/2012\/04\/osgi-modularizing-your-application.html#breadcrumb"},"inLanguage":"en-US","potentialAction":[{"@type":"ReadAction","target":["https:\/\/www.javacodegeeks.com\/2012\/04\/osgi-modularizing-your-application.html"]}]},{"@type":"ImageObject","inLanguage":"en-US","@id":"https:\/\/www.javacodegeeks.com\/2012\/04\/osgi-modularizing-your-application.html#primaryimage","url":"https:\/\/www.javacodegeeks.com\/wp-content\/uploads\/2012\/10\/osgi-alliance-logo.jpg","contentUrl":"https:\/\/www.javacodegeeks.com\/wp-content\/uploads\/2012\/10\/osgi-alliance-logo.jpg","width":150,"height":150},{"@type":"BreadcrumbList","@id":"https:\/\/www.javacodegeeks.com\/2012\/04\/osgi-modularizing-your-application.html#breadcrumb","itemListElement":[{"@type":"ListItem","position":1,"name":"Home","item":"https:\/\/www.javacodegeeks.com\/"},{"@type":"ListItem","position":2,"name":"Java","item":"https:\/\/www.javacodegeeks.com\/category\/java"},{"@type":"ListItem","position":3,"name":"Enterprise Java","item":"https:\/\/www.javacodegeeks.com\/category\/java\/enterprise-java"},{"@type":"ListItem","position":4,"name":"OSGI &#8211; Modularizing your application"}]},{"@type":"WebSite","@id":"https:\/\/www.javacodegeeks.com\/#website","url":"https:\/\/www.javacodegeeks.com\/","name":"Java Code Geeks","description":"Java Developers Resource Center","publisher":{"@id":"https:\/\/www.javacodegeeks.com\/#organization"},"alternateName":"JCG","potentialAction":[{"@type":"SearchAction","target":{"@type":"EntryPoint","urlTemplate":"https:\/\/www.javacodegeeks.com\/?s={search_term_string}"},"query-input":{"@type":"PropertyValueSpecification","valueRequired":true,"valueName":"search_term_string"}}],"inLanguage":"en-US"},{"@type":"Organization","@id":"https:\/\/www.javacodegeeks.com\/#organization","name":"Exelixis Media P.C.","url":"https:\/\/www.javacodegeeks.com\/","logo":{"@type":"ImageObject","inLanguage":"en-US","@id":"https:\/\/www.javacodegeeks.com\/#\/schema\/logo\/image\/","url":"https:\/\/www.javacodegeeks.com\/wp-content\/uploads\/2022\/06\/exelixis-logo.png","contentUrl":"https:\/\/www.javacodegeeks.com\/wp-content\/uploads\/2022\/06\/exelixis-logo.png","width":864,"height":246,"caption":"Exelixis Media P.C."},"image":{"@id":"https:\/\/www.javacodegeeks.com\/#\/schema\/logo\/image\/"},"sameAs":["https:\/\/www.facebook.com\/javacodegeeks","https:\/\/x.com\/javacodegeeks"]},{"@type":"Person","@id":"https:\/\/www.javacodegeeks.com\/#\/schema\/person\/ad307180cad0aa382e482b6616e245a0","name":"Luis Carlos Moreira da Costa","image":{"@type":"ImageObject","inLanguage":"en-US","@id":"https:\/\/secure.gravatar.com\/avatar\/d9fc88ad847f9b672e7b6bcac18c977c10799ac641d0827a64198bfc574c5226?s=96&d=mm&r=g","url":"https:\/\/secure.gravatar.com\/avatar\/d9fc88ad847f9b672e7b6bcac18c977c10799ac641d0827a64198bfc574c5226?s=96&d=mm&r=g","contentUrl":"https:\/\/secure.gravatar.com\/avatar\/d9fc88ad847f9b672e7b6bcac18c977c10799ac641d0827a64198bfc574c5226?s=96&d=mm&r=g","caption":"Luis Carlos Moreira da Costa"},"description":"Architect and Developer. OSGi, Eclipse Platform and various programming languages\u200b\u200b.","sameAs":["http:\/\/eclipsebrazil.wordpress.com\/"],"url":"https:\/\/www.javacodegeeks.com\/author\/luis-carlos-moreira-da-costa"}]}},"_links":{"self":[{"href":"https:\/\/www.javacodegeeks.com\/wp-json\/wp\/v2\/posts\/1066","targetHints":{"allow":["GET"]}}],"collection":[{"href":"https:\/\/www.javacodegeeks.com\/wp-json\/wp\/v2\/posts"}],"about":[{"href":"https:\/\/www.javacodegeeks.com\/wp-json\/wp\/v2\/types\/post"}],"author":[{"embeddable":true,"href":"https:\/\/www.javacodegeeks.com\/wp-json\/wp\/v2\/users\/216"}],"replies":[{"embeddable":true,"href":"https:\/\/www.javacodegeeks.com\/wp-json\/wp\/v2\/comments?post=1066"}],"version-history":[{"count":0,"href":"https:\/\/www.javacodegeeks.com\/wp-json\/wp\/v2\/posts\/1066\/revisions"}],"wp:featuredmedia":[{"embeddable":true,"href":"https:\/\/www.javacodegeeks.com\/wp-json\/wp\/v2\/media\/211"}],"wp:attachment":[{"href":"https:\/\/www.javacodegeeks.com\/wp-json\/wp\/v2\/media?parent=1066"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/www.javacodegeeks.com\/wp-json\/wp\/v2\/categories?post=1066"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/www.javacodegeeks.com\/wp-json\/wp\/v2\/tags?post=1066"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}