Monthly Archives: July 2014

The ultimate idiot’s handbook for build obfuscation

Prologue

This piece is dedicated to those demented souls, who bungle around our industry. Their only aim is to to make life complex and difficult for their co-workers. They are the Rube Goldbergs of the software industry. They have taken obfuscation and unnecessary complexity to a kind of art form. I have encountered many such instances over the years. This particular case is particularly interesting, as I spent weeks understanding the process, deciphering the actual requirements, unraveling layers upon layers of redundant and complex logic to finally come up with a workable solution.

Problem

We were using Maven 2 for our builds. I wanted to upgrade that to Maven 3. The damn thing would fail saying:

It turns out that apart from the regular Maven pom.xml, we also use an Ant build.xml.

Analysis

I ran with -X, and predictably:

I upgraded the maven ant task version, maven ant run plugin, and all that. Still no luck. I googled a bit and gathered that Maven 3.x onwards, there has been a change in how Maven interacts with its artifacts. It is now done through Aether. So, thats the reason why the maven-ant-task is not working in Maven 3.

Working with Aether-Ant

I some how managed to modify my ant script to use the AetherAntTask instead of the MavenAntTask. Everything was hunky dory, the build went fine, generated the zip with all dependencies and life was good. Till I decided to actually deployed the build. And thank my lucky stars that I did it. Though the build went fine, the application wont start. Apparently Aether messed up with some Spring dependencies which we working fine with the earlier MavenAntTask. It turns out Aether is still bleeding edge.

Solution

I had actually given up. Then after a couple of weeks, I was thinking about this problem again, and I spotted something very odd. The overall interaction looked something like this:

Existing build flow
Existing build flow

I am outlining the steps below:

  1. The build is kicked off by Maven
  2. Maven does the compilation, and also builds the jar out of the project. After that, it invokes Ant’s build.xml through the MavenAntPlugin
  3. Ant needs to access the Maven dependencies.  It does this trough the MavenAntTask or the AetherAntTask. Thereafter, it zips all these dependencies into a single archive.
  4. Maven picks up this zipped archive from Ant and all is good

What is odd here, is the fact that Maven already knows its own dependencies. So, why does it need to outsource that to Ant? That, I thought was the real obfuscation. I modified the flow as below:

  1. The build is kicked off by Maven
  2. Maven does the compilation, and also builds the jar out of the project.
  3. Before calling the Ant’s build.xml, Maven copies all its dependencies to a predefined directory using the Application Assembler plugin
  4. After that, it invokes Ant’s build.xml through the MavenAntPlugin
  5. Ant does not need to know Maven dependencies, as its already copied in a predefined directory. Ant zips all these dependencies from the predefined directory into a single archive.
  6. Maven picks up this zipped archive from Ant and all is good

I modified my pom.xml and build.xml according to the new strategy, and all worked fine! I was finally able to migrate to Maven 3.

Simple ehCache Example

Problem Statement

I have a data provider (basically, system-of-record) which can return me a huge data set. What I want to do is, write these records in a cache, and then, return a set of records page-by-page from the cache. The cache here acts like a buffer to ensure that there is no strain on the memory. In the following example, I have just stopped short of the actual paging solution. Instead I have tried to illustrate how its possible using EhCache.

Maven Configuration

Just putting ehcache and slf4j should be good enough.

EhCache Configuration

The ehCache configuration file, my-demo-ehcache.xml in this case, looks like:

Getting a handle to the Cache

Note that we are loading the ehCache configuration file and then retrieving a cache named myCache1, which I had defined in the configuartion xml.

 Putting stuff into the cache

If you are planning to write this cache on a disk, then you need to make sure that the object that you are storing is Serializable.

Retrieving stuff from the cache

Resources

The sources for this can be found here: https://github.com/paawak/blog/tree/master/code/ehcache-simple

[Jaspersoft] Creating custom Spring managed DataSource

Problem Statement

Often for reporting, we need to gather data from many diverse resources. In case we are using Jaspersoft server, its sometimes not possible to manage with the existing DataSources provided by Jaspersoft. In this article, we will explore step by step how to write our custom DataSource. The main challenge is that in the given examples like the WebScraperDataSource, the factory beans are not Spring managed. They are instantiated by the framework through a no-argument constructor by reflection. In case I need to talk to other Spring managed beans, it becomes incredibly difficult. In the below example, I will try to put a hack so that we can use our own Spring managed DataSourceFactory.

Dev Environment Setup

I would need to hook into the Jaspersoft’s framework and for that, I need to create my own jar which can then be deployed into the WEB-INF/lib directory of Jaspersoft’s webapp. I am using Maven. The following dependencies need to be declared:

Note that some of these are not available in Maven public repos and need to manually deployed from the webapps/WEB-INF/lib directory:

Spring bean configuration

Jaspersoft works with Spring, thanks God for that!

jasper-bean-creation-sequence-1

jasper-bean-creation-sequence-2

Finally, this is what the Spring file looks like:

Information flow

jasper-flow-highlevel-1

 

jasper-flow-highlevel-2

Making our custom Query appear on the Jaspersoft

We need to make further configuration changes before our custom query appears on the Jaspersoft screen.

Make an entry in the applicationContext-rest-services.xml

Register your factory at WEB-INF/classes/jasperreports.properties

Make the following entry:

net.sf.jasperreports.query.executer.factory.SpringBeanQuery=com.swayam.demo.jasper.SpringBeanQueryExecutorFactory

Generate report

We are all set now to generate a report. Create the DataSource we have just now defined. Then create a JRXML and define the query there:

Link the DataSource and the JRXML. You need to define an Input as well. Then run the report. You should see the below report:

generated-reportResources

The sources for this can be found here: https://github.com/paawak/blog/tree/master/code/jasper/custom-datasource

 

Demystifying JINI: Non-Secure Server: Part 2

In Part 1, we had sieved through the example available on the JINI site and distilled the Rmi client server code to the bare minimum. But still, its far from production ready. Its not Spring-ified yet. Lets try to do that here. We will build this on top of Part 1.

Server

I need the following utility which can double up as a Spring bean, will do the export for me.

This is the main Spring configuration:

And, see how simple my main class has become, just loads the Spring file:

Client

The client is a bit tricky, as I need to lookup the remote service from the registry. In Spring’s nomenclature, this is nothing but a FactoryBean.

The Spring configuration is:

And this is the way we can use it.

Resources

The code can be found in GitHub, under the code/jini/unsecure/plain:

https://github.com/paawak/blog.git