{"id":68,"date":"2010-12-11T15:53:48","date_gmt":"2010-12-11T22:53:48","guid":{"rendered":"http:\/\/sloanseaman.com\/wordpress\/?page_id=68"},"modified":"2010-12-16T05:57:38","modified_gmt":"2010-12-16T12:57:38","slug":"jlockit","status":"publish","type":"page","link":"http:\/\/sloanseaman.com\/wordpress\/jlockit\/","title":{"rendered":"jLockit"},"content":{"rendered":"<p>jLockit is a small lightweight architecture for object locking in Java.  It allows developers to mark objects as being locked and then have their code check if the object is locked or not.  It also provides a small work flow engine that can plugs into your applications existing architecture so that code may or may not be executed based upon the lock status of some object.<\/p>\n<p\/>\njLockit is based on the EhCache caching system.  This is because EhCache can be plugged into Terracotta to provide a distributed cache which means that locks created in jLockit can be distributed among JVM&#8217;s for a distributed locking mechanism.<\/p>\n<p\/>\nI wrote jLockit because I&#8217;ve had a need for a locking architecture for so many different projects and I was always amazed that I could never find a small already thought-out locking system.<\/p>\n<p\/>\njLockit can be found on SourceForge at <A href=\"https:\/\/sourceforge.net\/projects\/jlockit\/\">https:\/\/sourceforge.net\/projects\/jlockit\/<\/a><\/p>\n<p\/>\n<h3>Making an object Lockable<\/h3>\n<p>To make an object lockable, have the object implement <code>ILockIdentifiable<\/code> and <code>ILock<\/code> like so:<\/p>\n<pre class=\"brush: java; light: false; title: ; wrap-lines: false; notranslate\" title=\"\">\r\npublic class Employee\r\n    implements ILockIdentifiable, ILock\r\n{\r\n    private long id;\r\n    private String firstName;\r\n    private String lastName;\r\n\r\n    public Employee() {}\r\n\r\n    public String getLockDescription() { return \u201cEmployee +firstName+\u201d \u201c+lastName; }\r\n    public String getLockKey() { return LockKeyUtil.generateDomainKey(this.getClass(), getId()); }\r\n    public ILockInfo getLockInfo() { return LockUtil.getLockInfo(this); }\r\n    public ILockInfo lock(String lockOwner) { return LockUtil.lock(this, lockOwner); }\r\n    public ILockInfo unlock() { return LockUtil.unlock(this); }\r\n}\r\n<\/pre>\n<p>As you can see, a <code>LockUtil<\/code> object exists to assist in the actual locking and status reporting of the lock.<br \/>\n<code>LockKeyUtil<\/code> exists to assist in the generation of keys to uniquely identify the object.<\/p>\n<p\/>\nThis framework lends itself to being placed in a parent object for code reusability like so:<\/p>\n<pre class=\"brush: java; light: false; title: ; wrap-lines: false; notranslate\" title=\"\">\r\npublic abstract class AbstractLockable\r\n    implements ILockIdentifiable, ILock\r\n{\r\n    public abstract long getId();\r\n\r\n    public String getLockKey() { return LockKeyUtil.generateDomainKey(this.getClass(), getId()); }\r\n    public ILockInfo getLockInfo() { return LockUtil.getLockInfo(this); }\r\n    public ILockInfo lock(String lockOwner) { return LockUtil.lock(this, lockOwner); }\r\n    public ILockInfo unlock() { return LockUtil.unlock(this); }\r\n}\r\n\r\npublic class Employee\r\n    extends AbstractLockable\r\n{\r\n    private long id;\r\n    private String firstName;\r\n    private String lastName;\r\n\r\n    public getLockDescription() { return \u201cEmployee +firstName+\u201d \u201c+lastName; }\r\n    public long getId() { return id; }\r\n}\r\n<\/pre>\n<p\/>\n<h3>Checking a Lock<\/h3>\n<p>Because the object encapsulates the locking we can easily check the lock status of an object by asking it if it is locked or not:<\/p>\n<pre class=\"brush: java; light: false; title: ; wrap-lines: false; notranslate\" title=\"\">\r\nif (employee.getLockInfo().isLocked())...\r\n<\/pre>\n<p>or, if you want to see if the person who owns the lock is the current user (a common check since you want that person to be able to operate against the object:<\/p>\n<pre class=\"brush: java; light: false; title: ; notranslate\" title=\"\">\r\nif (employee.getLockInfo().isMyLock(currentUser))...\r\n<\/pre>\n<p\/>\n<h3>Global locks<\/h3>\n<p>jLockit also supports the idea of Global locks.  A Global lock is a lock that is not specific to a specific instance of an object, but is more of a lock for more generic purposes (such as not allowing anyone else to do anything to a specific piece of the application while someone else is).<\/p>\n<p\/>\nGlobal locks work much like a regular lock except that you lock a singleton object.<\/p>\n<pre class=\"brush: java; light: false; title: ; wrap-lines: false; notranslate\" title=\"\">\r\npublic class NoOneCanEditEmployeesLock\r\n    extends GlobalLockAdapter\r\n{\r\n    private static final String DESC = \u201cEdit Employee\u201d;\r\n    \/* Make a single instance since it is supposed to be global *\/\r\n    private static final NoOneCanEditEmployeesLock INSTANCE =  new NoOneCanEditEmployeesLock();\r\n\r\n    private NoOneCanEditEmployeesLock() {}\r\n\r\n    public String getLockDescription() { return DESC; }\r\n\r\n    public static NoOneCanEditEmployeesLock getInstance() { return INSTANCE; }\r\n}\r\n\r\npublic class SomeBusinessLogic {\r\n    public void lockEmployeeEdits() {\r\n        NoOneCanEditEmployeesLock.getInstance().lock(\u201cGLOBAL\u201d);\r\n    }\r\n\r\n    public void editEmployee() {\r\n        \/\/ If it is locked, don\u2019t do anything\r\n        if (NoOneCanEditEmployeesLock.getInstance().getLockInfo().isLocked()) return;\r\n        \r\n        \/\/ do the edit \r\n    }\r\n}\r\n<\/pre>\n<p>If this method is a bit to &#8216;heavy&#8217; jLockit also provides a StringLockable object that allows locks based on simple strings.  The above, using StringLockable, could be implemented like so:<\/p>\n<pre class=\"brush: java; light: false; title: ; wrap-lines: false; notranslate\" title=\"\">\r\npublic class Constants {\r\n     public static final StringLockable LOCK_NO_EMPLOYEES = \r\n        new StringLockable(&quot;noEmployees&quot;, &quot;No Employees can be edited&quot;);\r\n}\r\npublic class SomeBusinessLogic {\r\n    public void lockEmployeeEdits() {\r\n        Constants.LOCK_NO_EMPLOYEES.lock(\u201cGLOBAL\u201d);\r\n    }\r\n\r\n    public void editEmployee() {\r\n        \/\/ If it is locked, don\u2019t do anything\r\n        if (Constants.LOCK_NO_EMPLOYEES.getLockInfo().isLocked()) return;\r\n        \r\n        \/\/ do the edit \r\n    }\r\n}\r\n<\/pre>\n<p\/>\n<h3>Work flow<\/h3>\n<p>jLockit comes with a work flow engine that allows developers to restrict code execution based upon object lock status. This piece is admittedly a bit more complex than the above code to allow maximum flexibility.<\/p>\n<p\/>\nThe work flow engine, <code>LockDispatcher<\/code> follows a event\/listener model for code execution. Let&#8217;s first look at how you could have some executable code be influenced by the lock state of an object:<\/p>\n<pre class=\"brush: java; light: false; title: ; wrap-lines: false; notranslate\" title=\"\">\r\npublic class MyObject {\r\n    implements ILockAcquireEventListener&lt;MyLockEvent, MyReturnObject&gt;\r\n    ILockExecutable&lt;MyLockEvent, MyReturnObject &gt;\r\n    ILockReleaseEventListener&lt;MyLockEvent, MyReturnObject&gt;\r\n\r\n    public boolean acquireLock(MyLockEvent _evt) {\r\n        \/\/some code to see if we can get the lock on the object like\r\n        String currentUser = _evt.getCurrentUser();\r\n        Employee employee = Session.get(_evt.getEmployeeId(), Employee.class);\r\n        \/\/ true if currentUser got the lock, false is someone owns it\r\n        return employee.lock(currentUser).isMyLock(currentUser); \r\n    }\r\n\r\n    public MyReturnObject handleAcquireLockFailure(MyLockEvent _evt) {\r\n        return new MyReturnObject(&quot;Employee &quot;+_evt.getEmployeeId()+&quot; already locked&quot;);\r\n    }\r\n\r\n    public MyReturnObject execute(MyLockEvent _evt) {\r\n        \/\/ do something like update the user\r\n        return MyReturnObject(&quot;Employee updated&quot;);;\r\n    }\r\n}\r\n<\/pre>\n<p>The code above, if called in the context of the work flow (more on that in a minute) would <code>execute()<\/code> only if a lock could be acquired on the Employee object.  This would be useful for something like only allowing one person to update a specific Employee record at one time.<\/p>\n<p\/>\nTo call the code under the work flow engine:<\/p>\n<pre class=\"brush: java; light: false; title: ; wrap-lines: false; notranslate\" title=\"\">\r\npublic class MyWorkflowSystem {\r\n    public void something() {\r\n        MyObject mo = new MyObject();\r\n        MyLockEvent le = new MyLockEvent();\r\n        le.setEmployeeId(someId);\r\n        le.setCurrentUser(currentUser);\r\n\r\n        LockEventContext&lt;MyLockEvent, MyReturnObject &gt; lec = new LockEventContext&lt;MyLockEvent, MyReturnObject&gt;();\r\n        lec.setExecutable(mo);\r\n        lec.setAcquireEventListener(mo);\r\n        MyReturnObject wasExecuteSuccessful = LockDispatcher.dispatchLockEvent(lec);\r\n    }\r\n}\r\n<\/pre>\n<p>The work flow and how is it implemented is discussed in much more detail in the documentation found at the SourceForge project page.<\/p>\n<p\/>\nRealistically your code would not be creating events and calling LockDispatcher every time but would instead be implemented in something like an Interceptor (in Struts 2) or some type of wrapper around calling code.  Doing something with Java Annotations would also be a very clean way of doing things (maybe in a future version of the library?)<\/p>\n","protected":false},"excerpt":{"rendered":"<p>jLockit is a small lightweight architecture for object locking in Java. It allows developers to mark objects as being locked and then have their code check if the object is locked or not. It also provides a small work flow &hellip; <a href=\"http:\/\/sloanseaman.com\/wordpress\/jlockit\/\">Continue reading <span class=\"meta-nav\">&rarr;<\/span><\/a><\/p>\n","protected":false},"author":1,"featured_media":0,"parent":0,"menu_order":0,"comment_status":"open","ping_status":"open","template":"","meta":[],"_links":{"self":[{"href":"http:\/\/sloanseaman.com\/wordpress\/wp-json\/wp\/v2\/pages\/68"}],"collection":[{"href":"http:\/\/sloanseaman.com\/wordpress\/wp-json\/wp\/v2\/pages"}],"about":[{"href":"http:\/\/sloanseaman.com\/wordpress\/wp-json\/wp\/v2\/types\/page"}],"author":[{"embeddable":true,"href":"http:\/\/sloanseaman.com\/wordpress\/wp-json\/wp\/v2\/users\/1"}],"replies":[{"embeddable":true,"href":"http:\/\/sloanseaman.com\/wordpress\/wp-json\/wp\/v2\/comments?post=68"}],"version-history":[{"count":17,"href":"http:\/\/sloanseaman.com\/wordpress\/wp-json\/wp\/v2\/pages\/68\/revisions"}],"predecessor-version":[{"id":91,"href":"http:\/\/sloanseaman.com\/wordpress\/wp-json\/wp\/v2\/pages\/68\/revisions\/91"}],"wp:attachment":[{"href":"http:\/\/sloanseaman.com\/wordpress\/wp-json\/wp\/v2\/media?parent=68"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}