Saturday, February 23, 2013

Working with Spring Embedded Database

Sometimes it is very useful to work with an in memory databases when you want to demonstrate certain database centric features of an application during development phase. Spring supports HSQL, H2, and Derby as default embedded databases but, you can also use an extensible API to plug in new embedded database types and “DataSource” implementations.

In this tutorial we’ll see how to configure and use embedded database (HSQL) using spring. Spring supports XML as well as Programmatic configuration of beans. For, simplicity I’ll use XML based configuration in this article. Here are the items that we’ll cover in this article

1.    Configuring embedded database using spring.
2.    Define a simple domain object (User) and creating a simple DAO layer for accessing underling embedded database.
3.    Create two Spring MVC controllers & views to create users and display users.

I’ll suggest you to download the example code for this article from SVN before you start, this will help you to follow the article and refer the actual code. You can download working code of this article from my SVN repository at Google: http://suryakand.googlecode.com/svn/trunk/boilerplate

I’ll be using Maven for this project. Before you start, add following dependencies to your project’s pom.xml file       

 org.springframework
 spring-jdbc
 ${spring.version}



 org.hsqldb
 hsqldb
 2.2.9


Above dependencies are specifically needed for HSQL DB and spring’s JDBC template. You’ll also need to add other dependencies, for detailed configuration about dependencies please refer the actual pom.xml (it is self explanatory) of project (http://suryakand.googlecode.com/svn/trunk/boilerplate/pom.xml)

Once you are done with setting up pom.xml file, you’ll need to perform following steps to get up and running with an embedded database:

1.    Configure embedded database using Spring XML
Spring has provided “jdbc” namespace for easy and quick configuration of embedded JDBC Data Sources. Here is an example configuration that you’ll need to add in application context file:



 
 

•    “id”: this is the bean ID for our “dataSource” that we’ll be referring from other bean definition (DAO) to get hold of database.
•    “type”: this is the type of database that we want use. In this example we’ll be using HSQL DB.
•    “location”: this the location where spring will look for SQL script files to create schema and insert sample data (if you want to). In this case we have stored SQL script files “schema.sql” (to create database schema) and “test-data.sql” (to insert sample data) in maven’s main/resource directory.

See "applicationContext.xml" file for more details.

2.    Define a simple domain object & DAO
We’ll create a simple domain object (POJO) called as User.java and a DAO class UserDaoImpl.java that will facilitate representation of database rows as java objects and database access.

public class User {
 private int userId;
 private int groupId;
 private String username;
 private String password; 
 private String firstName;
 private String middleName;
 private String lastName;
 private int phoneNumber;
 private String verificationCode;
 private String resetPaswordCode;
 private String passwordQuestion;
 private String passwordAnswer;
 
 // Omitted getters and setter 
}

UserDao Interface
public interface UserDao {
 public List getAllUsers();
 public User getUserByUserName(String userName);
 public void createUser(User user);
}

UserDao Implementation
We’ll use the “dataSource” that we have defined in step 1 and spring’s “JdbcTemplate” for accessing database. For simplicity, I have used “JdbcTemplate” and have manually populated our domain object “User.java” but, you can use any ORM framework like Hibernate, MyBatis etc. to do this task in more elegant way.
public class UserDaoImpl implements UserDao {
 private DataSource dataSource;
 private JdbcTemplate jdbcTemplate;

 public void createUser(User user) {
  jdbcTemplate.update("insert into users (group_id,username,password,first_name," +
    "middle_name,last_name,phone_number) " +
    "values (?,?,?,?,?,?,?)", new Object[] {new Integer(1), user.getUsername(), user.getPassword(), 
    user.getFirstName(), user.getMiddleName(), user.getLastName(), 
    new Integer(user.getPhoneNumber())});
 }

 public List getAllUsers() {
  return jdbcTemplate.query("SELECT * from users", new UserMapper());
 }

 public User getUserByUserName(String userName) {
  User user = null;

  if(StringUtils.isNotBlank(userName)) {
   List users = jdbcTemplate.query("SELECT * from users where username = ?", new UserMapper(), new Object[] {userName});

   if(users != null && users.size() > 0) {
    user = users.get(0);
   }
  }

  return user;
 }

 private static final class UserMapper implements RowMapper {
  public User mapRow(ResultSet rs, int rowNum) throws SQLException {
   User user = new User();
   user.setUserId(rs.getInt("user_id"));
   user.setGroupId(rs.getInt("group_id"));
   user.setUsername(rs.getString("username"));
   user.setPassword(rs.getString("password"));
   user.setFirstName(rs.getString("first_name"));
   user.setMiddleName(rs.getString("middle_name"));
   user.setLastName(rs.getString("last_name"));
   user.setPhoneNumber(rs.getInt("phone_number"));
   user.setVerificationCode(rs.getString("verification_code"));
   user.setResetPaswordCode(rs.getString("reset_pasword_code"));
   user.setPasswordQuestion(rs.getString("password_question"));
   user.setPasswordAnswer(rs.getString("password_answer"));
   return user;
  }
 }

 public void setDataSource(DataSource dataSource) {
  this.dataSource = dataSource;
  this.jdbcTemplate = new JdbcTemplate(this.dataSource);
 }

 public DataSource getDataSource() {
  return dataSource;
 }
}


Once the domain object and DAO is implemented, we’ll define a DAO in our bean definition file and will inject the “dataSource” dependency that we have defined in step 1.  Here is the DAO bean definition:

 



3.    Define controllers and views for creating and displaying users

We’ll create two controllers “CreateUserController” and “UserListController” to create and display users respectively from a web page/browser.
@Controller
public class CreateUserController {
 private String viewName;
 private String createSucessView;
 private UserDao userDao;

 @RequestMapping(value = {"/user/create"} , method = RequestMethod.POST)
 public ModelAndView createUser(@ModelAttribute("userModel") User userModel) {
  userDao.createUser(userModel);
  ModelAndView mv = new ModelAndView(createSucessView);
  return mv;
 }

 @RequestMapping(value = {"/user/create"} , method = RequestMethod.GET)
 public ModelAndView createUserForm(User userModel) {
  ModelAndView mv = new ModelAndView(viewName);
  mv.addObject("userModel", new User());
  return mv;
 }

 @RequestMapping(value = {"/user/isavailbale"} , method = RequestMethod.POST)
 public @ResponseBody Boolean createUser(@RequestParam("username") String username){
  User user = userDao.getUserByUserName(username);
  if(user != null) {
   return Boolean.FALSE;
  }
  return Boolean.TRUE;
 }
}


"Create User" Form
<%@ taglib uri="http://www.springframework.org/tags/form" prefix="form"%>
<%@ taglib uri="http://java.sun.com/jsp/jstl/core" prefix="c" %>
<%@ taglib uri="http://java.sun.com/jsp/jstl/fmt" prefix="fmt"%>


Create New User

@Controller
public class UserListController {
 private String viewName;
 private UserDao userDao;

 @RequestMapping("/user/all")
 public ModelAndView showUserList() {
  List userList = userDao.getAllUsers();

  ModelAndView mv = new ModelAndView(viewName);
  mv.addObject("userList", userList);

  return mv;
 }
}

User List View
<%@ taglib uri='http://java.sun.com/jsp/jstl/core' prefix='c'%> 

User ID First Name User Name
${userRow.userId} ${userRow.firstName} ${userRow.username}


Fig. 1: Create User Form

Fig. 2: User List
I hope this article will help you to understand and quickly get started with spring embedded database feature. If you have any questions or suggestion, please feel free to post them.

Thank you very much for reading!

Sunday, February 10, 2013

Programming CSS Using LESS Preprocessor & Maven Integration


In this article I am going to introduce you to a couple of tools and development practices which are very cool from UI development perspective and I am sure you’ll be tempted to adopt it for your next project.

You can download full working example/source code for this article from my SVN repository at googlecodes http://suryakand.googlecode.com/svn/trunk/boilerplate/

Since last 7 years I am working on web application development using Java/J2EE and various other frameworks. I am not an UI developer and my work is mainly focused on server side development that includes designing application framework and coding them in java (web service, performance tuning, transaction management etc.) Writing code takes less time but, designing stable and maintainable applications is something that needs more time. One of the various must have qualities of a software is reusability. The general rule of software development is “develop reusable components/code”. It’s very easy to achieve reusability when we are writing code/functionality using Java/.NET (or any other language that supports Object Oriented Programming i.e. OOP) but, how to develop reusable and maintainable UI resources mainly CSS and JS? This is the topic that we are going to cover in this article. We’ll mainly focus on CSS in this article but, similar concept and tools are available for JS as well.

CSS, the style sheet language used to format markup on web pages. CSS itself is extremely simple, consisting of rule sets and declaration blocks, what to style, how to style it and it does pretty much everything you want, right? Well, not quite. As far as we all know CSS is static resource and have some limitations. These limitations, like the inability to set variables or to perform operations, this means that we inevitably end up repeating the same pieces of styling in different places. Not a good best practices to follow and difficult to maintain in log run.

There is a solution out there to overcome some of these limitations. The solution is “CSS preprocessor”. In simple terms, CSS preprocessing is a method of extending the feature set of CSS by first writing the style sheets in a new extended language, then compiling the code to classic CSS so that it can be read by web browsers. Several CSS preprocessors are available today, most notably Sass and LESS.

Ok, what’s the deal and how it is useful to me? This might be your first question but, believe me by end of this tutorial you’ll see the real benefit. Let’s start to make our hand dirty. For better understanding, we’ll try to integrate the LESS CSS preprocessor in a real application (developed using Spring MVC and Maven). Here is the focus of this article:

1)      How to write CSS in extended language that will be processed by LESS preprocessor.
2)      Integrate LESS CSS preprocessor in a Maven project.
3)      Use case & how LESS preprocessor is beneficial to us?

Maven is a build tool that is used by a lot of developers/organizations for building and continuous integration of projects. If you want to read more about maven, please visit http://maven.apache.org/. Also, you can read more about LESS CSS preprocessor at http://lesscss.org/.

1.      How to write CSS in extended language that will be processed by LESS preprocessor.

LESS extends CSS with dynamic behavior such as variables, mixins, operations and functions. We’ll see few example in this section that will give us better understanding of these features. It’s like programming CSS not just designing/writing CSS (CSS developers, more fun is coming in your way). First thing, you’ll learn is that the file extension of LESS compatible CSS file is (*.less, e.g. mysite.less). Let’s see how to define variables, functions and how to perform some operations:

a) Defining Variables: Here is an example that shows how to define variables in LESS. A variable name starts with “@” symbol.

/* ==== CSS LESS Variables ===*/
@default-font-family: Helvetica, Arial, sans-serif;
@default-radius: 8px;
@default-color: #5B83AD;



b) Defining Functions: Here is an example that shows an example function definition in LESS. A function definition starts with a “.” symbol. In below example “@top-left”, “@top-right” are function parameters.

/* Generic rounded corner function example */
.rounded-corners(@top-left: @default-radius, @top-right: @default-radius, @bottom-left: @default-radius, @bottom-right: @default-radius) {
 -moz-border-radius: @top-left @top-right @bottom-right @bottom-left;
 -webkit-border-radius: @top-left @top-right @bottom-right @bottom-left;
 border-radius: @top-left @top-right @bottom-right @bottom-left;
}


c) Performing Operations: LESS allows us to perform operations like addition, subtraction, multiplication etc. Here are few examples that show how we can use variables/values to calculate CSS style attributes:

@base-height: 20%;
@body-height: (@base-height * 2);

@default-color: #5B83AD;
@dark-color: default-color + 222;


d) Mixins: In LESS, it is possible to include properties from one CSS ruleset into another CSS ruleset, pretty much similar to extending a Java class from another Java class. So let’s say we have a class “.general-text-color” and we want everything from this class with an additional style attribute to define a CSS class for “h4” tag, this is how we can do it using LESS:

.general-text-color {
    color: @default-color;
}

h4 {
 .general-text-color; /* Mixin example: including other CSS class in current style. See general-text-color style */
 font-size: @heading;
}

Here is an example LESS CSS that I have developed for this example.site.less (Before Preprocessing)

/* ============ CSS LESS Variables and Functions (START) ===========*/
@default-font-family: Helvetica, Arial, sans-serif;
@default-radius: 8px;
@default-color: #5B83AD;
@icon-pencil: 0 -144px;
@heading: 16px;
@base-height: 20%;
@body-height: (@base-height * 2);
@logo-height: 30px;
@logo-width: 30px;

/*Generic rounded corner function example*/
.rounded-corners(@top-left: @default-radius, @top-right: @default-radius, @bottom-left: @default-radius, @bottom-right: @default-radius) {
 -moz-border-radius: @top-left @top-right @bottom-right @bottom-left;
 -webkit-border-radius: @top-left @top-right @bottom-right @bottom-left;
 border-radius: @top-left @top-right @bottom-right @bottom-left;
}

/* rounded corenrs function for well class*/
.well-rounded-corners (@radius: @default-radius) {
 .rounded-corners(@radius, @radius, 5px, 5px)
}
/* ================= END ===================*/


/* ================= Actual CSS Starts Here =============== */
body {
 font-family: @default-font-family;
    background-color: @default-color; /* background-color change example using css less. See variable default-color */
    padding-bottom: 40px;
    padding-top: 60px;
}

.icon-pencil {
 background-position: @icon-pencil; /* background-position change example. See variable icon-pencil */
}

.well {
 .well-rounded-corners; /* rounded corner change example using LESS function call. See function call well-rounded-corners */
}

.general-text-color {
    color: @default-color;
}

h4 {
 .general-text-color; /* Mixin example: including other CSS class in current style. See general-text-color style */
 font-size: @heading;
}

.body-height {
 height: @body-height; /*Operations example: body-height is calculated by multiplying base-heigh with 2 (base-heigh*2) */
}

.logo {
 height: @logo-height;
 width: @logo-width;
}


This is what we get (in site.css) once site.less is preprocessed by LESS.site.css (After Preprocessing)

body {
 font-family: Helvetica, Arial, sans-serif;
 background-color: #5b83ad;
 padding-bottom: 40px;
 padding-top: 60px;
}

.icon-pencil {
 background-position: 0 -144px;
}

.well {
 -moz-border-radius: 8px 8px 5px 5px;
 -webkit-border-radius: 8px 8px 5px 5px;
 border-radius: 8px 8px 5px 5px;
}

.general-text-color {
 color: #5b83ad;
}

h4 {
 color: #5b83ad;
 font-size: 16px;
}

.body-height {
 height: 40%;
}

.logo {
 height: 30px;
 width: 30px;
}


For full set of features and examples please visit http://lesscss.org/#docs.


2. Integrate LESS CSS preprocessor in a Maven project

Ok, now you have basic idea about what is LESS and how to write basic CSS using LESS and what happens before and after CSS preprocessing. In this section we’ll integrate LESS preprocessor with a Maven project so that the CSS that we have written (in extended language) for our project gets preprocessed during build process automatically to generate classic CSS understood by browsers.

We’ll use “lesscss-maven-plugin” maven plugin for preprocessing our CSS. Here is example configuration that you’ll need to add to your pom.xml file to enable LESS CSS preprocessing:


   
   
    org.lesscss
    lesscss-maven-plugin
    1.3.0
    
     ${project.basedir}/src/main/webapp/themes
     ${project.build.directory}/${project.build.finalName}/themes
     true
    
    
     
      
       compile
      
     
    
   
  

Few things to note:
i) “sourceDirectory” tag: this is directory path in our project where.less files (CSS files coded using LESS extended language) resides.
ii) “outputDirectory” tag: This is the destination director where we want our final complied CSS to be placed after build process is finished.
iii) “compress” tag: This tags tells LESS maven plugin whether to compress/minify the preprocessed CSS or not.

For more configuration options visit https://github.com/marceloverdijk/lesscss-maven-plugin (official site of LESS maven plugin).

Here is the maven project structure for the example that I have developed for this article. Download full source code from http://suryakand.googlecode.com/svn/trunk/boilerplate.


Once project is built, we’ll get preprocessed classic CSS in our target folder (as show in above project structure).

3) Use case & how LESS preprocessor is beneficial to us?

In above example I have used LESS with spring’s THEME feature. Basically, I have created single LESS CSS file for two themes “default” and “olive” and have defined variables that’ll be replaced by LESS preprocessor during build process to generate two different theme specific CSS files from a single (site.less) source file. So, one CSS (basically a LESS) file (written using LESS’s extended language) will give us 2 CSS files just by preprocessing/replacing variables during build process.

Here are screen shots of both themes:

Fig. 3: Default Spring Theme


Fig. 3: Olive Spring Theme
 Here are some situations that’ll tempt you to use LESS in your next project:

i) Think of situation where you have to add more themes in future to your project. In traditional way you’ll copy an existing CSS and will manually find all the places in CSS and will replace it with theme specific values but, with LESS you just need to change the variable values and preprocessor will do everything for us.

ii) Another use case is, let’s say a customer asked us to change color and fonts on all existing themes and if we have 20 themes (each CSS of 1000 lines) then manually finding and replacing is time consuming and error prone but, LESS will reduce the time and with no room for error.

There are several other ways in which we can integrate LESS with our projects. To read more about LESS and different ways to use, please visit: http://lesscss.org/#usage

Also, as I mentioned earlier in this article there are various preprocessor available but, mainly LESS and SASS are used. What’s the difference? Sass was designed to both simplify and extend CSS, so things like curly braces were removed from the syntax. LESS was designed to be as close to CSS as possible, so the syntax is identical to your current CSS code. This means you can use it right away with your existing code. Recently, Sass also introduced a CSS-like syntax called SCSS (Sassy CSS) to make migrating easier.

I hope this article will help you to understand basics of LESS and how you can integrate LESS preprocessor with Maven. If you have any question or suggestions please feel free to post them.

Thank you very much for reading. Happy Coding!

Resources


Saturday, February 2, 2013

OSGi and Modular Java Applications

What is Modular Application?
In simple words, an application that is divided into many independent/isolated functional or non-functional modules/components (user interface or business logic) is a modular application. Modules can be installed and uninstalled dynamically from application’s core framework. When a module is installed, the application serves features/functionalities available in that module. Similarly, when a module is uninstalled from application, certain features/functionalities from removed module will also be removed from application without affecting rest of the application and its functionality.

“Eclipse Editor” is a well-known Java editor and it is a very good example of modular application. Whenever we need a feature, we install appropriate plug-in (i.e. module) and that feature is available in our eclipse. We can also uninstall a plug-in if we don’t need specific feature, uninstalling a plug-in will only remove a specific feature from eclipse without affecting other plug-ins or editor.

Modular applications are more flexible and extendable as compared to traditional application and the concept of modularization can be applied to wide range of applications.

Benefits of Modular Application
You are probably already building a well-architected application using assemblies, interfaces, and classes, and employing good object-oriented design principles. Even so, unless great care is taken, your application design may still be "monolithic" (where all the functionality is implemented in a tightly coupled way within the application), which can make the application difficult to develop, test, extend, and maintain.

The modular application approach, on the other hand, can help you to identify the large scale functional areas of your application and allow you to develop and test that functionality independently. This can make development and testing easier, but it can also make your application more flexible and easier to extend in the future. The benefit of the modular approach is that it can make your overall application architecture more flexible and maintainable because it allows you to break your application into manageable pieces. Each piece encapsulates specific functionality, and each piece is integrated through clear but loosely coupled communication channels.

OSGi, JBoss Modules, JSF2 & CDI are some example technologies for developing modular Java applications. OSGi is the most popular technology with clear specification and we can use it as an underlying framework for developing “Modular Java Applications” (web as well as desktop). Eclipse, GlassFish, Apache Sling, DataNucleus, Adobe CQ, Atlassian Confluence and JIRA are some well-known examples that uses OSGi framework for modularization.

What is OSGi?
OSGi (Open Services Gateway initiative) is a specification. The core of the OSGi specification defines a component and service model for Java. The components and services can be dynamically activated, de-activated, updated and uninstalled.

A very practical advantage of OSGi is that every bundle must define its exported Java packages and its required dependencies. This way you can effectively control the provided API and the dependencies of your plug-ins/bundles.

The OSGi has a layered model that is depicted in the following figure.

Figure 1: OSGi Building Blocks

The following list contains a short definition of the terms:
• Bundles - Bundles are the OSGi components made by the developers. From technical point of view bundles are jar files which have a bit extended META-INF/MANIFEST.MF file and OSGI-INF.
• Services - The services layer connects bundles in a dynamic way by offering a publish-find-bind model for plain old Java objects.
• Life-Cycle - The API to install, start, stop, update, and uninstall bundles.
• Modules - The layer that defines how a bundle can import and export code.
• Security - The layer that handles the security aspects.
• Execution Environment - Defines what methods and classes are available in a specific platform.

OSGi has several implementations, for example Equinox (used by eclipse IDE), Knopflerfish OSGi or Apache Felix. Core concept of OSGi remains same across all implementation only certain services and features vary from one implementation to another.


We’ll take an example use case to see how OSGi can be used to develop a “Modular Java Application”. A modular application itself is composed of various loosely coupled bundles/plugin-ins, every bundle that has been developed using OSGi and is being used by application will show up in the “Bundles” section of Figure 1.

Benefits of OSGi
1. Reduced Complexity - Developing with OSGi technology means developing bundles: the OSGi components. Bundles are modules. They hide their internals from other bundles and communicate through well-defined services.
2. Reuse - The OSGi component model makes it very easy to use many third party components in an application.
3. Dynamic Updates - The OSGi component model is a dynamic model. Bundles can be installed, started, stopped, updated, and uninstalled without bringing down the whole system.
4. Adaptive - The OSGi component model is designed from the ground up to allow the mixing and matching of components. This requires that the dependencies of components need to be specified and it requires components to live in an environment where their optional dependencies are not always available. The OSGi service registry is a dynamic registry where bundles can register, get, and listen to services. This dynamic service model allows bundles to find out what capabilities are available on the system and adapt the functionality they can provide.
5. Transparency - Bundles and services are first class citizens in the OSGi environment. The management API provides access to the internal state of a bundle as well as how it is connected to other bundles.
6. Supported by Key Companies - OSGi counts some of the largest computing companies from a diverse set of industries as its members. Members are from: Oracle, IBM, Samsung, Nokia, Progress, Motorola, NTT, Siemens, Hitachi, Deutsche Telekom, Redhat, Ericsson, and many more.

Disadvantages of OSGi
1. Every dependency/jar/bundle that we want to use in OSGi container must include OSGi META information for exported services and packages. E.g. If we want to use write a plug-in for accessing SOAP web services using apache axis, then we have make sure that the axis.jar is OSGi enabled (contains OSGI-INF along with META-INF) else we cannot use it inside OSGi container.
2. Cannot use traditional/existing J2EE infrastructure & concepts. Everything in OSGi is a module/plug-in; even a web application (WAR) is deployed inside OSGi container (not on a web server) as a bundle and exposed to end users using OSGi HTTP Service Bridge.
3. OSGi is useful while building modular applications but, this is not for free. It is rather a heavy standard which may disallow you to do some things and force you to do the things in “The OSGi way”.

Use Case 
Let’s say, we are developing a banking software product and that product will be used by various countries around the globe. Since it is a banking application we have to consider some facts, e.g.:
1) Taxation rules that varies from country to country.
2) Bank policies with in a country may vary from bank to bank.
3) Customer from different countries may ask for different look and feel of application.
4) Some paid features that are only available in premium version of product.

If we develop this application using a traditional approach, we have to maintain a separate code base for individual customers/countries and lot of things gets replicated in various code bases. Or, a single code base with lots of “ifs” and “programmatic conditions” to enable/disable features based on customer, which not a good practice.

How can OSGi help us to develop this application? To develop an OSGi application we have to divide our application mainly in two parts:
1) Core Application Bundle This is the core part of application that manages loading/unloading of various plug-in(s), provides access to application’s infrastructure (e.g. database), glue various bundles together. This part of application does not contain any business logic, user interface or customer specific implementation.
2) Modules (plug-ins) Modules are smaller building blocks that can be dynamically added or removed from application as and when required. Each module is responsible for specific features/functionality. In our case we’ll have plug-ins/modules for country/customer specific requirements:
a) Taxation
b) Banking policies
c) User interface
d) Premium features

Below diagram shows a very high level structure of banking application running inside an OSGi container and bundles associated with banking application.


Figure 2: Banking Application inside OSGi Container

Bundles can come and go dynamically as and when required. E.g. If we want to remove a feature e.g. premium features from our banking application, we just need to uninstall the “premium feature” bundle from OSGi container and OSGi container will take care of removing all services, UI and logic related to premium functionality. Similarly, if want to upgrade a classic version of product to premium version, then we just need to add “premium feature” bundle in OSGi container. We don’t need to re-build the complete application; OSGi bundles can be installed and uninstalled dynamically.

Conclusion
OSGi is a great framework for developing modular applications and we have witnessed many successful products around us developed using OSGi. OSGi is in market from almost last 10+ years but, it was not popular among developers. Recently, OSGi has picked up momentum in developer and business stake holder’s community.

Initially, OSGi may look complex and expensive because of learning curve, inadequate availability of experienced OSGi developers and time required during design phase of application to break down everything into smaller functional units (plug-ins). But, in long term OSGi will pay off the initial investment. In today’s fast moving world with constantly changing business requirements everyone want to reduce the time to hit market and who’d like to change majority of application when application can adapt quickly by installing/uninstalling modules.

Any framework or technology cannot be set as a default development standard for all applications. Every application has different requirement therefore, we need to think and glue various technologies together to come up with an optimized solution. OSGi has lots of potential and great future so; it’s worth considering it for development.

Strapi CMS Plugin - Generate Content using Gen AI

An AI Strapi Plugin (@genai/gemini-content-generator) to generate content using Gen AI in Strapi Introduction The @genai/gemini-content-ge...