File Semaphore / Mutex

Posted: August 19, 2009 in Java, Technical
Tags: , , ,

Below is an implementation of a File based mutex in Java

import java.io.File;
import java.io.FileWriter;
import java.io.IOException;
import java.io.RandomAccessFile;
import java.nio.channels.FileChannel;
import java.nio.channels.FileLock;
import java.nio.channels.OverlappingFileLockException;
import java.util.Date;
import java.util.concurrent.ExecutorService;
import java.util.concurrent.Executors;

/**
 * A file based mutual exclusion lock that allows to acquire and release the underlying 
 * resource. On acquiring the lock the file is created with the given contents. The 
 * lock is free on construction.
 * 
 * The lock is also associated with a maximum unused period. If the lock is not 
 * updated during the given period, any other thread waiting to acquire the lock
 * will be given the lock.
 * 
 * The lock is said to be acquired only when the file exists and file last used 
 * timestamp is within unusedMsec. permitted
 * 
 * The read and write operation to the mutex file are synchronized across 
 * different process by encapsulating that with a create & lock operation
 * on a separate file. So before a process can acquire/read mutex (update mutex
 * content & timestamp) , it needs to create & lock another predefined
 * file and also delete the lock file after the operation on mutex are done. This is
 * to ensure that multiple processes/threads dont acquire the mutex at the same time
 */
public class FileMutex {
    /** The lock file name **/
    private String mutex = System.getProperty("java.io.tmpdir") + "app.lck";

    /** Msecs. file can be left unused before another thread acquires the lock File **/
    private long unusedMSec;

    /** file contents telling which component/application is holding the lock **/
    private String mutexContent;

    /** FileName of the lock for mutex **/
    private String lockOnMutex = mutex + ".lck";

    public static final long ONE_SECOND = 1000;
    public static final long ONE_MINUTE = 60 * ONE_SECOND;

    /**
     * @param lockFileContent
     * @param unusedMSec
     */
    public FileMutex(String lockFileContent, long unusedMSec) {
        this.mutexContent = lockFileContent;
        this.unusedMSec = unusedMSec;
    }

    public void acquire() throws InterruptedException {
        try {
            while (isInuseMutex())
                Thread.sleep(ONE_SECOND);
            createMutex();
        } catch (Exception e) {
            throw new InterruptedException("Error acquiring lock: " + e.getMessage());
        }
    }

    public synchronized void release() {
        releaseMutex();
    }

    public boolean tryAcquire() throws InterruptedException {
        try {
            if (!isInuseMutex()) {
                boolean created = createMutex();
                return created;
            }
        } catch (Exception e) {
            throw new InterruptedException("Error acquiring lock: " + e.getMessage());
        }
        return false;
    }

    public boolean update() {
        createMutex();
        return true;
    }

    /**
     * @return
     */
    private boolean isInuseMutex() {
        File lockOnMutexFile = new File(lockOnMutex);
        FileChannel channel = null;
        FileLock lock = null;
        try {
            channel = new RandomAccessFile(lockOnMutexFile, "rw").getChannel();
            lockOnMutexFile.createNewFile();
            try {
                lock = channel.tryLock();
            } catch (OverlappingFileLockException e) {
                // File is already locked in this thread or virtual machine
                return true;
            }

            File mutexFile = new File(mutex);
            if (!mutexFile.exists()) {
                return false;
            }

            Date lockLastUsedDate = new Date(mutexFile.lastModified());
            Date oldestAllowedLockUsedDate = 
                         new Date(System.currentTimeMillis() - unusedMSec);
            if (lockLastUsedDate.before(oldestAllowedLockUsedDate)) {
                return false;
            }
        } catch (Exception e) {
            System.out.println("Error acquiring lock: " + e.getMessage());
        } finally {
            try {
                if (lock != null)
                    lock.release();
            } catch (IOException e) {
            }
            try {
                channel.close();
            } catch (IOException e) {
            }
            lockOnMutexFile.delete();
        }
        return true;
    }

    /**
     * Creates the lock file with the given contents.
     * 
     */
    private boolean createMutex() {
        File lockOnMutexFile = new File(lockOnMutex);
        FileChannel channel = null;
        FileLock lock = null;
        try {
            channel = new RandomAccessFile(lockOnMutexFile, "rw").getChannel();
            lockOnMutexFile.createNewFile();
            try {
                lock = channel.tryLock();
            } catch (OverlappingFileLockException e) {
                // File is already locked in this thread or virtual machine
                return false;
            }

            File mutexFile = new File(mutex);
            mutexFile.createNewFile();
            FileWriter writer = new FileWriter(mutexFile);
            writer.append(mutexContent);
            writer.flush();
            writer.close();
        } catch (IOException e) {
            System.out.println("Error acquiring lock: " + e.getMessage());
        } finally {
            try {
                if (lock != null)
                    lock.release();
            } catch (IOException e) {
            }
            try {
                channel.close();
            } catch (IOException e) {
            }
            lockOnMutexFile.delete();
        }
        return true;
    }

    /**
     * Release the mutex .. that is Delete the underlying lock file, if it exists
     */
    private void releaseMutex() {
        File mutexFile = new File(mutex);
        mutexFile.delete();
    }
}

Working on Spring, we do read a lot on AOP – Aspect Oriented Programming. Is it something different from Object Oriented Programming. Nope, AOP is kind of a design pattern that we had been using fairly regularly in our natural programming but has been given a big name by Spring, coz of the beauty with which it has been implemented by Rod Johnson.

Its called a Proxy-pattern. Its a facade. If you have dealt with proxies in core java or with an interface called java.lang.reflect.InvocationHandler, you would agree with me. For more details, see my previous post https://sanchit6.wordpress.com/2008/08/02/springing-dynamic-proxy-with-pure-java
However thats not all what spring does. There are few limitations with using this core java way of Proxy. It only works on classes that have Interfaces. So if you want to proxy your class, without using an interface, you can’t; untill you use the savior CGLib (Code Generation Library). This library can even help you proxy or advice your classes.

<bean id="name"
	class="org.springframework.aop.framework.ProxyFactoryBean" >
	<property name="target" ref="myClassTargetBean"></property>
	<property name="interfaces">
		<list>
			<value>com.java.MyInterface</value>
		</list>
	</property>
	<property name="interceptorNames" >
		<list>
			<value>someInterceptor</value>
		</list>
	</property>
</bean>

This is a sample spring configuration to define a proxy around some class implementing com.java.MyInterface declared as myClassTargetBean and advised/proxied by someInterceptor. What if we don’t have an interface. Invoking CGLib is fairly simple. Just don’t provide the interfaces property; instead declare this property

<property name="proxyTargetClass" value="true" />

Hope that helps…cheers, bye.

Lets see the magic of Spring, although at a very base level but would give you a fair idea about Spring AOP/IOC and particularly the ‘Proxy’. I ll be using plain java to show how the Proxy pattern works.

Lets take up a simple Interface depicting our business requirement

public interface IBusiness {
    public String getData();
}

Lets take its implementation class

public class BusinessImpl implements IBusiness {
    String data;
    public BusinessImpl() {
        System.out.println("BusinessImpl: Constructor invoked");
        this.data= "spring without spring";
    }

    public String getData() {
        System.out.println("BusinessImpl: getVersion invoked");
        return version;
    }
}

Now, since we don’t want anyone to know what kind of BusinessImpl we have, we need a factory, that simply returns to our users the IBusiness interface. Beneath, It may be Hibernate/JDBC/IBAtis or some abstract logic of our own (considering our business is considered with accessing data).

public class Factory {
    private static Factory factory = new Factory();
    public static Factory instance() {
        return factory;
    }

    public IBusiness getBusiness() {
        IBusiness business = new BusinessImpl();
        return business;
    }
}

And what the users of our Business would do is Factory.instance().getBusiness() to get a handle to our BusinessImpl, which actually they dont know. Untill now it was just abstarction I was telling you about. Now lets look into actually creating a proxy, lets say a LoggerProxy.
Any Proxy in java must implement java.lang.reflect.InvocationHandler Interface and override its public Object invoke(Object proxy, Method method, Object[] args) throws Throwable; method

public class LoggerProxy implements InvocationHandler {
    IBusiness target;
    public LoggerProxy(IBusiness target) {
        this.target = target;
    }

    public Object invoke(Object proxy, Method method, Object[] args) 
              throws Throwable {
        String result = null;
        System.out.println("Log start");
        System.out.println("Logging Proxy .." + proxy.getClass().
              getName());
        result = (String) method.invoke(target, args);
        System.out.println("Log end");
        return result;
    }
}

So, now we have a Proxy, that thats gonna do some logging, invoke our actual business class and again do some logging at exit. However what is missing still is plugging it all together in our factory’s getBusiness() method. So lets change that method a bit

    public IBusiness getBusiness() {
        Class[] interfaces = new Class[] { IBusiness.class };
        IBusiness bus = new BusinessImpl();
        IBusiness business = (IBusiness) Proxy.newProxyInstance(
             IBusiness.class.getClassLoader(), 
             interfaces,
             new LoggerProxy(bus));
        return business;
    }

Confused??? OK! What I have done is instantiated a Proxy class for our LoggerProxy using Proxy.newProxyInstance(ClassLoader loader,Class[] interfaces,InvocationHandler h) method. Also now Proxy has a handle to our actual business class when we did new LoggerProxy(bus)

Now lets test all that.

public class Springing {
    public static void main(String[] args) {
        IBusiness business = Factory.instance().getBusiness();
        System.out.println("GET --->" + business.getData());
        System.out.println("My business object is a proxy.."
             + business.getClass().getName());
    }
}

Now what you get in output would make it more clear…I wont write it here, instead leave it as an exercise for you to find that fire any question you have for me…Hope you find it interesting as have I. cheers…bye.

When using joins(outer join fetch or join fetch) in HQL or when using Criteria… you may end up having duplicate objects in your result list. The way is simple to filter the results. Simply use a HashSet or LinkedHashSet or TreeSet

Example:

List list = session.session.getNamedQuery(“My.Named.Query.With.Joins”).list();
// you might have duplicates now
Set set = new HashSet(list);
list.clear();
list.addAll(set);
// no duplicates now

You might use LinkedHashSet or TreeSet if you really care about the order of results, else cheers – BYE.

Use the following targets to auto generate hibernate mapping files from database and pojos from .hbm.xml files.

<taskdef name=”hbm2java”
classname=”net.sf.hibernate.tool.hbm2java.Hbm2JavaTask”>
<classpath refid=”hbm2java.class.path” />
</taskdef>

<taskdef name=”middlegen” classname=”middlegen.MiddlegenTask”>
<classpath refid=”middlegen.class.path” />
</taskdef>

<target name=”hbm2java” description=”Generate Java Pojos from the Hibernate mapping files”>
<hbm2java output=”${source.generated}”
config=”hibernate.cfg.xml”>
<fileset dir=”${hibernate.source}”>
<include name=”**/*.hbm.xml” />
</fileset>
</hbm2java>
</target>

<target name=”middlegen” description=”Generate Hibernate mapping files”>
<middlegen appname=”Hibernate-Spring” prefsdir=”${middlegen.temp}”
gui=”false” databaseurl=”${jdbc.url}” driver=”${jdbc.driver}”
username=”${database.username}” password=”${database.password}”
schema=”${database.schema}” catalog=”${database.catalog}”>
<!– Optionally declare table elements –>
<!– Optionally declare many2many elements –>
<!– One or more plugins –>
<hibernate destination=”${source.generated}”
package=”${package.name}”
javaTypeMapper=”middlegen.plugins.hibernate.HibernateJavaTypeMapper” />
</middlegen>
</target>

Sample build.properties file

# MSJava, Hibernate, Middlegen
hibernate.home=C:/Hibernate/hibernate-2.1
hibernate.extensions.home=C:/Hibernate/hibernate-extensions-2.1.3
middlegen.home=C:/Hibernate/middlegen-2.1
middlegen.temp=C:/middlegen.temp

# Source Folders/Packages
source.generated=packages
hibernate.source=packages/java/test
package.name=java.test

# Database connection
jdbc.url=
jdbc.driver=
database.username=
database.password=
database.schema=
database.catalog=

I hope that helps, Cheers Bye

start stop tomcat with ant

Posted: May 5, 2008 in Technical
Tags: , , ,

Here is a simple ant target to start/stop your instance of tomcat running

<target name=”start-tomcat”>
<if>
<not>
<http url=”http://localhost:8080&#8243; />
</not>
<then>
<java jar=”${tomcat.home}/bin/bootstrap.jar” fork=”true”>
<jvmarg value=”-Dcatalina.home=${tomcat.home}” />
</java>
<echo message=”Server Started”></echo>
</then>
<else>
<echo message=”Tomcat Instance Already Running”></echo>
</else>
</if>
</target>

<target name=”stop-tomcat”>
<if>
<http url=”http://localhost:8080&#8243; />
<then>
<java jar=”${tomcat.home}/bin/bootstrap.jar” fork=”true”>
<jvmarg value=”-Dcatalina.home=${tomcat.home}” />
<arg line=”stop” />
</java>
<echo message=”Server Terminated”></echo>
</then>
<else>
<echo message=”No Tomcat Instance Running”></echo>
</else>
</if>
</target>

These targets would first check to see if any instance of tomcat is running or not else would initiate the process

Conditions:

  • your tomcat.home variable is set
  • server runs on localhost:8080

What is a Data Service

Posted: March 27, 2008 in Technical

A Data Service is about exposing data through Services. Data Services provides abstarcted and consolidated view of data between the consumer and diverse data source kinds. Data services are like virtual datasouces, consuming data from different sources and providing a complex view of data according to our needs. Data Services simplfies our data access by providing multiple ways of data access like web services, java clients, mediator api (SDO), etc. They once created are highly reusable across different applications. They highly simplfy the development process by eliminating the need to write any code but providing a graphical enviroment to generate the code.