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.

AspectJ
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)
}
}

Conclusion
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.

References
  1. http://www.ubookcase.com/book/Addison.Wesley/Eclipse.AspectJ/
  2. http://www.sable.mcgill.ca/~hendren/AspectJ.html
  3. http://www.stepwise.com/Articles/AspectJ/index.html
  4. http://www.eclipse.org/aspectj/doc/released/progguide/language-joinPoints.html
  5. http://www.javaworld.com/javaworld/jw-04-2002/jw-0412-aspect3.html

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.