Thursday, September 2, 2010

Changing SSH port on Ubuntu Server

I followed so many online postings that did not work for me. Apparently Ubuntu has two files for SSHD configuration:
Both of these files have the port setting, but only the second one works for me.
Everyone is giving advice to change the port in the first file, however it just does not work.
After I changed the setting in the
and restarted the SSH daemon, all was fine!
Do not forget to restart the daemon:
sudo /etc/init.d/ssh restart


Monday, July 19, 2010

ActiveJDBC has been released on Google code

Good news for those waiting for ActiveJDBC, it has been released under Apache 2 license. The project code can be found on Google Code:
Going forward, I will be blogging about this project on a ProductiveEdge Java Blog.

Thank you for patience, enjoy!


Thursday, April 22, 2010

ActiveJDBC the Basics

The title of this post has a class name in it...almost. The real class name is activejdbc.Base

This is an interesting class, in a sense that it is a completely static class (all methods static) and it is designed to wrap standard JDBC functionality in the most simple and succinct way humanly possible.
It allows to open a connection, query DB and close a connection in 3 lines of code - you have to write a half of page for this in any Java technology!
Here are some examples:"oracle.jdbc.driver.OracleDriver", "jdbc:oracle:thin:@localhost:1521:xe", "usr", "pwd1");
List<Map> records = Base.findAll("select * from people");
//..iterate over list
As you can see, this exposes all SQL that is interesting to a developer and hides all the ungodliness of JDBC, including driver, connection, exceptions, etc.
I literally bent backwards (well almost:)) to make this code as clear as possible.
In the example above, the opens a connection and attaches it to a thread. This allows any subsequent call consume it, while Base.close() closes the connection, obviously.
Another example:
List<Map> records = Base.findAll("select * from people where last_name = ? and name = ?", "Smith", "John");
I think this one is self-explanatory...and another one:
Base.find("select * from people", new RowListenerAdapter() {
            public void onNext(Map record) {
In the former examples, the entire result set (findAll()) was read into a list, but in some cases you will need to read millions of records and process them as in the stream (SAX - style of sorts).
The latter example achieves this goal, and you do not have to write a loop, the Base class takes care of it.

The Base class is not a super class to anything. It is just a utility that can be used externally and of course is used internally by the framework.


Tuesday, March 16, 2010

ActiveJDBC Features - Birds View

August 12 update: it seems that some people link directly to this post and do not see in later posts that this project has been published on Google Code:
Original post text follows:

This blog is not really a tutorial, but rather a high level overview of some important features this framework has. As I stated in a previous post, I really bent backwards when implementing it, only to make it easier for developers to access persistent data.

I will present various use cases in a list format:

How to run a simple query

//find by id:
Person p = Person.findById(0);

//find first:
Person p = Person.first("name = ?", "John");

//simple select of multiples:
List<Person> people = 
Person.where("department = ? and hire_date > ? ", "IT", hireDate);

How to build pageable resultsets

List<Employee> people = 
Employee.where("department = ? and hire_date > ? ", "IT", hireDate)
                    .orderBy("hire_date asc");

This query will ensure that the returned result set will start at the 21st record and will return only 10 records, according to the "orderBy". The ActiveJDBC has a built in facility for various database flavors and it will generate appropriate SQL statement that is specific for a DB (Oracle, MySQL, etc) and is efficient. It will not fetch all records, starting with 1.
I tried these queries on tables with millions of records on Oracle and performance is flat.
In fact, you can learn how to create queries like this if ActiveJDBC logging is enabled.

How to create new records

Person p = new Person();
p.set("name", "Marilyn");
p.set("last_name", "Monroe");
p.set("dob", "1935-12-06");

This code should be self explanatory. As you can see, ActiveJDBC does not require to have getters and setters. You can write them, if you like, but IMHO, they are nothing but code pollution.

The set(name, value) method returns reference to the same model object, which makes it possible to string method calls like this:

Person p = new Person();
p.set("name", "Marilyn").set("last_name", "Monroe").set("dob", "1935-12-06").saveIt();

There is even a third way to set values into a model:

String[] names = {"first_name", "last_name", "dob"};
Object[] values = {"John", "Doe", new Date(johnsDobTime)}

Person john = new Person();
john.set(names, values).saveIt();
...and yet another way to set values into a model is with a use of a map:
Map values = ... initialize map
Person p = new Person();

I hope this was entertaining. I will write more about features of ActiveJDBC in future posts. Specifically how it handles relationships.

Constructive feedback is much appreciated!

Have fun :)

Monday, February 1, 2010

ActiveRecord in Java == ActiveJDBC

As a Java developer, I spent a a couple of years working in a mixed environment where Java and Ruby intermixed. Working side by side with Ruby developers made me aware of things outside the Java world. To some extend, this was my own fault for ignoring the Ruby world. I clearly remember beng at the SD West conference in 2005 when the Ruby frenzy began. I looked at what RoR can do and was unimpressed by it mostly because the presentations at the conference focused on generating an application from scratch using scaffolding. Having to implement web app generators for Hibernate/Tiles/Struts-Layout two years prior, this looked boring and I put my interest to Ruby on the back burner. I was wrong. A couple of years later, working in a mixed environment (Java/Ruby) I learned a whole a lot more about Ruby and Rails, and was pleasantly surprised by the level of innovation. Over the years I have developed somewhat a disgust for big frameworks and "architectures" using them. The biggest offender IMHO is Spring. I really, really, REALLY do not understand what value it provides. The Spring context files multiply like rabbits, making it extremely difficult to debug the application. As you can imagine, in a mixed environment, there were many heated discussions on the merits of different languages, and I tended to protect Java, stating that the Java environment was poisoned by large useless frameworks as well as a large number of corporate developer-drones, and really there is nothing wrong with the language. The argument that the Ruby folks had was that Ruby is more elegant, dynamic and powerful and therefore attracts a more sophisticated crowd. My arguments that there are plenty examples of outstanding software created in whatever language (including Java) were just brushed aside.  On the flip side, when Ruby becomes as successful and as prominent as Java, it too will be flooded by corporate bonehead developers. I think that some of the Ruby folks behave as Ruby were a cult, not another tool at developers' disposal. So, to make the story short, the desire to prove that it is totally possible to create a lightweight persistence layer in Java similar to ActiveRecord, and make it even simpler to use in some regard, as well as desire to roll up my sleeves and just do some coding (I have done too much architecture and management over the past few years), drove me to create another ORM framework in Java, named ActiveJDBC.
The idea is to model the behavior and feel similar that of ActiveRecord, but make it for the Java developer. It is amazing how little Java developers know of Ruby. RoR has some great features, and despite the fact that there is no method_missing in Java, many ideas are possible to borrow and implement in Java.
The ActiveJDBC is already used on one commercial project, and according to developers who are used to Hibernate, they "do not even notice it, it just works".
My design goals were:
  • Should infer all metadata from DB (like ActiveRecord)
  • Should be very easy to work with
  • Should reduce amount of code to a minimum
  • No configuration, just conventions
  • Some conventions are overridable in code by simply calling methods (this will be aided by IDEs)
  • No need to learn another language
  • No need to learn another QL - SQL is sufficient
  • Code must be lightweight and intuitive, should read like English
  • No sessions, no "attaching, re-attaching" 
  • No persistence managers. 
  • No classes outside your own models.
  • Models are lightweight, no transient fields
  • No proxying. What you write is what you get (WYWIWYG :))
  • Should have the least possible resistance to startup a project
  • No useless getters and setters (they just pollute code). You can still write them if you like.
  • No DAOs and DTOs  - this mostly junk code anyway
Well, enough suspense, I can say that I started development on my free time around September, and at the end of October I had something I could use in a real system.
Let's look at code examples.
Here is an example of a model:

public class Person extends Model {}

Despite the fact that there is no code in it, it is fully functional and will map to a table called PEOPLE automatically. Here is how to use it:

List<Person> people = Person.find("name = 'John'");
Person aJohn =  people.get(0);
String johnsLastName = aJohn.get("last_name");

As you can see, the amount of code is reduced to a level when it is actually readable.
Finder methods can also be parametrized like this:

List<Person> teenagers = Person.find("age > ? and age < ?", 10, 20);

ActiveJDBC supports many features and is great for building web applications as well. It has a nice validation mechanism similar that of ActiveRecord, automatic support of many to one and many to many relationships, batch deletes and updates (conditional too), etc. Too many to list. I hope this wets your appetite. Any feedback and suggestions are welcome.