Tuesday, October 31, 2017

Callable and Future in Java | Callable vs Runnable | Java Callable Future Example

Callable and Future in Java | Callable vs Runnable | Java Callable Future Example

Java Callable and Future are used a lot in multithreaded programming. Java 5 introduced java.util.concurrent.Callable interface in concurrency package that is similar to Runnable interface but it can return any Object and able to throw Exception. Java Callable tasks return java.util.concurrent.Future object. Using Java Future object, we can find out the status of the Callable task and get the returned Object. It provides get() method that can wait for the Callable to finish and then return the result.
Below is a simple example:


package com.pkm;

import java.security.SecureRandom;
import java.util.Date;
import java.util.concurrent.Callable;
import java.util.concurrent.FutureTask;

/**
 * Created by pritom on 31/10/2017.
 */
public class CallableTest implements Callable {
    private Integer n;

    public static void main(String[] args) throws Exception {
        FutureTask[] futureTasks = new FutureTask[5];
        for (Integer i = 0; i < 5; i++) {
            CallableTest callable = new CallableTest(i);
            futureTasks[i] = new FutureTask(callable);
            Thread thread = new Thread(futureTasks[i]);
            thread.start();
        }
        for (Integer i = 0; i < 5; i++) {
            System.out.println(futureTasks[i].get());
        }
    }

    public CallableTest(Integer n) {
        this.n = n;
    }

    @Override
    public Object call() throws Exception {
        System.out.println("Thread called at = " + (new Date()));
        Thread.sleep(1000L * (1 + (new SecureRandom().nextInt(5))));
        return "Thread executed at = " + (new Date()) +
                ", name=" + Thread.currentThread().getName() + "." + n;
    }
}


Output is below:


Thread called at = Tue Oct 31 16:02:08 BDT 2017
Thread called at = Tue Oct 31 16:02:08 BDT 2017
Thread called at = Tue Oct 31 16:02:08 BDT 2017
Thread called at = Tue Oct 31 16:02:08 BDT 2017
Thread called at = Tue Oct 31 16:02:08 BDT 2017
Thread executed at = Tue Oct 31 16:02:13 BDT 2017, name=Thread-0.0
Thread executed at = Tue Oct 31 16:02:13 BDT 2017, name=Thread-1.1
Thread executed at = Tue Oct 31 16:02:11 BDT 2017, name=Thread-2.2
Thread executed at = Tue Oct 31 16:02:10 BDT 2017, name=Thread-3.3
Thread executed at = Tue Oct 31 16:02:09 BDT 2017, name=Thread-4.4


Java Thread Example by extending Thread class | Java Thread Example by implementing Runnable interface

Java Thread Example by extending Thread class



package com.pkm;

import java.util.Date;

/**
 * Created by pritom on 31/10/2017.
 */
public class ThreadTest extends Thread {
    public static void main(String[] args) throws Exception {
        System.out.println("Thread called at = " + (new Date()));
        new ThreadTest().start();
    }

    public void run() {
        try {
            sleep(10000L);
        }
        catch (InterruptedException e) {
            e.printStackTrace();
        }
        System.out.println("Thread executed at = " + (new Date()));
    }
}


Java Thread Example by implementing Runnable interface


package com.pkm;

import java.util.Date;

/**
 * Created by pritom on 31/10/2017.
 */
public class RunnableTest implements Runnable {
    public static void main(String[] args) throws Exception {
        System.out.println("Thread called at = " + (new Date()));
        new Thread(new RunnableTest()).start();
    }

    @Override
    public void run() {
        try {
            Thread.sleep(10000L);
        }
        catch (InterruptedException e) {
            e.printStackTrace();
        }
        System.out.println("Thread executed at = " + (new Date()));
    }
}

So we can use "Runnable" interface, it will help us inherit another class, because if we use "Thread" inheritance then we should loose one scope to inherit another class if we need.


Monday, October 23, 2017

Grails Link Generator | Generate Links Outside Controllers or Tag Libraries | Using grailsLinkGenerator to generate link | Custom Link Generator

Grails Link Generator | Generate Links Outside Controllers or Tag Libraries | Using grailsLinkGenerator to generate link | Custom Link Generator

It's easy, just need to follow below steps:
First create a properties file named "application.properties" under web-app/WEB-INF as follows:


configs.serverURL=http://localhost:8033/custom-link-generator-bean


Now create a Groovy file named "ConfigurationProperties.groovy" with below contents:


package com.link

import grails.util.Environment

/**
 * Created by pritom on 23/10/2017.
 */
class ConfigurationProperties {
    public static final String DEV_DIR = "web-app/WEB-INF"
    private static Properties ppt

    static getProperty(String name, def defaultV = null) {
        if (ppt == null) {
            ppt = new Properties()
            loadProperties("application.properties")
        }

        def result = ppt.getProperty(name, defaultV?.toString())
        return result == "" ? defaultV : result
    }

    static loadProperties(String fileName) {
        URL url = ConfigurationProperties.class.getResource("ConfigurationProperties.class")
        String thisPath = url.getPath(), path
        if(Environment.current == Environment.DEVELOPMENT || Environment.current == Environment.TEST) {
            path = "file://" + thisPath.substring(0, thisPath.lastIndexOf("target")) + "${DEV_DIR}/${fileName}"
        }
        else {
            path = "file://" + thisPath.substring(0, thisPath.lastIndexOf("classes")) + fileName
        }

        new File(path.toURI()).getCanonicalFile().withInputStream { InputStream stream ->
            ppt.load(stream)
        }
    }
}


Now create a Groovy file named "MyLinkGenerator.groovy" with below contents:


package com.link

import org.codehaus.groovy.grails.web.mapping.DefaultLinkGenerator
import org.codehaus.groovy.grails.web.mapping.LinkGenerator
/**
 * Created by pritom on 23/10/2017.
 */
class MyLinkGenerator extends DefaultLinkGenerator implements LinkGenerator {
    MyLinkGenerator(String serverBaseURL, String contextPath) {
        super(serverBaseURL, contextPath)
    }

    MyLinkGenerator(String serverBaseURL) {
        super(serverBaseURL)
    }

    String makeServerURL() {
        return ConfigurationProperties.getProperty("configs.serverURL")
    }

    String link(Map attrs, String encoding = 'UTF-8') {
        String cp = super.getContextPath()
        String url = super.link(attrs, encoding)
        if (cp) {
            if (cp != null && url.startsWith(cp)) url = url.substring(cp.length())
            if (url.startsWith("/")) url = url.substring(1)
            return makeServerURL() + "/" + url
        }
        return url
    }
}


Now add below lines to BootStrap.groovy


import com.link.MyLinkGenerator
import grails.spring.BeanBuilder
import org.codehaus.groovy.grails.commons.GrailsApplication

import javax.servlet.ServletContext

class BootStrap {
    ServletContext servletContext
    GrailsApplication grailsApplication

    def init = { servletContext ->
        grailsApplication.mainContext.removeBeanDefinition("grailsLinkGenerator")
        BeanBuilder bb = new BeanBuilder()
        bb.beans {
            grailsLinkGenerator(MyLinkGenerator, null)
        }
        bb.registerBeans(grailsApplication.mainContext)
    }

    def destroy = {

    }
}


And create another Groovy file named "AsyncManager.groovy" with below contents to check it in thread:


package com.link

/**
 * Created by pritom on 23/10/2017.
 */
class AsyncManager {
    static void run(Closure closure) {
        TimerTask task = new TimerTask() {
            @Override
            void run() {
                try {
                    closure.call()
                }
                catch (Exception e) {
                    e.printStackTrace()
                }
            }
        }
        new Timer().schedule(task, 1000L)
    }
}


And finally add a controller with below contents:


package com.link

class CustomLinkController {
    def grailsLinkGenerator

    def index() {
        println "In-request"
        println "Generator=${grailsLinkGenerator.class}"
        println "Base-url=${grailsLinkGenerator.serverBaseURL}"
        println "Controller-url=${grailsLinkGenerator.link(controller: "customLink", action: "index", params: [id: 2, name: "Pritom Kumar"])}"

        AsyncManager.run {
            println ""
            println "In-non-request"
            println "Generator=${grailsLinkGenerator.class}"
            println "Base-url=${grailsLinkGenerator.serverBaseURL}"
            println "Controller-url=${grailsLinkGenerator.link(controller: "customLink", action: "index", params: [id: 2, name: "Pritom Kumar"])}"
        }
        render ""
    }
}


Output would be as follows:


--------------WITHOUT CUSTOM LINK GENERATOR-----------------------
In-request
Generator=class asset.pipeline.grails.CachingLinkGenerator
Base-url=http://localhost:8033/custom-link-generator-bean
Controller-url=/custom-link-generator-bean/customLink/index/2?name=Pritom+Kumar

In-non-request
Generator=class asset.pipeline.grails.CachingLinkGenerator
Base-url=http://localhost:8080/custom-link-generator-bean
Controller-url=/custom-link-generator-bean/customLink/index/2?name=Pritom+Kumar


--------------WITH CUSTOM LINK GENERATOR-----------------------
In-request
Generator=class com.link.MyLinkGenerator
Base-url=http://localhost:8033/custom-link-generator-bean
Controller-url=http://localhost:8033/custom-link-generator-bean/customLink/index/2?name=Pritom+Kumar

In-non-request
Generator=class com.link.MyLinkGenerator
Base-url=http://localhost:8033/custom-link-generator-bean
Controller-url=http://localhost:8033/custom-link-generator-bean/customLink/index/2?name=Pritom+Kumar




Friday, October 20, 2017

MySQL SUM function in multiple joins | MySQL JOIN with multiple tables and SUMS | Using SUM with multiple joins in mysql

MySQL SUM function in multiple joins | MySQL JOIN with multiple tables and SUMS | Using SUM with multiple joins in mysql


SELECT x1.id,SUM(x1.amount) as fake_total,COUNT(x1.id) as count,
(SELECT SUM(amount) FROM t1 WHERE t1.id=x1.id) as actual_total
FROM t1 x1 LEFT JOIN t2 x2 on x2.t1=x1.id
GROUP BY x1.id
ORDER BY x1.id asc

If you on "EXPLAIN" mode then you will get the below data:


EXPLAIN
SELECT x1.id,SUM(x1.amount) as fake_total,COUNT(x1.id) as count,
(SELECT SUM(amount) FROM t1 WHERE t1.id=x1.id) as actual_total
FROM t1 x1 LEFT JOIN t2 x2 on x2.t1=x1.id
GROUP BY x1.id
ORDER BY x1.id asc




Actually it will not take too much time to execute

Wednesday, October 18, 2017

Hooking into GORM events | Hooking into GORM custom event listener from plugin in Grails | Grails Custom Gorm Event Listener

Hooking into GORM events | Hooking into GORM custom event listener from plugin in Grails | Grails Custom Gorm Event Listener

At first configure your datasource.groovy to connect with your desired database as below:


dataSource {
    pooled = true
    jmxExport = true
    driverClassName = "org.h2.Driver"
    username = "sa"
    password = ""
}
hibernate {
    cache.use_second_level_cache = true
    cache.use_query_cache = true
    cache.region.factory_class = 'net.sf.ehcache.hibernate.EhCacheRegionFactory'
    cache.provider_class = 'net.sf.ehcache.hibernate.EhCacheProvider'
    format_sql = false
    use_sql_comments = false
}

// environment specific settings
environments {
    development {
        dataSource {
            pooled = true
            url = "jdbc:mysql://localhost/my_db?useUnicode=yes&characterEncoding=UTF-8"
            driverClassName = "com.mysql.jdbc.Driver"
            username = "root"
            password = ""
            dialect = "org.hibernate.dialect.MySQL5InnoDBDialect"
            dbCreate = "update"
            properties {
                jmxEnabled = true
                initialSize = 5
                maxActive = 50
                minIdle = 5
                maxIdle = 25
                maxWait = 10000
                maxAge = 10 * 60000
                timeBetweenEvictionRunsMillis = 5000
                minEvictableIdleTimeMillis = 60000
                validationQuery = "SELECT 1"
                validationQueryTimeout = 3
                validationInterval = 15000
                testOnBorrow = true
                testWhileIdle = true
                testOnReturn = false
                jdbcInterceptors = "ConnectionState"
                defaultTransactionIsolation = java.sql.Connection.TRANSACTION_READ_COMMITTED
            }
            logSql = true
            loggingSql = true
        }
    }
    test {
        dataSource {
            
        }
    }
    production {
        dataSource {
            
        }
    }
}


Now add "runtime 'mysql:mysql-connector-java:5.1.29'" to your BiuldConfig.groovy file under "dependencies" section if you used MySQL.
Now create controller like below:

package com.custom_gorm_event_listener

class HomeController {
    def index() {
        println("Tracking-post-load-function")
        println(Home.list())
        println("")
        println("")
        println("Tracking-post-update-function")
        Home.last().departmentName = "Department-${System.currentTimeMillis()}".toString()
        render ""
    }
}

And as well as a Domain class as below:

package com.custom_gorm_event_listener

class Home {
    Long id
    String name
    String roll
    String departmentName

    static constraints = {
        departmentName nullable: true
    }
}

This is the most important step, need to create and gorm event listener class as below:

package com.custom_gorm_event_listener

import grails.util.Holders
import org.codehaus.groovy.grails.orm.hibernate.EventTriggeringInterceptor
import org.codehaus.groovy.grails.orm.hibernate.HibernateDatastore
import org.grails.datastore.mapping.core.Datastore
import org.grails.datastore.mapping.engine.event.AbstractPersistenceEvent
import org.grails.datastore.mapping.engine.event.ValidationEvent
import org.hibernate.HibernateException
import org.hibernate.event.spi.AbstractPreDatabaseOperationEvent
import org.hibernate.event.spi.PostDeleteEvent
import org.hibernate.event.spi.PostInsertEvent
import org.hibernate.event.spi.PostLoadEvent
import org.hibernate.event.spi.PostUpdateEvent
import org.hibernate.event.spi.PreDeleteEvent
import org.hibernate.event.spi.PreInsertEvent
import org.hibernate.event.spi.PreLoadEvent
import org.hibernate.event.spi.PreUpdateEvent
import org.hibernate.event.spi.SaveOrUpdateEvent

/**
 * Created by pritom on 18/10/2017.
 */
class GormEventListener extends EventTriggeringInterceptor {
    GormEventListener() {
        this((HibernateDatastore) Holders.applicationContext.getBean(Datastore), new ConfigObject())
    }

    GormEventListener(HibernateDatastore datastore, ConfigObject co) {
        super(datastore, co)
    }

    protected void onPersistenceEvent(AbstractPersistenceEvent event) {
        super.onPersistenceEvent(event)
    }

    private void updateState(AbstractPreDatabaseOperationEvent event) {
        Object[] newState = event.persister.getPropertyValuesToInsert(event.entity, null, event.session)
        Object[] oldState = event.state
        newState.eachWithIndex { m, i ->
            oldState[i] = m
        }
    }

    boolean onPreInsert(PreInsertEvent event) {
        updateState(event)
        return false
    }

    void onPostInsert(PostInsertEvent event) {
        println("onPostInsert::${event.entity}")
    }

    boolean onPreUpdate(PreUpdateEvent event) {
        updateState(event)
        return false
    }

    void onPostUpdate(PostUpdateEvent event) {
        println("onPostUpdate::${event.entity}")
    }

    boolean onPreDelete(PreDeleteEvent event) {
        return false
    }

    void onPostDelete(PostDeleteEvent event) {
        println("onPostDelete::${event.entity}")
    }

    void onPreLoad(PreLoadEvent event) {

    }

    void onPostLoad(PostLoadEvent event) {
        println("onPostLoad::${event.entity}")
    }

    void onSaveOrUpdate(SaveOrUpdateEvent event) throws HibernateException {
        println("onSaveOrUpdate::${event.entity}")
    }

    void onValidate(ValidationEvent event) {

    }
}

And finally need to hook our custom gorm event listener to gorm event, to do so we have to add some functionalities to BootStrap.groovy as below:

import com.custom_gorm_event_listener.GormEventListener
import org.codehaus.groovy.grails.commons.GrailsApplication
import org.springframework.context.event.AbstractApplicationEventMulticaster
import org.springframework.context.support.AbstractApplicationContext

class BootStrap {
    GrailsApplication grailsApplication

    def init = { servletContext ->
        addGormListener()
    }

    def destroy = {

    }

    void addGormListener() {
        AbstractApplicationContext context = grailsApplication.mainContext
        AbstractApplicationEventMulticaster multicaster = context.applicationEventMulticaster
        List listeners = multicaster.applicationListeners
        multicaster.removeAllListeners()
        /* Placing our listener at first */
        multicaster.addApplicationListener(new GormEventListener())
        listeners.each {
            multicaster.addApplicationListener(it)
        }
    }
}

We are finished, if we run our project we can track when an instance create, update or read through our listener:

Tracking-post-load-function
Hibernate: select this_.id as id1_0_0_, this_.version as version2_0_0_, this_.department_name as departme3_0_0_, this_.name as name4_0_0_, this_.roll as roll5_0_0_ from home this_
onPostLoad::com.custom_gorm_event_listener.Home : 53
onPostLoad::com.custom_gorm_event_listener.Home : 54
onPostLoad::com.custom_gorm_event_listener.Home : 55
[com.custom_gorm_event_listener.Home : 53, com.custom_gorm_event_listener.Home : 54, com.custom_gorm_event_listener.Home : 55]


Tracking-post-update-function
Hibernate: select this_.id as id1_0_0_, this_.version as version2_0_0_, this_.department_name as departme3_0_0_, this_.name as name4_0_0_, this_.roll as roll5_0_0_ from home this_ order by this_.id desc limit ?
Hibernate: update home set version=?, department_name=?, name=?, roll=? where id=? and version=?
onPostUpdate::com.custom_gorm_event_listener.Home : 55




Grails Bind Function | Method For Groovy Page View

Grails Bind Function | Method For Groovy Page View

Have to extend metaclass as below:


import org.codehaus.groovy.grails.web.pages.GroovyPage

GroovyPage.metaClass.with {
    xor = {
        "XOR-VALUE"
    }
    isTrue = { Map attrs = null ->
        println(attrs)
        return true
    }
}

And then you can use function/method in gsp page as below:


<h1>${xor()} ${isTrue(param1: 'value1', params2: 'value2') ? 'IS-TRUE' : 'IS-FALSE'}</h1>
<-- --="">

And output is as below:

XOR-VALUE IS-TRUE


Tuesday, October 17, 2017

Grails How to change logging level in runtime | Grails Set Log Level for Grails

Grails How to change logging level in runtime | Grails Set Log Level for Grails

Need to create a util class at first as below:


package com.log4j

import grails.util.Holders
import org.apache.log4j.Category
import org.apache.log4j.Level
import org.apache.log4j.Logger

/**
 * Created by pritom on 17/10/2017.
 */
class UtilsBase {
    protected static Logger log

    static void setLogLevel() {
        Level level = Holders.config?.myconfig?.log4j?.logLevel ?: Level.ERROR
        println("SETTING-LOG-LEVEL=${level}")
        Enumeration allLoggers = log.getLoggerRepository().getCurrentCategories()
        log.setLevel(level)
        while (allLoggers.hasMoreElements()) {
            Category category = (Category) allLoggers.nextElement()
            category.setLevel(level)
        }
    }

    static {
        println("Log-enabled-for-${this.class.simpleName}")
        log = Logger.getLogger(this.class)
    }
}

Need to do something in Config.groovy as below:


myconfig {
    log4j {
        /* Here you can define your LOG level */
        logLevel = Level.INFO
    }
}

// log4j configuration
// log4j configuration
log4j.main = {
    def pattern = new PatternLayout("%d{yyyy-MM-dd//HH:mm:ss.SSS} [%t] %x %-5p %c{2} - %m%n")

    appenders {
        console name: "stdout", layout: pattern
    }

    error   'org.codehaus.groovy.grails.web.servlet',        // controllers
            'org.codehaus.groovy.grails.web.pages',          // GSP
            'org.codehaus.groovy.grails.web.sitemesh',       // layouts
            'org.codehaus.groovy.grails.web.mapping.filter', // URL mapping
            'org.codehaus.groovy.grails.web.mapping',        // URL mapping
            'org.codehaus.groovy.grails.commons',            // core / classloading
            'org.codehaus.groovy.grails.plugins',            // plugins
            'org.codehaus.groovy.grails.orm.hibernate',      // hibernate integration
            'org.springframework',
            'org.hibernate',
            'net.sf.ehcache.hibernate',
            'com.log4j'

    debug   'com.log4j'

    warn    'org.springframework',
            'org.hibernate',
            'grails.plugins.springsecurity',
            'groovyx.net.http',
            'com.log4j'

    all     'grails.app'
}


Now you have to set log level fro BootStrap.goovy as below


import com.log4j.UtilsBase

class BootStrap {

    def init = { servletContext ->
        UtilsBase.setLogLevel()
    }
    def destroy = {

    }
}


And finally start loggin


package com.log4j

class Log4jController extends UtilsBase {
    def index() {
        log.info("Info")
        log.warn("Warn")
        log.error("Error")
        render ""
    }
}

Will output as below:


2017-10-17//16:16:15.512 [http-bio-8808-exec-4]  INFO  log4j.Log4jController - Info
2017-10-17//16:16:15.515 [http-bio-8808-exec-4]  WARN  log4j.Log4jController - Warn
2017-10-17//16:16:15.515 [http-bio-8808-exec-4]  ERROR log4j.Log4jController - Error