• Enter Slide 1 Title Here

    This is slide 1 description. Go to Edit HTML of your blogger blog. Find these sentences. You can replace these sentences with your own words.

  • Enter Slide 2 Title Here

    This is slide 2 description. Go to Edit HTML of your blogger blog. Find these sentences. You can replace these sentences with your own words.

  • Enter Slide 3 Title Here

    This is slide 3 description. Go to Edit HTML of your blogger blog. Find these sentences. You can replace these sentences with your own words.

Tuesday, September 19, 2017

Transfer domain to namecheap in 2 steps


Transferring domains from any registrar to namecheap is quite simple and straightforward and involves only 2 steps. I am writing this to express how happy I am, on my digizol.com domain transfer experience. Before looking at the steps, let's check motivational factors behind my decision on transferring the domain to namecheap.

Motivations for namecheap

I had few motivations compared to my previous domain registrar.
  1. Ease of use & great customer service rumor
    • Yes, this rumor proved true in my transfer experience
  2. Username is my email address
    • Seriously! my previous domain registrar used a 7 digit number to identify me & I could never remember it. I believe it to be a security feature, but I am not happy with that approach.
  3. Originally paid remaining period is carried forward
    • For my transfer, the expiry date was set including the remaining duration in previous registra. Read more details here
  4. Namecheap promotions for transfers
    • With that, the cost is $ 9.02 at the time I did the transfer
  5. Free Whois protection
    • This is free and saves some money but only for the first year, so I do not count this as a motivation. 

Steps in domain transfer

As mentioned above, this has only two steps.

Step 1 - Follow the straightforward UI

Search for the domain name, click transfer & follow the simple UI. I am not listing down the details as the steps are straightforward.

Step 2 - Chat with online support members

From the point you get stuck or looking for some help, simply use the support. The online chat support is extremely good, I would call it a rockstar. They will stay with you online and do all the needed configurations/changes and instructs on anything to be done on previous registrar's end. You chat will be completed only when everything is in place; at least that is how it ended for me 😄.

Disclaimer: I am not an employee of namecheap.com

Thursday, August 24, 2017

Without root/sudo permission install Node.js on Linux/CentOS

Node.js is a free and open source JavaScript runtime for server side programming. For *nix environments, users can do installations with RPMs or via package managers like yum. However, most often developers face restrictions during installation due to the need of root permission for directories like "/usr/local/bin". Here, we will be installing Node.js inside a directory under user_home.

1. Download binary distribution

Latest binaries can be downloaded from Node.js official release directory.

https://nodejs.org/download/release/
For CentOS 6.7, I downloaded Linux 64-bit binary of latest version (8.4.0) from below link.
https://nodejs.org/download/release/v8.4.0/node-v8.4.0-linux-x64.tar.gz
Make sure to pick suitable binary for your installation.

2. Extract into installation directory

This binary file must be extracted into the directory that you are installing Node.js. In my machine, I extracted it into below directory.
/home/user/software/nodejs_v8.4.0/

3. Add Node.js to PATH

It is required to append Node.js installation to PATH variable. For that, you can update either ~/.bash_profile or ~/.bashrc file as below.

export NODEJS_HOME=/home/user/software/nodejs_v8.4.0
export PATH=$PATH:$NODEJS_HOME/bin

4. Verify installation

Open up a console and check Node.js version to verify the installation as below.

bash$ node --version
v8.4.0
If you see the installed version as v8.4.0, that confirms the installation is completed. For this we did not use any additional *inx user privileges.

Related Articles

Tuesday, August 22, 2017

[Solved] Nginx - error: HTTP rewrite module requires the PCRE library

Nginx $ ./configure: error: the HTTP rewrite module requires the PCRE library. While trying to install Nginx server using the source distribution, "./configure" command failed on CentOS 6.7 with below error message. It complains that PCRE library is not available on the system.

./configure: error: the HTTP rewrite module requires the PCRE library.
You can either disable the module by using
--without-http_rewrite_module option, or
install the PCRE library into the system,
or build the PCRE library statically from
the source with nginx by using --with-pcre=<path> option.

Solution

You can install this library either via command line or GUI.

Resolve via Command line

yum install pcre-devel

Resolve via GUI

Go to "System" -> "Administration" -> "Add/Remove Software" as shown below.

Then search for "pcre-devel", select "Development files for pcre" and install by clicking "Apply" as shown below.
After that, you can rerun the "./configure" command to continue installing Nginx 1.12.1 server.
Hope this helps.

Related Articles

Tuesday, July 25, 2017

[Tutorial] Plotly graph drawing in Java webapp - Part 2

Plotly Javascript library supports generating various charts. Java Servlet & JSP based web applications can use it to display graphical representations of data.

In this tutorial, you will learn to include graphs into a simple Java web application. Image above shows the graph generated at the end of the tutorial. Complete project is already moved to github for your references.

This tutorial consists of two parts.

Part 1

First step is to create a simple web application with index.jsp that can submit a user entered parameter to a Servlet which is redirecting the user back to original index.jsp.

Part 2

Here the servlet is modified to return some data (collection of Customer objects) and index.jsp is modified to draw a chart using that data.

Note: If you are not that familiar with Java web applications, I recommend you to start with previous Part 1 of this tutorial before moving further.

Part 2

Java web application project structure in Part 1 must be modified as shown in below image.

Servlet Changes

Servlet class must return a list of Customers to the index.jsp. For that, a simple Customer class and a modification to Servlet is needed.

1. Create a Customer class

This class is used to represent the data send to index.jsp from CustomerServlet. It has an id as well as age & salesCount.

package com.digizol.webapp.plotly;

public class Customer {

private String id;
private int age;
private int salesCount;

public Customer(String id, int age, int salesCount) {
this.id = id;
this.age = age;
this.salesCount = salesCount;
}

public String getId() {
return id;
}
public int getAge() {
return age;
}
public int getSalesCount() {
return salesCount;
}
}

2. CustomerServlet returning Customer object list

doGet() method is modified to return a list of Customer objects. This class has 10 Customer objects. Size of returned list will be based on the 'size' request parameter submitted via index.jsp. This Servlet will return that list as "customersList" to index.jsp.

package com.digizol.webapp.plotly;

import javax.servlet.ServletException;
import javax.servlet.http.*;
import java.io.IOException;
import java.util.*;

public class CustomerServlet extends HttpServlet {

@Override
protected void doGet(HttpServletRequest request, HttpServletResponse response)
throws ServletException, IOException {

System.out.println("Parameter [size] value = " + request.getParameter("size"));
// return a customers list to index.jsp
request.setAttribute("customersList",
getCustomers(resultSize(request.getParameter("size"))));
request.getRequestDispatcher("/index.jsp").forward(request, response);
}

private List<Customer> customers = new ArrayList<Customer>();

public CustomerServlet() {
initCustomersList();
}

private int resultSize(String sizeParam) {
return sizeParam==null?customers.size():Integer.parseInt(sizeParam);
}

private List<Customer> getCustomers(int size) {
return customers.subList(0, size);
}

private void initCustomersList() {
customers.add(new Customer("cust-1", 25, 17));
customers.add(new Customer("cust-2", 36, 99));
customers.add(new Customer("cust-3", 17, 0));
customers.add(new Customer("cust-4", 58, 10));
customers.add(new Customer("cust-5", 49, 32));
customers.add(new Customer("cust-6", 80, 14));
customers.add(new Customer("cust-7", 31, 78));
customers.add(new Customer("cust-8", 22, 89));
customers.add(new Customer("cust-9", 43, 21));
customers.add(new Customer("cust-10", 74, 45));
}
}

3. Get plotly javascript

Download the plotly-latest.min.js Javascript file from here. Place this file under src/main/webapp/plotly/js directory as shown in image.

4. index.js Changes

index.js file needs below changes.

1. Add plotly javascript file to index.jsp
2. Javascript function to draw chart
3. Add a DIV for chart
4. Update index.jsp to organize data for Javascript
5. Update index.jsp to draw chart

Fully completed index.jsp page code looks as below, do not worry. Each change is explained in details after the code.

<%@ taglib prefix="c" uri="http://java.sun.com/jsp/jstl/core" %>

<html>

<head>
<title>Customer Information Center</title>
<script src="plotly/js/plotly-latest.min.js" type="text/javascript"></script>

<script type="text/javascript">
function plotChart(elementId, data, layout) {
Plotly.newPlot(document.getElementById(elementId),
data, layout, {displayModeBar: false});
}
</script>
</head>

<body>

<div style="background:#ffffee; text-align:center; padding-bottom:2px">
<h1>Customer Information Center</h1>

Draw customer information graph.<p/>

<form action="customers" method="get">

Results size:
<select name="size">
<option value="5">5</option>
<option value="10">10</option>
</select>
<p/>
<button style="padding:5px">Draw Chart</button>
</form>
</div>

<c:if test="${not empty customersList}">

<h2>Age and Sales Count Chart</h2>

<div id="customersChart" ></div>

<script>

var customerAges = {
name: 'Age',
type: 'lines+markers',
line: { width: 6},
marker: { size: 8}
};
var customerSalesCount = {
name: 'Sales Count',
type: 'lines+markers',
line: { width: 3},
marker: { size: 4}
};
var age_X = new Array();
var age_Y = new Array();
var sales_count_X = new Array();
var sales_count_Y = new Array();

<c:forEach items="${customersList}" var="customer" varStatus="i">
age_X[${i.index}] = "${customer.id}";
age_Y[${i.index}] = "${customer.age}";

sales_count_X[${i.index}] = "${customer.id}";
sales_count_Y[${i.index}] = "${customer.salesCount}";
</c:forEach>

customerAges.x = age_X;
customerAges.y = age_Y;

customerSalesCount.x = sales_count_X;
customerSalesCount.y = sales_count_Y;

var data = [customerAges, customerSalesCount];
var layout = {
xaxis: {
title: 'ID',
showgrid: true,
zeroline: true,
},
yaxis: {
showgrid: true,
showline: true,
zeroline: true,
}
};

plotChart("customersChart", data, layout);
</script>
</c:if>

</body>
</html>
Each change has a specific reason.

1. Add plotly javascript file to index.jsp

A reference to plotly Javascript file is placed within <head> tags of index.jsp as below.

<head>
<title>Customer Information Center</title>
<script src="plotly/js/plotly-latest.min.js" type="text/javascript"></script>
</head>
2. Javascript function to draw chart
Write a simple function named "plotChart" to draw graphs using plotly as follows inside <head> tag of index.jsp

<head>
<title>Customer Information Center</title>
<script src="plotly/js/plotly-latest.min.js" type="text/javascript"></script>

<script type="text/javascript">
function plotChart(elementId, data, layout) {
Plotly.newPlot(document.getElementById(elementId),
data, layout, {displayModeBar: false});
}
</script>
</head>
3. Add a DIV for chart

It is required to provide an empty DIV element for plotly to generate the chart.

<div id="customersChart" ></div>
4. Update index.jsp to organize data for Javascript
index.jsp page must iterate through the list of Customer objects returns from CustomerServlet as "customersList". Then, Javascript objects must be populated using that data in order to generate the graphs.

As Customer has two attributes age & salesCount, it is possible to draw two lines in one chart. As shown below, x & y properties of customerAges and customerSalesCount must be populated correctly.

var customerAges = {
name: 'Age',
type: 'lines+markers'
};
var customerSalesCount = {
name: 'Sales Count',
type: 'lines+markers',
};
var age_X = new Array();
var age_Y = new Array();
var sales_count_X = new Array();
var sales_count_Y = new Array();


age_X[${i.index}] = "${customer.id}";
age_Y[${i.index}] = "${customer.age}";

sales_count_X[${i.index}] = "${customer.id}";
sales_count_Y[${i.index}] = "${customer.salesCount}";


customerAges.x = age_X;
customerAges.y = age_Y;

customerSalesCount.x = sales_count_X;
customerSalesCount.y = sales_count_Y;
5. Update index.jsp to draw chart

Using customerAges & customerSalesCount Javascript objects, invoke plotChart() method to generate a chart inside "customersChart" div.

var data = [customerAges, customerSalesCount];
var layout = {
xaxis: {
title: 'ID'
},
yaxis: {
showgrid: true
}
};

plotChart("customersChart", data, layout);

Final Result

Below is the final outcome of the application after building & deploying. It shows two line graphs, for age and sales count.



Hope this helps.

Draw graphs in Java webapp with Plotly - Tutorial

Plotly Javascript library supports generating various charts. Java Servlet & JSP based web applications can use it to display graphical representations of data.

In this tutorial, you will learn to include graphs into a simple Java web application. Image above shows the graph generated at the end of the tutorial. Complete project is already moved to github for your references.

This tutorial consists of two parts.

Part 1

First step is to create a simple web application with index.jsp that can submit a user entered parameter to a Servlet which is redirecting the user back to original index.jsp.

Part 2

Here the above servlet is modified to return some data (collection of Customer objects) and index.jsp is modified to draw a chart using those data.

Note: If you are familiar with Java web applications, you can jump to Part 2 directly.

Part 1

1. Build a simple web application

This project contains only one JSP page and a Servlet. JSP is used to display a form & a chart while the Servlet is used to generate raw data for the chart.

First create the Java web application project structure as shown in image.

An index.jsp and a CustomerServlet with web.xml for a simple web application. It also has a pom.xml for the build.

CustomerServlet

doGet() method prints the size parameter in the request; then forwards the request to index.jsp page.

package com.digizol.webapp.plotly;

import javax.servlet.ServletException;
import javax.servlet.http.*;
import java.io.IOException;

public class CustomerServlet extends HttpServlet {

@Override
protected void doGet(HttpServletRequest request, HttpServletResponse response)
throws ServletException, IOException {

System.out.println("Parameter [size] value = " + request.getParameter("size"));
request.getRequestDispatcher("/index.jsp").forward(request, response);
}
}

web.xml

This is the file that configures Servlet related information. Here URL "/customers" is mapped to CustomerServlet.

<web-app xmlns="http://xmlns.jcp.org/xml/ns/javaee"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://xmlns.jcp.org/xml/ns/javaee
http://xmlns.jcp.org/xml/ns/javaee/web-app_3_1.xsd"
version="3.1">

<servlet>
<servlet-name>customers</servlet-name>
<servlet-class>com.digizol.webapp.plotly.CustomerServlet</servlet-class>
</servlet>

<servlet-mapping>
<servlet-name>customers</servlet-name>
<url-pattern>/customers</url-pattern>
</servlet-mapping>

</web-app>

index.jsp

This has the ability to submit the results size to "/customers" URL which actually is received by CustomerServlet.

<html>
<body>
<div>
<h1>Customer Information Center</h1>
Draw customer information graph.<p/>
<form action="customers" method="get">
Results size:
<select name="size">
<option value="5">5</option>
<option value="10">10</option>
</select>
<p/>
<button style="padding:5px">Draw Chart</button>
</form>
</div>
</body>
</html>
Clicking on "Draw Chart" button caused the doGet() method to be invoked on CustomerServlet.

pom.xml

Maven build file is used to generate the WAR file including the libraries.

<project xmlns="http://maven.apache.org/POM/4.0.0"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0
http://maven.apache.org/maven-v4_0_0.xsd">

<modelVersion>4.0.0</modelVersion>
<groupId>com.digizol.webapp.plotly</groupId>
<artifactId>webapp-with-plotly</artifactId>
<packaging>war</packaging>
<version>1.0-SNAPSHOT</version>
<name>webapp-with-plotly maven webapp</name>

<dependencies>
<dependency>
<groupId>javax.servlet</groupId>
<artifactId>javax.servlet-api</artifactId>
<version>3.1.0</version>
</dependency>
<dependency>
<groupId>javax.servlet</groupId>
<artifactId>jstl</artifactId>
<version>1.2</version>
</dependency>
</dependencies>

<build>
<finalName>customers-plotly</finalName>
</build>

</project>

2. Build & Deploy

With Maven 3.*, you can build the project using "mvn clean package" command. Deployable customers-plotly.war is generated inside target folder.

Copy customers-plotly.war into webapps directory of a Tomcat deployment and start Tomcat server.

Use below URL to see the web page & try clicking "Draw Chart" button.

http://localhost:8080/customers-plotly



Adding charts to this webpage is covered in Part 2.

Tuesday, November 19, 2013

[Eclipse] How to use local DTDs to validate XMLs

By default Eclipse does not support local DTD files. Because of this, many developers loose a privilege of Eclipse; content assistance for parameter/attribute is missing while working with DTD based XML files. However if you are connected to Internet, you will not face this issue.

Here is a tip to show you how to point your Eclipse instance to local DTD files.

1. Add XML Catalogs

First you need to open up the "XML Catalog" dialog by:
Windows -> Preferences -> XML -> XML Catalog
Then click on "Add..." and select "Catalog Entry". For a single local DTD file you need to add one Catalog Entry.

For the location: you need to find DTD file from your local disk.
For the Key: you need to enter the relevant key as per the <!DOCTYPE entry of your XML files.

2. Hibernate Examples Demo

This tip is demoed using Hibernate as an example. Hibernate Configuration DTD and Hibernate Mappings DTD is added locally into Eclipse below. First of all, you need to download and store hibernate jar file somewhere in your local disk; we used hibernate-core-3.6.10.Final version (available here as well as here).

2.1 Hibernate Configuration DTD

DTD file referred by hibernate.cfg.xml file is "hibernate-configuration-3.0.dtd". To point eclipse to that DTD, you need to enter below values and select OK in above "Catalog Entry" screen.


Key: -//Hibernate/Hibernate Configuration DTD 3.0//EN
Location: jar:file:/<path/to/jar>/hibernate-core.jar!/org/hibernate/hibernate-configuration-3.0.dtd

Then Eclipse will create a new Catalog and save with below details.

Entry element: Public
Location: org/hibernate/hibernate-configuration-3.0.dtd in jar file opt/libs/hibernate-core.jar
URI: jar:file:/opt/libs/hibernate-core.jar!/org/hibernate/hibernate-configuration-3.0.dtd
Key type: Public ID
Key: -//Hibernate/Hibernate Configuration DTD 3.0//EN

2.2 Hibernate Mappings DTD

DTD file referred by <entity>.hbm.xml file is "hibernate-mapping-3.0.dtd". Same as above step, in "Catalog Entry" screen you need to enter below values and select OK.

Eclipse will create a new Catalog and save with below details.

Entry element: Public
Location: org/hibernate/hibernate-mapping-3.0.dtd in jar file opt/libs/hibernate-core.jar
URI: jar:file:/opt/libs/hibernate-core.jar!/org/hibernate/hibernate-mapping-3.0.dtd
Key type: Public ID
Key: -//Hibernate/Hibernate Mapping DTD 3.0//EN

2.3 Results


After creating the Catalogs, you can check this my opening your hibernate.cfg.xml file and trying to open up the DTD file link in the top of the file by "Ctrl + Mouse Over". You will notice that Eclipse prompts two links and one is the local DTD.

Similarly, Eclipse will provide content assistance for XML file editing even when internet connectivity is gone.

3. Conclusion

Using this method, you can create catalogs for any DTD and let Eclipse point to your local DTD files. Hope this helps you.

Thursday, November 7, 2013

[Eclipse] Exporting & Importing Launch configurations

Many Eclipse "Launch Configuration" created has so much details; OSGi configurations for instance. So there arises a requirement of exporting the launch configurations and later importing them into other Eclipse workspaces. Interestingly, Eclipse has an import/export feature for "Launch Configuration"; which is quite simple but handy. I believe some software developers are not taking the advantage of this.

Here are the steps to follow.

1. Exporting Configurations

First you need to select:
  File -> Export...
Then select:
  Run/Debug -> Launch Configurations

Then you will see a view with all available launch configurations as shown below. You can select the configurations you need to export. You need a provide a location to store the exported configurations.

Each configuration will be saved into separate XML files, but with the extension as ".launch".

2. Importing Configurations

Similar to export, first you need to select:
  File -> Import...
Then select:
  Run/Debug -> Launch Configurations

Then you will see a view where you can select a directory with ".launch" files. When that folder is selected, available launch configurations will be displayed in the UI; so that you can select which ones to be imported as shown below.

3. Sample .launch file

Below is the exporter file for the OSGi launch configuration we created for Eclipse Kepler 4.3.1.
<?xml version="1.0" encoding="UTF-8" standalone="no"?>
<launchConfiguration type="org.eclipse.pde.ui.EquinoxLauncher">
<booleanAttribute key="append.args" value="true"/>
<booleanAttribute key="automaticAdd" value="true"/>
<booleanAttribute key="automaticValidate" value="false"/>
<stringAttribute key="bootstrap" value=""/>
<stringAttribute key="checked" value="[NONE]"/>
<booleanAttribute key="clearConfig" value="false"/>
<stringAttribute key="configLocation" value="${workspace_loc}/.metadata/.plugins/org.eclipse.pde.core/Multi-Management-App"/>
<booleanAttribute key="default" value="true"/>
<booleanAttribute key="default_auto_start" value="true"/>
<intAttribute key="default_start_level" value="4"/>
<booleanAttribute key="includeOptional" value="true"/>
<booleanAttribute key="org.eclipse.jdt.launching.ATTR_USE_START_ON_FIRST_THREAD" value="true"/>
<stringAttribute key="org.eclipse.jdt.launching.JRE_CONTAINER" value="org.eclipse.jdt.launching.JRE_CONTAINER/org.eclipse.jdt.internal.debug.ui.launcher.StandardVMType/JavaSE-1.6"/>
<stringAttribute key="org.eclipse.jdt.launching.PROGRAM_ARGUMENTS" value="-os ${target.os} -ws ${target.ws} -arch ${target.arch} -nl ${target.nl} -consoleLog -console"/>
<stringAttribute key="org.eclipse.jdt.launching.SOURCE_PATH_PROVIDER" value="org.eclipse.pde.ui.workbenchClasspathProvider"/>
<stringAttribute key="org.eclipse.jdt.launching.VM_ARGUMENTS" value="-Declipse.ignoreApp=true -Dosgi.noShutdown=true"/>
<stringAttribute key="pde.version" value="3.3"/>
<booleanAttribute key="show_selected_only" value="true"/>
<stringAttribute key="target_bundles" value="org.apache.felix.gogo.command@default:default,org.apache.felix.gogo.runtime@default:default,org.apache.felix.gogo.shell@default:default,org.eclipse.equinox.console@default:default,org.eclipse.osgi@-1:true"/>
<booleanAttribute key="tracing" value="false"/>
<booleanAttribute key="useCustomFeatures" value="false"/>
<booleanAttribute key="useDefaultConfigArea" value="true"/>
<stringAttribute key="workspace_bundles" value="com.digizol.osgi.multiservice.english@default:default,com.digizol.osgi.multiservice.sinhala@default:default,com.digizol.osgi.multiservice@default:default,com.digizol.osgi.baseservice@default:default"/>
</launchConfiguration>

Hope this helps you.

Wednesday, November 6, 2013

[Eclipse] org.osgi.framework.BundleException: Could not find bundle: org.eclipse.equinox.console

With latest Eclipse Kepler 4.3.1 SR1, I tried to run one of my older OSGi projects. Earlier this project was running smoothly with Eclipse Indigo (3.7.1).

However, when I tried to execute it via Eclipse Kepler version as a "OSGI Framework" configuration; I was surprised since it showed an exception as org.osgi.framework.BundleException: Could not find bundle: org.eclipse.equinox.console .

Below is the complete stack-trace.

!SESSION date time -----------------------------------------------
eclipse.buildId=unknown
java.version=1.6.0_26
java.vendor=Sun Microsystems Inc.
BootLoader constants: OS=linux, ARCH=x86, WS=gtk, NL=en_US
Command-line arguments: -dev file:$Location/dev.properties -os linux
-ws gtk -arch x86 -consoleLog -console

!ENTRY org.eclipse.osgi 4 0 date time
!MESSAGE Could not find bundle: org.eclipse.equinox.console
!STACK 0
org.osgi.framework.BundleException: Could not find bundle: org.eclipse.equinox.console
at org.eclipse.osgi.framework.internal.core.ConsoleManager.checkForConsoleBundle(ConsoleManager.java:211)
at org.eclipse.core.runtime.adaptor.EclipseStarter.startup(EclipseStarter.java:298)
at org.eclipse.core.runtime.adaptor.EclipseStarter.run(EclipseStarter.java:177)
at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:39)
at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:25)
at java.lang.reflect.Method.invoke(Method.java:597)
at org.eclipse.equinox.launcher.Main.invokeFramework(Main.java:636)
at org.eclipse.equinox.launcher.Main.basicRun(Main.java:591)
at org.eclipse.equinox.launcher.Main.run(Main.java:1450)
at org.eclipse.equinox.launcher.Main.main(Main.java:1426)

Solution

A quick look into the details revealed that the default shell of Eclipse has been moved to "Apache Felix Gogo"; so the necessary bundles must be added to the "Run Configuration" before running. Followings are the four bundled that you need to select from the list.

org.apache.felix.gogo.command_0.10.0v<version>.jar
org.apache.felix.gogo.runtime_0.10.0v<version>.jar
org.apache.felix.gogo.shell_0.10.0v<version>.jar
org.eclipse.equinox.console_1.0.100<version>.jar

After adding these as shown in the above diagram, the program runs smoothly.

For more details on the changes on OSGi shell, please refer here.

Monday, November 4, 2013

OSGi Console of Eclipse Kepler 4.3.1

Eclipse IDE is developed based on OSGi plugin architecture, but I had not seen the list of OSGi bundles that are used in my Eclipse installation. Today I noticed that there is a way to find the list of bundled used, and it is quite simple. So I thought of sharing it with you.

I am running Eclipse version 4.3.1 (JEE Kepler). First we need to open the OSGi console of the running Eclipse instance. For that we need to open up the 'Console view' first via:

Window -> Show view -> Console

Then you need to select "Host OSGi Console" on the sub-toolbar in this Console view as shown in the image below.
As soon as you go to this console view, you will see below WARNING, which is quite OK since our intention is also to connect to the running instance of Eclipse.
WARNING: This console is connected to the current running instance of Eclipse!
osgi>

If you are already familiar with OSGi console in OSGi software development, then most likely you know how to find details about the plugins. However even if you are new to OSGi, no need to worry. You simple have to enter "ss" command in this console to see the list of bundles with id and state. I got a list of 822 plugins and below is a trimmed down version of the output I received.

WARNING: This console is connected to the current running instance of Eclipse!
osgi> ss
"Framework is launched."


id State Bundle
0 ACTIVE org.eclipse.osgi_3.9.1.v20130814-1242
1 ACTIVE org.eclipse.equinox.simpleconfigurator_1.0.400.v20130327-2119
2 RESOLVED ch.qos.logback.classic_1.0.7.v20121108-1250
Fragments=525
3 RESOLVED ch.qos.logback.core_1.0.7.v20121108-1250
4 RESOLVED ch.qos.logback.slf4j_1.0.7.v20121108-1250
Master=817
5 ACTIVE com.ibm.icu_50.1.1.v201304230130
6 RESOLVED com.jcraft.jsch_0.1.46.v201205102330
7 RESOLVED com.ning.async-http-client_1.6.5.20130531-2315
8 RESOLVED com.sun.el_2.2.0.v201303151357
9 RESOLVED com.sun.syndication_0.9.0.v200803061811
10 RESOLVED java_cup.runtime_0.10.0.v201005080400
11 RESOLVED javaewah_0.5.6.v201307211000
12 RESOLVED javax.activation_1.1.0.v201211130549
13 RESOLVED javax.annotation_1.1.0.v201209060031
14 RESOLVED javax.el_2.2.0.v201303151357
15 RESOLVED javax.inject_1.0.0.v20091030
16 RESOLVED javax.jws_2.0.0.v201005080400
17 RESOLVED javax.mail_1.4.0.v201005080615
18 RESOLVED javax.persistence_2.1.0.v201304241213
19 RESOLVED javax.servlet_3.0.0.v201112011016
20 RESOLVED javax.servlet.jsp_2.2.0.v201112011158
21 RESOLVED javax.wsdl_1.6.2.v201012040545
22 RESOLVED javax.wsdl_1.5.1.v201012040544
23 RESOLVED javax.xml_1.3.4.v201005080400
24 RESOLVED javax.xml.bind_2.1.9.v201005080401
25 RESOLVED javax.xml.rpc_1.1.0.v201209140446
26 RESOLVED javax.xml.soap_1.2.0.v201005080501
27 RESOLVED javax.xml.stream_1.0.1.v201004272200
28 RESOLVED javax.xml.ws_2.1.0.v200902101523
29 RESOLVED net.sourceforge.lpg.lpgjavaruntime_1.1.0.v201004271650
30 RESOLVED org.apache.ant_1.8.4.v201303080030
31 RESOLVED org.apache.axis_1.4.0.v201005080400
32 RESOLVED org.apache.batik.css_1.6.0.v201011041432
33 RESOLVED org.apache.batik.util_1.6.0.v201011041432
34 RESOLVED org.apache.batik.util.gui_1.6.0.v201011041432
35 RESOLVED org.apache.bcel_5.2.0.v201005080400
36 RESOLVED org.apache.commons.codec_1.4.0.v201209201156
37 RESOLVED org.apache.commons.collections_3.2.0.v2013030210310
38 RESOLVED org.apache.commons.discovery_0.2.0.v201004190315
39 RESOLVED org.apache.commons.httpclient_3.1.0.v201012070820
40 RESOLVED org.apache.commons.io_2.0.1.v201105210651
41 RESOLVED org.apache.commons.lang_2.6.0.v201205030909
42 RESOLVED org.apache.commons.logging_1.1.1.v201101211721
43 RESOLVED org.apache.commons.logging_1.0.4.v201101211617
44 RESOLVED org.apache.commons.net_3.2.0.v201305141515
45 ACTIVE org.apache.felix.gogo.command_0.10.0.v201209301215
46 ACTIVE org.apache.felix.gogo.runtime_0.10.0.v201209301036
47 ACTIVE org.apache.felix.gogo.shell_0.10.0.v201212101605
48 RESOLVED org.apache.httpcomponents.httpclient_4.1.3.v201209201135
49 RESOLVED org.apache.httpcomponents.httpcore_4.1.4.v201203221030
50 RESOLVED org.apache.jasper.glassfish_2.2.2.v201205150955
51 RESOLVED org.apache.log4j_1.2.15.v201012070815
52 RESOLVED org.apache.lucene.analysis_3.5.0.v20120725-1805
53 RESOLVED org.apache.lucene.core_3.5.0.v20120725-1805
54 RESOLVED org.apache.velocity_1.5.0.v200905192330
55 RESOLVED org.apache.ws.commons.util_1.0.1.v20100518-1140
56 RESOLVED org.apache.wsil4j_1.0.0.v200901211807
57 RESOLVED org.apache.xalan_2.7.1.v201005080400
58 RESOLVED org.apache.xerces_2.9.0.v201101211617
59 RESOLVED org.apache.xml.resolver_1.2.0.v201005080400
60 RESOLVED org.apache.xml.serializer_2.7.1.v201005080400
61 RESOLVED org.apache.xmlrpc_3.0.0.v20100427-1100
62 STARTING org.eclipse.ant.core_3.2.500.v20130402-1746
63 STARTING org.eclipse.ant.launching_1.0.300.v20130514-1341
64 STARTING org.eclipse.ant.ui_3.5.400.v20130514-1341
65 STARTING org.eclipse.compare_3.5.401.v20130709-1308
66 STARTING org.eclipse.compare.core_3.5.300.v20130514-1224
67 RESOLVED org.eclipse.core.commands_3.6.100.v20130515-1857

...

818 RESOLVED org.sonatype.m2e.mavenarchiver_0.15.0.201207090125-signed-20130612210623
819 RESOLVED org.uddi4j_2.0.5.v200805270300
820 RESOLVED org.w3c.css.sac_1.3.1.v200903091627
821 RESOLVED org.w3c.dom.smil_1.0.0.v200806040011
822 RESOLVED org.w3c.dom.svg_1.1.0.v201011041433
osgi>
If you are interested in finding further details about these OSGi bundles, you can enter 'help' in the OSGi console and find the list of commands to try out.

[Ubuntu] Multiple launchers for each individual Eclipse installation

I have multiple Eclipse versions installed in my Ubuntu 12.04, so I wanted to have separate launcher icons in Launchpad. However I noticed it is not possible to create launch icons simply using:
"Right click -> Lock to Launcher" approach since the same launcher icon is used for all Eclipse installations; simply said there will be only one launcher icon for all Eclipse installations. 


It is quite easy to create multiple launcher icons for multiple installations. Below is the 4 steps you need to follow.

1. Create <eclipse-name>.desktop files for each installation

I created eclipse-jee-kepler.desktop file inside Kepler Eclipse installation folders, but you use any preferred location.

2. Update <eclipse-name>.desktop file with information

For "Eclipse JEE Kepler" installation, add the below content to eclipse-jee-kepler.desktop. You will have to change the path to the executable eclipse file.
[Desktop Entry]
Version=4.3.1
Name=Eclipse JEE Kepler
Comment=Eclipse JEE Kepler
Exec=/<path>/eclipse-jee-kepler-SR1-linux-gtk/eclipse
Icon=/<path>/eclipse-jee-kepler-SR1-linux-gtk/eclipse.ico
StartupNotify=false
Terminal=false
Type=Application
Categories=Development

You can create an eclipse.ico file to be displayed in the Launchpad yourself. As displayed here, I have created a simple file for my usage.

3. Grant permission to execute

Right click on this eclipse-jee-kepler.desktop file and select "Properties". Then go to the "Permissions" tab and select execute permission as shown in the image.

4. Run the eclipse installation

You can double click on the eclipse-jee-kepler.desktop file to start your eclipse installation. When this eclipse installation is started, the provided eclipse.ico will be displayed in the Launchpad. Now you can create a launch icon simply using "Right click -> Lock to Launcher".

Finally...

For each of your eclipse installations, you can create separate files with above 4 steps; then replace the property values to match with each eclipse installations (including a separate .ico).

If you are interested in finding more information about Unity Launchers and Desktop files, you can refer here.

Saturday, November 2, 2013

[Java] String format against opening & closing characters

How to validate the format of a given string according to a given set of opening-closing character pairs? This has been raised as an interview question, so I thought of writing a simple program to solve this.

Let me elaborate the question. There are characters that are considered as opening characters and closing characters; when '(' is an opening character, the relevant closing character is ')' For example; ([]) is correctly formatted, but ([) is not. So your task is to find out whether all the starting characters are properly ended with a ending character.

Here, I am using a Stack (java.util.Stack) to solve the problem.

GroupingPair class

A simple class named GroupingPair is written to hold pair of opening and closing characters. For instance, '[' for starting and ']' for ending.
package com.digizol.interviews.string.format;

public class GroupingPair {

private Character start;
private Character end;

public GroupingPair(Character start, Character end) {
this.start = start;
this.end = end;
}

public Character getStart() {
return start;
}

public Character getEnd() {
return end;
}
}

FormatValidator class

This class has implemented the logic using a stack. This can be initialized with a list of GroupingPair objects. Then a given strings each character is compared against the GroupingPair objects to find out whether there is an opening or closing characters. If an opening character is found, related GroupingPair instance is pushed to the stack. Similarly, if a closing tag is found, the top GroupingPair is popped and compared with the character to see whether it matches with the expected.
package com.digizol.interviews.string.format;

import java.util.HashMap;
import java.util.Map;
import java.util.Stack;

public class FormatValidator {

private Map<Character, GroupingPair> openingChars;
private Map<Character, GroupingPair> closingChars;

public FormatValidator(GroupingPair[] pairs) {
initOpeningCharacters(pairs);
initClosingCharacters(pairs);
}

private void initClosingCharacters(GroupingPair[] pairs) {
closingChars = new HashMap<Character, GroupingPair>();
for (GroupingPair pair: pairs) {
closingChars.put(pair.getEnd(), pair);
}
}

private void initOpeningCharacters(GroupingPair[] pairs) {
openingChars = new HashMap<Character, GroupingPair>();
for (GroupingPair pair: pairs) {
openingChars.put(pair.getStart(), pair);
}
}

public boolean validate(String string) {
return validate(string, false);
}

public boolean validate(String string, boolean validateOtherCharacters) {

Stack<GroupingPair> stack = new Stack<GroupingPair>();

char[] characterArray = string.toCharArray();

for (Character c: characterArray) {

if (openingChars.containsKey(c)) {
stack.push(openingChars.get(c));
} else if (closingChars.containsKey(c)) {
if (!c.equals(stack.pop().getEnd())) {
return false;
}
} else if (validateOtherCharacters) {
System.out.println("Unexpected character '" + c + "' found in string: " + string);
return false;
}
}
return stack.isEmpty();
}
}

Test class

This is a simple class with the main method to test few examples. Character pairs (), '<'>' and [] are given for initialization.
package com.digizol.interviews.string.format;

public class Test {

public static void main(String[] args) {

FormatValidator validator = new FormatValidator(createPairs());

String[] toTest = { "[(])",
"([<>])",
"([)",
"()[]<>",
"(()[]<>)",
"(mal [ formatted )",
"(this [ is < well > formatted ] text)"
};

for (String string : toTest) {

boolean valid = validator.validate(string, false);

if (valid) {
System.out.println(string + " \t-> well formatted");
} else {
System.out.println(string + " \t-> malformed");
}
}
}

private static GroupingPair[] createPairs() {
GroupingPair[] pairs = new GroupingPair[] {
new GroupingPair('(', ')'),
new GroupingPair('<', '>'),
new GroupingPair('[', ']')
};
return pairs;
}
}

Following is the output you will get when this Test class is executed.
[(]) -> malformed
([<>]) -> well formatted
([) -> malformed
()[]<> -> well formatted
(()[]<>) -> well formatted
(mal [ formatted ) -> malformed
(this [ is < well > formatted ] text) -> well formatted

As you can see, the program has identified whether a string is well formatted or not. This eclipse project is available for download.