Thursday, October 11, 2007

Introduction to Struts 2.x

I finally had the chance to work on a project using Struts 2.x. As I wrote code my code from scratch, I had to admit that my background from Struts 1.x worked against me in some cases where in others it helped understand basic concepts. All in all, I was very pleased with my experience with Struts 2.x. Granted, documentation is still under progress, however I found the email list to be a great tool to be informed and to receive answers to my specific questions. Although I don’t think I can possibly write about every feature I used in Struts 2.x, I can certainly write an introduction for those who are either new to MVC or trying to move from Struts 1.x to Struts 2.x

Reasons to Migrate

First I need to emphasize that unless you strictly have a good reason (and budget) to change your current MVC architecture, then I would recommend to switch to it. The migration is not as trivial and depending on what kind of code in your presentation view (JSP, Velocity, Freemarker, JSTL, etc) your migration may or may not be that transparent. One thing is for sure, Struts 2.x migration is not meant to be a “drop-in” replacement, so expect several gotchas as you move along. Also, note that regardless of your background, Struts 2.x can also be an appropriate MVC choice for a new application (depending on your needs, of course). If your moving from Struts 1.x, know that both can coexist during your migration, so you don’t need to break your existing code, however the process can become very confusing and unless absolutely necessary would I recommend it.

No Struts 1.x is required to start, in my opinion, however decent understanding of MVC (as with most frameworks) is always a plus. You want to also understand EL expressions (and now UEL as well). Understanding of additional concepts such as JEE Filters, Dependency Injection, Servlet Specification are going to help to get you going really fast, however note that if you have done any JSP work before, you’ll learn that with the Value Stack (Struts 2.x), now you have to account for a new “scope”. It’s not hard to understand or use, however one must understand where the values are coming from.

Using Struts 2.x

At a minimum, you are going to need the following jar files within your lib directory. These come as part of the struts2 distribution:

  1. struts-core-xxx.jar
  2. xwork-xxx.jar
  3. ognl-xxx.jar
  4. freemarker-xxx.jar

Of course there are other libraries needed. These are dependencies to the struts 2 framework (e.g. Collections, BeanUtils, Digester, etc). Although these are not part of the Struts2 project, these are reusable components that are part of the Jakarta Commons project. If you are not familiar with it, I highly recommend spending time on them. All required jar files come as part of the distribution. Of course if you are using maven, you don’t need to worry about any of these (maven places all needed dependencies within the lib directory).

Now you need to setup the org.apache.struts2.dispatcher.FilterDispatcher filter in web.xml. This filter should go primarily mapped to all “/*” (web.xml filter mapping). Now to your struts.xml file. This file needs to be in your classpath. Even if you try to put it somewhere else using a context-param in web.xml, other things will break. To be on the safe side, just put it in your WEB-INF/classes directory. As for “struts.xml”, I’m going to let you read some more on it in the official documentation since it’s pretty self explanatory, however a good thing to know is that the concept of “package” inheritance is widely used (similar to the one used in the tiles framework). This hierarchy allows you to have pre-configured elements in your configuration (e.g. validation, interceptors, etc) that are ready for you to use (thus the convention over configuration). You can change, modify, reuse any file. A good practice to learn is to checkout the source code and see how files are read. Warning, the source code uses maven, so unless you are familiar with how maven uses resources, this may be a bit unusual. Looking at the source code has helped me tremendously in picking up Struts 2 fast.

If you come from a Struts 1.x background, you may want to be aware that type conversion is done for you automatically. So there is no need to play around with custom converters (registered in BeanUtils, or custom processing to process conversions), however this conversion may/may not affect the way your validation occurs. This means that errors detected in the conversion process are managed as “fieldErrors” which in turn can be displayed using the appropriate tag. This may/may not be the desired behavior, but it a much better approach to Struts 1.x where strong typing properties in Form objects didn’t work well with certain validator types.

I hope to write very soon a lot more about specifics features within Struts2 as I find them, specially about the migration process which I’m sure it would be a lot more interesting. In the mean time, checkout Struts 2 and start playing with it. According to the goals of the project, you are supposed to be able to write a web application a lot faster (which I tested to be true) as well as to make it coexist with a Struts 1 application (also tested to be true). Have fun!

Sunday, October 7, 2007

Learning about AOP

I was told that once I start writing code in AspectJ and learn in depth Aspect Oriented Programming (AOP), it will be difficult to look at Java source code again in the same way as before. And now, the more I get into it, the more I realize how important it is to have this knowledge as part of your skill set. Until now, I had heard a lot about AOP and, just as anyone else who has used the Spring Framework, I thought I knew all I would ever need from AOP. Then, I was presented with a challenge where Spring support was not enough so I was faced with the opportunity to learn AspectJ's language constructs to address my client's concerns. I was very impressed with the things I was able to accomplish with this extension to the language and in general I highly recommend everyone to take the time to learn it and use it often.

One of biggest goals and hopes of every Software Architect is to design and lead a software development effort that can scale well. This means that maintenance should be more than technically feasible, but rather simple enough within budget. Experience proves that despite every effort of preparing for every change, it is difficult to address every potential concern that will rise in the future. Specifically, when these concerns appears spread out through the code base. This separation of concerns is what is referred to as "cross cutting concerns". AOP provides an API that allows you to write code to address these "concerns" in a desirable manner.

Aspect Oriented Programming (AOP)
Cross cutting concerns are address by way of, what is referred to as, "Aspects". Just as much as an Object models an Entity, an Aspect models a "Cross Cutting Concern". Getting familiar with these concepts takes some time, however as you take the time to write your own Aspects, it will become very easy to follow.

Every Aspect contains an entry point, a Pointcut. This basically describes how is the crossing concern identified. For example, the concern may be "all Constructors calls (from a specified package) must passed through an Authentication process prior to instantiation". So, the Pointcut will be all "calls to the Constructor within the package in question". This Pointcut description, interestingly enough, is one of the reasons where Spring AOP couldn't help me (Spring can not manage objects that are created somewhere else - e.g. Hibernate's Proxy objects). These Pointcuts delegate processing to a handler called Advise which is where most of the logic occurs. An Advise reflects the concern that is trying to be addressed. Continuing with our previous example, the Advise will be "before calling the constructor call check authenticating roles else throw an exception". Additionally, an Aspect may have multiple Pointcuts and each Pointcut will have a minimum of one Advise.

In the Java Programming language, AspectJ provides the ability to use these concepts in terms of objects. In general, AspectJ is an extension to the language. Originally developed by Xerox-PARC, it is now maintained by the Eclipse Foundation. The following code in AspectJ reflects the sample we have discussed thus far (for an object class name Foo):

public aspect AuthenticatedConstructorAspect {
pointcut constructorCheck() : call(* *.Foo());

before() : constructorCheck() {
// Do some coding (e.g. throw an Exception, etc)

In general, aspect oriented programming provides a great strength to your development efforts if used appropriately. It can become a strong part of your development efforts if used properly and can scale well since it can be plugged in as a requirement is enforced.


Thursday, October 4, 2007

Rethinking the Enterprise

Some years ago, I took a "Data Structures" class in college where I felt I received more than what I had signed up for. During my lectures, my professor challenged us to think outside the box constantly. On one occasion, a midterm exam was promising to be hard for the whole class. I was particularly puzzled with a bonus question (worth a lot more than the usual). Although I felt prepared for the exam, I was somewhat troubled, even upset at the question. If I recall correctly, the question was something like:
(x-99)(x-98)(x-97)... (x-2)(x-1)

And we were asked to calculate the product when "X" was 15. This puzzled me for a second since my first reaction was "why do I need to solve this in a Data Structures exam?". To my despair, I made the decision that I would spend 1 minute in trying to solve this question, since these midterms were known for being extremely long and difficult to finish. A few days later, during our next lecture, one of my classmates took the courage to ask the reasoning behind these "absurd" question. Our professor kindly explained that such question was to help us understand a principle that we had to remember if we were to succeed as Engineers. Thinking outside the box is not as simple as you may think and often times it requires a great determination to just do simple things. Although the answer may be simple, too much knowledge can lead us to add complexity to a simple problem, thus our skills are poorly used. By the way, the answer to question above mentioned was zero (if your need a detail explanation, please send me an email).

Simple and Plain concepts
Similarly to the incident I had in college, I attended a seminar not that long ago where the speaker spoke about this same exact principle. The approach he took was probably more eloquent than what I would like to be, but I feel he made a good point. This had to do with Enterprise Applications development. If you have noticed, the first word "Enterprise" is a simple word, yet as soon as one adds the second (Applications), a developer can start associating different technology concepts (EJB, Spring, .NET, Ruby, PHP). Normally, one is biased about a familiar technology, yet no one has even discussed anything about requirements. I met once an Engineer who had already designed (or at least he thought he had) an Application using EJBs without understanding the problem domain and/or requirements. This made me think in how we, as Engineers, are using the knowledge we have to develop simple solutions and avoid adding complexity to a business problem. I really stress this point because there seems to be an untold fear to learn/use different technologies and we seem to prefer to add more complexity over using the appropriate approach to solve a problem.

Facing our Engineering Fear
So why should you use EJBs? Do you fully understand what are the benefits of using these? Is .NET perhaps a better approach to the company's goals? Would you recommend building an application in RoR (Ruby on Rails) over J2EE (or .NET)? If not, could you number such reasoning? What is our real bias about the technology we choose to use when solving a problem?. Interestingly enough, I've found Engineers using a set of technologies that are known well, not necessarily because they are the best, but because is convenient. Engineering staff must understand the tool set available to them when solving problems, and unless required, not "re-inventing the wheel".

From the management perspective, there are very few cases when a developer may start working off a clean repository. This means that there is an existing asset to be maintained and/or extend. Management is skeptical about investing in such a change. In fact, it will take a lot of convincing to help management realize what is the really added value to a product in a potential "re-architecture" phase. Although this is understandable in most cases, an Enterprise Application can certainly benefit from a fresh new code base when situations allow them. This however should not make us believe that such architecture is the only and true way of solving every Enterprise Business need. A simple example is the case when Hibernate may not be the solution to every persistence problem. There are valid cases when JDBC is a perfect example. Or in the case of .NET, is the MS Oracle Client better than the ODP (Oracle Data Provider) for connections to an Oracle database?

The Hope of the Enterprise
To have a broader view of different technologies can certainly help us see an Enterprise Application from different perspectives. Being willing to learn new technologies can only help us and the Enterprise, but ultimately is up to us to drive the effort. So, when thinking about the Enterprise, one must think about the problem domain, and not only the tools available within our domain knowledge, but also what other alternatives available to solve the problem effectively. As scientists, we have a responsibility not only to solve technical problems, but to also use the most effective methods to do so. So read on documentations, download and test many frameworks and prepare yourself for we are the true hope of the Enterprise.

Monday, October 1, 2007

Leveraging Persistence with Hibernate

Most Applications today depend on some sort of persistence layer to maintain state. When developing applications using JEE, the Java Database Connectivity specification (JDBC) empowers developers to use a database as the persistence repository of choice. With the JDBC API, most development efforts become technically feasible as it provides standard CRUD operations to a relational database. Unfortunately, programming with this API can also become cumbersome and repetitive in most cases. The question that remains is "Can we do better?" - It turns out that the answer to this question is "of course!". In fact, there are many other things we could do that is "better", however, for purposes of this entry, I'd like to discuss role and concept of Relational Mappers (ORMs) in the enterprise, and more specifically, Hibernate.

Object Relational Mappers with Java

Although Java is an Object Oriented programming language, the JDBC API lacks the ability to relate to a relational model in a database in a complete object oriented way. This is where Object-Relational Mappers (ORMs) help. Generally speaking, ORMs help model a relational database in terms of Objects that represent a business phenomena. This mapping is maintained in some configuration file (e.g. XML file, annotation, etc). In addition to this kind of mapping, ORMs also provide additional features such as caching, query language support, RDBMS independence (more on this below) and what I like the most, tools to build and monitor this layer among others. Now, having said these, an ORM is not the answer to all solutions. There are times when straight JDBC programming may be more effective, however I've found easier to maintain code written using an ORM than without. Not to mention how elegant the code looks.

Learning Hibernate

Hibernate is an Open Source ORM framework, now part of the JBOSS family of products. As of the time of this writing, Hibernate 3 is the latest release with improved features and nice tools for automatic configuration file generation, code generation, code/table verification, reverse engineering, etc. The documentation is very clear and easy to follow and they now use JIRA to maintain all bug reports. One important thing about Hibernate that I consider strongly is its large number of support for other RDBMs. This means that as long as the code reference Hibernate's API for persistence, an application can be migrated to different databases. This also improves scalability and promotes loose coupling to database specific code. Starting Hibernate for the first time is very simple, but just as much as every other framework, it can become cumbersome if configuration is not designed properly. So, besides being open-source and "elegant", what are some of the reasons when I would suggest to use Hibernate?

Advantages of using Hibernate
Hibernate is a very mature ORM framework, widely used in Enterprise applications. This is not by accident but because it adds value to an application from different perspectives. Here are some of the reasons I would recommend Hibernate:

  • Object Orientation - Hibernate allows development using object oriented constructs when dealing with persistent objects. This means, you can take advantage (programmatically) of associations, polymorphism and inheritance. Depending on your current data model, there may not be a big difference in how a database is represented in terms of objects, thus using Hibernate is a great improvement in your code. I understand that with EJB3, this may not be a unique advantange to Hibernate, however for legacy applications (EJB2, JDBC), this is a clear option.
  • Transparent Persistence - Hibernate maintains all mappings between database tables and objects. This means that all interactions with the database can be done with objects instead of the JDBC API. This level of abstraction adds no more overhead than the average JDBC code. The ability to now write code to objects, without writing SQL code to read/write/delete to a database makes persistence transparent. This means that the persistence layer is now delegated (at least significantly) to Hibernate.
  • Support for polymorphic queries - JDBC supports native SQL when building queries. This can become difficult to maintain and cumbersome to extend. Hibernate's polymorphism support for object mappings allows developers to write queries using the Hibernate Query Language (HQL) using polymorphic objects which can improve the level of abstraction used for modeling data in your queries. Additionally, Hibernate's API promotes object orientation when dealing with queries. (See note below for disadvantages to consider about this feature)
  • Database independence - depending on your business model, an Enterprise Application may need to be deployed in different RDBMs. This is typically dependent upon a business requirement, or a client customization. For this scenario, Hibernate adds value to your application due to the level of abstraction added over the database. This reduced dependency means increased portability of your application. In constrast, nothing in JDBC promotes code to be database neutral and it's up to the developer/architect to ensure portability.
  • Optimized Performance - Hibernate has a powerful caching architecture that allows developers to write code with fewer trips to the database. This is done by virtue of the cached mapped objects as these are "hydrated" from the database and reused when others needed. This kind of caching is difficult to accomplish using straight JDBC.

As an Engineer, one must remember that Hibernate is a tool and not a solution for every problem. Once you used it once, it is very tempting to use it again in every scenario, however one must understand the disadvantages associated with every framework.

Disadvantages in using Hibernate
Depending on your needs, Hibernate may or may not be what you really need. This all depends on different factors (e.g. budget, deadlines, current assets, etc). One must consider all factors before deciding to use Hibernate (just as much as with any other framework).

  • Learning curve - Depending on your current staff, learning Hibernate may be difficult, specially if the application in question is heavily dependant in persistence using already another ORM solution, JDBC or even EJB. Mainly because Hibernate has a lot of publicity does not mean one has to spend budget on it. Although the documentation is very clean, there are many concepts to understand in Hibernate (e.g. dirty checking, caching, lazy-loading, get vs load, etc).
  • Mappings to the Database - The main assumption that all ORMs do is that every table can be modeled to an Object. This is, for the most part true, however you can certainly find cases when representing tables in objects is not necessarily simpler, specially if the database model is not normalized, or poorly designed. Additionally, some DBAs would prefer to use database specific constructs (e.g. triggers, stored procedures) to handle some business logic which may contradict with your intentions in decoupling business logic from persistence. In general, you should not assume that a database can always be represented in terms of objects without understanding all requirements. I recommend getting familiar with the object-relational impedance mismatch for further reference.
  • Performance Bottlenecks - Complex database model may prove to add performance bottlenecks to certain queries (specially if they are polymorphic in nature). Hibernate does an excellent job at building joins for you automatically, but is not able to improve the performance of those queries as a database would do (e.g. analyze the execution plan). This is the kind of optimization that is expected to be done manually. If an Application demands this type of queries in most cases, I would probably consider JDBC instead of Hibernate. It is true that you can also run SQL queries with Hibernate, but if most of the application is doing straight SQL, then we are not using the tool properly (thus defeating the purpose of the ORM).
  • Complex queries - Hibernate provides the "Hibernate Query Language" (HQL) which allows developers to write queries very similar to SQL with object orientation (polymorphism). Depending on the type of inheritance chosen to persist certain schemas, queries can grow in complexity, thus adding complexity to the nature of the query. One could write native SQL queries and make them more efficient than HQL (a DBA should be able to help you here). Once again, this all depends on the type of application that we are dealing with.
Hibernate is a very mature and powerful ORM that in most cases, adds value to your application. Depending on your requirements, Hibernate can reduce the complexity of code maintenance as related to persistence. When dealing with complex data models, one must carefully consider the advantages of using Hibernate (just as much as with any other framework).