Open Source “Duke Nukem Forever”

One of my favorite games of all time, Duke Nukem 3D had me waiting “forever”, for DNF (Duke Nukem Forever). Then in May 2009 the wait finally ended, when the DNF team got axed. And the game was then kicked into the back burner of Apogee. I think the fans of Duke deserve better, we waited 13 years for the game and in the end it was all in vein.

I think it is time to make DNF Open Source and let the community and fans develop it, and I am pretty sure it won’t take that long for the game to be completed. The Open Source guys have done it in the past by developing the High Resolution Pack for Duke Nukem 3D, and I am sure they can do it again.

I’ll end this entry with my favorite dialog from DN3D: “it’s time to kick ass and chew bubble gum, and I’m all outta gum.”

Cyber Sanctions: “Freedom” the American way

US government has recently asked Sourceforge to deny content to certain countries, including Cuba, Iran, North Korea, Syria and Sudan. This means that users in these countries trying to post or access content on Sourceforge will get a big 403 error. Here is what Sourceforge is saying about it, although not happy but they don’t seem to have a choice:

Since 2003, the SourceForge.net Terms and Conditions of Use have prohibited certain persons from receiving services pursuant to U.S. laws, including, without limitations, the Denied Persons List and the Entity List, and other lists issued by the U.S. Department of Commerce, Bureau of Industry and Security. The specific list of sanctions that affect our users concern the transfer and export of certain technology to foreign persons and governments on the sanctions list. This means users residing in countries on the United States Office of Foreign Assets Control (OFAC) sanction list, including Cuba, Iran, North Korea, Sudan, and Syria, may not post content to, or access content available through, SourceForge.net. Last week, SourceForge.net began automatic blocking of certain IP addresses to enforce those conditions of use.

This move will only divide the open source community and will not achieve anything. There are other ways to access content through mirrors and other project hosts; and people will be forced to use anonymizers etc. to hide their identity. But will the US government stop Microsoft, Apple etc. to sell their applications to businesses in these countries? I doubt that. So why target Open Source alone? And what is next? denying free email and web hosting services?

On a more serious note, we all know that most of the affected countries are poor and belong to the third world, so it will just push the users towards piracy. It also means that Internet and WWW are still not global and have a lot of American influence. The US seem to have their own definition of freedom, which just serves the US interests with hypocrisy written all over it. On one side US is trying to battle the Chinese censorship on Google and on the other hand they are doing the same thing by denying people services, which are licensed to be free for all.

Log4J: Emailing specific errors only

Log4J’s SMTPAppender provides enough basic functionality to send out error messages as emails. Although emailing error messages is not always a good idea, unless something really goes wrong in system. Sometimes it is required to send out only specific errors in specific areas of the system. It is possible to do that with the SMTPAppender, even if these specific errors lie in the same category(WARN, ERROR etc.) as other errors. This is achieved with TriggeringEventEvaluator. Here is a sample config for the SMTPAppender.

The parameter EvaluatorClass is where we specify the implementation of TriggeringEventEvaluator, which acts like a filter to allow emailing only specific errors:

Now only ERRORs from “SomeSeriousErrorLogger” will be emailed.

Merging arrays in Java

I was playing around with java arrays and ran into a problem where I wanted to merge smaller arrays into a single big array. So the first thing I thought was to make a new array of size equal to the total length of all smaller arrays and then populating the values using loops. Then I went on to make a generic method to merge Generic arrays of same type but I realized that I cannot create a Generic array. So I thought of another way to merge Generic arrays using List.

This code here will merge any number of generic arrays into one single array. The last line gives an unchecked cast warning, but can be ignored because we already assumed that the arrays are of same type.

Resolving log4j.dtd error on JBoss

I recently faced an issue where the application was not able to find the log4j.dtd, when deployed on jboss. We were using our own repository selector for logging and an isolated classloader. But could see a “FileNotFoundException” for log4j.dtd in the JBoss log when the application was deployed, although the dtd was part of the log4j jar contained within the application. The reason for that was the xml parser was not looking in the classpath resources for the dtd, but was just looking in a path relative to the application’s root directory.

Now in order to load the dtd from the classpath I updated the repository selector and set an EntityResolver to the DocumentBuilder so that when the parser encounters the dtd reference the resolver looks it up from the classpath. Here is the code to that.

Assuming that the doctype reference in log4j.xml is:

The code to override the default behavior of the parser to look for the dtd in the classpath:

Now our EntityResolver will return the dtd from classpath whenever the parser encounters it. Although I wish the parser could support the “classpath” protocol in the doctype uri.

Guice and JMX on JBoss

It is very easy to use Guice’s runtime injector bindings to register MBeans on any instance of mbean server. Lets look at a simple example of a HelloMBean. In this example a simple MBean is created and registered on JBoss using google-guice runtime injection.

The implementation of this MBean needs to have a method for the injection of the MBeanServer.

Now all that needs to be done is creating an Injector with bean and server bindings. The following piece of code can be used in any class (like a Servlet) to register the MBean when the application is deployed or as part of your injection bootstrap.

You can also use “ManagementFactory.getPlatformMBeanServer()” to get/create an MBeanServer. Unfortunately this method cannot be used to get/locate the current JBoss MBeanServer, so “MBeanServerLocator” in the last code snippet above is the only way to locate a JBoss MBean Server instance. After the bean is registered you can use jboss jmx-console or jdk’s jconsole to access the mbean.

RegEx based Spring AOP auto-proxy creator

When using Spring AOP in a medium-large application to add behavior to objects using crosscutting, it is desirable to have auto-proxy creators rather then creating a proxy for each bean (Spring AOP is proxy based). When auto-proxying a subset of beans, BeanNameAutoProxyCreator is most commonly used. But it has certain limitations, you have to provide a whole list of beanNames, which in a fairly large application becomes cumbersome and sometimes hard to maintain. Now because the application we were using had fairly well categorized beans with similar IDs, it was convenient to use a pattern or regular expression to identify them, but BeanNameAutoProxyCreator doesn’t support regular expressions. So I extended the BeanNameAutoProxyCreator to provide regular expression support.

This auto-proxy creator takes a regular expression and matches all the beans available in the Spring Application Context to create implicit runtime proxies for the matched beans. The bean definition for RegExpBeanNameAutoProxyCreator is similar to BeanNameAutoProxyCreator but it takes a “pattern” rather then the “beanNames”.

Here the “pattern” property takes the regular expression to match the beans available in spring context. It is pretty handy if you don’t want to put the whole list of beanNames here; you can also use this to exclude beans as illustrated by the regular expression in this example.

Handling DWR Session timeouts

I recently had an issue in an application using Acegi and DWR, where even after the session invalidation the DWR calls could still be made. It seemed DWR calls were ignoring session timeouts. In order to over come this issue I wrote a little Ajax filter to check for session invalidation for DWR calls and throw an Exception if session has timed out. Throwing exception is more of a natural way of handling such scenarios then sending “plain/text” messages as recommended in DWR 2 API.

Then attach this filter with DWR bean:

In version 3.0RC-2 or later it is possible to have a global filter (<dwr:global-filter>) that can be used by all DWR beans.

Now after this all you need to do is catch the thrown LoginRequiredException on the client side.

Here reloading the page was helpful because we were using Acegi (now known as spring security) and we had the FilterSecurityInterceptor setup to take care of the request. DWR guys also recommend something similar but that requires reverse Ajax and it also is not a natural way of handling this.

In Acegi it is also possible to have method-level role-based authorization for DWR calls using the MethodSecurityInterceptor. I will try to explain that in the next blog entry.

XML Serialization of Java Objects

Sometimes it is necessary to stream objects in a standard way like XML or JSON. There are different ways of doing so. Below I will take an example of XStream to illustrate how Java Objects can be serialized into XML.

XStream
is an open source, a very light weight and easy to use API to Serialize Java Objects into XML and back. Below is a simple example:

The above code will serialize the object of type Person to the following XML. There are other toXML(..) methods available to write the XML to a Writer and OutputStream.

The above XML can be deserialized back to the Java object. The following fromXML(..) method is overloaded, see the API for more details.

Another approach is using JAXB, a Java-XML binding API. JAXB uses XML Schemas to generate Java classes; the objects of these generated artifacts can then be serialized to XML.

Deep cloning of Serializable objects

The following code snippet shows how to use Object I/O streams to deep clone Serializable objects. The object bytes once written on an ObjectOutputStream can be read back to a new object with all the populated values intact. The only catch is that, because the object is written and then read from a stream, this process is slower then the normal getter-setter approach.

Fork me on GitHub