Archive for the ‘Software’ Category

Creating Transactional Proxy Classes

Saturday, July 10th, 2010

One of the frequent patterns I make use of for Java backend systems are transactional code blocks, and not transactional in the sense of JPA, Hibernate, Databases, etc. I mean generic transactional blocks in which you have to wrap a piece of code with a begin and end block. For example, JPA is just one style in which you invoke:

try {
    em.getTransaction().begin();
    // invoke code
} finally {
    em.getTransaction().end();
}

Another common example is using pools in which you must borrow and return objects such as:

Object data = null;
try {
    data = pool.borrowObject();
    // do something
} finally {
    pool.returnObject(data);
}

These are just common examples. Often times, I have my own type of transactional block that references some other type of system that must maintain a begin and end state. However, even as simple as

try { begin(); } finally { end(); }

is, it can easily be screwed up. For example, a common mistake is forgetting to put the end() in a finally block to ensure it runs. Further, it violates the DRY (don’t repeat yourself) principle such that if you need to change the processing a bit, you would need to change every invocation of begin/end. That creates a possible maintenance issue.

So, how do we avoid using transactional blocks? The easiest solution is something that most modern libraries such as Spring or Java EE already do, which is creating proxy classes to invoke the blocks automatically. If you are already using Spring or Java EE, you prolly already do this with the @Transactional annotation. However, this post will help demonstrate a simple and easy method of achieving this same behavior for custom transactional blocks.

The first step is creating a marker annotation that will be used on classes and methods to denote a transactional block of code. For example:

@Retention(RetentionPolicy.RUNTIME)
@Target({ElementType.TYPE, ElementType.METHOD})
public static @interface Transactional {
    // annotation specific values
}

This annotation allows us to mark either a class or a method. This is basically what the Spring/Java EE Transactional annotation does. The next thing we need to do is actually mark methods as transactional. We can do this either at the class level meaning every method in the class will be transactional or at the method level. The choice is completely a personal preference. However, if you mark the class, then you can ensure that every method will be transactional even if you add a new method. That will help reduce the accidental likelihood of adding a new method but forgetting the transaction annotation. However, if you do not want certain methods to be wrapped in a transactional block, then you will need to annotate at the method level one by one. Here is an example:

@Transactional
public class Test1 {
     public void method1() {
          // this will be invoked in transactional block
     }
 
     public void method2() {
          // so will this
     }
}
 
public class Test2 {
     public void method3() {
          // this will not be transactional
     }
 
     @Transactional
     public void method4() {
          // but this will
     }
}

Now that we have our transactional code we need to create proxy classes to automatically wrap the code. My preferred way of achieving this and the purpose of this blog is to use CGLIB proxy classes. There are several other ways to achieve such as AspectJ. I will leave learning those ways to the reader. Anyways, back to CGLIB. CGLIB provides a proxy creation class called Enhancer. It is very similar to the Proxy class in the standard Java reflection package. However, there is one major difference. The standard Java Proxy class may only use and proxy interfaces, not concrete classes. Enhancer and CGLIB can proxy concrete classes. It is concrete classes that are essential so that we can proxy our existing classes and wrap the methods in transactional code block. Before we can use CGLIB, we must add it to our classpath. The version I am actively using is 2.1_3. You can either download the JARs directly or use the following Maven dependency:

<![CDATA[
        <dependency>
            <groupId>cglib</groupId>
            <artifactId>cglib</artifactId>
            <version>2.1_3</version>
        </dependency>
]]>

Once you have added CGLIB, here is the basic way of creating those blocks:

public class Transactions {
        @SuppressWarnings("unchecked")
        public static <T> T proxy(final T object) {
            // check if transactional specified at class level of class or 
            // any parent classes or interfaces
            boolean isTransactional = false;
            Class<?> parent = object.getClass();
            while (!isTransactional && parent != null) {
                if (parent.getAnnotation(Transactional.class) != null) {
                    isTransactional = true;
                }
 
                for (Class<?> ifclass : parent.getInterfaces()) {
                    Class<?> ifparent = ifclass;
                    while (!isTransactional && ifparent != null) {
                        if (ifparent.getAnnotation(Transactional.class) != null) {
                            isTransactional = true;
                        }
 
                        ifparent = ifparent.getSuperclass();
                    }
                }
 
                parent = parent.getSuperclass();
            }
 
            // create proxy class from concrete class
            final boolean transactional = isTransactional;
            return (T) Enhancer.create(object.getClass(),
                new InvocationHandler() {
                    @Override
                    public Object invoke(Object proxy, Method method, Object[] args)
                        throws Throwable {
 
                        // check if transactional at class level or if current method
                        // is transactional.  Note that this ignore overrides.  You
                        // may want to extend this to search for all subclasses and
                        // interfaces defining the method and check those annotatations
                        // as well
                        if (transactional ||
                            method.getAnnotation(Transactional.class) != null) {
                            try {
                                // start transaction block
                                // this could be anything you needed to do such as borrow
                                // from a pool, etc
                                Transactions.begin();
 
                                // invoke method and return its value if provided
                                return method.invoke(object, args);
                            } finally {
                                // finalize the block
                                // this should be the corresponding end block to the begin block
                                Transactions.end();
                            }
                        }
 
                        // not transactional, so invoke as normal
                        else {
                            return method.invoke(object, args);
                        }
                    }
                });
        }
}

Now that we have that code in place, we can create proxy classes and invoke the methods without worrying about the transactional blocks. Going back to our initial test class, we could invoke via:

    Test1 test = Transactions.proxy(new Test1());
    test.method2(); // this will be invoked in a transactional block

That’s all there is to it.

Simple Performance Improvement with Large Ehcache Disk Store Data Sets

Thursday, April 29th, 2010

One of my applications has several millions cacheable entries.  In order to cache as much as possible without going back to the database I use both a  memory store and a disk store in my Ehcache configuration.  Loading a serialized item from disk is still faster than loading from a database generally.  That being said I was running into performance issues due to the constant reads and writes to and from the disk store.   Due to the serialized nature of the data file it would block on subsequent accesses resulting in lag and performance issues.  So, how did I address it?  I decided to partition the single cache into multiple caches.  So, rather than using something like:

ehcache.getRegion(CONSTANT).get(id);

I now use:

ehcache.getRegion(CONSTANT + (id % 10));

I now have 10 different cache regions resulting in less concurrent access and better performance.  A very simple trick when you have extremely large data sets.  Remember, partitioning is always your friend regardless of what type of data you use.

UPDATE: This is being done in Ehcache 1.5.0…I understand there are better improvements in Ehcache 2.x, so please consult the documentation for more information.

RSS Viewer: Down for Maintenance

Thursday, April 22nd, 2010

Unfortunately, we have filled out disk space to capacity and will need to take some time to clean things up.  We apologize for the inconvenience.

RSS Viewer: Where We Stand

Wednesday, April 21st, 2010

I have not posted an update for a while, so here is where things stand.  We were planning on release version 2.0 last month, but we decided it was in the best interest to fix the scalability issues.  We are finalizing those issues this week hopefully.  These updates on the server side should result in more frequent crawling of feeds resulting in faster notifications.  We are also working on the notification engine to push notifications faster and ensure delivery of those notifications.  Finally, downloading content from the server via the app should be much faster resulting in improved usage of the app.  Once we release those updates on the server side, we will follow with the launch of our 2.0 version.  Stay tuned for more information as we work through this.  Once again, thanks for everyone’s continued support and we apologize for any issues over the past few months.

Thanks,

Nicholas Hagen

RSS Viewer: Upcoming Maintenance Tonite [Complete]

Wednesday, February 17th, 2010

[Updated Feb 19, 2010 6:48 AM EST] We apologize for the extra downtime.  Everything should be back up.  Let us know if you see any issues.  We hope to get our 2.0 testing started this weekend.  Note that we still have room for testers, so email us to get on board.

—–

[Updated Feb 18, 2010 8:30 AM EST] Unfortunately our update process did not go as smooth as we hoped so things are taking longer to resolve.  We hope to be back up by mid day.  Thanks for your continued patience.

—–

[Updated Feb 17, 2010 11:30 PM EST] RSS Viewer is now down through the nite for updates

—–

RSS Viewer will be going down for maintenance tonite at 11 PM EST in order to begin transitioning to our next release set to begin alpha testing this weekend.  We plan to be down all nite migrating everything over.  All access including logging into RSS Viewer will be unavailable.  We will update this blog and our twitter account when the maintenance starts and completes.

If you are interested in alpha/beta testing and have not yet replied, please send an email to info@znetdevelopment.com.  We still have spots available.

Thanks,

Nicholas Hagen

RSS Viewer 2.0 Status

Tuesday, February 2nd, 2010

As many of you know we were trying to get our 2.0 release out by end of January.  Unfortunately, that date has passed, but we are still hard at work trying to tie up the final loose ends of the release.  All of our planned features have been implemented and we are just cleaning up and trying to get everything nice and polished.  We want to ensure a great experience when we release our update, so continue to bear with us.

That being said, we will be looking for beta testers in the upcoming weeks to help us test this release to ensure we meet that great experience.  If you are interested in helping us out, send us an email at info@znetdevelopment.com with your registered email address.  Note that you must not be using a jailbroken device to participate in the beta program.  Unfortunately, we will only be selecting a few users.  In particular we are looking for users who want to test out the following:

  • Google Reader synchronization
  • Friends and sharing items
  • Authenticated Feeds
  • UTF-8 and International Support

Thanks again for everyone’s continued patience.

Next RSS Viewer Update Status

Friday, January 15th, 2010

Several people have asked when the next version of RSS Viewer will be coming.  Here is an update to that question as well as a list of some of the more prominent features.  We are currently trying to release a version to Apple by the end of January.  The following features are some of the highlights for this release:

  • Google Reader support including synchronization of feeds in both directions and synchronization of read/unread status
  • True read/unread status of articles
  • Authentication support for basic and digest authentication modes
  • Privacy settings to restrict feeds from showing up in popular feeds or in searches
  • Friends support to quickly share articles with friends as well as view your friends favorite feeds
  • Unicode and better international support
  • Notification specific settings per feed including customized sounds and interval

We are also improving performance and several bug fixes.

Thanks,

Nicholas Hagen

RSS Viewer Maintenance Outage (Nov 16) [Updated]

Friday, November 13th, 2009

[Update 1:15 AM]  We are back online and everything looks good.  Let us know if you see any issues.

RSS Viewer will be having a maintenance outage on Monday,  Nov 16 at 12:30 AM.  The outage should only last 1-2 hours at which point all services will be unavailable.  We are further expanding our capacity to provide faster updates once again.

Thanks

RSS Viewer: Quick Maintenance [Resolved]

Wednesday, October 21st, 2009

Everything is back up again.  There was an intermittent issue with accounts not creating properly.  The issue has been addressed and everything should be functional again.  If you notice any issues, drop us a note so we can help resolve it quickly.

We will be down for a quick maintenance at 1:00 AM EST.  We should be back up within 15-30 minutes.

20,000+ Push Notifications per Day

Wednesday, October 21st, 2009

Thank you to everyone who has purchased our application and stayed with us as we continue to improve upon things.  We are now averaging about 20,000+ push notifications per day and only expect that number to climb more and more.  We have much more in store over the coming months and hope you continue to stay with us as we improve our application and systems each day.