"; */ ?>


24
Jun 09

What is The Best Java Web Framework?

What is the best Java web framework

No, really, what is it? Are you one of those people who ever wondered why there is actually more than one? Or you work with Struts for 5 years in a row, and think it is the best, just because you know all the nasty hooks you have to implement to make it do what you actually need?

Are you one of those die hard Rails fans, who (as most of Rails developers) does not really know Java, but already has a lot to say how bad it is?

Do you work in C++, and feel absolutely confident, that the framework, your company had developed for the last 25 years, that build web pages via socket programming is the best, and the most efficient one out there?

Is your company big enough, so it has a mature team of software (what they call themselves) architects, that take open source frameworks, and write their own single wrapper framework around it that, as they think (since they wrote it), is the 8th wonder of the (ancient) world?

You, see, I am a consultant – I know many of you, since I met “you” before :)

This one will be a very short article about my experiences with several Java Web Frameworks out there. Here we go:

Spring MVC Would be a good choice for the most of your needs

(I’ll give a short controller example below)

Wicket Interesting to look at – no XML, no JSP (JSTL), just Java and HTML. Can mimic a flow in a WebPage object. Better separation of concerns than, for example, in GWT (e.g. no Javish CSS, etc.). Good Community

The only thing that is off is your dynamic HTML elements are done in Java

Spring Webflow Yes – it is a separate beast. It mostly is good, and makes sense, however, in practice, once you need to do something a bit more complex that a shopping cart or a hotel booking app (hint, hint), you can run into problems. “Back button” and “Double click” are not very well handled by the framework, may get an exception while bookmarking (there is a magic recipe, but far from being simple, and intuitive), sharing data across the flow, last resort error handling are not simple, etc.
Stripes Good / simple (no XML – conventions), but not very actively maintained – hence not as mature. (good community though) Worth to look at for simple projects.
Struts Just architected wrong from the very beginning: Validation (XML – why? What about minimum search criteria, what about several, what about nested OO validators!?) / 0 for NULLs / Multi Action Forms / Testing (without StrutsTestcase) / etc. ) Improved a bit since WebWork merging, but still lots of “code smells”.
JSF Quite hard to keep up with all these JSF based JSP tags + integration with security is not simple + full JSF solutions are usually Frankensteins with many pieces from different vendors.
Tapestry Not bad, actually make sense, when you get it. But have you ever looked and tried to follow the Tapestry code? – Very complex implementation, if ever need to look inside the code + Tapestry does take time to learn, so forget about a new off-shore team, or fresh out of college not so geeky grads, taking it on.

And here is why I like Spring MVC:

  • Binding / Validation is done just right – clean, testable, reusable
  • Multiple View options ( PDF, XML, Excel, Atom, etc… ) done easy [AbstractExcelView, AbstractFeedView, AbstractJExcelView, AbstractPdfView, AbstractUrlBasedView, AbstractXsltView ]
  • Annotation based – no XML madness, and very clear when looking at the code – check the Pet Clinic in Spring 3.0 M3
  • Integrates with Spring JS very nicely ( in case needed )
  • Handing requests and parameters with ( Spring ) expression language – quite flexible
  • In Spring 3, MVC is actually REST aware (GET, POST, PUT, DELETE)

You can download Spring STS, import sample projects, and see many examples on how to use it, but here is a very simple controller example from Spring’s Pet Clinic:

@Controller                                                 // it’s a controller
public class ClinicController {
 
      @RequestMapping("/welcome.do")           // that all there is to mapping
      public void welcomeHandler() {
      }
 
      /** @return a ModelMap with the model attributes for the view
                                 uses org.springframework.core.Conventions */
      @RequestMapping("/vets.do")
      public ModelMap vetsHandler() {
            return new ModelMap(this.clinic.getVets());
      }
 
      @RequestMapping("/owner.do")
      public ModelMap ownerHandler(@RequestParam("ownerId") int ownerId) {  // parameters are passed in easily
            return new ModelMap(this.clinic.loadOwner(ownerId));
      }
}

It all depends on project’s requirements / timeline / resources / requirements / technologies already in place / etc… But having a choice, I do choose Spring MVC – it just makes sense: easy implementaion with Spring Roo / integration with Spring’s back end / support / community / releases / etc… I also like where Wicket is going, but it feels like “it is still going…”

In any case – good luck, and remember – if it does not have to be Java, but you still like to “stay close”, I would definitely give Grails a shot.


29
Mar 09

Adobe Flex in Ubuntu: Develop, Compile and Run

Flex on UbuntuRecently, browsing InfoQ I stumbled upon a very visual and interesting presentation by Christophe Coenraets “Rich Internet Applications with Flex and AIR“.

This presentation took place during QCon London 2008, where Christophe Coenraets, a Senior Technical Evangelist at Adobe, presented Flex and AIR, two technologies from Adobe used to create, deploy and run Rich Internet Applications.

I have not had any experience with Flex in the past, and, naturally, right after the presentation, I decided to give it a try – to develop, compile, and run an ultra simple Flex application. After some research, I found that there are two choices that are out there for Flex developers:

Adobe® Flex® Builder™ – software is a highly productive Eclipse™ based development tool enabling intelligent coding, interactive step-through debugging, and visual design of the user interface layout, appearance, and behavior of rich Internet applications (RIAs).

OR

Adobe® Flex™ 3 Software Development Kit (SDK) – includes the Flex framework (component class library) and Flex compiler, enabling you to freely develop and deploy Flex applications using an IDE of your choice.

While Adobe® Flex® Builder™ is an appealing option, it is not free. It starts from $300, and goes up to $700 for a professional edition. Whereas Flex SDK is open source and free – which is “a bit” cheaper than $300. The biggest difference between the two is that with just SDK, I will have to use my own IDE / text editor to write Flex applications, which is totally fine by me.

Step 1. Download Flex SDK.

Go to download Flex SDK, and check the box with “I have read the Adobe Flex SDK License, and by downloading the software listed below I agree to the terms of the agreement.”, you should see the “Download the Flex SDK for all Platforms” link to a Flex SDK zip file. Download it.

Unzip it to any directory that you like (in my case it is /opt/flex-sdk)

unzip flex_sdk_3.3.0.4589.zip

Step 2. Create an alias to compile MXML, ActionScript, etc. Flex applications.

Make sure java 6 is installed:

sudo apt-get install sun-java6-jdk

I need to have JAVA_HOME pointed to java 5 (JAVA_HOME=/usr/lib/jvm/java-1.5.0-sun), so I’ll hardcode the path to java 6 into flex compiler alias:

in ~/.bashrc:

# flex SDK home
export FLEX_SDK_HOME=/opt/flex-sdk
alias mxmlc='/usr/lib/jvm/java-6-sun/bin/java -jar "$FLEX_SDK_HOME/lib/mxmlc.jar" +flexlib="$FLEX_SDK_HOME/frameworks" "$@"'

re-login to the terminal (open a new terminal session). Now you can execute:

mxmlc youFlexApp.mxml

to compile an MXML file into an executable “youFlexApp.swf”

Step 3. Write a simple MXML application and compile it with Flex SDK.

Create a simple MXML file “flexTest.mxml”, that would create a button:

<?xml version="1.0" encoding="utf-8"?>
<mx:Application xmlns:mx="http://www.adobe.com/2006/mxml" layout="absolute">
        <mx:Button label="I am a simple flexy button" x="10" y="10" />
</mx:Application>

Compile it:

$ mxmlc flexTest.mxml
Loading configuration file /opt/flex-sdk/frameworks/flex-config.xml
/path/to/flexTest.swf (172884 bytes)

Now you should see a new SWF once the compiler is done:

$ ls -l
total 180
-rw-r--r-- 1 user group    217 2009-03-29 02:38 flexTest.mxml
-rw-r--r-- 1 user group 172884 2009-03-29 02:40 flexTest.swf

Step 4. Run compiled Flex application.

Open it with Firefox (make sure you have Adobe Flash Player plugin installed. If not, install it):

$ firefox flexTest.swf &

Now you should see that flexy button:

a simple button written in MXML and compiled by flex SDK

It is quite simple, really. Good Luck Flexing!


22
Mar 09

VNC Into Remote Server Without Typing a Password

vnc without typing a password

I have a simple setup where one of my Ubuntu boxes is hooked up to the old Mitsubishi 50” TV via s-video. The box is hidden behind the TV, and is, of course, online. It has Mythbuntu installed, and functions as a full blown multi media center.

Besides all other goodies that are installed on the box, I recently installed rtGui (A web based front-end for rTorrent) on it. Hence anywhere I go, I can connect to it over the web, and throw a torrent link that will start the download right away – convenient. ( here is how to “install rtGui on Ubuntu” )

Currently, I control my media box the most straightforward way – from my laptop. There are many other options available: Gyration Remote (In-air cursor control using Patented Gyroscopic Motion-Sensing technology – 2.4GHz RF technology for up to 100 ft), mini wireless keyboard, and many others, but I don’t mind a semi-manual way to control the box by using my laptop. There is one little problem though – every time I am VNCing to the box, I have to enter a password – not convenient…

First thing I tried to find a “no typing password” solution was:

$ vncviewer remotehost.com -p dummypasswd
VNC server supports protocol version 3.8 (viewer 3.3)
Cannot read valid password from file "dummypasswd"

Here I just wanted to see what the error message would pop up, to get more clues on where to look. Now I’ve got the clue: “there should be a valid password file”. Next thing to do is to read about “vncviewer”:

$ man vncviewer
 
       -passwd passwd-file
              File from which to get the password (as generated by the vncpasswd(1) program).

Excellent – now it is official, just need to use “vncpasswd”:

$ vncpasswd
The program 'vncpasswd' can be found in the following packages:
 * tightvncserver
 * vnc4-common
Try: sudo apt-get install
<selected package>
bash: vncpasswd: command not found

Seems like its not installed, which is an easy problem to solve…

Step 1. Install “tightvncserver”.

$ sudo apt-get install tightvncserver

Check that “vncpasswd” is installed:

$ vnc [TAB][TAB]
vncconnect  vncpasswd   vncserver   vncviewer

Step 2. Create a vnc password file with “vncpassword”.

$ vncpasswd
Using password file /home/user/.vnc/passwd
VNC directory /home/user/.vnc does not exist, creating.
Password: [TYPE YOUR VNC PASSWORD HERE]
Verify: [TYPE YOUR VNC PASSWORD HERE]
Would you like to enter a view-only password (y/n)? n

Step 3. VNC into the remote system without typing the password.

$ vncviewer remotehost.com -p /home/user/.vnc/passwd

As you see the only thing I need to provide now is the password file – no need to type the password every time I need to watch a movie. And to make it even more convenient, I can now create a launcher that will launch “vncviewer remotehost.com -p /home/user/.vnc/passwd” on a simple mouse click:

media center launcher

Want to do something else simple and convenient? Try to “run commands remotely via SSH with no password“.

VNC away!


10
Mar 09

Run Commands Remotely via SSH with No Password

Run Commands Remotely via SSH with No Password

Extremely useful for system administrators, very useful for application developers when testing with remote services, or how some buzz developers refer to it: Service Oriented Architecture (SOA). Also remote execution is widely used by web masters to sync/backup/create mirrors.

Below 5 simple steps will enable you to run any commands on the remote box/host/server via SSH without a need to provide a password. That is usually useful, if such remote calls need to be automated (work without manual/human intervention).

Step number 6 has an example on how to actually run a command on remote host via SSH.

from the local host

Step 1. Create a public/private keys with “ssh-keygen” (ENTER through everything):

      user@host:~/.ssh$ ssh-keygen -t rsa
 
      Generating public/private rsa key pair.
 
      Enter file in which to save the key (/home/toly/.ssh/id_rsa): 		[ENTER]
      Enter passphrase (empty for no passphrase): 				[ENTER]
      Enter same passphrase again: 							[ENTER]
 
      Your identification has been saved in /home/user/.ssh/id_rsa.
      Your public key has been saved in /home/user/.ssh/id_rsa.pub.
      The key fingerprint is:
      66:fd:11:ca:2d:21:b9:73:c1:b6:fa:1d:b2:2c:71:cd user@host
 
      The key's randomart image is:
      +--[ RSA 2048]----+
      |                         |
      |           .             |
      |          . o           |
      |         o + o         |
      |        E S.o o       |
      |       o. .+.o .       |
      |       . +o o.         |
      |        +. o...        |
      |       ... ..=.         |
      +-----------------+

At this point the public and private keys should be created and saved into “~/.ssh” directory:

      user@host:~/.ssh$ ls -l
      total 20
      -rw------- 1 user group 1675 2009-03-10 14:18 id_rsa
      -rw-r--r-- 1 user group 392 2009-03-10 14:18 id_rsa.pub
      -rw-r--r-- 1 user group 8642 2009-03-10 12:10 known_hosts

Step 2. Add identity to the local ssh authorizer with “ssh-add”.

If you “entered” through the “Enter file in which to save the key (/home/toly/.ssh/id_rsa)” in the previous step, then your identity file should be “id_rsa”:

      user@host:~/.ssh$ ssh-add id_rsa

Otherwise replace “id_rsa” with the file you chose to save your identity in.

In case of a friendly “Could not open a connection to your authentication agent.” error message, start “ssh-agent” as:

eval `ssh-agent`

and re-run “ssh-add”.

Step 3. Copy the public key to the remote host ( server ) under “~/.ssh”:

From the step above “id_rsa.pub” would be the public key that needs to be copied to the remote system you would like to run commands on.

      user@host:~/.ssh$ scp id_rsa.pub remoteuser@remotehost.com:~/.ssh/

from the remote host

Step 4. On remote host add this public key to “authorized_keys”:

      remoteuser@remotehost:~$ cd ~/.ssh
      remoteuser@remotehost:~/.ssh~$ cat id_rsa.pub >> authorized_keys

Step 5. Change “authorized_keys” permissions to allow only you to read/write it:

      remoteuser@remotehost:~/.ssh$ chmod 600 authorized_keys

from the local host

Step 6. Now you can run any command on the remote box from the local box with no password:

Let’s see what that remote box is running at:

       user@host:~$ ssh remoteuser@remotehost.com  uname -a
 
       Linux remotehost 2.6.27-01-generic #1 SMP Thu Mar 21 10:34:21 UTC 2009 i686 GNU/Linux

By runing “ssh remoteuser@remotehost.com uname -a” from the local box, you just ran “uname -a” command on the remote box without a need to enter the password.

Good Luck Remoting!


19
Feb 09

Make Hibernate Update/Create Changed Objects

Make Hibernate Update/Create Changed Objects

While Hibernate is a mature framework it still has a a lot of room for improvement. Starting from polishing documentation: e.g. “MappingException JavaDoc: An exception that usually occurs at configuration time, rather than runtime, as a result of something screwy in the O-R mappings.“, and going towards more powerful default optimization.

In fact, Rod Johnson (leader of Spring Framework’s parenthood gang :)), and other SpringSource consultants, constantly mention that most of their time, on projects that use Hibernate, is spent fixing Hibernate optimization bugs.

A lot of people form their opinions on what characteristics of “a good software framework” are. There are books, articles about it, but people are different, so opinions vary. One of the characteristics that makes a good framework, in my opinion is “while allowing clients to hook into the internal framework code, do not encourage it”. Meaning the flexibility is there, but the framework should not encourage its clients to get inside framework’s stereotypes. This way framework’s code (internal stereotypes) can alter, and still have “older version clients” running without (significant) change.

One of such hooks that Hibernate actually encourages to use is evicting the object from the session.

Here is an example:

While reviewing one of a Spring Batch jobs, I found that under the same “transaction management roof” (HibernateTransactionManager) jdbcTemplate and hibernateTemplate behaved differently: jdbcTemplate updated records in DB, but hibernateTemplate was not even trying.

So I enabled Hibernate logging in “log4j.properties”:

log4j.rootLogger = ERROR, errorsLog
 
# Hibernate logs
log4j.logger.org.hibernate = DEBUG, hibernateLog
log4j.additivity.org.hibernate = false
 
# HIBERNATE APPENDER
log4j.appender.hibernateLog = org.apache.log4j.RollingFileAppender
log4j.appender.hibernateLog.File = ./path-to/hibernate.log
# Set the maximum log file size (use KB, MB or GB)
log4j.appender.hibernateLog.MaxFileSize = 4096KB
# Set the number of log files (0 means no backup files at all)
log4j.appender.hibernateLog.MaxBackupIndex = 10
# Append to the end of the file or overwrites the file at start.
log4j.appender.hibernateLog.Append = false
log4j.appender.hibernateLog.layout = org.apache.log4j.PatternLayout
log4j.appender.hibernateLog.layout.ConversionPattern = [%p] [%d{yyyy-MM-dd @ HH:mm:ss}] [%t|%c{1}] %m%n
 
# ERRORS APPENDER
log4j.appender.errorsLog = org.apache.log4j.RollingFileAppender
log4j.appender.errorsLog.File = ./path-to/hibernate-error.log
log4j.appender.errorsLog.MaxFileSize = 4096KB
log4j.appender.errorsLog.MaxBackupIndex = 1
log4j.appender.errorsLog.layout = org.apache.log4j.PatternLayout
log4j.appender.errorsLog.layout.ConversionPattern = [%p] [%d{yyyy-MM-dd @ HH:mm:ss}] [%t|%c{1}] %m%n

First, I read an object via Hibernate, update it in the code, and then call a dao’s update method to persist it – pretty simple. However while debugging it step by step, after executing the Hibernate update query, in a log, I saw:

[DEBUG] [main|DefaultSaveOrUpdateEventListener] ignoring persistent instance
[DEBUG] [main|DefaultSaveOrUpdateEventListener] object already associated with session: [EntityName#3]

So the Hibernate did not update the object due the fact that it thought that another object was already associated with this Hibernate session. Which, in fact, was the same reference to the same object, only the update was called from a different instance.

The solution to this was to evict the object from the Hibernate session right after reading it:

  ObjectDto objectDto = dao.findById( id );
  dao.getHibernateTemplate().evict( objectDto )

Once the fix was applied, after Hibernate update call, I saw:

[DEBUG] [main|DefaultEvictEventListener] evicting [EntityName]
[DEBUG] [main|DefaultSaveOrUpdateEventListener] updating detached instance
[DEBUG] [main|DefaultSaveOrUpdateEventListener] updating [EntityName#3]
[DEBUG] [main|DefaultSaveOrUpdateEventListener] updating [EntityName#3]

And the object was successfully persisted into the database.

Happy ORMing!