Wednesday, December 26, 2012

Did you noticed Spring Loaded is here?

Well... I didn't! Not for almost a whole month! And it's the best damn thing ever!

Here's how you use it:
MAVEN_OPTS="-javaagent:/path/to/springloaded.jar -noverify" mvn tomcat:run
Next you open Eclipse, do changes, reload pages - all changes occur immediately! Sure you can't add new Spring artifacts (which is odd), change class hierarchy (no surprise there) but you can add/remove methods which is more that what you had before.

Well - it isn't JRebel - but it is good enough!

Have fun!

Monday, December 10, 2012

Named inner classes in methods

Do you know the feeling when you write something that should totally be wrong and it turns out perfectly ok? Well that's what I just experienced: A "WTF?! This is really cool" moment. What gives?

I've been entertaining myself with a little bit of Spring Data exercise. Trying to understand how much will I gain from using JdbcTemplate I dug a little into the sources of that class. At one point I saw that there's a named class (not an anonymous one) declared inside a method. WTF?

I know if I say it like that it is kind of lame of me not to know this. But this is such a nice feature I can't really understand why it's being used so rarely...
public String getName(String user) {
    JdbcTemplate template = new JdbcTemplate(this.datasource);

    class NameExtractor implements ResultSetExtractor {
        @Override
        public String extractData(ResultSet rs) 
            throws SQLException, DataAccessException {
            return rs.getString("firstName") + " " + rs.getString("lastName");
        }
    }

    return template.query("SELECT * FROM users WHERE id=1", new NameExtractor());
}
I know there's like a ton of different ways of writing that code but I have chosen this simple example to show you (and me in a couple of weeks maybe) that inner classes don't need to be defined on class levels.

Have fun!

Thursday, November 22, 2012

Who cares?!

Seriously, who cares? Who cares how HashMap or Hashtable is implemented? Or maybe an ArrayList, ha? How about DynaBlasterRollerCoster? Do you care how it's doing what it's doing?

I just got off a phone interview with some guys in the UK but the same thing was happening in other places. Do you really need to know this? And if so is this ever going to impact the way you design a distributed, highly scalable system if all you know is how to implement a HashMap on your own?

Seriously, we're past that point where we need to manufacture our own specialized collections (even though the Java Collection API sucks big time). Get over it! Maybe when I'll switch back to Microchip MCUs I'll look back to find out how to implement a dictionary then. Oh wait! It's implemented in SDCC already! And I bet there's a pure asm library doing this on Z80 as well.

And if there ain't one laying around there's this thing called Google, with this little box and a "Search" button (hell, these days you don't even have to press this key anymore) that will tell you what you're after

Edit 25.11, 05:17, on the airport: I wonder if the next question (since they asked me if I feel like a polyglot programmer) would be So how's implemented a Hash in Ruby and how does it compare to the inner workings of Dictionary in .NET?. Why not, right?

I just needed to get this out of my system...

Wednesday, November 21, 2012

Simple and effective: Spring and customizable configuration

The problem

The problem is to have the configuration customization possible after deployment. There are settings your hosting department for whatever reason will not let you know (like database password for instance). This fits really nicely to the ways Spring handles configuration.

The solution

The solution in Spring 3.1.x is to use the <context:property-placeholder> tag configured as follows:
    <context:property-placeholder 
     system-properties-mode="OVERRIDE"
     ignore-resource-not-found="true"
     location="
      classpath:defaults.properties,
      file:${config.location:/etc/example.properties}" />

The explanation

First of all there have to be sensible defaults the application can work with. I personally favor them to be good for development so other developers can just get the application, execute mvn tomcat7:run and have it running in minutes rather than to fiddle with all the moving parts of configuration.
Now deployment and the hosting team is a totally different beast all together. They will always want to have things configured their way. <joke>I don't know why :)</joke>

So here we have it - on the classpath there are the defaults in defaults.properties. Now the second part is interesting. First of all it makes an assumption that hosting will follow the best practices and store configuration where it belongs, which in almost all Linux distros is the /etc/ folder. Here's the trick though: some admins will cut your fingers an inch shorter if you force them to put anything anywhere. Especially for that occasion the second option is there to save the day. It allows you to specify a JVM parameter -Dconfig.location=... for Spring to look for configuration options in a completely different place. Neat, ain't it? Finally the system-properties-mode="OVERRIDE" allows for in-place overrides using JVM system variables (the ones specified with -Dvariable=value)

I hope it'll save someone some precious time. I know it'll save me from re-inventing this solution time and time again.

Sunday, October 28, 2012

Revisions

Back in the days when I switched over from Delphi (the day that Delphi died) I felt the overwhelming amount of frameworks for pretty much everything was giving me a headache. And I think everyone out there will agree with me. Hibernate, Spring MVC, Spring Integration, Spring Data, Spring Mobile, Spring WS, Spring Batch, Hazelcast, EhCache, C3P0, a whole range of Apache Commons - just to name a few prominent ones. Oh boy can this be a pain in the royal butt to learn all of them. An then there's the ever changing world we live in where new versions of open source frameworks come out like crazy. Pretty much a 100 times a year one can get something new to learn, try out, fiddle with, get angry with or embrace.

When I first started using Spring all it was for me was the dependency injection framework with stupid XML config and training that takes forever, costs a fortune and makes no sense. Remember, I came from a world where documentation was pristine (for both Turbo Pascal and Delphi), examples came in spades and the classes started with a T and all interfaces with I. All the separation of concern, testability and other ilities were not so needed in the Delphi world. Also inheritance was in the zone (now we all know it's bad and should be avoided). With Java everything was different and I felt lost.

I turned my attention to something I though would be a little bit more familiar - the .NET framework and C# language. Oh boy was I happy to see the notion of properties built into the language (so missed in Java). I though I've had the world by the balls with this one: modern platform, fantastic language (created by the same guy who created Pascal and Delphi) so I was right at home.

At that time job opportunities for C# web application developers were scarce and so I was sort of forced to stay with Java. At first I hated it with a passion (http://www.ihatejsf.com). In the mean time along came Guice and showed me why dependency injection makes sense and how to do it right. After some time I learned to live with it mostly because I discovered that there's more to it that meets the eye. Basically I learned about Groovy and Grails. That was the sweet spot for me: elegant and dynamic language, similar to Java but oh so much more powerful and a framework that finally doesn't suck like JSF did. That was the best time ever!

With time wisdom came and I started looking around what else can be done with this thing. That was the time when JavaEE 6 came out with Glassfish 3 (man you really have got to love something that's called Glassfish, don't you?). Finally all the stupid things like web.xml went away, web services creation started to be a breeze and all was cool again. Then I leared about EJB3 and all that comes with it. Can't say I was happy with what I saw after living on Grails, Guice and Spring for a while.

Now it's years later. I'd describe myself as TDD junkie with a healthy dose of polyglot programming skills. I've learned a great deal about the so called Spring programming model. I've learned a lot about Spring and the modules it brings to the fold. I learned not to hate XML. I've learned Ruby and got acquainted with Sinatra. Every day is a new challenge and every day I learn more. The more I learn the less I write and the more I integrate.

During all that time there has been only one constant: Internet. All I know, all I ever learned beyond the 6502 assembler, 68k assembler, Pascal, Turbo Vision, Delphi and VCL (which I learned ages ago from dead-tree books) came from the Internet. This is the best, most demanding and absolutely the most rewarding university in the world. All this because of open source projects and awesome communities that make the world go around these days.

It's a beautiful time to be a programmer!

Do we really need another build tool?

Recently I've been getting to know Maven a little bit better. Underneath all the XML fuzz there's a really good, well designed and extremely modular application that does pretty much everything one can ask for (and then some).

With Maven things are simple: bloated XML contains every possible setting for every possible plugin, every possible dependency and what have you. You might hate the fact that it is XML. I say screw it - let's try to live with it.

On many occasions the XML nature has been the corner stone for many people to start developing their own build tools. I'd say their repulsion came from Ant and if so it wasn't totally unjustified. I hate Ant with a passion when it comes to building Java projects. Ant is great for cross-platform imperative tasks (download this, unzip, make a link, go get coffee) but Java projects are a completely different beast. It's not that you can't do it with Ant but rather that it takes forever to do everything (not to mention that everyone is doing it differently).

Like I said people's repulsion to XML configuration files pushed some of them into the hands of Groovy (my absolutely favorite language) to create Gradle. One of my very good friends, Szczepan Faber, works on this tool and I am grateful for his efforts. It makes the landscape of build tools a lot more interesting. It's from diversity that the progress comes in this case.

Being all Groovy geek and loving the language and what one can do with it I must say I am a little bit confused as to why I'd use Gradle. I mean I get that the build file is terse, that the default source/target compiler makes more sense, that I can declare 10 dependencies in one line... But what about plugin support?

From my personal perspective the idea of creating a new tool from scratch is pure nonsense. Maven is the de-factor standard in Java world and not without reason. It does what it does and does it good. Where Maven lacks in features is imperative programming but that can easily be overcome with either custom Maven plugins or GMaven plugin. For me it'd make a lot more sense if Gradle adopted the Maven API for plugins and build on that to gain the much needed functionality into the fold before it is missing.

Like I said before, I get that one can feel intimidated by all the XML in Maven builds. I get that one can mess things up with Maven really bad. I also get that Gradle, Buildr and others might be better in some cases. What I hate about the overall landscape is that the plugins for build systems aren't compatible and even if I'd like to use Gradle to build my next gen rocking cool enterprise java application I'd dead in the water pretty soon because the EAR/EJB archive support in Gradle is non-existent. I hope this changes some day...

Have a nice day!

Tomcat Clustering and a pile of problems

I've been trying to familiarize myself with Tomcat's clustering capabilities today. At the end of it I succeeded but the experience was way less than pleasant. But let's start from the beginning...

At first all seemed really nice: Sunday afternoon, not much to do, some thoughts around playing with Tomcat for the sake of finding out what it's capable of.. Basically the idyll. So I though wouldn't it be nice if I learned how to setup a Tomcat cluster? I already done some horrible things to Tomcat in the past (Single Sing On for instance) but I've never tried clustering. How about that? And so I started what anybody would do - to read the configuration files. No - I'm kidding :) I started to Google for some clustering HOWTO to see if I'm alone in what I'm trying to accomplish. Fortunately it turned out to be a pretty well described topic with some ready-to-copy-and-paste examples. Highly encouraged by what I found myself copying parts of what I found in that miserable HOWTO into configuration of my 2 Tomcats that are supposed to form "the cluster". After about 2 minutes of frantic alt-tabbing, CTRL+C/CTRL+V-ing I arrived at the glamorous point where I was able to start at least one of the Tomcat's to see if the configuration even allows to the server to start. Well, it started, all right. But it didn't work.
Oct 28, 2012 5:14:09 PM org.apache.catalina.ha.deploy.FarmWarDeployer start
SEVERE: FarmWarDeployer can only work as host cluster subelement!
Oh what the heck is this? I though.Wasn't the example from original documentation? I was always banking on those to be really of good quality and now this dissapointment? There's a number of things wrong with the example (and as it turned out with the original server.xml as well). But let's start from the beginning.

server.xml and it's comments

There is a dark place in server.xml that shows how to configure a cluster in Tomcat.
      <!--For clustering, please take a look at documentation at:
          /docs/cluster-howto.html  (simple how to)
          /docs/config/cluster.html (reference documentation) -->
      <!-- <Cluster className="org.apache.catalina.ha.tcp.SimpleTcpCluster"/> -->
So I removed the comment in two instances but it turned out not to be what I expected. Well it did something (not sure what exactly) but it wasn't all that inspiring. There is however a reference to further documentation. I followed that and then the frantic copy/paste activity started. All was quite nice up until I started Tomcat and saw the SEVERE I mentioned before. Back to Google. And then some. Finally I arrived at this discussion where I learned that the <Cluster> element is supposed to be nested within the <Host> element and not where it was suggested by the original server.xml file. Go figure. Anyways, I moved the section down to the Host and this time
Oct 28, 2012 5:01:34 PM org.apache.catalina.ha.deploy.FarmWarDeployer start
INFO: Cluster FarmWarDeployer started.
Great Scott! It will work now! And so I copied my beloved distributable, servlet-api-3.0-enabled hello.war into the /tmp/war-listen folder hoping to see Tomcat spring to work, install the application and make my day. But nothing happened! The example in Tomcat documentation specifies watchEnable="false" by default. What was going through the mind of that someone who wrote it is beyond my understanding of the universe. Anyways, after I changed it to true finally something started to happen.

Since Tomcat ain't for the faint-hearted I was presented with a puzzle:
Oct 28, 2012 5:29:36 PM org.apache.catalina.ha.deploy.FarmWarDeployer fileModified
INFO: Installing webapp [/hello] from [/tmp/war-deploy1/hello.war]
Oct 28, 2012 5:29:36 PM org.apache.catalina.ha.deploy.FarmWarDeployer remove
INFO: Cluster wide remove of web app [/hello]
What the heck? Cluster wide what? I just installed this application, didn't I? I mean thought it will be enough to copy the file in the proper folder and that should be it, should it not?

As it turns out it does work quite nicely if you specify the deployDir to where Tomcat expects to auto deploy applications (by default webapps, or rather ${catalina.base}/webapps). After I changed that, copied the Cluster configuration to the second Tomcat, started both and copied the hello.war application to /tmp/war-listen both Tomcats have received the proper nourishment and started talking my language.

Summary

There's a number of lessons learned from this encounter. First and foremost Tomcat is just awesome. It's so unbelievably small yet so feature-packed. It just makes my day. While debugging Tomcat configuration issues it really helps to start it (at least under Linux) not by ./startup.sh but ./catalina.sh run. This way you'll have the console to view the logs and to terminate it all in case you're not happy with what you see. And last but not least: Google is your friend. I mean it. It is the one thing all this could not be possible without in terms of knowledge sharing.

Have a nice day!

Maven and Tomcat 7

You might be unaware of this but Maven is capable of running Tomcat 7 as embedded container. The maven-tomcat-plugin has been moved under the Apache Foundation umbrella and is being developed further. The current version is 2.0, packing in both versions of Tomcat, 6 and 7. Setting it up is explained here. All the configuration is very similar to the original one and your IDE will help you out there (at least Eclipse does).

Finally... It's been way to long to wait for an update on this one.

Sunday, October 14, 2012

GitHub, Travis and status image

Since not so long ago GitHub provides an opportunity to build OpenSource projects on Travis CI. The integration is quite stunning and includes among other things:
  • Single sign-on with GitHuub
  • Automatic build setup with a single mouse click
  • Status image generation
Well, I tried to setup build of my Spring examples today and Markdown gave ma a little bit of a hard time to figure out how to put together an image link to by build status. Finally I stumbled upon this stackoverflow.com question but the brackets were all wrong. Here's what it should look like:
[![_alt_text_](_image_url_)](_link_)
With the parentheses instead of brackets all works nice :)

And live is good again :)

Friday, September 28, 2012

Foreman and multiple ports per process

The problem

Composing an application of multiple software components is the de facto standard these days. It's rarely the case for the application to embed a database server, queue server or the like. To help manage the ever growing complexity of this kind of systems we can use Foreman - a Ruby application using a Procfile to spin off instances of declared services (same as for example Heroku uses to manage processes).

Many software components these days besides providing the core functionality tend to give the user some sort of administration interface. That interface is often available under different a port. Up until now Foreman assigned only one single port per process, via the $PORT environment variable. As I started using Foreman recently this inconvenience became a stopper for me trying to start ActiveMQ, 2 instances of MongoDB in a shard and Neo4j with my Sinatra application. All was nice but the lack of ability to start MongoDB's control interface on separate ports blew it all out of the water.

The solution

I've came to the conclusion that it'd be a really handy to use multiple ports not just for the case I just described. And so I created a ticket on GitHub for this. Being a forthcoming guy and all I decided to take a crack at implementing this functionality myself. A few hours later a working and tested solution covering all the cases was ready to be pulled in. Let's see if the maintainer will agree to pull it in :)

How to use it?

Assuming David will pull it in the formula is as follows:
alpha: command_to_start -p1 $PORT -p2 $PORT0
beta:  command_to_start -p1 $PORT1 -p3 $PORT9
What would that mean?

alpha would get assigned 2 ports: $PORT = 50xx and $PORT0 = 51xx
beta would get assigned 3 ports: $PORT = 52xx, $PORT1 = 53xx and $PORT9 = 54xx

Since Foreman makes an assumption that at most 100 ports are assigned to one variable this new functionality uses that to assign ranges for subsequent ports. And because I wanted to stay compatible with results not using this new feature the original port range numeration regardless of the usage of $PORT in the command stayed the same. That's why beta still gets the $PORT assigned even though it is not used.

Have a nice day!

Thursday, September 6, 2012

AMQP, RabbitMQ and round robin

I'm working on a set of examples of how to use RabbitMQ from different languages. Among other things I've worked on reviewing the ruby AMQP gem examples. Unfortunately when it came to demonstrating multiple consumers (a sort of scalability example) I hit a snag: even though I have had 4 consumers only the first one was used.

After setting the number of test messages to a really high number things were finally looking up - the second and third and forth consumers were involved. But that sucked big time and to prove it I started digging further to find out what actually makes it do the things it does.

:prefetch => 1 was the setting (as stated on some stackoverflow.com page) but setting it alone didn't do the trick because that made the channel get only one message and that was it. To continue receiving messages they have had to be ack'ed.

Talking is cheap - here's the example code



Have fun!