Monday, September 12, 2011

ActiveJDBC cascades deep and shallow

Each ORM adds functionality not found in standard DB access layer, and ActiveJDBC is no exception. Lets say delete with cascade. Method:
model.deleteCascade();
has been in existence for a while, but had somewhat limited functionality. It deleted the model and its immediate children in case One to Many and Polymorphic associations. In case of Many to Many, it was merely clearing links in a join table. The main reason for this was performance. In order to implement a true cascade delete, an ORM must follow all relationships until none left, but unfortunately in the process, it has to load every record instance into memory. This process might allocate huge chunks of memory and generate unexpected number of DELETE statements to the database.

So, initially performance considerations stopped me from implementing a true cascade delete. After all, deleting immediate children is very efficient: clean all of them in one SQL, then delete the parent.

However, once people started using ActiveJDBC, many asked a question: "this deleteCascade() is not really cascading, what the heck?" (well, they are all nice people, but I need to add some drama here keep you reading:)).
In any case, they pointed out inconsistencies of a name and the actual semantics. This prompted me to implement delete cascade true to its name. So, a new version just published to Sonatype will cascade like there is no tomorrow. It will navigate all child and many to many relationships of a model being deleted, find their children, grand children, grand-grand kinds, etc. No one walks out alive, if you know what I mean:)

Implications might be strange at first, but logical if you think about it. Imagine you have a relationship where doctors treat patients and patients visit doctors. In other words, this is a many to many relationship. If you delete a doctor, then all patients associated to that doctor are also deleted. But, what if a patient also visits another doctor? Guess what, that doctor is also deleted (because it is a dependency of a patient being deleted) and so are his/her patients, and so on. So, "deleteCascade()" really knows how to cascade!

But, what about the fast and efficient delete if all I want is to delete a model and immediate children (assuming no grand kids)? For that, there is a new method:

model.deleteCascadeShallow();
which retained the same functionality deleteCascade() had before.

So, deleting models in ActiveJDBC is an easy business, with methods:
delete();
deleteCascade();
deleteCascadeShallow();

For more detailed info, see this Wiki page: http://code.google.com/p/activejdbc/wiki/DeleteCascade

cheers..

Sunday, July 24, 2011

Stop hating Java 2

This post is in response to Andrzej on Software/ Stop hating Java post. I support most of the ideas Andrzej expressed in that post. Think of this post as continuation. This is my brain dump on things that was sitting somewhere in the back of my mind for some time and Andrzej's post jolted it out.

Ruby developers are prone to cults (observation).
It is interesting to see that Ruby developers (most people I worked with are good smart guys)  seem to have all drank several cool-aids: Ruby/Rails/Apple MBPs/IPhones/TextMate. They are "green", look to be "democratic", wear sloppy clothes, and are "laid back". They certainly fall into a few stereotypical descriptions. They religiously follow another big gorilla (Apple), whose policies are even more tight than that of Microsoft. What is more interesting is that we were able to pinpoint a Ruby developer in a group photo shot! Overall, I'd say because Ruby developers are prone to cult-like behavior, they miss a bigger picture sometimes. For them if it is not Ruby, it must be crap. Ruby developers are sometimes categorical to the extend bordering adolescent behavior. I think it is generally a human thing to resists other peoples' opinions and change. (note to self: Ruby developers are humans :)).

Any platform will do
Most people dislike languages they do not use, and Ruby developers are not exception. However, any language/platform can be used to build excellent piece of software, and there are many examples of that. Most all (as someone mentioned on Andrzej's post comments) think that PHP is crap, but although I'm not a PHP developer, I enjoyed this post from MailChimp, who has proven that if you have a brain you can build a great system ... even in PHP:) - http://blog.mailchimp.com/ewww-you-use-php/

How Java screwed up royally
  • Standards - the biggest flop in the Java history was Java Enterprise. This does not require any explanation, I hope. Standards are a plague of Java. They are designed to make different implementations together, but this is not happening. Instead, they take years to "standardize", when Internet years are even shorter than dog years. There is a handful of low level good standards: JDBC, Servlets, JMS, but the rest is just a waste of time.
  • Trying to circumvent standards - Spring/XML mess. Spring came to mass market some time  in 2003, and spread like wild fire (due to complexity of JEE). I personally do not like Spring and try to avoid it at all costs (same goes for JEE). Spring projects are messy, impossible to debug, and tend to grow like a cactus: in all directions.
  • Way of thinking that if you have a hammer(Spring/XML) in your hand, every problem looks like a nail (your project).
  • Popularity of Java sucked a lot of people into the Java world who should not be there (maybe they should not even be in IT in general). I'd argue that when (if ever) Ruby becomes as popular, it will get all the problems Java has: boring business applications, millions of lines of unmaintainable legacy code, army of non-talented and non-passionate developers, corporate culture,  heavy management, etc.
  • Java developers are ostriches - they keep their heads in the Java sand and are afraid to look around.
Ruby would be in obscurity if not for Rails
Ruby developers say they have things other than Rails. I'd say this is BS. All things non-Rails came about to support Rails in one form or another. I think that Rails undoubtedly made Ruby famous. Rails is a Ruby killer application. Ruby is actually older than Java by a year or two, but has been in obscurity all these years until Rails came along. If it were possible to predict a different past, I'd say that if DHH used PHP for his projects and never wrote Rails, the world as we know it would associate the word ruby with a precious stone, rather than a programming language.

My History of Rails experience
I worked on a website project for Sears that was all Java, but slowly became a blend of Java and Rails. When this was happening, the project was joined by a number of good Ruby developers. While we had disagreements and arguments, I adopted a strategy to learn as much as I could from these folks, and about Ruby/Rails thing. As it turned out, there was much to learn and so I did. In the process, I also saw that many good things in Rails can certainly be implemented in Java, to the benefit of Java community.

What I did to make Java developers happier
Needless to say, I like Rails for its productivity and think that the Rails way of conventions and style of web development is(was) better than anything I knew in Java. So, I waited for someone to do cross-pollination and implement these ideas in Java. And then I waited some more. After a 2 - 3 year wait, I realized this is not happening, and decided to take the initiative in my hands. I wrote JSpec with DSL similar that of  RSpec, ActiveJDBC - implementation of ActiveRecord in Java, and ActiveWeb - dynamic web framework similar to Rails. I manage a team of 10  developers and we have a mixed environment Rails/ActiveWeb/ActiveJDBC and about 10 commercial websites/batch applications. All new sites are built with Active* stuff, and I can attest that developer productivity in Java are the same as using Rails.

What I seriously miss in Java
Closures! Of all the stupid useless language features that Sun has been adding for years (generics for instance - only a madman can understand their syntax), they
missed the boat with closures, the one and only feature I genuinely miss. Closures certainly would make all the callbacks and stupid inner anonymous  classes go away - and this will be the biggest contribution to making Java more readable. IN addition, closures would make most Java APIs concise and easy to use, as Groovy has already done by adding a ton of methods to JDK classes.

Message to haters
It seems that people who start sentences with: "I hate..." have constipation or something. My advice: take some Metamucil, after that a few beers with friends, and then surprise people you know by always starting with: "I like ...".

Conclusion
Whew, if you are reading this sentence, you are one patient person! All these Java vs Ruby vs .NET vs PHP [plug your abbreviation here] discussions are water under bridge. People call Java Cobol of the day. I'd say that if a Java program runs a business for 30 - 40 years, it is a huge success. Who knows what languages we will be using 30 - 40 years from now? So far, we have a good selection, let's enjoy!

Monday, April 18, 2011

What is good for Ruby is good for Java: JSpec

People familiar with Ruby will invariably learn RSpec. RSpec is a great library for writing specifications, or specs as Ruby developers call them. Some time ago, I developed JSpec somewhat modeled after RSpec. I needed a better language for writing expectations. What is an expectation and how is it different from assertion?

In a Java tests, people usually use assertions to check conditions after some code is executed, such as:

assertEquals(stirng1, string1); 

In the case above if string1 and string2 are not equal, the assertion fails thus failing the test. In general, having a test is much better than not having one, but after learning RSpec, I really felt that the asserts are inadequate.
Asserts are an old way of saying: "I have developed code, and I will check that it works". I really prefer a more modern TDD/BDD approach that says: "I captured requirements of a system in test code, and will implement it after". This allows me to develop the implementation of my system after I write a specification. There is so much written on the virtues of good TDD/BDD development. Those interested should at least watch this: Dave Astels BDD presentation.

As part of the work I did while working on ActiveJDBC , I developed the JSpec library.
The main idea is to replace "assert" language with "should" language and make it as close to English as possible. This forces the brain to work in a different mode, writing a "specification of behavior" for your program rather than "assertion" that the program works. The difference might seem subtle, but requires a different style of thinking and promotes true TDD/BDD - when specifications are written before implementation, sometimes even by different people.

Here is an example of "standard" JUnit code:
@Test
public void testCalculator(){
   Calculator c = new Calculator();
   c.add(2, 2);
   assertEquals(c.result(), 4);
}
and here is the same written in JSpec (also with JUnit):
@Test
public void shouldAddNumbersCorrectly(){
   Calculator c = new Calculator();
   c.add(2, 2);
   a(c.result()).shouldBeEqual(4);
}

As you can see, the difference is subtle, but profound. More information on the use of this library can be found here: http://code.google.com/p/activejdbc/wiki/JSpec


happy coding!
igor

Thursday, April 14, 2011

An easier GWT starter project

GWT is a powerful technology for Rich Internet Applications (RIA), hands down more powerful than anything else I know that can produce quality JavaScript. It comes with a simple script to generate new projects called webAppCreator. You would think that this will create a simple project structure you can then enhance and call your own, right? Kinda...

The product of this script is a working application with a server round trip that shows the power and simplicity of GWT RPC. Unfortunately, this project is chock full of comments and unnecessary code so much, that it is hard to see trees behind forest! I cleaned this many times to figure out simple things, but this time decided to drop it into the blogo-sphere so that other people could benefit as well.

I was able to reduce the amount of code to about 1/4th of the original, leaving the same functionality in place.

Here is the link: http://igorpolevoy.com/public/attach/GWT/test.zip
enjoy
igor

Tuesday, February 1, 2011

JavaLite HTTP gets Basic HTTP Authentication

While I'm not a big proponent of Basic HTTP Authentication, some people find it useful. Usually when you use internal services, you do not need any authentication - you use firewalls and other restrictions.

When we expose services to partners, we usually define some sort of token based authentication that is application - specific. However, the JavaLite HTTP package being general purpose HTTP client needed Basic Auth.

The new method I added is basic(user, password), here is a sample of code using basic authentication:

Get get = Http.get("http://localhost:8080/manager/html").basic("tomcat", "tomcat");
System.out.println(get.text());
System.out.println(get.headers());
System.out.println(get.responseCode());

I used Tomcat 6 to test against, and it worked just fine after simple Tomcat configuration:

<tomcat-users>
  <role rolename="tomcat"/>
  <role rolename="role1"/>
  <user username="tomcat" password="tomcat" roles="tomcat,manager"/>
  <user username="both" password="tomcat" roles="tomcat,role1"/>
  <user username="role1" password="tomcat" roles="role1"/>
</tomcat-users>

What you see above is tomcat-users.xml file, where I uncommented all XML and added a "manager" role to "tomcat" user.

As usual, I like it when: simple things are simple.

Enjoy,

Igor

Wednesday, January 12, 2011

Java: REST with ease :)

Update: you can get the latest Http client from Maven central:
http://search.maven.org/#search|gav|1|g%3A%22org.javalite%22%20AND%20a%3A%22javalite-common%22

Ever wanted to just send an HTTP request from Java? What should be easy is actually not. There are myriads of ways to do this in Java; you can write a half of page of ugly code with exceptions, use Apache HTTPClient library (which has its own dependencies), find another library, learn its API, etc. I told myself: "... but I just need to call a service and get a reply back!".
Eventually I got tired of this situation, and wrote my own tiny library for doing this: JavaLite.

Here is an example. If all you need is to send a GET request and get a response back, you could do this in one line:
Get get = Http.get("http://yahoo.com");
System.out.println(get.text());
System.out.println(get.headers());
System.out.println(get.responseCode());
The implementation has no dependencies and relies solely on standard Java API. The library even sets sensible defaults for timeouts. Also supports POST, DELETE and PUT.
The reason I developed it is because we are heavily relying on using REST services and a simple call to a service is really a must have.
So, an example of a service call would look like this:
if(Http.post("http://host/context/resources", postContent).text().equals("OK")){
    //..success
else{
    //failure
}
Eat that, SOAP! The code is so unobtrusive, sometimes it is hard to see. Oh, boy, I can breath now... head is cool, feet are warm...live is better now :)
Happy coding!
igor