Archive for the ‘Java’ Category

Lombok

Posted: June 9, 2018 in General, Java, Java8
Tags: , ,

Lets take a look at a following sample code.

import java.io.Serializable;
import java.util.Objects;

public class User implements Serializable {

    private long id;
    private String username;
    private String login;

    public long getId() {
        return id;
    }

    public void setId(long id) {
        this.id = id;
    }

    public String getUsername() {
        return username;
    }

    public void setUsername(String username) {
        this.username = username;
    }

    public String getLogin() {
        return login;
    }

    public void setLogin(String login) {
        this.login = login;
    }

    @Override
    public boolean equals(Object o) {
        if (this == o) return true;
        if (o == null || getClass() != o.getClass()) return false;
        User user = (User) o;
        return id == user.id &&
                Objects.equals(username, user.username) &&
                Objects.equals(login, user.login);
    }

    @Override
    public int hashCode() {

        return Objects.hash(id, username, login);
    }
}

A class should have getter-setters for the instance variables, equals & hashCode method implementation, all field constructors and an implementation of toString method. This class so far has no business logic and even without it is 50+ lines of code. This is insane.

Lombok is used to reduce boilerplate code for model/data objects, e.g., it can generate getters and setters for those object automatically by using Lombok annotations. The easiest way is to use the @Data annotation.

import java.io.Serializable;
import lombok.data

@Data
public class User implements Serializable {

    private long id;
    private String username;
    private String login;
}

How to add Lombok to your java project ?

Using Gradle

dependencies {
    compileOnly('org.projectlombok:lombok:1.16.20')
}

Using Maven

<dependency>
    <groupId>org.projectlombok</groupId>
    <artifactId>lombok</artifactId>
    <version>1.16.20</version>
</dependency>

Tips to remember while using Lombok

  1. Don’t mix logic with lombok
  2. Use @Data for your DAOs
  3. Use @Value for immutable value objects
  4. Use @Builder when you have an object with many fields with the same type
  5. Exclude generated classes from Sonar report. If you are using Maven and Sonar, you can do this using the sonar.exclusions property.
Advertisements

Java 8 introduced Optional<T> as a container object which may contain null values. It’s often used to indicate to a caller that a value might be null and that it need to be handled to avoid NullPointerExceptions.

With the release of Hibernate 5.2, we could use them in our persistence layer for optional entity attributes or when loading entities that may or may not exist.

Lets see how we can use Optional<T> to indicate optional attributes and query results which might not return a result.

Consider a sample Tour Booking app where i need to search a tour package by region. The database design has a 2 tables  ‘TourPackage’  and ‘CustomerReview’  The ‘TourPackage’ entity is the root in our entity aggregate. There can be a CustomerReview associated with every TourPackage but not mandatory.

So when we searched for a TourPackage by region, what if there was tour package for which the optional ‘customerReview’ attribute is null? With previous Java versions, the getCustomerReview() method would just return null. The caller would need to know about the possible null value and handle it. With Java 8, you can return an Optional to make the caller aware of possible null values and to avoid NullPointerExceptions.

But if you just change the type of the customerReview attribute from CustomerReview to Optional<CustomerReview>, Hibernate isn’t able to determine the type of the attribute and throws a MappingException.

javax.persistence.PersistenceException: [PersistenceUnit: my-persistence-unit] Unable to build Hibernate SessionFactory

Caused by: org.hibernate.MappingException: Could not determine type for: java.util.Optional, at table: TourPackage, for columns: [org.hibernate.mapping.Column(customerReview)]

To avoid this Exception, you have to use field-type access and keep Attachment as the type of the attachment attribute. Hibernate is then able to determine the data type of the attribute but doesn’t return an Optional.

Lets see how we can see the comment given by the customer.

Optional<CustomerReview> customerReview = tourPackage.getCusomerReview();
if (customerReview.isPresent()) {
CustomerReview review = customerReview.get();
System.out.print(“Review Comment :: ” + review.getComment());
}

Lets also take a look at the various methods in the Optional class.

Optional.empty() – Return an empty Optional object.
Optional.of() – Return an Optional object with a non-null value. It will throw NullPointerException if value is null.
Optional.ofNullable() – Return an Optional object with a non-null value. It will return empty Optional object if value is null.
Optional#isPresent() – Return true if a value is present in the Optional object, otherwise false.
Optional#get() – Return a value from Optional object, if value is present, otherwise throws NoSuchElementException.
Optional#ifPresent() – This method invoke a Consumer if a value is present in Optional object, otherwise do nothing.
Optional#orElse() – Return a value if present, otherwise return other specified value.
Optional#orElseGet() – Return a value if present, otherwise invoke a Supplier that return other value.
Optional#orElseThrow() – Return a value if present, otherwise invoke a Supplier that create and throws an exception.
Optional#filter() – Return an Optional object if a value is present, and matches the given Predicate, otherwise return an empty Optional object.
Optional#map() – Return an Optional object if a value is present, and applies the given mapping Function to it, otherwise return an empty Optional object.
Optional#flatMap() – Return an Optional object if a value is present, and applies the provided Optional-bearing mapping Function to it, otherwise return an empty Optional object.

 

 

Recently I was reading about serialization and I noticed that all the ManagedBean in my JSF project implements Serializable interface.

Normally, we use Serialization to send an object over the network or if the state of an object needs to be persisted to a flat file or a database.
But my managedBean was just a means to value bind the UI components. I digged deep into this topic and I think its useful to share my findings with you all.

We need not make every ManagedBean serializable. It depends upon the Scope the MBean. If you don’t want to serialize your MBean, make sure the scope is ‘request’.

Instead, if you are dealing with ‘session’ scope or ‘view’ scope (even view scope is using session scope). The session scope is backed by the Servlet’s HttpSession.
All session attributes are supposed to implement Serializable because the servlet container tries to persist session data to file system
to be able to survive heavy load and/or reviving sessions during server restart.

Sometimes you might have noticed that your post contructs in your MBean get executed on server restart. Why ?
Some containers will require you to explicitly disable session serialization (or else they will be generating exceptions).
Tomcat by default enables persisting session through server restart.

Importance of SerialVersionUID

Posted: April 23, 2014 in General, Java

In java, serialization is the process of turning an object-in-memory into a stream of bytes so you can store it on disk or send it over the network.
De-serialization is the reverse process: turning a stream of bytes into an object in memory.
During serialization, runtime associates each serializable class with a version number, called a serialVersionUID, which is used during de-serialization
to verify that the sender and receiver of a serialized object have loaded classes for that object that are compatible with respect to serialization.

If the receiver has loaded a class for the object that has a different serialVersionUID than that of the corresponding sender’s class,
then de-serialization will result in an InvalidClassException.

A serializable class can declare its own serialVersionUID explicitly by declaring a field named “serialVersionUID
that must be static, final, and of type long as it is not useful as a inherited member.

Points to remember:
1. Transient and static fields are ignored in serialization. After de-serialization transient fields and non-final static fields will be null.
But final static variables will still hold the values as they are part of the class.

2.Serialization and de-serialization can be used for copying and cloning objects. It is slower than regular clone, but can produce a deep copy very easily.

Now let’s see some of the commonly asked questions regarding serializaion

What if I want to serialize a class B that implements Serializable interface but its super class is not serializable ?
Serialization is possible in this case as long there is a no-arg constructor in the super class, which gets called to initialize superclass during de-serialization.

Why should we explicitly declare a serialVersionID in our classes to be serialized?
If class does not contain a serialVersionUID field, its serialVersionUID will be automatically generated by the compiler.
Different compilers, or different versions of the same compiler, will generate potentially different values.

String intern() – Good or Bad ?

Posted: April 22, 2014 in General, Java

Today I am gonna share my view on the intern() method of String.

Let’s say I create 2 new String objects

String a = new String(“Suhas”);
String b = new String(“Suhas”);

Since we are using new operator, there are 2 different memory locations holding the same String “Suhas”.

So, how do we do String pooling in this case ? – Using intern() of String

So I would rewrite my code as follows

String a = new String(“Suhas”).intern();
String b = new String(“Suhas”).intern();

When the intern method is called, if the string pool already contains a string equal to this String object as determined by the equals(Object) method,
then the string from the pool is returned. Otherwise, this String object is added to the pool and a reference to this String object is returned.

But when the number of strings in the pool grows, the amount of time to lookup one string from the pool goes up.
So I don’t recommend using intern() unless we are handling with a few Strings.

public class Suhasjavablog {

public void createNewInstances() {

// 1. Using Class.forName
Suhasjavablog obj1 = null;
try {
Class ref = Class.forName(“Suhasjavablog”);
obj1 = (Suhasjavablog) ref.newInstance();
} catch (ClassNotFoundException e) {
e.printStackTrace();
} catch (InstantiationException e) {
e.printStackTrace();
} catch (IllegalAccessException e) {
e.printStackTrace();
}

//2. Using Clone()
try {
Suhasjavablog obj2 = (Suhasjavablog) obj1.clone();
} catch (CloneNotSupportedException e1) {
e1.printStackTrace();
}

//3. Using ClassLoader.loadClass()
try {
Suhasjavablog obj3 = (Suhasjavablog) this.getClass().getClassLoader()
.loadClass(“Suhasjavablog”).newInstance();
} catch (InstantiationException e) {
e.printStackTrace();
} catch (IllegalAccessException e) {
e.printStackTrace();
} catch (ClassNotFoundException e) {
e.printStackTrace();
}

//4. Using Reflection
try {
Suhasjavablog obj4 = this.getClass().newInstance();
} catch (InstantiationException e) {
e.printStackTrace();
} catch (IllegalAccessException e) {
e.printStackTrace();
}

// 5. Using the new operator
Suhasjavablog obj5 = new Suhasjavablog();

}

}

Today we are gonna see a custom utility class that converts a date object to a cron expression

public class CronUtil {

private final Date mDate;
private final Calendar mCal;
private final String mSeconds = “0”;
private final String mDaysOfWeek = “?”;

private String mMins;
private String mHours;
private String mDaysOfMonth;
private String mMonths;
private String mYears;

public CronUtil(Date pDate) {
this.mDate = pDate;
mCal = Calendar.getInstance();
this.generateCronExpression();
}

private void generateCronExpression() {
mCal.setTime(mDate);

String hours = String.valueOf(mCal.get(Calendar.HOUR_OF_DAY));
this.mHours = hours;

String mins = String.valueOf(mCal.get(Calendar.MINUTE));
this.mMins = mins;

String days = String.valueOf(mCal.get(Calendar.DAY_OF_MONTH));
this.mDaysOfMonth = days;

String months = new java.text.SimpleDateFormat(“MM”).format(mCal.getTime());
this.mMonths = months;

String years = String.valueOf(mCal.get(Calendar.YEAR));
this.mYears = years;

}

public Date getDate() {
return mDate;
}

public String getSeconds() {
return mSeconds;
}

public String getMins() {
return mMins;
}

public String getDaysOfWeek() {
return mDaysOfWeek;
}

public String getHours() {
return mHours;
}

public String getDaysOfMonth() {
return mDaysOfMonth;
}

public String getMonths() {
return mMonths;
}

public String getYears() {
return mYears;
}

}

 

Now lets see how to use this class

 

public void generateCronExpression(Date date) {

try {

SimpleDateFormat dateFormat = new SimpleDateFormat(“yyyy-MM-dd HH:mm:ss”);
String dt = dateFormat.format(date);

Date cronDate = new SimpleDateFormat(“yyyy-MM-dd HH:mm:ss”).parse(dt);

CronUtil calHelper = new CronUtil (cronDate);
String cron = calHelper.getSecondsDuration() + ” ” +
calHelper.getMinsDuration() + ” ” +
calHelper.getHoursDuration() + ” ” +
calHelper.getDaysOfMonthDuration() + ” ” +
calHelper.getMonthsDuration() + ” ” +
calHelper.getDaysOfWeekDuration() + ” ” +
calHelper.getYearsDuration();
logger.debug(“Cron Expression ” + cron);

}