Quantcast
Channel: Liferay Savvy
Viewing all 99 articles
Browse latest View live

OSGi Dependency Management Example

$
0
0
OSGi dependency management explain, how components or bundles share code between bundles. OSGi is dynamic component development so each application composed of components. Dependency Management define how code can be shared between bundles or we can say how we can access one bundle classes/interfaces in other bundles.

When we develop OSGi bundles any class or interfaces which we developed in the bundles accessible to within the bundle and not outside the bundle. Dependency management will explain how we can access one bundle resources in other bundles.

The following articles will give the introduction about OSGi dependency management


Usually to understand example we have two bundles and one bundles will have interface with set of service and its implementation. Other bundle will access the services which are developed by other bundle

The following are the steps

Bundle A Creation

  • Create New Bundle A
  • Define Service in the Interface
  • Implements Service defined in the Interface
  • Export Service Package
  • Register Service Implementation Object with Bundle Context


Bundle B Creation

  • Create New Bundle B
  • Import Service Provider Bundle Services Package
  • Access Service Provider Bundle Service Implementation Object in Consumer Bundle

Prerequisites

Install Java 8
Latest Eclipse IDE (Oxygen Release (4.7.0))

Create New Bundle A

Create New Bundle A

Create new bundle using eclipse with activator class. This bundle will have one interface and its service implementation.

Start Eclipse

File à New Project àNew Plugin Project


Bundle Name: com.ls.de.LSServiceProvider

Target Platform à OSGi Framework à standard





Click on next

Click on Check Box Generate Activator Class and provide name


Example:

com.ls.de.lsserviceprovider.ServiceActivator





Click on Finish then new bundle will be created. Bundle can be visible in the project explorer with generated activator class and MANIFEST file



Define Services in the Interface

We already created bundle and now create Service Interface and define the service.
Create new package and create new java interface

Right Click on Project Src àNew Interface àProvide Details à Click On Finish

Package :           com.ls.de.lsserviceprovider.services
Interface Name: HelloService





Now define service method in the Interface finally it looks like as follows

HelloService.java


package com.ls.de.lsserviceprovider.services;

publicinterface HelloService {
      public String greetHello();
}


Implements Service defined in the Interface

We already define the service interface with method. Now we have to implements the service method in the implementation class. Create new package and new implementation class.

Right Click on Project Src àNew Class àProvide Details à Click on Finish

Package :           com.ls.de.lsserviceprovider.services.impl
Interface Name: HelloServiceImpl




Implement interface method in the implementation class, finally implementations class as follows.

HelloServiceImpl.java


package com.ls.de.lsserviceprovider.services.impl;

import com.ls.de.lsserviceprovider.services.HelloService;

publicclass HelloServiceImpl implements HelloService {
    
     @Override
      public String greetHello() {
          
           System.out.println("=====Inside HelloServiceImpl.greetHello()=====");
        return"Hello Greeting from Liferay Savvy World..";
     }

}

Export Services Package

Now we have to Export Services package from services bundles so that these interfaces or resources can be accessible in the other bundles. Remember here only we are exporting services package not implementation package.

MANIFEST have OSGi header called “Export-Package” and we need to add package names with comma separate value, so that we can access these resources in other bundles.

Add “com.ls.de.lsserviceprovider.services” package name under “Export-Package” in the Bundle MANIFEST file

Finally MANIFEST looks as follows

MANIFEST.MF


Manifest-Version: 1.0
Bundle-ManifestVersion: 2
Bundle-Name: LSServiceProvider
Bundle-SymbolicName: com.ls.de.LSServiceProvider
Bundle-Version: 1.0.0.qualifier
Bundle-Activator: com.ls.de.lsserviceprovider.ServiceActivator
Bundle-Vendor: LS
Bundle-RequiredExecutionEnvironment: JavaSE-1.8
Export-Package: com.ls.de.lsserviceprovider.services
Import-Package: org.osgi.framework;version="1.3.0"


Register Service Implementation Object with Bundle Context

Now we need to register service implantation in OSGi Bundle Context so that it will be accessible to other bundles.

The services registration and unregister information will managed by Service Registration object. When we register Service Implementation object with Bundle Context it will return Service Registration Object.

Usually when bundle is started then we register the services with bundle context. We will use Bundle Activator start (--) method to register service objects
Bundle Context have methods registerService(--) and unregister(--) methods to register and unregister service objects.

registerService(--) method will take three arguments

Argument: 1

Service object unique identification to identify the service, usually we will use fully qualified service interface class name

Argument: 2

Service Implementation Object to register with bundle context

Argument: 3

Its Java MAP object to filter the service objects. Sometime same interface have multiple implementation then we will use some filter properties to identify the service implementation object. Service Identification is same for all implementation so we will additional properties to get service objects. In this example we have only one implementation so we have passed null.

unregister(--) method will unregister service object from Bundle Context. Usually we unregister service when bundle is removed from the container then it will call stop(--) lifecycle method. We will unregister service when it execute stop(--) method.

Now go to Bundle Activator class add following code parts in the start (--) and stop (--) methods.  
  
ServiceActivator.java

package com.ls.de.lsserviceprovider;

import org.osgi.framework.BundleActivator;
import org.osgi.framework.BundleContext;
import org.osgi.framework.ServiceRegistration;

import com.ls.de.lsserviceprovider.services.HelloService;
import com.ls.de.lsserviceprovider.services.impl.HelloServiceImpl;

publicclass ServiceActivator implements BundleActivator {

     privatestatic BundleContext context;
     ServiceRegistrationserviceRegistration;

     static BundleContext getContext() {
           returncontext;
     }

     /*
      * (non-Javadoc)
      * @see org.osgi.framework.BundleActivator#start(org.osgi.framework.BundleContext)
      */
     publicvoid start(BundleContext bundleContext) throws Exception {
           ServiceActivator.context = bundleContext;
           System.out.println("Liferay Savvy Hello World Service Provider Bundle Activator Start");
           HelloService helloService = new HelloServiceImpl();
           serviceRegistration =context.registerService(HelloService.class.getName(), helloService, null);
     }

     /*
      * (non-Javadoc)
      * @see org.osgi.framework.BundleActivator#stop(org.osgi.framework.BundleContext)
      */
     publicvoid stop(BundleContext bundleContext) throws Exception {
           ServiceActivator.context = null;
           System.out.println("Liferay Savvy Hello World Service Provider Bundle Activator Stop");
           serviceRegistration.unregister();
     }

}


Create New Bundle B

Create new bundle using eclipse with activator class.
Start Eclipse

File à New Project àNew Plugin Project


Bundle Name: com.ls.de.LSServiceConsumer
Target Platform à OSGi Framework à standard





Click on next

Click on Check Box Generate Activator Class and provide name


Example:

com.ls.de.serviceconsumer.ServiceConsumerActivator



Click on Finish then new bundle will be created. Bundle can be visible in the project explorer with generated activator class and MANIFEST file




Import Service Provider Bundle Services Package

We have to Import Services package from services bundle so that these interfaces or resources can be accessible in the consumer bundle.

MANIFEST have OSGi header called “Import-Package” and we need to add package names with comma separate value, so that we can access these resources in current bundle.

Add “com.ls.de.lsserviceprovider.services” package name under “Import-Package” in the Bundle MANIFEST file

Finally MANIFEST looks as follows

MANIFEST.MF


Manifest-Version: 1.0
Bundle-ManifestVersion: 2
Bundle-Name: LSServiceConsumer
Bundle-SymbolicName: com.ls.de.LSServiceConsumer
Bundle-Version: 1.0.0.qualifier
Bundle-Activator: com.ls.de.serviceconsumer.ServiceConsumerActivator
Bundle-Vendor: LS
Bundle-RequiredExecutionEnvironment: JavaSE-1.8
Import-Package: com.ls.de.lsserviceprovider.services,
 org.osgi.framework;version="1.3.0"


When we use import header then the listed java classes and interfaces are available in the current working bundles.

Access Service Provider Bundle Service Implementation Object in Consumer Bundle

We already register services object and exported package in the consumer bundle. Now we can user service implementation in the consumer bundle. Now we can access service implementation object from consumer bundle context.

We have Bundle Context getService(--) method and it will return the service implementation object. We need to pass service reference object for this method.

We will identify the Service Implementation Object by service interface name. We already register the service with same name. So we will use same name to identify the service implementation Object.

We will use consumer Activator Class to get implementation object and call the required services.

Go to Consumer Bundle Activator class add the following code part in the Start (--) method and invoke service method using service implementation object.

ServiceConsumerActivator.java

package com.ls.de.serviceconsumer;

import org.osgi.framework.BundleActivator;
import org.osgi.framework.BundleContext;
import org.osgi.framework.ServiceReference;

import com.ls.de.lsserviceprovider.services.HelloService;

publicclassServiceConsumerActivatorimplements BundleActivator {

     privatestatic BundleContext context;
     ServiceReferencehelloServiceReference;

     static BundleContext getContext() {
           returncontext;
     }

     /*
      * (non-Javadoc)
      * @see org.osgi.framework.BundleActivator#start(org.osgi.framework.BundleContext)
      */
     publicvoid start(BundleContext bundleContext) throws Exception {
            ServiceConsumerActivator.context = bundleContext;
            System.out.println("Hello World Consumer Bundle Activator Start");
          helloServiceReference= context.getServiceReference(HelloService.class.getName());
          HelloService helloService =(HelloService)context.getService(helloServiceReference);
          System.out.println(helloService.greetHello());

     }

     /*
      * (non-Javadoc)
      * @see org.osgi.framework.BundleActivator#stop(org.osgi.framework.BundleContext)
      */
     publicvoid stop(BundleContext bundleContext) throws Exception {
           ServiceConsumerActivator.context = null;
           System.out.println("Hello World Consumer Bundle Activator Stop");
           context.ungetService(helloServiceReference);
     }

}



Execute Bundles

We have two bundles Service Provider Bundle and Service Consumer bundle.
Service Consumer bundle dependence on Service Provider Bundle. So we have to activate Service Provider bundler before access services in the consumer bundle.


Service Provider Bundle Name:
 com.ls.de.LSServiceProvider

Service Consumer Bundle Name:
com.ls.de.LSServiceConsumer



Start com.ls.de.LSServiceProvider

Go to com.ls.de.LSServiceProvider Activator Class and Right click on class you can see Run

Right Click à Run àRun Configuration

Run configuration window check the required bundles then click on run
Basically we need OSGi implementation bundles that equinox and we can also use other implementation as well like apache Felix. Other two bundles are that we developed. Select only service provider bundle so that only provider bundle will be executed.



Once you run then bundle will activated you can see messages in the console.
In the console just type OSGi gogo shell command to list the bundles then you can see Service Provider Bundle in the list and we can see status that is activated.

Type following command in the gogo shell then we can see all bundles list

lb



Now you can see Service Provider bundle in the list with active state and bundle number.


Now use following stop and start commands then you can see console messages. It will invoke Bundle Activator class


osgi> stop 1003
Liferay Savvy Hello World Service Provider Bundle Activator Stop
osgi> start 1003
Liferay Savvy Hello World Service Provider Bundle Activator Start
osgi>


Note:

We will use bundle number to start or stop bundle in the OSGi container.

The following console shows Invoking Service Provider Bundle Life cycle methods.


Start com.ls.de.LSServiceConsumer

Service Provide Bundle is activated and Now execute Service Consumer bundles so that it will invoke the greetHello(--) method which is implemented in the Service Provider bundle.
Go to com.ls.de.LSServiceConsumerActivator Class and Right click on class you can see Run

Right Click à Run à Run Configuration

Run configuration window check the required bundles then click on run
Basically we need OSGi implementation bundles that equinox and we can also use other implementation as well like apache Felix. Other two bundles are that we developed. Select both bundle and click on run.


Go to Console and list bundles using lb command then you can see both bundles are in active state

Now use stop and start shell commands for service consumer bundle then we can see the console message that make sure that is invoking greetHell(--) method from service provider bundle from consumer bundle

osgi> stop 1003
Liferay Savvy Hello World Service Provider Bundle Activator Stop

osgi> stop 1004

osgi> start 1003
Liferay Savvy Hello World Service Provider Bundle Activator Start

osgi> start 1004
Liferay Savvy Hello World Consumer Bundle Activator Start
=====Inside HelloServiceImpl.greetHello()=====
Hello Greeting from Liferay Savvy World..

osgi>

The following is console which shows its invoked greetHello(--) method




Author

OSGi Bundle MANIFEST Headers

$
0
0
OSGi bundle MANIFEST file is core resource of bundle and we can say its bundle deployment configuration file. OSGi containers will read the information from MANIFEST file and do subsequent actions. We can use many standard OSGi bundle headers in bundle MANIFEST file. Each header have their own significant meaning. Bundle header and its value separated with colon:

The following are headers which proposed by OSGi Alliance. We have other vendor specific headers like Eclipse Foundation, Spring Source and aQute.

OSGi Alliance Standard Headers

The headers proposes by OSGi alliance supported by all OSGi implementation environments like Apache Felix, Equinox and Knopflerfish.

Bundle-ActivationPolicy

Bundle-ActivationPolicy will notify to the container when should bundle available to use or activated. Usually when we deploy bundle, it is immediately available.

Bundle-ActivationPolicy value is lazy it means when bundle will get first request then bundle will be activated.

Example:


Bundle-ActivationPolicy: lazy 


Bundle-Activator

Bundle-Activator header specify the bundle activator java class. Bundle Activator is java class, which manage the bundle life cycle. Each bundle must have activator class and OSGi container invoke the lifecycle methods based on bundle lifecycle stages.

Example:


Bundle-Activator : com.liferaysavvy.bundle.Activator


Bundle-Classpath

Bundle-Classpath is list of values separated by comma delimiter. The values may be jar files or directories and directories have jar files or java classes. Bundle will look for required classes in the given location.

Example:


Bundle-Classpath : apache-commons.jar, apache-logs.jar

OR

Bundle-Classpath : .,WEB-INF/classes,foo1.jar

OR

Bundle-ClassPath: ., A.jar, B.jar, C.jar



Note:

The values separated by comma and dot will specify the current bundle directory.

Bundle-ContactAddress

Bundle-ContactAddress its just information which will use to contact bundle vendors. It’s some text or may be company URL

Example:


Bundle-ContactAddress : Liferay Savvy India

OR

Bundle-ContactAddress : http://www.liferaysavvy.com


Bundle-Copyright

Bundle-Copyright is just copyright information.

Bundle-Description

Bundle-Description is description about bundle and its simple human readable text.

Bundle-License

Bundle-License specify the license information of bundle and it is a text.

Bundle-ManifestVersion:

This header is required and marks the jar as a bundle, the value is always 2 (newer OSGi specifications might add more features in which case the number would be increased).

Value 1 indicates OSGi release 3

Value 2 indicate OSGi release 4

Example:


Bundle-ManifestVersion : 2


Bundle-Name:

Bundle-Name is human readable name for bundle.

Example:


Bundle-Name: LSServiceProvider


Bundle-SymbolicName

Bundle-SymbolicName is unique identification name for bundle. This name will used by other bundle when they have dependency.

Example:


Bundle-SymbolicName: com.ls.de.LSServiceProvider


Bundle-Vendor

Bundle-Vendor is vendor name who implemented the bundle.

Example:


Bundle-Vendor : Liferay Savvy


Bundle-RequiredExecutionEnvironment

Bundle-RequiredExecutionEnvironment is specify the JRE execution environment.

Example:


Bundle-RequiredExecutionEnvironment:  JavaSE-1.8

OR

Bundle-RequiredExecutionEnvironment:  JavaSE-1.7

OR

Bundle-RequiredExecutionEnvironment:  JavaSE-1.6



Bundle-Version

Bundle-Version specify the version number for bundle.

Example:


Bundle-Version: 1.0.0.qualifier

OR

Bundle-Version: 1.0.0


Export-Package

Export-Package contains list of java packages separated by comma delimiter that will be exported and available to other bundles. Only the packages specified by the header will be exported, the rest will be private and will not be seen outside the bundle.

Example:


Export-Package: com.ls.de.lsserviceprovider.services

OR

Export-Package:org.springframework.core.task;uses:="org.springframework.core,org.springframework.util";version=2.5.1 org.springframework.core.type;uses:=org.springframework.core.annotation;version=2.5.1[...]


Export-Service

Export-Service specify the services, which are exported from the bundle, and it will be available to other bundles. List separated by comma delimiter. This header will work when we work with multiple bundles and there is dependency between each other.

Example:


Export-Service: org.osgi.service.log.LogService,org.osgi.service.log.LogReaderService


Import-Package

Import-Package specify the list of bundle packages, which required in the current working bundle. What are the packages exported by other bundles, can import in the current bundle with help of Import-Package header. This header will work when we work with multiple bundles and there is dependency between each other.

Example:


Import-Package: com.ls.de.lsserviceprovider.services

OR

Import-Package:org.apache.commons.logging,edu.emory.mathcs.backport.java.util.concurrent;resolution:=optional[...]


Import-Service

Import-Service is similar to Export-service but it is vice versa. The list of service class names which required by the bundle. Services which are already exported can use in the list.

Example:


Import-Service: org.osgi.service.log.LogService,org.osgi.service.log.LogReaderService


Provide-Capability


More details you can found here



Require-Bundle

Require-Bundle specify the dependency on other bundle. The bundle we specified in the header must be required to activate current bundle. This bundle similar to Import-Bundle header proposed by Spring Source.

Example:


Require-Bundle: org.example.foo; bundle-version=3.0,org.example.bar; bundle-version=1.0



The following are very important headers and we use very regular in the OSGi bundle development.


Manifest-Version
Bundle-ManifestVersion
Bundle-Name
Bundle-SymbolicName
Bundle-Version
Bundle-Activator
Bundle-Vendor
Bundle-RequiredExecutionEnvironment
Export-Package
Import-Package



Spring Source MANIFEST headers

The following are Spring Source proposed MANIFEST headers. To use these headers we must have vendor specific implementation bundle in the OSGi container.

Import-Bundle

Import-Bundle is similar to Require-Bundle proposed by OSGi Alliance and both are same meaning.

Example:

Import-Bundle: org.example.foo; bundle-version=3.0,org.example.bar; bundle-version=1.0


Web-ContextPath.

The default context from which the web content is hosted. You must set the value of the Web-ContextPath header to the value of the <context-root> element for the corresponding web module in the application.xml file. The presence of this header identifies this bundle as a web application bundle.

Example:


Web-ContextPath: /contextRoot


Web-DispatcherServletUrlPatterns

Web-DispatcherServletUrlPatterns specify the URL patterns for Dispatcher servlet.

Example:


Web-DispatcherServletUrlPatterns : /spring/*


Web-FilterMappings

Web-FilterMappings specify the application filter mappings

Example:


Web-FilterMappings  : /secure/*


aQute MANIFEST headers

The following are aQuteproposed MANIFEST headers. To use these headers we must have vendor specific implementation bundle in the OSGi container.

Include-Resource

Include-Resource is path where bundle resource files are available like properties files

Example


Include-Resource: src/main/resources


Private-Package

List of packages, which are specific, the current bundle and it will not be available outside. Other bundles cannot access these packages. This header will used in bnd tools developed OSGi environment. Usually we specify the bundle services implementation packages in the list.

Example:


Private-Package: com.ls.de.lsserviceprovider.services.impl



Eclipse Foundation MANIFEST headers

The following are Eclipse Foundation proposed MANIFEST headers. To use these headers we must have vendor specific implementation bundle in the OSGi container. Equinox implementation support these headers.

The following are headers proposed by Eclipse Foundation.


Eclipse-BuddyPolicy
Eclipse-BundleShape
Eclipse-ExtensibleAPI
Eclipse-PlatformFilter
Eclipse-RegisterBuddy


Reference Links


Author

Liferay WeDeploy Project

$
0
0
Liferay have introduced one of the project called WeDeploy. WeDeploy provides deployment services. We deploy provides the PASS based cloud platform where we can get different services. Liferay WeDeploy offer services such as data, auth, hosting, email and deploy service.

The following is website to get more information


It is very easy to install services and can use it.


WeDeploy offered services



Data Service:

Data Services provide data storage. It has API to store and manage data.


Auth Service

Auth service is providing authentication services and we can integrate to our application as separate service. It is providing API to integrate with other application. We can manage all users credentials at one place such a way we can get authentication service to any of our application rather implement same service to all applications.


Email Service

Email service is providing email-sending functionality. It is very simple to install and can use in any of our application as service. We have good API to get email services integrate with third party applications.


Deploy Service

Deploy Service is offering different application deployment like Java, NodeJS, Ruby and Liferay.

One of the interesting service is Liferay Service, we can create Liferay DXP service for one-month free trail. Its simple few minutes we can install Liferay DXP and it will be available in the internet.


I have recently created liferay service in few minutes here is UR.



We can map our Custom Domain to reach our Liferay Instance.

Currently WeDeploy is released Beta version. We can only get Liferay DXP as 30 days trail. It is also providing Liferay 7 CE version deployment but it is based on Docker way of deployment. It is more like Enterprise Services and can get more support once we get account from them.

Author

Java 9 Features

$
0
0
Java 9 is now available and it has many promising features.

Java platform module system
Jshell Command Line Tool
New Java Version String format
Compile for Older Platform Versions
Private methods in Interface
Http API Support
Core Libraries in JDK 9 Improvements


Java platform module system

Java 9 enabled with new way of development based on modules. A module is self-described collection of code and data with unique identification name. It is kind of Dynamic Component development similar to OSGi.

Usually we need other modular framework to enable dynamic component development in java and now Java platform itself support Dynamic Component Development.

To support module development capability they have introduced different tools such as javac, jlink, jmod and java, which helps to develop and run the modules.

Java 9 is introduced new phase link time for modules, which comes between compile and run time. In this phase module assembled and optimized.

Find more details about Jlink Tool from below link


 Java 9 come up with new packaging system JMOD for modules, which is similar to JAR in addition to JAR feature JMOD (Java Module) contained native code and configuration files as well.

Find more details about JMOD from the below link


Java Platform Module System compliances specified in JSR376
JDK also divided into set of modules, if the application required specific modules we can defined in the application rather than load all modules in the Java Run Time Image. This feature will make application lightweight and its improved performance of application.
Java 9 Removes rt.jar and tools.jar from the Java runtime image

Jshell Command Line Tool (REPL)

Java 9 provided JshellCommand Line Tool to execute and run the java code in the shell.
Usually this kind of interface available for Python and Scala languages. Now it is available in Java 9. JShell is Read–Eval–Print-Loop – REPL for short. We can write java statements in the shell and evaluate then execute.

Find more details from below link


New Java Version String format

New Java Version Sting format makes easy understand when any release is out. It have specific pattern it will explain what kind of release like Major /Minor/Patch/ Security.
The following is release version format


$MAJOR.$MINOR.$SECURITY.$PATCH


Provided more custom selection for installers

For windows have optional selection for web deployment. We can enable or disable web deployment through installers.

Added more Diagnostic Commands

Java 9 have defined additional Diagnostic Commands to improve the ability to diagnose issues with hostspot and JDK. Jcmd is tool, which have set commands to diagnose issues
Find more details about Jcmd from the below link.


Compile for Older Platform Versions

Java 9 improved the javac tool to compile java code in older version java, such way it can run in older version JVM.

Find the more details about javac from the below link


JVM Command-Line Flag Arguments Validation

Java 9 provides the way to validate JVM command line arguments such a way it will avoid the failures and display error message after execute the commands.

Unified JVM Logging

Unified JVM Logging helps common logging system for all java modules.
-Xloggcjava option will enable Unified JVM Logging

Find more about –Xloggcfrom following link


New HTTP Client

Java 9 now have Http support and its replacement for old HttpURLConnection. It support HTTP/2 protocol and Web Socket handshake. Before we use Apache Http client libraries to work with Http URL handshake. Now this support added in Java 9, now we do not required additional external libraries when work with http handshaking.

Private methods in Interface

Java 9 introduced the Private methods in the interface and it will help us to split lengthy default methods in interfaces.

Core Libraries in JDK 9 Improvements

The following are some of features, which improved in the Java core Libraries.

Process API Updates
Variable Handles
Compact String
Platform Logging API and Service
Convenience Factory Methods for Collections
XML Catalogs
Filter Incoming Serialization Data

The following is place you can find all Java 9 features in detail.


Author

OSGi Declarative Services Detailed Information

$
0
0
OSGI Declarative Services is a mechanism to create components and manage dependencies among the components. DS we can also called Service ComponentRuntime and DS and SCR convey same thing in the OSGi Development.

DS will use the XML configuration to define components and its references.  XML files available in the OSGi bundle. When we are talking about DS/SCR, we have following terminology such as Component, Services and Lifecycle.

The following article will gives idea of OSGI Declarative Services.


Components

OSGi primary artifact is Components. Declarative Services created the Component and managed by the OSGi Service Component Runtime.

The following terminology required when we are talking about OSGi components.

Service Component

Service Component is java class declared by Component Description and managed by OSGi Component Service Runtime. This configuration is defined in the XML file with in the bundle.

Usually Service Components are providing set of services and these services perform certain tasks. These components services will be used in the other bundles.

We can declare every java class as OSGi components and not every component have services.  Sometimes component may not provide any service.

Once we declared java class as Service Component then services available to all the bundles, which deployed in the OSGi container.

Component Description

Component Description is XML configuration to Declare Service Component in the bundle. Usually this configuration is available in XML file in the bundle.

Component Configuration

Component Configuration consist of set of properties and it will be used to track the dependencies and manage the Component instance.

Component Instance

The instance of the component implementation class. It is created when a Component Configuration is activated and discarded if the Component Configuration is deactivated.

Note:

Usually XML configuration file should be available in OSGI-INF folder in the bundle.
We have to use following header in the bundle MANIFEST file to identify the XML file by OSGi SCR


Service-Component: OSGI-INF/com.liferaysavvy.example.HelloComponent.xml


Service References

Service reference manage the dependencies among the components. Usually OSGi Application development composed of one or more components. Most of the time there will be dependencies between components, it means one component services will be used in other component. Services Reference is the way to identity the other components services and consume in the dependency components.

Usually when we declare components then the service available to all other bundles and it will be automatically managed by Service Component Runtime.

Service reference will help us to identify the exact services in dependency bundles by using some filers and properties.

When we talking about Service Reference we have following terminology comes into picture

Reference:

Reference is definition of dependency to other service. It is key point which explain the component service depends on other component service.

Target Services

Target services is used to identify the exact reference implementation for the given interface configured in the configuration. Target reference will use some properties to filter service and find exact match.

Usually one interface have multiple implementations so to find required implementation from multiple implementation we will use target services to identify and hook the exact match.

 Bound Services

The services that are bound to a Component Configuration. The binding is done on activating a Component Configuration.

Component Lifecycle

We have different types of components available. The following are deferent component types

Delayed Components

Delayed component will not activated until its get first request to service from other component. This we will defined in the component description based on configuration component will ready and services are available to other components.

Immediate Components

Immediate Components will be ready as soon as deployed in the OSGi container. These services immediately available to other components.

Factory Component

Creates and activates new Component Configurations on request. The created Component Configurations are not re-used if they become unsatisfied or unregistered.
The following Lifecycle state possible for each component

ENABLED/DISABLED

Component initial enable state manage by component description. These component state controlled dynamically by using Component Context.

UNSATISFIED

Component will be unsatisfied if the dependency services not resolved. Sometimes dependency services might not be ready component will be in unsatisfied state.

SATISFIED

If component resolved by all dependency services then it will be in satisfied state and it will be ready to use.

RIGISTERED

If the component is satisfied then it will be registered in SCR and these services can be used in other components once it registered.

ACTIVE

Component activation dependent on its type. If the component is declared as immediate component in the component description then services will be in active state. If it is delayed component then it will be get ready once it gets first request to the service object.

Immediate Component Lifecycle


When we deployed the bundle it will be loaded into OSGi container and the bundle is in active state.

Based on Component description Component will be enabled and we already know its immediate component.

If the component reference not resolved then it will goes to UNSATISFIED state.

If the all reference services resolved then it will go to active state then component will be activated.

If any case other references not resolved then it will goes to unsatisfied state and component will be deactivated.

If the bundle is stopped then component will be disabled.

Delayed Components


Delayed component is little different then immediate component.

As soon as bundle started, Based on component description bundle goes to enabled state.
Once all the dependencies resolved then the component will registered with SCR

When the component get first request then component will be in Active state. Usually we will use getService/bind method to get service.

Once it’s in Active state then component will be activated and available to use.

If any case dependences not resolved then it will goes to Deactivate state finally it will be unregistered.

When will call unGetService/Unbind method then Component will goes to registered state. It means component ready to use, when it get requested.

Before Going through implementation please go through following articles to understand develop basic bundles with OSGi framework.


Example Implementation

Step: 1

Service API Bundle

Usually Service API bundle have service interfaces. We need to declare all services in the interface. Once we declared all services then we need to export package to make available to other bundles.

HelloService.java


packagecom.ls.ds.lsserviceprovider.services;

publicinterface HelloService {
      public String greetHello();
}


Export Services Package

Now we have to Export Services package from services bundles so that these interfaces or resources can be accessible in the other bundles. Remember here only we are exporting services package not implementation package.

MANIFEST have OSGi header called “Export-Package” and we need to add package names with comma separate value, so that we can access these resources in other bundles.

Add “com.ls.ds.lsserviceprovider.services” package name under “Export-Package” in the 
Bundle MANIFEST file

Finally, MANIFEST looks as follows

MANIFEST.MF


Manifest-Version: 1.0
Bundle-ManifestVersion: 2
Bundle-Name: LSServiceProvider
Bundle-SymbolicName: com.ls.de.LSServiceProvider
Bundle-Version: 1.0.0.qualifier
Bundle-Activator: com.ls.de.lsserviceprovider.ServiceActivator
Bundle-Vendor: LS
Bundle-RequiredExecutionEnvironment: JavaSE-1.8
Export-Package: com.ls.ds.lsserviceprovider.services
Import-Package: org.osgi.framework;version="1.3.0"


Step: 2

Service Provider Bundle

We already have Service API bundle and the services exported. Now we have to implements the service method in the implementation class. Create new bundle and implement the services, which defined in Service API, bundle.Implement interface method in the implementation class, finally implementations class as follows.

HelloServiceImpl.java


packagecom.ls.ds.lsserviceprovider.services.impl;
importcom.ls.de.lsserviceprovider.services.HelloService;
publicclassHelloServiceImplimplementsHelloService
     @Override
      public String greetHello() {
         
        System.out.println("=====Inside HelloServiceImpl.greetHello()=====");
        return"Hello Greeting from Liferay Savvy World..";
     }
}


MANIFEST.MF

To use Service API bundle service interfaces in the Provider bundle we need to import the package in the MANIFEST file with Import-Package Header.


Manifest-Version: 1.0
Bundle-ManifestVersion: 2
Bundle-Name: LSServiceProviderImpl
Bundle-SymbolicName: com.ls.de.LSServiceProviderImpl
Bundle-Version: 1.0.0.qualifier
Bundle-Vendor: LS
Bundle-RequiredExecutionEnvironment: JavaSE-1.8
Import-Package: com.ls.ds.lsserviceprovider.services,
 org.osgi.framework;version="1.3.0"
Service-Component:OSGI-INF/com.ls.ds.lsserviceproviderimpl.servicescomponent.xml


Component Declaration

We have to declare component description in services component XML file, which is in bundle OSGI-INF folder. Name can be anything in this case its “com.ls.ds.lsserviceproviderimpl.servicescomponent.xml”

The following is component declaration in the xml file


<?xmlversion="1.0"encoding="UTF-8"?>
<scr:componentxmlns:scr="http://www.osgi.org/xmlns/scr/v1.1.0"
     name="com.ls.ds.lsserviceprovider.services.impl.HelloServiceImpl">
     <implementation
          class="com.ls.ds.lsserviceprovider.services.impl.HelloServiceImpl"/>
     <propertyname="service.description"value="Sample Hello Service"/>
     <propertyname="service.vendor"value="Liferay Savvy"/>
     <service>
           <provideinterface="com.ls.ds.lsserviceprovider.services.HelloService"/>
     </service>
</scr:component>


Note:

We have many XML tags, which we can find in the SCR XML DTD file.


Step: 3

Service Consumer Bundle

Usually in the Service Consumer bundle, we will use component services, which implemented in the other bundles. In this case, we will use services, which are developed in the Service Provider Bundle. We have to use bind method setXXX() type . If we observed in the below implementation we are using service greetHello that was implemented in other bundle. This is how we can reference one-bundle services in other bundles.

ConsumerComponent.java


packagecom.ls.ds.consumer.component;
importcom.ls.ds.lsserviceprovider.services.HelloService;
publicclassConsumerComponent {
   
      publicvoid activate() {
         
           System.out.println("=====Consumer Component Active=====");
     }
      publicvoid setHelloService(HelloService helloService) {
           System.out.println("=====Inside Consumer Component setService()=====");
           System.out.println(helloService.greetHello());    
     }

}


MANIFEST.MF

To use Service API bundle service interfaces in the Provider bundle we need to import the package in the MANIFEST file with Import-Package Header.


Manifest-Version: 1.0
Bundle-ManifestVersion: 2
Bundle-Name: LSServiceConsumer
Bundle-SymbolicName: com.ls.ds.ConsumerComponent
Bundle-Version: 1.0.0.qualifier
Bundle-Vendor: LS
Bundle-RequiredExecutionEnvironment: JavaSE-1.8
Import-Package: com.ls.de.lsserviceprovider.services,
 org.osgi.framework;version="1.3.0"
Service-Component:OSGI-INF/com.ls.ds.consumercomponent.xml


Component Declaration

We have to declare component description in services component XML file, which is in bundle OSGI-INF folder. Name can be anything in this case its “com.ls.ds.consumercomponent.xml” to consume other services in the component we have use reference tag. We have to specify the bind method name and service interface in the properties.

The following is component declaration in the xml file


<?xmlversion="1.0"encoding="UTF-8"?>
<scr:componentxmlns:scr="http://www.osgi.org/xmlns/scr/v1.1.0"
     name="com.ls.ds.ConsumerComponent">
     <implementationclass="com.ls.ds.ConsumerComponent"/>
     <propertyname="service.description"value="Sample Consumer Component"/>
     <propertyname="service.vendor"value="Liferay Savvy"/>
     <referencebind="setHelloService"cardinality="1..1"
     interface="com.ls.ds.lsserviceprovider.services.HelloService"name="HelloService"policy="static"/>
</scr:component>


Note:

We have many XML tags, which we can find in the SCR XML DTD file.


From the three steps, we can understand that how we can implement services and how we can referred into other bundles. This is how declarative services will help share service among bundles.

Important Note

We can implement Declarative Service with help of annotations. XML configuration will be replaced by annotations. So this article will explain how exactly happen when we use Declarative Services.

Author

Liferay 7/DXP Development Options

$
0
0
Liferay 7/DXP is latest portal release from Liferay Inc. Liferay 7 / DXP came up with many promising features.

Liferay 7/DXP supported module development by using OSGi framework and its major architectural change from its previous versions.

Before Liferay 7 / DXP, when we talk about Liferay Development, we always talk about Plugins and now Liferay 7 standpoint, we have bundles.

Liferay 6.2 and before versions, Liferay Application Development and Portal Customization through Plugins, we have different plugins types and each one has its own significant in the portal.

Liferay 7 / Liferay DXP have introduced new type of artifact called Bundle. Bundle is basic unit in the OSGi applications development.

As we already know Liferay 7 / Liferay DXP is support modular way of application development and Liferay 7 / DXP have used OSGi to achieve that capability.

Therefore, in Liferay 7 / DXP each Liferay Application we can call it as bundle. Liferay customization or adding new features to the portal can be developed as bundles.

OSGi bundle or we can say Liferay Application bundles are packaged jar file with set of java and configuration files and it has followed the OSGi application development specifications. These bundles will be executed in the OSGi containers.

Now Liferay 7 / DXP application development completely based on bundles, it means customization and adding new features.

To develop these bundles Liferay has provided different tools. We use these tools to build and deploy the bundles.


Liferay 7 Application bundles development primarily using following tools

LIFERAY IDE
BLADE CLI
LIFERAY WORKSPACE

Build Tools

Maven
Gradle

LIFERAY IDE

Liferay Inc. always develop its own IDE to develop Liferay Applications. Now Liferay Inc. have developed Eclipse plugin to develop Liferay 7 / DXP OSGi bundles.
Liferay IDE will provide GUI to create Liferay 7 / DXP bundles with two types of build environments

MAVEN BUILD:

Liferay IDE will create Liferay 7 bundles and it will use MAVEN to build and deploy the bundles in the Liferay OSGi environment. We have GUI option to select to build tool while creating Liferay OSGi bundles.

GRADLE BUILD

Liferay IDE also support Gradle based build for Liferay OSGi applications.  People who have good hands on Gradle they can choose Gradle build tool.

Liferay IDE plugins internally use the Bndtools framework to create bundles and Bndtools are specially to develop OSGi bundles. Finally Liferay IDE based in Bndtools framework.
Please follow the below article for more information


To know more about Liferay IDE follow the below link


BLADE CLI

Liferay 7 have introduced new Command Line Interface called BLADE CLI. It’s specially to develop Liferay 7 OSGi bundles and deployed into the OSGi environment.

Bootstrap Liferay Advanced Developer Environments shortly call it as BLADE.

BLADE CLI based on GRADLE build tool and it’s internally use the Bndtools Gradle flavor.

BLADE CLI have set of predefined bundle templates to generated different skeleton liferay bundles.

BLADE CLI have provided set of commands and options to choose these templates and its options.


LIFERAY WORKSPACE

LIFERAY WORKSPACE is managing Liferay applications at one place. Its generated environment to hold set of liferay applications. LIFERAY WORKSPACE is not a tool finally its use the BLADE CLI and GRADLE to build and deploy the applications.

Its Independent environment we can easily move to one place to other place. It means we can easily move from one platform to other platforms.

Liferay Workspace based on OSGi workspace, introduced by enroute project to manage OSGi bundles.


Liferay Workspace holding different Gradle environment properties so that we can easy to deploy into different environments such as DEV, UAT and PROD. These configuration has provided in properties file, while building the application Gradle will pick the given environment properties.

Liferay Workspace have many advantages and follow the below articles to get more information.


LIFERAY SAMPLE MODULES

Liferay 7 have provided sample bundles to the developers to understand Liferay 7 / DXP bundles development. We can BLADE CLI to get those sample bundles then deploy into your portal OSGi environment


Author

Differences between Liferay 7 / DXP and Liferay 6.2

$
0
0
Liferay 7 / DXP have many new features when compare with its previous versions. The following are some of differences between Liferay 7/DXP and Liferay 6.2. There are many changes can find, following are major changes we can find in Liferay 7 / DXP




Liferay 7 support modularity development using OSGi framework.


Liferay 6.2 partially support and it’s an experiment and it need more effort to achieve the modularity


Liferay 7 support Bootstrap 3 UI framework.


Support Bootstrap 2 UI framework.


AUI 3.X component used.


AUI 2.x components


AUI components built using JQuery Framework


AUI components built using YUI framework


Liferay Application Development based on OSGi bundles


Liferay Application Development based on Plugins


Liferay 7 EE called Liferay DXP


We simply call Liferay 6.2 EE


Liferay Applications packaged as OSGi bundle jar files and deployed in OSGi container. It support WAR deployment as well.


Liferay Applications packaged as war files and deployed in traditional application server.


User interface improved more and portal look and feel completely changed.


Liferay 6.2 look and feel improved when compare with its previous versions


Liferay 7 separate core portal and its default portlets. Core portal only have core features rest of features made it as portlets and packaged as bundles. Core portal files in ROOT directory deployed in Application Server. All portlet bundles available in data/OSGI directory. It means bundles deployed in OSGi container.


Liferay 6.2 core portal and its default portlets all available in ROOT directory and deployed in Application Server.


We can easily deactivate default portlets if we are not using. We simply deactivate portlet bundle.


We cannot deactivate without change in the code.


Liferay 7 Applications call it as OSGi bundles. Customization and adding new features developed using bundles.


Liferay 6.2 Application Development using Plugins and we have different types of plugins portlet, hook, theme, layout and webs.


Liferay 7 inbuilt search engine Elastic Search. It support SOLR search as well.


Liferay 6.2 in built search engine Apache Lucene. Liferay 6.2 have SOLR web to enable SOLR search.


Liferay 7 removed inbuilt database configuration for Proprietary Databases like Oracle. It support Community databases like MySQL, Hypersonic SQL and MariaDB.


Its support all types of databases like Oracle, MySQL, DB2 and Sybase.


Liferay 7 have Single Page Application inbuilt support using Senna.js


Liferay 6.2 does not have inbuilt Single Page Application support but we can integrate SPA framework to achieve it.


Liferay 7 have introduced Clay and Lexicon language to design UI. Lexicon is a design language that provides a common framework for building interfaces. Clay is web implementation of Lexicon.It's built with HTML, CSS, and Javascript with Bootstrap as a foundation


Liferay 6.2 does not have these design languages.


Liferay 7 form feature improved lot and we can design tow column forms and multiple page forms.


Liferay 6.2 forms are very basic and we cannot design two column forms.


Liferay 7 portlet can break into multiple bundles and deployed in OSGi container.


Liferay 6.2 we should put all files and configuration in one Plugin.


Liferay 7 support MAVEN, GRADLE build tools.


Liferay 6.2 support MAVEN, ANT.


Liferay IDE for Liferay 7 Application Development based on OSGi bundle development features using Bndtools framework. Bundles use MAVEN or GRADLE build tool.


Liferay IDE for Liferay 6.2 Application Development based on Plugins and we can develop different types of plugins like portlet, hook, theme, layout and web. It uses the MAVEN or ANT build tool.


Liferay 7 introduce new tool called BLADE CLI to develop Liferay 7 Application as bundles. Internally its uses the Bndtools GRADLE flavor.


Liferay 6.2 have Plugins SDK Command Line Interface to create portlet, hook, theme and layout.


Class load issues resolved before bundle activate or available in the container. We cannot see Class Not Found run time issues. All these will be resolved before bundle available for use.


We can experience many times Class Not Found issues in Liferay 6.2 Environment.


We can activate/deactivate  Liferay Application Bundles simply using Apache Gogo shell Command Line Interface without un-deploy the bundle from the container.


Liferay 6.2 it is not possible. We should un-deploy the plugins from the server so that we can remove the unused features.


Author

Apache Blueprint Introduction

$
0
0
Apache Blueprint is container specification, which defines the dependency injection for OSGi. It is a dependency framework for OSGi bundle development.


Liferay 7/DXP came up with OSGi support. We can use Apache Blueprint framework to develop Liferay Application OSGi bundles. We can use either OSGi Declarative Services (DS) or Apache Blueprint to develop Liferay bundles. This article give basic idea of Apache Blueprint framework.

We already know Declarative Services in OSGi and Apache Blueprint is similar to DS. Blueprint is enable component services make it available and unavailable at any point of time. Apache Blue Print based on OSGi Compendium R4.2 specifications.


Apache Blueprint is container specification based on OSGi extender pattern. Extender pattern is very used pattern in OSGi environment to extend semantics of bundle by adding new MANIFEST headers. To add addition features to existing bundle nature we will use OSGi extender pattern. Best example is OSGi Declarative Services. OSGi Declarative Services used extender pattern so that it will provide dynamic nature to the components and it services.

Apache Blueprint is used extender pattern as well.  Apache Blue print extender bundles monitor the bundles state in the framework and perform the action on behalf of the bundle based on their actual state.

Extender bundle is responsible to identify the bundle is blueprint bundle or not, once the bundle activated the OSGi container. Extender bundle will look for the Blueprint xml files in the bundle. If any bundle have Blueprint xml files then it will treat bundle as blue print framework bundle. Usually blueprint xml files located in the fixed location in the place OSGI-INF/blueprint/ directory or are specified explicitly in the Bundle-Blueprint manifest header.

Once bundle is blueprint bundle, then it will create the Blueprint container for the bundle and it is responsible for following actions. These actions are similar to Spring Framework Dependency Injection. If we are familiar with Spring framework then it will be easy to understand OSGi dependency Injection through Blueprint framework.

XML file parsing
Instantiate the components
Wiring the component together
Registering the services
Looking up service references

Blueprint XML Configuration

Blueprint framework uses the XML configurations to declare beans and its wiring. Blueprint container read this xml configuration file to instantiate and wiring the beans. Blueprint is top-level xml tag.

The following is basic declaration which specify the blueprint configuration


<?xml version="1.0"encoding="UTF-8"?>
<blueprint xmlns="http://www.osgi.org/xmlns/blueprint/v1.0.0">
...
</
blueprint>


The XML namespace identifies the document as conforming to the Blueprint version 1.0.0. The top-level blueprint element identifies the document as a blueprint module definition.

Bean Declaration

Blueprint uses the bean tag to declare beans. Bean tag have id attribute, which is unique identification for bean.

The following is example of bean declaration.


<?xml version="1.0"encoding="UTF-8"?>
<blueprint xmlns="http://www.osgi.org/xmlns/blueprint/v1.0.0">
<
bean id="helloServiceOne"
class="com.liferaysavvy.blueprint.HelloService"/>
</
blueprint>


Bean Constriction

Blueprint container will look for right constrictor to instantiate the beans. This information provided as bean attributes or its child tags. Instantiation can be happen with the constrictor or factory method.By default, the Blueprint Container uses the number and order of the argument elements in XML to find the right constructor or method.

To help the Blueprint Container pick the right constructor, method, or parameter arrangement, additional attributes, such as index or type, can be specified on the argument element. For example, the type attribute specifies a class name used to match the argument element to a parameter by the exact type.

Beans instantiation with constructor

The following example for bean instantiation with constructor

Java Class


public class HelloService {
   
public HelloService(long number) {
    }
}


Blueprint XML configuration


<bean id=" helloServiceOne"
class="com.liferaysavvy.blueprint.HelloService">
<
argument value="1"/>
</
bean>


Beans instantiation with factory method.

Bean construction can be happen through the static factory method as well. We will use bean factory-method attribute so that Blueprint container identify it and it will instantiate bean by using factory method.

The following is example for Beans instantiation with factory method.

Java Class

 
public class StaticHelloServiceFactory {
   
public static HelloService createHelloService(long number) {
       
return new HelloService(number);
    }
}
 

Blueprint XML configuration

<bean id="helloServiceTwo"
class="com.liferaysavvy.blueprint.StaticHelloServiceFactory"
factory-method="createHelloService">
<
argument value="2"/>
</
bean>
 

Bean Properties

Blueprint have property tag to provide additional configuration to the bean and the container will use it whenever bean required.

The following is example to access and declare the properties for the beans.

Java class


public class HelloService {
   
public HelloService(long number) {
    }
    
public String getMessage() {
    }
}


Blueprint XML configuration

<bean id="helloServiceOne"
class="com.liferaysavvy.blueprint.HelloService">
<
argument value="1"/>
<
property name="message"value="Hi I am Hello Service"/>
</
bean>


Bean Wiring

Sometimes one bean dependence on other bean. We should wire the bean into the current bean. Property injection is used for wiring beans together. In the following example, helloServiceOne is injected with a DependencyService bean.

Java Classes


public class HelloService {
   
public HelloService() {
    }
   
public void setDependencyService (Currency currency) {
    }
}

public class DependencyService  {
   
public DependencyService () {
    }
}


Blueprint XML configuration


<bean id="helloServiceOne"
class="com.liferaysavvy.blueprint.HelloService">
<
property name="dependencyService"ref="dependencyService"/>
</
bean>
<
bean id="dependencyService"
class="com.liferaysavvy.blueprint.DependencyService"/>


Services

Blueprint framework provide the configuration to register service in OSGi service registry. Blueprint xml have service tag it will register the declared services. Service implementation will be referred through ref attribute.

Service Interface

Service Interface container set of services and its simple java interface.

 
public interface HelloService {
    public String sayHello();
}


Service Implementation

Service implementation provided the implementation to the service interface.


public class HelloServiceImpl implements HelloService {
   
public HelloServiceImpl () {
    }
   
public void sayHello() {
    }
}


Blueprint XML configuration


<service id="helloServiceOne"ref="helloServiceImpl"
interface="com.liferaysavvy.blueprint.api.HelloService"/>
<
bean id="helloServiceImpl"
class="com.liferaysavvy.blueprint.impl.HelloServiceImpl"/>


Without using ref attribute we can also declared service implementation as inline to the service declaration


<service id="helloServiceTwo"  
interface="com.liferaysavvy.blueprint.api.HelloService">
<
bean class="com.liferaysavvy.blueprint.impl.HelloServiceImpl"/>
</
service>


The interfaces under which a service is registered can be determined by Blueprint using auto-export. The following registers the service under all the bean's interfaces


<service id="helloServiceOne"ref="helloServiceImpl"
auto-export="interfaces"/>
<
bean id="helloServiceImpl"
class="com.liferaysavvy.blueprint.impl.HelloServiceImpl"/>


Note:

Other values for auto-export are disabled (the default) class-hierarchy and all-classes.

Service Properties

We also configure requires properties for the service using service-properties tag. This service-properties tag contains multiple entry tags to declared properties and it has key and type as attributes. The service property values can be of different types, but only OSGi service property types are permitted: primitives, primitive wrapper classes, collections, or arrays of primitive types.

The following is example for property declaration

<service id="helloService"ref="helloServiceImpl"
autoExport="all-classes">
<
service-properties>
    <
entry key="active">
        <
value type="java.lang.Boolean">true</value>
    </
entry>
    <
entry key="message"value="say hi"/>
</
service-properties>
</service>


Service Ranking

When one service have multiple implementation then service ranking used to choose the matching service implementation. The default ranking value is 0. Service ranking is specified using the ranking attributes as follows:

   
<service id="serviceFive"ref="account"auto-export="all-classes"
  ranking="3"/>


Service Reference
Services are found in the OSGi service registry using the reference element from the Blueprint xml file. The following configuration reference tag referencing the HelloService. If this service found in the OSGi registry then it will be set in the HelloServiceClient.

Blueprint Service Reference XML configuration

<bean id="helloworldClient"
class="com.liferaysavvy.blueprint.client.HelloServiceClient">
<
property name="helloService"ref="helloServiceRef"/>
</
bean>
<
reference id="helloServiceRef"
interface="com.liferaysavvy.blueprint.api.HelloService"/>


Blueprint Implementation Example

Usually OSGi service implementation have their basic bundles. Service API, Service API Provider and Service Client.

Follow below articles


Service API

Service API consist set of services. It means simple interfaces and its abstract methods. These we will make it as bundle. Usually we use export mechanism to make these interfaces available to other bundles.

Hello Service Interface

 
public interface HelloService {
   
public String sayHello();
}


Service API Provider

Service Provider bundle usually implement the services defined in the Service API bundle.

Hello Service Implementation


public class HelloServiceImpl implements HelloService {
   
public String sayHello(){
    }
}


XML configuration


<?xml version="1.0"encoding="UTF-8"?>
<blueprint xmlns="http://www.osgi.org/xmlns/blueprint/v1.0.0">
<
service id="helloServiceOne"ref="helloServiceImpl"
interface="com.liferaysavvy.blueprint.api.HelloService"/>
<
bean id="helloServiceImpl"
class="com.liferaysavvy.blueprint.impl.HelloServiceImpl"/>
</
blueprint>


Service Client

Service Client is other bundle, which use the services provided by Service Provider bundles.
 
public class HelloServiceClient {
    HelloService
helloService = null;
   
public HelloService getHelloService() {
       
return helloService
   
}
   
public HelloService setHelloService(HelloService helloService) {
       
this.helloService = helloService;
    }
}


XML configuration

 
<?xml version="1.0"encoding="UTF-8"?>
<
blueprint xmlns="http://www.osgi.org/xmlns/blueprint/v1.0.0">
<
bean id="helloworldClient"
class="com.liferaysavvy.blueprint.client.HelloServiceClient">
<
property name="helloService"ref="helloServiceRef"/>
</bean>
<
reference id="helloServiceRef"
interface="com.liferaysavvy.blueprint.api.HelloService"/>
</blueprint>



Author

Liferay 7 / DXP Interesting Features

$
0
0
Technological Updates

Tomcat 8
JDK 8
Mysql 5.7
Eclipse Update / Liferay IDE 3

Look and Feel

Lexicon Design Language
set of patterns (visual and interaction)
designed to be fluid and extensible
Optimized product navigation
New Forms user experience
Geolocation any content
New image, file and media selector
Fast response - avoiding full page refreshes
Single Page Applications – senna.js
Very Good News - IE support 10,11/Edg
Bootstrap 3.0 Look and Feel

Modularity – OSGI

Monolithic to Micro services
Now 500+ new modules (bundles in the OSGi world),
We can change any way we like, simply by overriding them with our own modules.

How OSGI

Liferay Module Framework
Apache Felix
Declarative Services (replaces .xml configurations)
Bndtools
Gogo Shell for manipulating the module lifecycle and many other things
Semantic Versioning
Blade Tool/Blade CLI
No ext plugins any more.

Other changes

Lucene Gone, Elastic Search(Separate Server)
Optionally Solr, support only in EE
Goodbye Ant, Hello Gradle (maven is still there)
Build tool based on Node.js for Theme development
New mobile SDK with Liferay screens 2
Clustering not supported in CE

Here are some key changes of interest to existing Liferay developers

Extraction of many features as modules: So far you have been used to working with Liferay as a large web application, of which all of it had to be deployed or none of it. In Liferay Portal CE 7.0, many out of the box portlets, features, and associated APIs have been extracted as OSGi modules. Developers can choose which ones to deploy and use.

Adoption of modern OSGi standards: OSGi is a set of standards for building modular systems. It’s very powerful. Although it was previously difficult to learn and use, its modernized standards, such as Declarative Services, have made learning and using it much easier.

Core Public APIs are provided through portal-kernel (previously known as portal-service); all other public APIs are provided by their own modules.

You can reuse modules and libraries, and manage the dependencies among them.

Registration of classes implementing extension points is now simpler and more consistent; it’s based on the standard @Component annotation instead of declarations it in portal. Properties (in some cases) or portlet.xml (in some others). Note, previous registration mechanisms have been preserved where possible.

Third party extensions and applications are now first-class citizens. Traditional plugins had some limitations that developments done in the core (or done as Ext Plugins) did not have. Modules don’t have these limitations and are much more powerful than plugins ever were.

What has not changed? Even though there are many improvements in Liferay Portal CE 7.0, there are also many great familiar aspects from previous versions that have been preserved. Here are some of the most relevant ones:

The Portal Core and each Liferay app continue to use the three layer architecture: presentation, services, and persistence. The presentation layer is now always provided as an independent module, facilitating replacing it with a different presentation, if desired.

Support remains for previously supported standards such as Portlets (JSR-168, JSR-286), CMIS, WebDAV, LDAP, JCP (JSR-170), etc.

Most Liferay APIs have remained functionally similar to those of 6.2, even if many of their classes have moved to new packages, as part of the modularization effort.

 Liferay IDE is still the preferred tool to develop for Liferay, even though you are still free to use tools that best fit your needs.

Service Builder and other developer tools and libraries continue to work as they have in 6.2.

Traditional plugins for portlets and hooks still work (once they’re adapted to Liferay Portal CE 7.0’s API) through a compatibility layer.

The legacy Plugins SDK can also still be used and transition to the new Liferay Workspace, if desired, is easy.

Contributed by


Liferay 7 / DXP Modularity Introduction

$
0
0
Liferay 7 /DXP is new release from Liferay Inc. Liferay 7 / DXP came up with new architecture based development that is OSGi.

As we know OSGi (Open Services Gateway Initiative) is Dynamic Component Development for Java platform. Its modular framework, where we can compose the application into several module and the modules communicate each other.  Liferay 7 / DXP have OSGi support so we can develop liferay applications as OSGi modules.  Modularity is interesting feature and have many capabilities to make application into several modules.

Follow the bellow articles to know more about OSGi


Interesting features of OSGi

Reduce the complexity and make the application sampler
Easy Deployment of applications
Reasonability of the components and modules
Easy version management
Cross platform support we can run anywhere
Widely used platform now a days.

When we consider all above interesting features OSGi promising platform to deliver many interesting capabilities.

Liferay 7 / DXP have used OSGi modularity features to build and develop the Liferay 7/ DXPApplications.

OSGi specification available in two popular implementations such as Apache Felix and Eclipse Equinox.


Liferay 7 have used both implementation capabilities to strengthen the Liferay Modular Application development.

Traditional Web application development have application servers, which runs the web applications. It means, we will develop applications based on web application standards using some J2EE Web application frameworks. We will package these applications as WAR files and deploy into the Application Servers. This is basic web application development and runs the applications.

Whereas OSGi environment have OSGi container to run the OSGi applications.
OSGi applications can call it as OSGi bundles. OSGi bundles is JAR file, which consist of Java and other configuration files. These bundle developments follow the OSGi specification so that it can run in OSGi containers.

When we are talking about OSGi bundles, we use Component terminology many times.  Component is piece of code, which runs independently and deliver some reusable feature or task.

OSGi application composed of several components and these components are talk each other and all together deliver complex feature or task.

We package the group of components as bundle. Bundles is an OSGi application based on OSGi specification and runs in OSGi containers. Interesting feature of OSGi is application composed into small components.  

OSGi have other interesting artifact called OSGi Service Registry, which manage the component and its service registration and manage the references. OSGi component dependency management controlled via OSGi service registry. OSGi service registry implemented by OSGi Declarative Services and shorty we call it as DS.


We also have other implementation called Apache Blueprint, which is similar to DS.


Liferay 7 /DXP can use both implementation while develop Liferay Application Modules.

Structure of OSGi Module

As per OSGi module development, we have following pieces in the application.

Service API:Service API bundles container the all service interfaces

Service Provider: Service provider bundles provide the implementation for the interfaces which definer in the Service API

Service Client: It will consume the component services.


Liferay 7 / DXP module development follows the same structure while developing the Liferay 7/DXP application bundles.

Structure of a Modular App in Liferay 7 / DXP

As per OSGi, we can break the application into several bundles. Same way Liferay 7 / DXP have several bundles/modules.

The following are important parts or bundles in the Liferay 7 / DXP module development.

API

API contains all interfaces java classes. It is separated from implementation bundle.

Service

Contains the service (business logic) and persistence implementations.

Web

Web contains the presentation layer files such as HTML, JSP, CSS and JavaScript files.

Test

Contains the tests. These are not included in the app for production.

Liferay Modular Architecture


Picture source form Liferay.com

Liferay 7/DXP have several layers in the architecture like Liferay Core, Foundation, and Web experience, Collaboration, Forms & Workflows and Independent Apps.

Liferay Core

Liferay Core consist of all core APIs and Liferay Kernel. Its basic components which will used by all other modules or layers in the Liferay portal.

Foundation

This layer consist of Liferay building blocks implementation such as Users, Roles, Groups, Themes and Permission System.

Applications Layer

Liferay application layer separated with different group of modules and these all are independent apps separated from Liferay Core and Foundation. It uses the both Liferay Core and Foundation layer APIs and Its independent modules.

Liferay core and Foundation layers are packaged as WAR file deployed in the traditional application layer. Usually all these APIs and Implementations available in ROOT directory that deployed in Application server deployment directory.

Liferay independent Apps are made it as OSGi bundles, deployed in the OSGi container. All liferay bundles are found in OSGi directory of Liferay portal.

Liferay have provides the gateway which communicate with Liferay Core and Foundation layer to fulfill liferay application features.

Liferay 7 /DXP still support the plugins development and its deployment. This is a reason still we can see traditional application server. Liferay older versions migration to Liferay 7 / DXP possible through to keep traditional application server in the Liferay 7/DXP.

To customize or develop new features in Liferay 7/DXP, Developer follows the OSGi modularity specification to develop Liferay 7 / DXP apps.

Now all liferay applications possible through the OSGi bundles. Still some of the limitations for Liferay Themes, so we follows the Web based development for themes. Portlets, hooks can make it as OSGi bundles and themes can make it as WARs. Liferay 7 / DXP still support Plugins SDK so that we can develop liferay applications as plugin wars.

Liferay 7 / DXP suggested using OSGi Declarative Services (DS) framework to develop Liferay 7 application bundles. We can use Apache Blueprintframework as well.

Liferay have used Apache Gogo shell Command Line Interface to manage bundles, its means Activate/Deactivate Start/Stop bundles in the OSGi container. Bundles lifecycle controlled via Apache Gogo shell.

Interesting point is, we can disable/ enable Liferay features through Apache Gogo shell and we do not need to un-deploy or remove bundle from OSGi container. Just we can deactivate or activate is enough.

Liferay have provided good tools to develop Liferay 7/DXP modules. Follow the below articles to know more about Liferay 7/DXP Module Development. Follow below link to find more details about Liferay Application Development Tools


Author

OSGi Whiteboard Design Pattern

$
0
0
Design patterns plays important role in the Software Development. It will define the reusable implementation to the commonly occurred problems. Usually in software development, we can see same problem repeatedly coming in the applications. To address these common problems, expert people came up with solution called design patterns. Design patterns define the solution so that we can implement solution to address the the common problems.

Whiteboard Design pattern is commonly and wide used pattern in OSGi implementations. OSGi Service Registry implemented on White Board Design Patter.

Liferay 7 / DXP have used OSGi Declarative Services (DS) to implements Liferay application modules. It is good to know White Board design pattern and Service Registry. It will give more idea about component services and its working.

When we work with Declarative Service Framework, bundle have several components and these components depends on other components.

Usually component have services and these services shared among other components. Service Registrymanage the services registration information and its dependency service information. It will manage services and its references information.

To manage these things OSGi have Service Registry that is based on Whiteboard Design Pattern.

White Board Design pattern will provide the mechanism to register the different component services and the dependency component can easily find it reference service based on their needs. Whenever new service implementation register with Service Registry then dependency will get to know the information so that it can find appropriate dependency service.

Assume Component C1have service S1 and perform certain task, it needed other service it means service S1 depends on other component services.

Assume S1service can have several option that can perform task, it means several component provides their services to S1 and S1 can choose any of that service to full fill the requirement. Now S1 have options like C2 component Service S2 and C3Components Service S3.


To provide these dependency service information or reference service information we need other component so that S1 service can identify its dependent service. To provide this king information we need other component called Whiteboard or Service Registry.

When the component is activated, all the services are register with Whiteboard / Service Registry.


Now C1 component Service S1 can identify, it’s required dependent service from the Whitboard / Service Registry to complete or perform the task.

Here S1have several option, it can choose any of the service based on its requirement. S1 will use some additional properties to identify the required service at the point of the time. Such a way whiteboarddesign pattern have used in OSGi to implement Service Registry.



Service Registry is key component in the OSGi implementation and OSGi Declarative Service have used Service Registry to provide dependency mechanism among the component services.  OSGi Declarative Service is core framework to develop OSGi components and its services.

Author

Liferay DXP/7 BLADE CLI Introduction and Its Commands

$
0
0
Liferay DXP/7 have exciting features and one of the major architectural change is to support OSGi modularity framework.

Follow the below article to know more information about Liferay DXP/7 Modularity introduction.



Now Liferay DXP/7 Application development through OSGi bundles and it has followed the OSGi specification.

Liferay DXP/7 introduced module development tool called BLADE CLI. BLADE is a Command Line Interface have set of commands to create Liferay DXP/7 modules and its deployment into the Liferay OSGi run time environment.

Bootstrapped Liferay Advanced Development Environment shortly we call it as BLDAE. It is very easy to install and very flexible to use and create Liferay Modules.

BLADE have implemented based on Gradle buildtool. Behind the scene, BLADE uses the Bndtools framework to create and deploy OSGi bundles.  Finally, we can say BLADE is based on the Gradle flavor Bndtools.


BLADE have provided the human readable commands to create Liferay modules. BLADE consist of several Module Templates to create Liferay 7 Application modules like portlet module, hook module and theme module. It also have commands to access sample projects and deploy into OSGi runtime.

 BLADE tools have commands to create Liferay 7 module and we can use any Development IDE to edit the code then deploy through BLADE CLI commands. Installation of BLADE tool and Module creation process will be explained in the future articles. Once we installed the BLADE, we can issue the predefined commands to create and deploy the modules.


The following are the set of BLADE CLI commands its description.

deploy:
Deploy commands will build and deploy the modules into Liferay OSGi environment. Usually deploy commands works similar to previous liferay MAVEN deploy but it’s in OSGi way. It will compile, build and package the module and place the module jar file into Liferay Portal deploy directory. Once the module jar file place in deploy directory then Liferay hot deploy process will handle subsequent steps to make the available of module to end user.

convert:
Convert previous Plugins SDK plugins to OSGi modules. Usually Liferay 7 have concept called Liferay Workspace.  It convert Plugins project to Workspace project based on Gradle.
As we know that Liferay DXP/7 based on OSGi and all Liferay 7 application, make it as modules. However, we already have Plugin Environment to develop Liferay previous versions applications so convert toll make it plugins to modules.

create:
Create command used to create new Liferay Application Module based on available module templates. BLADE has provided several module templates to create different types such as portlet, hook and them modules. These commands have several option so choose appropriate template.

gw:
gw is Gradle Wrapper on top of Gradle build to make work easier for developer to run Gradle build commands.

init:
Liferay has introduced Liferay Workspace to manage the Liferay modules and it’s easy to shift one place to other place. Init command will initialize the Liferay Workspace it means it will create directory structure to accommodate modules, related properties and liferay portal server instance.  All will be created once we use init command.

install:
This command install a liferay bundle into Liferay OSGi runtime environment. Bundle is packaged OSGi jar file, which run in OSGi runtime.

help:
Help commands will shows help information like list of available commands and its options.

open:
Open command open or import file in Liferay IDE and open project as well.

samples:
Samples project generated sample projects in Liferay Workspace. Liferay have provided sample project for the developers to understand more about Liferay module development.
Sample command will access those samples from repository and downloaded into local Liferay Workspace. We can edit, deploy and test the sample modules.

server:
This command start Liferay Portal Server Instance, which reside in Liferay Workspace bundle directory.

sh:
Sh command connect to Apache Gogo shell console to manage OSGi bundles which are available in OSGi runtime.


update:
Update command will update to latest versions when new version is available.

version:
It will display BLADE CLI version information.

Author

Liferay DXP/7 BLADE CLI Installation

$
0
0
BLADE CLI is Liferay DXP/7 Application Development Tool to create and deploy Liferay 7 Modules.

As we know that Liferay 7 introduces modularity to develop Liferay applications and BLADE is providing command line interface to create and deploy the application modules into Liferay Portal Module Framework.

BLADE have set of predefined commands to create different types of module to customize or create new features in Liferay Portal Environment.

It is really a different king of experience to develop Liferay OSGi bundles than regular web application development.

Please follow the below articles to know more about BLADE CLI and its commands.


Liferay have provided Liferay WorkspaceInstallerto install BLADE CLI in our local machines. Installer is available for all kinds of OS environments like Windows, Linux and Mac. BLADE CLI is available as part of Liferay WorkspaceInstaller. Liferay Workspace is manage the Liferay Modules and It configuration. We will more details of Liferay Workspace in the future articles.

Note:

Before Liferay Workspace Installer BLADE CLI used the Java Package Manager (JPM)to install BLADE CLI and we have other option as well that is directly download BLADE CLI java JAR file then simply execute using Java JAR command. Liferay WorkspaceInstaller is way to install BLADE CLI and it is recommended.

Step: 1

Go to following link to download Liferay Workspace Installer.


We can also go to Liferay IDE Download page and Select Liferay Workspace Installer in the Others Download dropdown.


Based on your Operating System download appropriate Installer and run in your machine.
The following screen shows you the Liferay Workspace Installer Download page.




Step: 2

In this example, I am showing for the Windows Operating System. Once you downloaded the Liferay Workspace Installer, double click in file then it open dialog. Click on Next


Step: 3

Here we have option to select directory for initialize the Liferay Workspace. However, here we would like to install only BLDE CLI so just select “Don’t Install Liferay Workspace Directory” then click on next.


Note:

Sometimes you can see the option to select Liferay portal Server. Either we can chose Liferay 7 Community Server bundle Or Liferay DXP server bundle.Select “Liferay Community Server Bundle” as we are using Liferay 7 Community Edition and it is free to use. If you already have Liferay DXP license then select Liferay DXP bundle.

Step: 4

Once you click on Next it will show dialog that “Setup is now to being install” then click on next.



Step: 5

Finally it installed all required thing and it shows finish dialog then click on finish. Now BLADE CLI installation is completed.



Step: 6

Once installation is completed then open Windows Command Prompt and type “blade” then you can list of commands. If you see all these commands, it means BLADE CLI successfully installed otherwise you can see 'blade' is not recognized as an internal or external command.



Now you can play with BLADE CLI commands. You can create and deploy the Liferay DXP/7 modules. Here you can find all available commands.


Note:

In this installation, we only installed BLADE CLI. It is recommended to initializing the Liferay Workspace through installer option. Liferay Workspace has provided the way to manage modules and deploy into different types of run time environment like DEV, UAT and PROD.

BLADE CLI also have command “blade init” to initialize the Liferay Workspace. We can create multiple Liferay Workspace based on our needs.

The following are the list of BLADE CLI commands.


blade convert
blade create
blade deploy
blade gw
blade help.
blade init
blade install
blade open
blade samples
blade server
blade sh
blade update.
blade version



Author

OSGi Declarative Services (DS) Annotations

$
0
0
Annotation are the replacement for traditional XML configuration in the application development. Usually any application we can see many xml configurations, which will have set of predefined tags. Server containers or other application execution engines will use these XML configurations. Example Spring Web Applications, we have many spring configuration files, which will be used by Spring Containers to make the Dependency Injection among the beans.  Similarly, Liferay have many xml configuration files while developing portlets.  To manage the many XML files in the project is little tedious so experts come up with Annotationsso that we can avoid most of the XML configurations while developing applications.

OSGi Declarative Services (DS) uses the XML configurations to manage component dependency injection in the OSGi Environment. To avoid old XML configuration, we have OSGi Declarative Services Annotations. Usage of annotation are very simple and simply define in the java classes wherever it requires.  All Annotation configurations finally turn into XML configuration and this kind of action will be taking care by the annotation implementation libraries. Developer do not need to worry about that part.

Previous Articles have given more details about XML configuration for the OSGi Components.


OSGi Declarative Service (DS) have following are the important annotations  to develop OSGi components.


@Component
@Reference
@Activate
@Deactivate
@Modified



Note:

All components are available in “org.osgi.service.component.annotations” package.

@Component

@Component is very important annotation in Declarative Services and it will make any simple java class into OSGi component. Its class level annotation so the java class turn into OSGi component.

Usually the component have service implementation so we will use @Component annotation to make the services implementation java class as Component to deliver services.

We can use @Component to any simple Java class in the OSGi component development and all the components need not to have service implementation. We can use @Component for any java class in the OSGi bundle development.

When we declare java class as component then the component registered in the Service Component Runtime registry so that the component will be available to other component when it needed.

The @Componenthave following attributes and all the attributes enclosed by braces. Each attributes separated by comma.

The following are the important attributes


name
immediate
service
property


Name:

Name uses to define the Component name. Usually its fully qualified class name. This name will be uses as the reference point for the other component.

Immediate:

Immediate is Boolean type value, which tell the OSGi container to activate component immediately when OSGi bundle deployed.

Service

Service attribute is java service interface. Which tells that, for which service interface the component is proving the implementation.

Property

If component, needed any other configuration information we will provided as properties and this will take list of key value pair values.

Note:

All the attributes are optional. As we know, each component not necessary to provide the service implementation. Some of them are service components and some of them are simple component, which does not have any service implementation.

Case: 1

Simple Component

When we use @Component it will turn into as OSGi component.

Example Component Java Class with @Component


package com.ls.ds.component;
import org.osgi.service.component.annotations.Component;
@Component
publicclass HelloComponent {
    public HelloComponent() {
        System.out.println("Hey I am Simple OSGi Component");
    }
}


Case: 2

Service Component

As we know that usually component will provide implementation for the services. Assume we have service interface and have implementation class. Now we can make services implementation as component with @Component annotation.

Example:

HelloService.java


package com.ls.ds.lsserviceprovider.services;

publicinterface HelloService {
      public String greetHello();
}


HelloServiceImpl Service Component

We will use @Component to service implementation class so that java class became service component and these services will be available to other components when it needed.

 
package com.ls.ds.lsserviceprovider.services.impl;
import com.ls.de.lsserviceprovider.services.HelloService;
@Component(
        name=com.ls.ds.lsserviceprovider.services.impl.HelloServiceImpl,
        immediate = true,
        service = HelloService.class
)
publicclass HelloServiceImpl implements HelloService {
    @Override
    public String greetHello() {
        System.out.println("=====Inside HelloServiceImpl.greetHello()=====");
        return"Hello Greeting from Liferay Savvy World..";
    }
}


@Componentequivalent configuration for the above example as follows.


<?xmlversion="1.0"encoding="UTF-8"?>
<scr:componentxmlns:scr="http://www.osgi.org/xmlns/scr/v1.1.0"
     name="com.ls.ds.lsserviceprovider.services.impl.HelloServiceImpl">
     <implementationclass="com.ls.ds.lsserviceprovider.services.impl.HelloServiceImpl"/>
     <service>
           <provideinterface="com.ls.ds.lsserviceprovider.services.HelloService"/>
     </service>
</scr:component>


Case: 3

Service Component with Properties

HelloService.java


package com.ls.ds.lsserviceprovider.services;

publicinterface HelloService {
      public String greetHello();
}


HelloServiceImpl Service Component

 

package com.ls.ds.lsserviceprovider.services.impl;
import com.ls.de.lsserviceprovider.services.HelloService;
@Component(
        name=com.ls.ds.lsserviceprovider.services.impl.HelloServiceImpl,
        immediate = true,
        property = {
                "service.vendore=Liferay Savvy",
                "service.description=Sample Hello Service",
        },
        service = HelloService.class
)
publicclass HelloServiceImpl implements HelloService {
    @Override
    public String greetHello() {
        System.out.println("=====Inside HelloServiceImpl.greetHello()=====");
        return"Hello Greeting from Liferay Savvy World..";
    }
}
 

@Componentequivalent configuration for the above example as follows.


<?xmlversion="1.0"encoding="UTF-8"?>
<scr:componentxmlns:scr="http://www.osgi.org/xmlns/scr/v1.1.0"
     name="com.ls.ds.lsserviceprovider.services.impl.HelloServiceImpl">
     <implementation
          class="com.ls.ds.lsserviceprovider.services.impl.HelloServiceImpl"/>
     <propertyname="service.description"value="Sample Hello Service"/>
     <propertyname="service.vendor"value="Liferay Savvy"/>
     <service>
           <provideinterface="com.ls.ds.lsserviceprovider.services.HelloService"/>
     </service>
</scr:component>


Liferay DXP/7 used the Declarative Services annotations to develop Liferay Application modules such as portlets and hooks.

Liferay Portlet Component

The following is simple example code for the portlet component with @ComponentAnnotation


package com.liferay.polls.web.internal.portlet;

import com.liferay.polls.constants.PollsPortletKeys;
import com.liferay.portal.kernel.portlet.bridges.mvc.MVCPortlet;
import javax.portlet.Portlet;
import org.osgi.service.component.annotations.Component;

@Component(
     immediate = true,
     property = {
           "com.liferay.portlet.add-default-resource=true",
           "com.liferay.portlet.css-class-wrapper=portlet-polls-display",
           "com.liferay.portlet.display-category=category.cms",
           "com.liferay.portlet.header-portlet-css=/css/main_polls_display.css",
           "com.liferay.portlet.icon=/icons/polls_display.png",
           "com.liferay.portlet.instanceable=true",
           "com.liferay.portlet.preferences-owned-by-group=true",
           "com.liferay.portlet.private-request-attributes=false",
           "com.liferay.portlet.private-session-attributes=false",
           "com.liferay.portlet.render-weight=50",
           "com.liferay.portlet.scopeable=true",
           "com.liferay.portlet.struts-path=polls_display",
           "com.liferay.portlet.use-default-template=true",
           "javax.portlet.display-name=Polls Display",
           "javax.portlet.expiration-cache=0",
             "javax.portlet.info.keywords=Polls",
           "javax.portlet.info.short-title=Polls Display",
           "javax.portlet.info.title=Polls Display",
           "javax.portlet.init-param.template-path=/",
           "javax.portlet.init-param.view-template=/polls_display/view.jsp",
           "javax.portlet.name=" + PollsPortletKeys.POLLS_DISPLAY,
           "javax.portlet.resource-bundle=content.Language",
           "javax.portlet.security-role-ref=power-user,user",
           "javax.portlet.supports.mime-type=text/html"
     },
     service = Portlet.class
)
publicclass PollsDisplayPortlet extends MVCPortlet {

}


@Reference

@Reference is opposite to @Component. @Component is will used to declare java class as service component and @Reference used to find the Service Component from the Service Component Runtime Registry.

To identify the required service component from the Service Registry we will use @Reference. @Reference will identify the dependent component and inject into the current component.

@Component is responsible to register the component in the OSGi Service Registry and make it available to other components.

@Reference used to identify the right dependent component and inject into the current component.

Example @Reference


package com.ls.ds.consumer.component;
import com.ls.ds.lsserviceprovider.services.HelloService;

@Component(
name=com.ls.ds.ConsumerComponent
)
publicclass ConsumerComponent {
      @Reference
      publicvoid setHelloService(HelloService helloService) {
           System.out.println("=====Inside Consumer Component setService()=====");
           System.out.println(helloService.greetHello());   
      }
}


@Referenceequivalent configuration for the above example as follows.


<?xmlversion="1.0"encoding="UTF-8"?>
<scr:componentxmlns:scr="http://www.osgi.org/xmlns/scr/v1.1.0"name="com.ls.ds.ConsumerComponent">
     <implementationclass="com.ls.ds.ConsumerComponent"/>
     <referencebind="setHelloService"cardinality="1..1"
     interface="com.ls.ds.lsserviceprovider.services.HelloService"name="HelloService"policy="static"/>
</scr:component>


The following are the important attributes for the @Reference


target
unbind


target

Target attribute will used to filter the reference components. Sometime we may have multiple implementation for service. It means we have many Service Components with different implementation. To identify the right Component instance, we will use target attribute. Usually we use set of properties for Component declaration so same properties will be used @Reference target to filter the reference components.

unbind

Unbind is used to declare setter method when the component is unbind or dissociated with the component. When the attribute with “-” it means there is no setter method is called after component unbind.

Example:


@Reference(
  target = "(javax.portlet.name=" + NotificationsPortletKeys.NOTIFICATIONS + ")",
  unbind = "-"
)
protectedvoid setPanelApp(PanelApp panelApp) {
  _panelApp = panelApp;
}


Liferay DXP/7 used the Declarative Services annotations to develop Liferay Application modules such as portlets, hooks.

Liferay Portlet Component with @Reference

The following is simple example code for the portlet component with @ReferenceAnnotation


@Component(
     immediate = true,
     property = {
           "com.liferay.portlet.add-default-resource=true",
           "com.liferay.portlet.css-class-wrapper=portlet-journal-content",
           "com.liferay.portlet.display-category=category.cms",
           "com.liferay.portlet.display-category=category.highlighted",
           "com.liferay.portlet.header-portlet-css=/css/main.css",
           "com.liferay.portlet.icon=/icons/journal_content.png",
           "com.liferay.portlet.instanceable=true",
           "com.liferay.portlet.layout-cacheable=true",
           "com.liferay.portlet.preferences-owned-by-group=true",
           "com.liferay.portlet.private-request-attributes=false",
           "com.liferay.portlet.private-session-attributes=false",
           "com.liferay.portlet.render-weight=50",
           "com.liferay.portlet.scopeable=true",
           "com.liferay.portlet.use-default-template=true",
           "javax.portlet.display-name=Web Content Display",
           "javax.portlet.expiration-cache=0",
           "javax.portlet.init-param.template-path=/",
           "javax.portlet.init-param.view-template=/view.jsp",
           "javax.portlet.name=" + JournalContentPortletKeys.JOURNAL_CONTENT,
           "javax.portlet.resource-bundle=content.Language",
           "javax.portlet.security-role-ref=guest,power-user,user",
           "javax.portlet.supports.mime-type=application/vnd.wap.xhtml+xml",
           "javax.portlet.supports.mime-type=text/html"
     },
     service = Portlet.class
)
publicclass JournalContentPortlet extends MVCPortlet {

     private ExportArticleUtil _exportArticleUtil;
     private JournalArticleLocalService _journalArticleLocalService;
     private JournalContent _journalContent;
     private TrashEntryService _trashEntryService;
    
     @Reference(unbind = "-")
     protectedvoid setExportArticleUtil(ExportArticleUtil exportArticleUtil) {
           _exportArticleUtil = exportArticleUtil;
     }

     @Reference(unbind = "-")
     protectedvoid setJournalContent(JournalContent journalContent) {
           _journalContent = journalContent;
     }

     @Reference(unbind = "-")
     protectedvoid setJournalContentSearchLocal(
           JournalArticleLocalService journalArticleLocalService) {

           _journalArticleLocalService = journalArticleLocalService;
     }

     @Reference(unbind = "-")
     protectedvoid setTrashEntryService(TrashEntryService trashEntryService) {
           _trashEntryService = trashEntryService;
     }

     protectedvoid unsetExportArticleUtil(ExportArticleUtil exportArticleUtil) {
           _exportArticleUtil = exportArticleUtil;
     }

     protectedvoid unsetJournalContent(JournalContent journalContent) {
           _journalContent = null;
     }

     protectedvoid unsetJournalContentSearchLocal(
           JournalArticleLocalService journalArticleLocalService) {

           _journalArticleLocalService = null;
     }

     @Override
     publicvoid doView(
                RenderRequest renderRequest, RenderResponse renderResponse)
           throws IOException, PortletException {

           ..........
     }

     @Override
     publicvoid render(
                RenderRequest renderRequest, RenderResponse renderResponse)
           throws IOException, PortletException {

           ............
     }

     publicvoid restoreJournalArticle(
                ActionRequest actionRequest, ActionResponse actionResponse)
           throws Exception {
         .................
     }

     @Override
     publicvoid serveResource(
                ResourceRequest resourceRequest, ResourceResponse resourceResponse)
           throws IOException, PortletException {

           ................
     }   

}



Component Lifecycle Annotations

Each component have its own lifecycle and each life cycle stage will call life cycle methods. To define these life cycle methods we will use following annotation


@Activate
@Deactivate
@Modified


@Activate

@Activate will define the method that will be called when the component is activated. When we deploy the bundle then all the components will be activated.

The activate method have 3 types of method signatures


@Activate
protectedvoid activate() {
  
}

@Activate
protectedvoid activate(Map<String, Object> properties) {
  
}

@Activate
protectedvoid activate(BundleContext bundleContext, Map<String, Object> properties) {
  
}



@Deactivate

@Deactivate will define the method that will be called when the component is deactivated. Usually when un-deploy or stop the bundle then the all component will be deactivated.

@Modified

@Modified will define the method that will be called when the component is modified.

Component with Lifecycle Annotations


package com.ls.ds.consumer.component;
import com.ls.ds.lsserviceprovider.services.HelloService;
@Component(
name=com.ls.ds.ConsumerComponent
)
publicclass ConsumerComponent {
      
      @Activate
      publicvoid activate() {
           System.out.println("=====Service Component is Activated=====");   
      }
      @Deactivate
      publicvoid@deactivate() {
           System.out.println("=====Service Component is Deactivated=====");   
      }
      @Modified
      publicvoid modified() {
           System.out.println("=====Service Component is Modified=====");  
      }
      @Reference
      publicvoid setHelloService(HelloService helloService) {
           System.out.println("=====Inside Consumer Component setService()=====");
           System.out.println(helloService.greetHello());   
      }
}



Author

Differences between Liferay Module and Liferay Plugin

$
0
0
The objective of this article is providing the major differences between Liferay Module and Liferay Plugin.

Before understand difference we must have basic idea of OSGi and Liferay 7 Fundamentals.
Follow Liferay DXP/7 Tutorial to get more information.




Liferay Modules
Liferay Plugins

Introduced in Liferay 7

Introduced since Liferay Started.
From Liferay 4.x to Liferay 7/DXP


Liferay Modules are based on OSGi framework

Liferay Plugins based traditional Java web application framework. Like we use more J2EE web application Frameworks.


Liferay Module will run in OSGi Run Time Environment.


Liferay Plugins run in Traditional Application Servers such as Tomcat, JBoss , Glassfish


Liferay Module we can call it as OSGi bundles and packaged as JAR file.


Liferay Plugins are web applications and packaged as WAR files.

Liferay Module provides the dynamic component injection with help OSGi so that we can make most of the features as independent components and can easily inject into the other components when it required.


Liferay plugins are like independent web applications we cannot share anything between two web applications. It is more coupled. If we want share some classes we have to put these jar files in some global class loaders then only other web application can use that classes.


We can avoid all the problems of class loader issues.


We can see more class loader issues.

No Class Definition Found, Class Not Found Run time errors completely vanished in the runtime.


We frequently experience No Class Definition Found, Class Not Found Run time errors in the runtime.


Liferay Modules have different types like Portlet Modules, Hook Modules.
Themes and Layouts partially support modularity.


Liferay plugins have different types such as portlets, themes, ext, layout and hooks.

Liferay Modules developed based on OSGi Framework and it used the several framework to develop modules such as Declarative Services (DS), Apache Blueprint and OSGi API.


Liferay Plugins uses the J2EE web application frameworks such as Struts, Spring, Liferay MVC, JSF and other web application frameworks.


Liferay Modules followed 3-tier architecture application development such as Persistence, Service and Presentation layered architecture.


Liferay Plugins uses the same 3-tier architecture application development such as Persistence, Service and Presentation layers architecture.


Usually Liferay Module development we separated each Layer as Independent Modules
Persistence Tier Module
Service Tier Module
Web Tier Module


Liferay Plugins Development all 3 tiers packaged as single WAR file.

Liferay Modules support the dynamic deployment feature and we can stop and start module without un-deploy the module.


Liferay Plugins we must un-deploy the war file from server to remove features.


Liferay Modules uses the Apache Gogo shell Command Line Interface (CLI) to manage the Liferay Modules in the OSGi run time environment. Like stop, start, activate and deactivate.

Liferay Portal Admin screen also have to manage these Liferay modules.


Liferay plugins does not have any Command Line Interface to un-deploy the bundles and we have to removed plugin war files from servers.

Some Enterprise Application Servers have administrative feature to do these things.

Liferay Portal Admin screen also have option to manage these Liferay plugins.



Liferay modules are available in Liferay Portal Server Bundle inside OSGI directory once the module is deployed.


All Liferay Plugins are available in Liferay Portal Server webapps directory.

Liferay Module have important configuration file METAINF which is like module deployment configuration file have more information used by OSGi run time environment.


Liferay Plugins have web.xml file and used by Portlet/Servlet containers.


Liferay portlet module all xml configuration files information turn into Declarative Services (DS) Component properties. Like portlet.xml, liferay-portlet.xml and liferay-display.xml files tags and values.



Liferay Plugins used the XML configuration such as portlet.xml, liferay-portlet.xml and liferay-display.xml

If the Liferay Application have more features then we divided into multiple independent modules and these modules can communicate each other very easy in OSGi environment.


Modularity is not that easy in Liferay Plugins development so we have to keep all the files in single WAR file.

Liferay Module introduced new tool called BLADE CLI to develop Liferay Modules.


Liferay Plugins have Plugins SDK to develop Liferay Applications.


Liferay Modules have several tools such as Liferay IDE, Liferay Studio, BLADE CLI


Liferay Plugins have tools such as Liferay IDE, Liferay Studio.


Liferay Module support GRADLE and MAVEN build environment.


Liferay Plugins support ANT and MAVEN build environment.


Liferay Modules used the Liferay Workspace concept to manage the application and its configuration across the platforms.


Liferay Plugins uses the Plugins SDK to develop and manage the plugins.


Liferay Modules used the OSGi API, Declarative Services and Apache Blueprint framework. So we have limited choice to use popular we application framework like Spring. Liferay still not fully supporting Spring Modules, it means we have to use the WAR deployment.



We can use any J2EE popular web application frameworks such as Spring, Struts and JSF.

Liferay Modules provides the Micro services Architecture based applications.


To bring Micro services Architecture we have to depend on other frameworks such as Spring Micro Services.


Liferay Modules have dynamic component development feature so we can easily turn on and off the feature at any point of time with minimal effort.


Liferay Plugins not like Dynamic Component Development so bunch of feature in one plugin application. If we remove one plugin, it can turn off many features.


Liferay Modules can provide easy way deployment process and we can move easily from one environment to other with minimal effort. Liferay Workspace provided this capability.



Liferay Plugin Deployment process and moving from one environment to other tedious. We do not have any special mechanism like Liferay Workspace.

Liferay Modules uses the Bndtools to develop and build the modules. We have BLADE CLI, Liferay IDE, GRADLE and MAVEN are used the Bndtools internally.



Liferay Plugins follow the J2EE web application development so MAVEN Liferay Plugin or Liferay IDE handle the Development and Deployment.



Author

Liferay 7.2/DXP Service Builder Behavior for Upgraded Database

$
0
0

When we upgrade portal from older version to newer version, we can see following issues when we deploy migrated service builder bundles. Specially from Liferay 6.1/6.2 to Liferay 7.2/DXP.

Liferay 6.1/6.2 Release_ tables will not add any records for service builder services until unless if write Upgrade Step Process. Liferay 7.2/DXP will behave very different and each and every service builder service must be register in Release_ tables then only service will be available in service registry.

Release_ Table



When we upgraded database, all tables for service builder portlets already existed and when we try to deploy migrated bundles in Liferay 7.2 we can see following issues.

The following service(s) are missing:
 * com.liferay.portal.kernel.configuration.Configuration (&(configuration.bundle.symbolic.name=com.foo.mytest.service)(name=service)) is not found in the service registry
 * com.liferay.portal.kernel.model.Release (&(release.bundle.symbolic.name=com.foo.mytest.service)(&(release.schema.version>=1.0.0)(!(release.schema.version>=1.1.0)))(|(!(release.state=*))(release.state=0))) is not found in the service registry

g! dm na
[950] com.foo.mytest.service
 [89] com.liferay.portal.spring.extender.internal.configuration.ServiceConfigurationInitializer unregistered
    com.liferay.portal.kernel.model.Release (&(release.bundle.symbolic.name=com.foo.mytest.service)(&(release.schema.version>=1.0.0)(!(release.schema.version>=1.1.0)))(|(!(release.state=*))(release.state=0))) service required unavailable
 [90] com.liferay.portal.spring.extender.internal.context.ModuleApplicationContextRegistrator unregistered
    com.liferay.portal.kernel.model.Release (&(release.bundle.symbolic.name=com.foo.mytest.service)(&(release.schema.version>=1.0.0)(!(release.schema.version>=1.1.0)))(|(!(release.state=*))(release.state=0))) service required unavailable
    com.liferay.portal.kernel.configuration.Configuration (&(configuration.bundle.symbolic.name=com.foo.mytest.service)(name=service)) service required unavailable
g!


Caused by: org.postgresql.util.PSQLException: ERROR: relation "foo_foo" already exists
    atorg.postgresql.core.v3.QueryExecutorImpl.receiveErrorResponse(QueryExecutorImpl.java:2412)
    at org.postgresql.core.v3.QueryExecutorImpl.processResults(QueryExecutorImpl.java:2125)

We can use following Gogo shell commands to know more about above issues.


ds:unsatisfied
scr:info <service-if>
inspect cap service <bundle-id>

dm wtf
dm na
dependencymanager:dm


Background of Issue

Liferay 7.2 Service builder portlet will use Release_ table to manage versions and each and every service must register in the table for first deployment (Service Builder Bundles). This will help to run Upgrade Step process in future to update/add database related activities for non-developer mode environments. For migrated database tables already existed for each and every service builder so its assumed that bundle already deployed once and looking for Release_ table version  to proceed and register service.

We can categorize these things into two types of environments

Developer Environment

Example:

Local Development environment for developers schema changes will reflect automatically through schema.module.build.auto.upgrade is trueand it will be run based on build number in the service.properties file.


Developer Environment Solution

We can resolve above two issues for Developer Environment with following options.

Option: 1

For local developments is very simple, delete service builder generated tables and delete record from Release_ table (If already exist) then redeploy service bundle then problem will be resolved.

Option: 2

This option will get rid of the manual deletion. We can use Liferay provided Maven or Gradle plugin called DB Support Plugin. Follow the reference links to know more about DB Support Plugin.

For Maven

Add DB Support plugin in the pom file and run db-support:clean-service-builder maven goal so that it will clean


For Gradle


Note:

Option: 1 and Option: 2 recommended for developer environment and your data will be lost in both cases. If you wanted avoid data lost follow the Non-Developer Environment solution.

Non-Developer Environment

Example: Production or Real Lower Level Environments DEV/SIT/UAT
For non-developer mode schema.module.build.auto.upgradeshould be false and we have to write Upgrade Step Process component class to update database schema changes. We can also use DBA to execute schema changes related service builder.

Non-Developer Environment Solution

Step:1

Delete bundle from portal osgi\modules directory if already deployed.

Step:2

Add release record in Release_ table with default version 1.0.0 for your service.  ServeletContextNameshould your service bundle symbolic name.


Step:3

Update service bundle bnd.bnd Liferay-Require-SchemaVersionto default version that we already enter in the Release_ table record.


Step:4

Write dummy upgrade step in service. Follow the reference to create upgrade step with my notes.


You can skip “Writing upgrade steps and Waiting for upgrade completion” because we are trying to use the Dummy Upgrade Step that already as part of portal class loader.
Declaring dependencies need be corrected use com.liferay.portal.upgrade.apiinstead of com.liferay.portal.upgrade

Gradle:

Add following in the service build.gradle file


compile group: "com.liferay", name: "com.liferay.portal.upgrade.api", version: "2.0.0"

Maven:
Add following in the service pom.xml

<dependency>
            <groupId>com.liferay</groupId>
            <artifactId>com.liferay.portal.upgrade.api</artifactId>
            <version>2.0.0</version>
</dependency>

Upgrade Step Registration

package com.liferaysavvy.student.upgrade;

import com.liferay.portal.kernel.upgrade.DummyUpgradeStep;
import com.liferay.portal.upgrade.registry.UpgradeStepRegistrator;

import org.osgi.service.component.annotations.Component;

@Component(immediate = true, service = UpgradeStepRegistrator.class)
publicclass MyCustomModuleUpgrade implements UpgradeStepRegistrator {

    @Override
    publicvoid register(Registry registry) {
        registry.register( "1.0.0", "1.0.1",new DummyUpgradeStep());

    }

}


Step:5

Restart Portal

Step:6

Build and deploy your service bundle. You can manually copy service jar to your OSGI module directory or use CI/CD to build and deploy service bundle to respective environments.

Step:7

You can verify the changes using above mentioned Gogo shell commands. Service should not be in the unsatisfied list. You can also can notice your upgrade step process (upgrade:check).
If still see issue you can delete osgi cache and repeat same steps one more time.


We can notice new version is updated in Release_ table for deployed service and it will be created by Dummy Upgrade Step Process.

Note:
If you plan for production portal database upgrade. Identify all modules that you are migrating as Service builder bundles, write SQL script to add records in Release_ table with default version and keep this step as part of post upgrade process.


References:


Author

Access Felix Gogo Shell in Liferay 7.2/DXP Portal Environment

$
0
0

Apache Felix Gogo shell is command line interface (CLI) to interact with Liferay Module Framework or OSGi container.

It will provide set of predefined commands to access bundle or modules information like list bundles installed in OSGi container, Services Registry Information and Dependency Management related details.

We have many ways to access the Apache Felix Gogo shell
  • Command Prompt in Windows
  • Putty Terminal
  • Liferay Blade CLI
  • From Liferay Portal Control Panel

Command Prompt in Windows

Make sure portal server should be started before start using Apache Gogo shell.

Open command prompt in windows and use following telenet command.

telnet localhost 11311

Use simple command lb it will list the bundles installed in the OSGi container.


Gogo shell using 11311 is default port number configured by Liferay Portal and we can change the port number as well.

Use disconnect to end the session.


Note:

Should not use shutdown, close, and exit commands in the Gogo shell and it will lead to showdown OSGi framework.

If you see “Telnet is not recognized as an internal or external command” enable Telenet in windows. Follow below link


Putty Terminal

We can also use putty terminal to connect to Gogo shell. If you don’t have putty, download portable putty from following link for windows and extract in local machine.


Click on putty executable and it will launch putty new session window.


Provide following details and open session and it will launch Gogo shell terminal.

Host Name: localhost
Port: 11311
Connection Type: telenet





Use help command to know about available commands.


Note:

We can also connect to remote host and need to provide valid remote host name or ip address.

Liferay Blade CLI

If Liferay Blade CLI already install simple use following command.

blade sh <gogo-shell-command>

Example


blade sh lb
blade sh help



If BLADE not installed follow below link.


From Liferay Control Panel

We can use Liferay Portal Control Panel to access Gogo shell. Login as Portal Admin and portal configuration, we can find Gogo shell app

Login As Portal Admin à Control Panel àConfiguration àClick on Gogo Shell


Enter valid Gogo shell command as input and click on execute.


Author

Useful Apache Gogo Shell Commands in Liferay 7.2/DXP

$
0
0

Apache Gogo Shell is command line interface (CLI) to interact with OSGi module framework or OSGi container.

Apache Gogo shell is very useful in trouble shooting of module issues, getting module information and perform certain action like install, active and de-active OSGi bundles.

Liferay is already using Apache Gogo Shell and when we start Liferay 7.2/DXP portal, it will start automatically and we can use different ways to access Apache Gogo Shell in Liferay Portal Environment.


We can categorize Gogo shell commands in the following types.

Basic Commands
Declarative Services (DS) | Service Component Registry Commands (SCR) Commands
Dependency Management (DM) Commands

Basic Commands

Its regular usage commands to get bundles/module information like list bundles and its status.
Following are list of useful basic commands.


lb
lb | grep <BUNDLE_MATCH_PATTERN>
bundle <BUNDLE_ID>
headers <BUNDLE_ID>
install [URI_JAR_FILE_PATH]
start [BUNDLE_ID]
stop [BUNDLE_ID]
uninstall [BUNDLE_ID]
inspect requirement service [BUNDLE_ID]
inspect capability service [BUNDLE_ID]
diag [BUNDLE_ID]
upgrade:check
system:check
history
help

Example Usage


lb
lb | grep student
bundle 1076
headers 1076
install "file:C://Liferay/Liferay7.2/student-web/target/student-web-1.0.0.jar"
start 1076
stop 1076
uninstall 1076
inspect requirement service 1076
inspect capability service 1076
diag 1076
upgrade:check
system:check
history
help


Identify Bundle ID

Use lb command in the Gogo shell it will display the list of bundles installed in the OSGi modules framework. In the console view first column represent the BUNDLE ID.

Example


Declarative Services (DS) | Service Component Registry Commands (SCR)

Liferay module framework uses the OSGi Declarative Services/Service Component Registry to manage module components and its services references. Gogo shell leverage the Service Component Registry and Declarative Services. We can access services information using Gogo shell commands. 
In Liferay 7.2/DXP most of modules are using DS/SCR framework. Only service builder components are using the Apache Felix Dependency Management Framework to register and manage service components.

If you see any @Component or @Reference annotations in the java class, it implies that module components are using the Declarative Services/Service Component Registry Framework.

The following are some of useful Gogo Shell commands to insect components and its references.

services
services grep [SEARCH-PATTERN]
ds:unsatisfied
ds:unsatisfied [BUNDLE_ID]
scr:info [COMPONENT_ID]
scr:list
scr:list | grep [SEARCH-PATTERN]


Example Usage


services
services | grep student
ds:unsatisfied
ds:unsatisfied 1075
scr:info 4884
scr:list
scr:list | grep student


Identify COMPONENT ID

Use services/ ds:unsatisfied go shell commands and it will display component information and its ID.

Example 1


Example 2


Dependency Management (DM) Commands

Liferay Service Builder is using Apache Felix Dependency Management framework to manage components and its dependencies. Apache Gogo Shell leverage the Dependency Management framework and have set of predefined commands to provide more details of service components.
These commands are very useful when we trouble shoot about unsatisfied services in the registry.

The following are some of useful Gogo Shell commands related to Dependency Management

dm
dm | grep [SEARCH-PATTERN]
dm cp
dm nd
dm na
dm wtf


OR

dm
dm | grep [SEARCH-PATTERN]
dm compact
dm nodeps
dm notavail
dm wtf

Example Usage

dm
dm | grep student
dm cp
dm nd
dm na
dm wtf


Example usage screen



Reference


Author


Apache Gogo Shell Commands Description

$
0
0

lb
Display list of bundles installed in OSGi module framework

lb | grep <BUNDLE_MATCH_PATTERN>
List of bundles with filter using grep command and you can pass any string or valid regex pattern.

bundle <BUNDLE_ID>
Print specific bundle information. It required bundle Id as parameter

headers <BUNDLE_ID>
Print all OSGi headers which is used by specified bundle. These headers are in MANIFEST.MF file. It is required bundle Id as parameter.

install [URI_JAR_FILE_PATH]
Install bundle into OSGi container and we need to specify the valid URI path.

start [BUNDLE_ID]
Command will start bundle and it is required bundle Id.

stop [BUNDLE_ID]
Command will stop bundle and it is required bundle Id.

uninstall [BUNDLE_ID]
Uninstall bundle and it required bundle Id.

inspect requirement service [BUNDLE_ID]
List all services required by bundle. Require-Capabilityheader is in MANIFEST.MF file is relevant to this command.

inspect capability service [BUNDLE_ID]
List all services provided by bundle. Provide-Capability header is in MANIFEST.MF file is related to this command.

diag [BUNDLE_ID]
Command will print unsatisfied constraints to specific bundle and its required bundle Id.

upgrade:check
Command will display all Upgrade Step Process Steps registered in the registry.

system:check
Command will show all unsatisfied components list along with Gogo shell commands to troubleshoot in detail. It will run Declarative Service Soft Circular Dependency Checker, Declarative Service Unsatisfied Component Checker, Spring Extender Unavailable Component Checker

history
history will print all commands used in the current session. It is similar to Unix/Linux history command.

help
It will show all available commands and its description.

services
Command will print all registered service components available in the OSGi module framework.

services grep [SEARCH-PATTERN]
Command will print all registered service components available in the OSGi module framework with filter. It will narrow down the list.

ds:unsatisfied
Command will display all unsatisfied service component list in the OSGi module framework.

ds:unsatisfied [BUNDLE_ID]
Command will display unsatisfied service components to specified bundle. It’s required bundle Id

scr:info [COMPONENT_ID]
Command will print detailed information of given component. It required the component Id and we can get component Id when we use services/ ds:unsatisfied commands.

scr:list
It will display all components registered in service registry.

scr:list | grep [SEARCH-PATTERN]
It will display matching components registered in service registry.

dm
List all dependency manager components and these are mostly service builder service components from Liferay OSGi Module Framework.

dm OR grep [SEARCH-PATTERN]
List all matching dependency manager components and these are mostly service builder service components from Liferay OSGi Module Framework.

dm cp OR  dm compact
Display components in compact from.

dm nd OR dm nodeps
Command will display only components and it is hiding dependencies of the component.

dm na OR dm notavail
It will print only not available dependency components. It is very useful when we troubleshoot unsatisfied service builder components.

dm wtf
Detects where are the root failures for components. This is also most useful command to troubleshoot service builder components

Example Usage of Commands

lb

lb | grep student

bundle 1076

headers 1076

install "file:C://Liferay/Liferay7.2/student-web/target/student-web-1.0.0.jar"

start 1076

stop 1076

uninstall 1076

inspect requirement service 1076

inspect capability service 1076

diag 1076

upgrade:check
system:check
history
help

services

services | grep student

ds:unsatisfied

ds:unsatisfied 1075

scr:info 4884

scr:list

scr:list | grep student

dm

dm | grep student

dm cp

dm nd

dm na

dm wtf

Author

Adding Third Party Non OSGi Jars to Liferay OSGi module

$
0
0

Liferay is using OSGi module framework and in real world we may not get all java libraries implementations as OSGi module. Sometimes we may need to add non OSGi jars to Liferay OSGi module. Liferay Module Framework provided a way to add external non OSGi jars in Liferay OSGi module. OSGi bndtools will be taking care of internal configuration.
  1. The package that Liferay module is using was not available as OSGi module.
  2. The package that Liferay module is using was not exported by Liferay Portal Bootstrap Module.
  3. The package that Liferay module is using was not exported by Liferay Portal Global Class Loader.
  4. The package that Liferay module is using was not exported by any of your custom modules and that already deployed in Liferay Module Framework.

The package imported in Liferay module is satisfying the above criteria then we have to go for adding third party non OSGi jars to Liferay OSGi module.

Take the example that your module need to use apache poi libraries to provide xl sheet related functionality. These jars are non-OSGi and it’s not exported by any of Liferay OSGi framework.

Following are the steps to add Third Party non-OSGi jars

Gradle Liferay OSGi Module

Module Source


Case:1 Add Jar and Its all dependencies

Use “compileInclude” scope dependencies in “build.gradle”, rest ofthe things will be taken care by gradle build process.

Compile Include configuration is transitive. It will be embedded jar and its dependencies in module lib directory. It will refer all jar references in module MANIFEST.MF “Bundle-ClassPath” header and packages are specified in Private-Package header.

Compile Include will not consider the optional dependencies and if module required optional dependencies then follow the Case:2

Example “build.gradle”


dependencies {
            compileInclude  group: 'org.apache.poi', name: 'poi', version: '4.1.2'
            compileInclude  group: 'org.apache.poi', name: 'poi-ooxml', version: '4.1.2'
            }




Case:2 Explicitly specify JARs in  module bnd file

In this case we will use gradle compile scope and bndincluderesource” header to specify jar and its dependencies (if required).

Option: 1

This option will add specified third-party jars in specific directory in the module(in the jar package) and jar references are specified in MANIFEST.MF “Bundle-ClassPath” header.

Example “build.gradle”


dependencies {
           
            compile  group: 'org.apache.poi', name: 'poi', version: '4.1.2'
            compile  group: 'org.apache.poi', name: 'poi-ooxml', version: '4.1.2'
}


 Add Jars in “includeresource” header in bnd.bnd file


-includeresource: \
META-INF/lib/poi-4.1.2.jar=poi-4.1.2.jar;lib:=true,\
META-INF/lib/poi-ooxml-4.1.2.jar=poi-ooxml-4.1.2.jar;lib:=true


META-INF/lib/poi-4.1.2.jar :will specify that jar will be copied to module META-INF/lib in the jar file.

poi-4.1.2.jar : It is actual jar file required by module. Name and version should match the dependency specified in “build.gradle” file.

we can also specify jar version regex pattern as follows


-includeresource: \
META-INF/lib/poi-4.1.2.jar=poi-[0-9]*.jar;lib:=true,\
META-INF/lib/poi-ooxml-4.1.2.jar=poi-ooxml-[0-9]*.jar;lib:=true


lib:=true : Will specify that jar references will be added to MANIFEST.MF “Bundle-ClassPath” header.


Option: 2

This option will directly add all jars as distributed packages in module and packages are specified in “Private-Package” header.

Example “build.gradle”


dependencies {
           
            compile  group: 'org.apache.poi', name: 'poi', version: '4.1.2'
            compile  group: 'org.apache.poi', name: 'poi-ooxml', version: '4.1.2'
}


Add Jars in include resources header in bnd.bnd file as follows


-includeresource: \
@poi-4.1.2.jar,\
@poi-ooxml-4.1.2.jar



Maven Liferay OSGi Module

Module Source


If you are developing Liferay OSGi Modules with MAVEN build tool, use pom.xml and bnd file to specify third party jars.

  1. Specify JAR as Maven dependency with provided scope
  2. Specify JAR information in “includeresource” header in bnd file.

Specify JAR as Maven dependency with provided scope

Example in pom.xml


<dependency>
       <groupId>org.apache.poi</groupId>
       <artifactId>poi</artifactId>
       <version>4.1.2</version>
       <scope>provided</scope>
</dependency>
<dependency>
       <groupId>org.apache.poi</groupId>
       <artifactId>poi-ooxml</artifactId>
       <version>4.1.2</version>
       <scope>provided</scope>
</dependency>


Specify JAR information in “includeresource” header in bnd file.

Option: 1

Add Jars in include resources header in module bnd.bndfile


-includeresource: \
META-INF/lib/poi-4.1.2.jar=poi-4.1.2.jar;lib:=true,\
META-INF/lib/poi-ooxml-4.1.2.jar=poi-ooxml-4.1.2.jar;lib:=true


META-INF/lib/poi-4.1.2.jar :will specify that jar will be copied to module META-INF/lib in the jar file package.

poi-4.1.2.jar : It is actual jar file required by module and name and version should match the dependency in specified in build.gradle file.

we can also specify jar version regex pattern as follows


-includeresource: \
META-INF/lib/poi-4.1.2.jar=poi-[0-9]*.jar;lib:=true,\
META-INF/lib/poi-ooxml-4.1.2.jar=poi-ooxml-[0-9]*.jar;lib:=true


lib:=true : Will specify that jar references will be added to MANIFEST.MF “Bundle-ClassPath” header.

Option: 2

This option will directly add all jars as distributed packages in module and packages are specified in “Private-Package” header.

Add Jars in include resources header in bnd.bnd file


-includeresource: \
@poi-4.1.2.jar,\
@poi-ooxml-4.1.2.jar


Important Note

When we add non OSGi third party jars we can expect “Unresolved requirement: Import-Package” error for specific packages and module might not deployed. These packages may not be used directly in the current Liferay OSGi module but we can see these errors.

Example


org.osgi.framework.BundleException: Could not resolve module: com.liferaysavvy.employee.portlet [1080]
  Unresolved requirement: Import-Package: com.graphbuilder.curve


Solution:

We can ignore packages using Import-Packageheader or we can add specified missing package jar as third party non OSGi jar.

Ignore Packages as follows.

Example


Import-Package: \
!com.graphbuilder.*,\
!com.github.luben.zstd.*,\
!com.github.luben.zstd.*,\
!com.microsoft.schemas.*,\
!net.sf.saxon.*,\
!org.apache.batik.*,\
!org.apache.jcp.xml.dsig.internal.*,\
!org.bouncycastle.asn1.*,\
!org.bouncycastle.*,\
!org.bouncycastle.cms.*,\
!org.brotli.dec.*,\
!org.etsi.uri.*,\
!org.openxmlformats.schemas.*,\
!org.tukaani.xz.*,\
!com.zaxxer.sparsebits.*,\
!org.apache.commons.codec.*,\
!org.apache.commons.collections4.*,\
!org.apache.commons.compress.*,\
!org.apache.commons.math3.*,\
!org.apache.xmlbeans.*,\
!org.w3.x2000.*,\
\
*


Don’t forget to add \ * end of configuration otherwise all Liferay default packages will be ignored in the “Import-Package” header in the jar file. It will lead to so many unresolved requirement errors.

Once modules deployed in Liferay OSGi module framework then you can add widget to the page.


Once portlet added in the console you can see that apache poi related code being executed.


Note:

The objective of code example is to understand the adding third party jars to OSGi module and its not real example to explain about apache poi.
Author

Viewing all 99 articles
Browse latest View live