Linux tweaks

1) Grub bootloader
To modify the grub bootloader to self preference, either we can use third party application or edit the grub config file. I prefer later.

$sudo gedit /boot/grub/grub.cfg


Open the grub config file in text editor.
Where we can make couple of changes like :

set default="2"
set gfxmode=1024x768
set timeout=20


“set default” – Menu highlighted by default. It’s value can’t be greater than number of available bootloader menu. Default value is 0.
“set gfxmode” – Loads boot loader menu in given resolution spec. Setting value higher than maximum supported resolution will lead to boot loader being loaded in default resolution.
“set timeout” – Maximum seconds the boot loader should wait before loading default choice.

Also, we can edit bootloader menu text, so that it’s simple & clear. Look for the syntax “menuentry” in file and make changes of content inside starting & ending within quote (‘)

menuentry 'Linux Mint 12' --class linuxmint --class gnu-linux --class gnu --class os {..}

2) Auto Mount
We can make hard drive partitions to auto mount on the start of session. First step is to create directory, which will act as mount point.

$sudo mkdir mydrive


It’ll create a directory named mydrive, which will act as mount point.

$sudo gedit /etc/fstab


Open’s fstab in text editor and add line similar to below.

/dev/sda6 /media/mydrive ntfs 0 0


The first parameter(‘/dev/sda6’) is drive’s name (which can be viewed by mount command), the second parameter(‘/media/mydrive’) is mount point and third is drive format.

3) Desktop Application Launcher
Application launcher is the script that creates a application launcher file in desktop.
Create a file named ‘myapp_launcher’ then copy & paste below code in file.

gnome-desktop-item-edit ~/Desktop/ --create-new


Copy the ‘myapp_launcher’ file to directory ‘nautilus-scripts’

$sudo mv launcher ~/.gnome2/nautilus-scripts/


4) Icon View
By default the desktop icons are big consuming huge desktop space. Having smaller icons are sometime more efficent to manage and good looking. To reduce the icon size, Open home folder, goto Edit > Preferences , under Views tab ‘Icon View Defaults’ set the zoom level to 66%.
Now you’ll have smaller icons in desktop, windows.

NO : float and double for monetary purpose


If you have used float or double for monetary calculation in Java, you must have noticed and said why is the calculation wrong. We’ll get ‘100.00999999999999’, if we subtract 0.01 from 100.02 (double type). This result is unacceptable in monetary calculation. So the question arises, why?


Well, this article can shed some lights on our why! Working with Money in Java


Let’s have a look at code that will calculate output for adding and subtracting using double.

public class DoubleIsBadForAmount {
	double amount = 100.00;
	double modifier = 0.01;

	public void doubleAdd() {
		for (int i = 0; i < 5; i++) {
			amount = amount - modifier;
			System.out.println(amount);
		}
	}

	public void doubleSubtract() {
		amount = 100.00;
		for (int i = 0; i < 5; i++) {
			amount = amount + modifier;
			System.out.println(amount);
		}
	}

	public static void main(String[] args) {
		DoubleIsBadForAmount main = new DoubleIsBadForAmount();
		main.doubleAdd();
		main.doubleSubtract();
	}
}

The output of above code :

99.99
99.97999999999999
99.96999999999998
99.95999999999998
99.94999999999997

100.01
100.02000000000001
100.03000000000002
100.04000000000002
100.05000000000003


We can see, that precision is lost, as the output is not as expected. Having ‘99.97999999999999’ as amount is not what we want. So, the solution is to use BigDecimal, to represent monetary values. The BigDecimal is slower in calculation than primitive double type, which’ll be case, if application involves heavy calculations.

public class BigDecimalForAmount {
	double amount = 100.00;
	double modifier = 0.01;

	public void doubleAdd() {
		BigDecimal sum = new BigDecimal(amount);
		BigDecimal mod = new BigDecimal(modifier);
		for (int i = 0; i < 5; i++) {
			sum = sum.add(mod);
			System.out.println(BigDecimalForAmount.roundHalfEven(sum.doubleValue()));
		}
	}

	public void doubleSubtract() {
		amount = 100.00;
		BigDecimal sum = new BigDecimal(amount);
		BigDecimal mod = new BigDecimal(modifier);
		for (int i = 0; i < 5; i++) {
			sum = sum.subtract(mod);
			System.out.println(BigDecimalForAmount.roundHalfEven(sum.doubleValue()));
		}
	}
	
	private static double roundHalfEven(double amount) {
		BigDecimal amt = new BigDecimal(amount);
		amt = amt.divide(new BigDecimal(1), 2, BigDecimal.ROUND_HALF_EVEN);
		return amt.doubleValue();
	}

	public static void main(String[] args) {
		BigDecimalForAmount main = new BigDecimalForAmount();
		main.doubleAdd();
		main.doubleSubtract();
	}
}


In above code we used BigDecimal with rounding to get precise result and the output is as expected.


Output :

100.01
100.02
100.03
100.04
100.05

99.99
99.98
99.97
99.96
99.95


Conclusion : using float or double for monetary calculation is a big NO, while BigDecimal is mostly recommended.

Java Programming Conventions (Part II)


We continue from where we left on part I. On this, we will cover more of fundamental standards that every Java programmers should adhere to. Remember, these standards or guidelines are here to improve code readability, maintainability and general quality. Programmers can differ and follow their own guideline if it improves general quality of code.

1. Singleton class instance

Singleton classes should return their sole instance through method getInstance.
private final static UnitManager instance_ = new UnitManager();
 public static UnitManager getInstance() { 
        return instance_;
 }
Don’t : get() or instance() or unitManager()
The above layout is the preferred pattern, though not followed consistently by all.

2. Import statement

Import statements must be sorted such that fundamental packages are first, and packages are grouped together with associated packages and a line must separate different groups.
import java.util.List;
import java.util.ArrayList;

import javax.swing.JPanel;
import javax.swing.event.ActionEvent;
The sorting and grouping makes it simple to browse import statements, manage more easily and collapse related dependencies in common units.

3. Explicit import classes list

Import classes should always be explicitly listed
Do :

import java.util.List;
import java.util.ArrayList;
import java.util.HashSet
Don’t :

import java.util.*;
Explicit import classes list helps to maintain and understand the class and it’s documentation.

4. No to implicit type conversion

Always perform explicit type conversion and avoid implicit type conversion.
Do : floatValue = (int) intvalue;
Don’t : floatValue = intValue;
Performing explicit type conversion helps to understand what that piece of code exactly does, while the later is vauge.

5. Class variables should be private

Class variables should always be private.
Do : private String myVariable;
Don’t : public String myVariable;
Use of public access for class variable voilates the concept of Java information hiding and encapsulation. Instead use public function to access these class variables.

6. Negated boolean variable name

Use of negated boolean varialbe must be avoided.
Do : boolean isEnabled;
Don’t : boolean isNotEnabled
Using negated boolean variable name decrease the readability of code. Apparently, it’s not always immediatly clear what does “!isNotEnabled” means!

7. Executable statements

Avoid using excecutable statements in conditonals cases.
Do : InputStream stream = File.open(fileName, “w”);
if (stream != null) {

}
Don’t : if (File.open(fileName, “w”) != null)) {

}

This article is primarily composed from this source.

Installing Maven 3

Installing maven 3 on linux platform involves few simple steps.


1. Download maven 3
You can download latest version from here or like

$sudo wget http://www.eng.lsu.edu/mirrors/apache/maven/binaries/apache-maven-3.0.4-bin.tar.gz

Unpack the maven :

$sudo tar -xvfz apache-maven-3.0.4-bin.tar.gz

Copy extracted maven to your desired location :

$sudo cp -R apache-maven-3.0.4/ /usr/sw/


2. Adding PATH variables
Open the user profile in text editor

$sudo gedit /etc/profile

Add following lines in the file content

export M3=/usr/sw/apache-maven-3.0.4/bin
export M3_HOME=/usr/sw/apache-maven-3.0.4
export MAVEN_HOME=/usr/sw/apache-maven-3.0.4

And edit the variable PATH to this

export PATH=”/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/sbin:/bin:/usr/games:/usr/sw/apache-maven-3.0.4/bin”

Or you can add those path variables in “/etc/environment”


3. Testing maven
Logout from current user’s session and log back in. In terminal, execute command to check maven version

$mvn -version

The output message should look like this

Apache Maven 3.0.4 (r1232337; 2012-01-17 14:29:56+0545)
Maven home: /usr/sw/apache-maven-3.0.4
Java version: 1.6.0_23, vendor: Sun Microsystems Inc.
Java home: /usr/sw/jdk1.6.0_23/jre
Default locale: en_US, platform encoding: UTF-8
OS name: "linux", version: "3.2.0-23-generic", arch: "i386", family: "unix"

Creating Custom annotations

This article is about to create using own custom annotations on java. This example illustrate how to create  custom annotation to support validation on java object.

1. Create Annotation class

There is a simple method to create annotation class.  Here there are two annotation class named @NotNull and @Length.

@NotNull is for validating the field againsts null value and @Length  is for restricting the length of the string.

filename : NotNull.java


package cc.validations;

import java.lang.annotation.ElementType;
import java.lang.annotation.Retention;
import java.lang.annotation.RetentionPolicy;
import java.lang.annotation.Target;

@Retention(RetentionPolicy.RUNTIME)
@Target(value = ElementType.FIELD)
public @interface NotNull {

String message();
 }

filename : Length.java

package cc.validations;

import java.lang.annotation.ElementType;
import java.lang.annotation.Retention;
import java.lang.annotation.RetentionPolicy;
import java.lang.annotation.Target;

@Retention(RetentionPolicy.RUNTIME)
@Target(value = ElementType.FIELD)
public @interface Length {

	int min() default 15;

	String messsage();

	int max() default 50;

}

filename Person.java

package cc.validations.test;

import cc.validations.Length;
import cc.validations.NotNull;

public class Person {

	@NotNull(message = "Firstname cannot be null")
	@Length(min = 15, max = 60, messsage = "Length must be between 15 and 60")
	private String firstName;

	@Length(min = 15, max = 60, messsage = "Length must be between 15 and 60")
	private String middleName;

	@NotNull(message = "Lastname cannot be null")
	@Length(min = 15, max = 60, messsage = "Length must be between 15 and 60")
	private String lastName;

	public String getFirstName() {
		return firstName;
	}

	public void setFirstName(String firstName) {
		this.firstName = firstName;
	}

	public String getMiddleName() {
		return middleName;
	}

	public void setMiddleName(String middleName) {
		this.middleName = middleName;
	}

	public String getLastName() {
		return lastName;
	}

	public void setLastName(String lastName) {
		this.lastName = lastName;
	}

}

2. Putting all together

filename : Main.java

package cc.validations.test;

import java.lang.reflect.Field;
import java.util.ArrayList;
import java.util.List;

import cc.validations.Length;
import cc.validations.NotNull;

public class Main {

	public static List<String> validate(Object obj) {

		List<String> errors = new ArrayList<String>();
		Field[] fields = obj.getClass().getDeclaredFields();
		for (int i = 0; i < fields.length; i++) {
			fields[i].setAccessible(true);
			NotNull annotations = fields[i].getAnnotation(NotNull.class);
			if (annotations != null) {
				try {
					if (fields[i].get(obj) == null) {
						errors.add(annotations.message());
						continue;
					}
				} catch (Exception e) {
					System.out.println(e.getMessage());
				}
			}
			// check for length only if @NotNull is present

			if (annotations != null) {
				Length lengthAnnotations = fields[i].getAnnotation(Length.class);
				if (lengthAnnotations != null) {
					try {
						int min = lengthAnnotations.min();
						int max = lengthAnnotations.max();
						String value = (String) fields[i].get(obj);
						if (value.length() < min || value.length() > max) {
							errors.add(fields[i].getName() + ": " + lengthAnnotations.messsage());
						}
					} catch (Exception e) {
						System.out.println(e.getMessage());
					}
				}
			}
		}
		return errors;
	}

	public static void main(String args[]) {
		Person p = new Person();
		p.setFirstName("Kusum");
		p.setLastName("Adhikari");
		List<String> msgs = validate(p);
		for (String msg : msgs) {
			System.out.println(msg);
		}
	}
}

Failed to load JavaHL Library

“Failed to load JavaHL Library …” : a popup error message which, whenever I see makes me say “che”. Not really annoying but just enough to make you glare at computer screen. Earlier, whenever I had this popup message, all I did was click ok and continued. ‘Ahh.. solved the problem for this session’. How foolish, forgot the google. Cud have found atleast one solution and rest in ease for all session.

Well, I did found a one good solution (after countless ‘ok’ clicks), which if you want to know in details, then go here. The page content will explain what is ‘JavaHL’ , why do you get it in first place and how to fix the issue across different platforms. I haven’t faced this popup error on window platform but it’s common in linux (tried couple of distro, installed eclipse with subclipse plugin and got popup in each one).

What is JavaHL?
JavaHL is a library that enables Subclipse to use Subversion api. Specifically, it is the Java language binding for the Subversion API.

How to Fix it?
Install a package named libsvn-java from repository and tell JVM where to look for it.

$sudo apt-get install libsvn-java

Now, the important part is to specify the location of the JavaHL library for JVM to find. Usually, the path is ‘/usr/lib/jni’ or ‘/usr/lib/i386-linux-gnu/jni’ (on newer distro). Add JavaHL path in a new line to eclipse.ini after ‘-vmargs’.

-vmargs
-Djava.library.path=/usr/lib/jni

Save the eclipse.ini and start the IDE, the popup will be gone.
But, if you couldn’t find the JavaHL library location, try using

$sudo find / -name jni

to get the location.


Update: You can also fix this issue like stated here

Java

For all java programmers who loves it.

1) The “Java Life” rap music video.

2)”Java is future” JDK 7.0 release video.

3)Java + You

My Comment : I have been programming in Java for couple of years and I believe it is good platform. I had my time with other languages and I have fair share of respect for them too. What matters most is what you do and how you do it. These videos are for entertainment purpose only.