Sunday, December 25, 2005

WTP, Eclipse, JDBC, and Dynamo

It's been a pretty significant 72 hours. I was talking about it with my wife, and realized that I've been pushing in this direction, being able to build java web apps, for the past 5 years. Through a handful of forks in the road, I got distracted. PHP got most of my attention, and most recently, Actionscript and Flash. But at long last, I've begun building a java web application. It's a content management system that I've decided to call "Dynamo" It's not the most original name, but I don't care. I like it.

I figure that it'd be a good idea to document the things that I've done to actually make this happen. In the most recent post, I was getting frustrated with the Eclipse plugin for Tomcat, provided by Sysdeo.com. I've since decided that the Web Tools Platform (WTP) plug in is much better suited. However, I will say that it's MUCH more heavy duty than the Tomcat plugin provided by sysdeo. WTP is made to build full fledged J2EE compliant web applications, and it shows. Interestingly enough, they released version 1.0 the same day that I found out about it.

A few notes about WTP should be noted.

First, this has most to do with my inexperience in using Eclipse, but it took me a while to figure out how to actually "build" a class. It turns out that by default, in Eclipse, this happens for you automatically. In the "Project" menu, there's an option named "Build Automatically". And guess what it does? Exactly! It builds stuff for you as soon as you save your java class. How Cool!

I ran into a bit of a problem at first because I was building a servlet, but in the browser, I was getting an error. This simply had to do with my bad java. Once I fixed the bad code, and re-launched the app, it worked. It took me a while to figure out what was going on because everything just worked without me thinking about it. I imagine this is how it must have felt when automatic transmissions were introduced in automobiles. "How do you make it go if you can't make it SHIFT!?!" I felt this way about compiling servlets.

What's really nice about WTP is that it places all of the classes in the correct places. Servlets that exist in the [Project]/src/ directory are built and placed in the WEB-INF/classes directory where they belong. You can also define any directory as a source directory. This gives you the ability to keep the source separated from the build. I like that.

Also of note is that it might be a good idea to have a plain vanilla, just-unzipped-and-left-alone, version of Tomcat installed for WTP to use. It seems to wrangle it somehow, taking over the Container entirely. I don't even know where the tested web applications are deployed from yet. Even in the unzipped-and-managed-by-eclipse/WTP installation of Tomcat, the developing web apps don't show up. Odd. I wonder where they go?

Another gotcha for me happened when trying to add a 3rd party driver (for the database). By default, the WTP creates a Web Application Library for these kinds of things, but I couldn't figure out a way to add this through the IDE. So, what I did was simply add it manually to the WEB-INF/lib directory in the project. I don't think that it was the right thing to do, but I couldn't figure out how to do it otherwise. However, once I did that, my application worked. I even tried to add another library, outside of the default web application library, but somehow, it wasn't recognized when deploying. Strange.

Although figuring out how to make Eclipse build, test and deploy web applications was a big deal, the biggest deal of the weekend happened when I was able to successfully build a page that connected to the database, and pull out content. I know that in itself is no big deal, but whenever you're working with a new technology, and things connect and work the way they should, it feels great!

I do have to say that it was a bit tricky figuring out how to get the database connection and query working though. I followed the unenlightening instructions at mysql.com, but something was missing. Other than the fact that my driver wasn't being loaded, I couldn't quite figure out how to go from making the connection to making a query and pulling out the results.

Making a database connection turns out to be a 2 step process.

First, define the driver.

Class.forName("com.mysql.jdbc.Driver").newInstance();
The second step is to make the connection.
 Connection conn = DriverManager.getConnection("jdbc:mysql://localhost/test?user=monty&password=greatsqldb");

Now, where should you do this in a web application? The answer, is simple. You do this wherever you want to connect to the database and make a query. I chose to do this by making a connection in the ServletContext, so it was created once, and globally available to all of the servlets in the application. In the long run, I don't know if this is the best thing to do in an MVC style web application. Servlets usually play the role of a controller, and it doesn't really make sense to ask a controller to pass along a Connection reference whenever communication has to happen with the database. This is like asking your boss everytime you have to go to the bathroom. He really doesn't need to know about it. So I will probably move the connection logic to the Model Layer. However, as I delve into Hibernate and Struts, I think most of the answers will be provided for me.

Now, as I write this, something odd has happened to my Eclipse and WTP installation. I no longer have the option to create a "Dynamic Web Application" and the "server" project doesn't notice my Tomcat installation anymore. Harrumph. The joys of open source flexibility, eh?

I've managed to fix it with a fresh installation of Eclipse 3.1 with WTP bundled. Something I do certainly like about Eclipse is the ability to just unzip and run it. The fact that there are no installers makes it super easy to experiment without causing irepparable harm. You can find the Web Tools Platform bundled with Eclipse on the downloads page. Look for the All-in-one. That's what you want.

Now that I feel empowered enough to build webapps in a development environment, my next goal is to jump head first into the deep end. I plan on creating a simlpe CRUD application for a database table using Struts. And after that, maybe in conjunction, I plan on doing this with Hibernate to manage the data. And after that, Probably in tandem with the others, is learning about JSTL, or perhaps a templating technology like Tiles and/or Velocity. Although, after looking briefly, I think that JSTL, and perhaps some custom tags for specific presentation features, might be enough to do the job. I'm excited to start playing around.

Friday, December 23, 2005

Using Eclipse to build Webapps

As much as I enjoy doing things by hand, I've realized that it's important to be efficient. Doing things by hand isn't necessarily very efficient. Which is why we have tools. It's easier to build a house with a pneumatic nail gun than it is with a hammer. There's obviously some overhead to doing things with more sophisticated tools, but often, the overhead is a minor concern. It usually becomes overshaddowed by the gained efficiency and rate at which things can be done.

For this reason, I've decided to lay asside my beloved UltraEdit and use Eclipse for developing my Java web applications. There's going to be a learning curve to be sure, but that's ok. I look at it as an investment. Investments are expensive, but in the long run they pay off. If everything goes well, that is. To help out, I found a good tutorial, which seems to address the goals I want to accomplish. It teaches how to use Eclipse to develop Struts applications for Tomcat. Just what I wanted.

Among the relevant tasks in this tutorial is setting up a plugin to connect Eclipse to Tomcat. This Eclipse plugin for Tomcat is available from sysdeo.com This plugin helps to create Tomcat-specific projects and start, stop and restart Tomcat.

After going through the above tutorial, however, there are a couple of things lacking. First is the lack of directions for building a servlet. To do this, you just need to go to File>new>class. This will start a new class. At that point, you can create a Servlet. I looked around for a while trying to figure out how to "build" or "run" the servlet, but there's no way to do this in Eclipse. Instead, going to the url that you define in the servlet mapping should do the trick. It took me an hour or more of fumbling around to figure it all out.

Additionally, the struts examples seem to be a bit out of date. When I tried this tutorial out, I used Struts 1.2.8, and the issue that the author mentions about the applications.properties file is irrelevant. As such, following the directions about changing the source location just causes problems. There's probably more going on there than I understand though.

All in all, after doing this tutorial, things are a little more clear. I don't know if I like this particular plugin for creating web applications though. I might try something different. I don't know if I like the way it sets up the development directory structure. What I'd really like, is a plugin that keeps the source out of the deployment environment, and allows me to deploy a war file. However, this plugin is nice in the way that it controls Tomcat. But there's gotta be something different. The search begins!

Apache, Tomcat, and mod_jk

Last evening I spent a couple of hours configuring Tomcat to work with Apache, with the help of mod_jk in a windows environment. mod_jk is a module that passes specific requests from Apache to Tomcat. Tomcat processes a request, and sends the response back through Apache. It's a simple enough concept, and fortunately, it's relatively simple to configure as well.

The first thing I did was install Tomcat. In a windows environment, the best way to do this is to install with the executable installer. This hooks into the windows services which control the startup and stop of Tomcat. Apache should be installed the same way. I chose to install Apache 2.0.45 and Tomcat 5.5.12. The Apache installation is a bit old, but the Tomcat version is the latest that's available. Installing these in a default way is the best way to start.

At this point, you can install mod_jk. This is available as a binary download, as well as in source for custom building. Simply place the mod_jk.so binary module file that you download in the modules folder for Apache to find. Then, in the httpd.conf for Apache, point to the module as such

LoadModule    jk_module  modules/mod_jk.so
I then followed the instructions layed out in the quick start guide for configuring mod_jk to work with Apache and Tomcat. The workers.properties file is very basic, so be forewarned. This should work pretty well for development purposes, but for a production environment, you'll probably want to set up some sort of load balancing.

OK, back to the httpd.conf. The entire relevant configuration for mod_jk looks like this:

LoadModule      jk_module  "C:/Program Files/Apache Group/Apache2/modules/mod_jk.so"
JkWorkersFile "C:/Program Files/Apache Group/Apache2/conf/workers.properties"
JkLogFile "C:/Program Files/Apache Group/Apache2/logs/mod_jk.log"
JkLogLevel info
JkOptions +ForwardKeySize +ForwardURICompat -ForwardDirectories
JkLogStampFormat "[%a %b %d %H:%M:%S %Y]"
But that's just for me. I simply placed this in a seperate file called mod_jk.conf, and included it in the httpd.conf file.

Then I set up a virtualhost, where I set the all important Jkmount directive. The virtualhost looks like this:

<virtualhost>                                               
DocumentRoot "C:/tomcat/webapps"
ServerName localhost
ErrorLog logs/localhost-error_log
CustomLog logs/localhost-access_log common

JkMount /jsp-examples/* worker1

DirectoryIndex index.jsp index.php index.html
ErrorDocument 404 /404.html
<directory>
Options MultiViews Indexes FollowSymlinks
AllowOverride All
</directory>

</virtualhost>

The place to note is the Jkmount directive. Now, when I go to http://localhost/jsp-examples, it looks the same as http://localhost:8080/jsp-examples. I am successfully serving jsp's and servlets through port 80.

Wednesday, December 21, 2005

It's a....

That's right, we're having a baby boy!!! This is what Junior looks like at 20 weeks

Monday, December 19, 2005

Struts and Hibernate in a Content Management System

I've recently decided that I would like to try my hand at building a Struts - driven Content Management System. I've almost completed the construction of a CMS written in PHP, and I'm dissatisfied with it. It took a long time to build, and it turns out to be less flexible than I had hoped.

So, now that I have some experience under my hat, and a bit of a better idea for what would work for a flexible and powerful content management system, I'm about to start over.

I've been wanting to dig into a Java based server environment for man, probably 5 years. I can't believe it's taken me this long. But it's time.

The goal is to build a CMS that's relatively simple in it's data model. I have a design drawn up with currently 9 tables. The records table contains the body of content. A collections table contains records which group the records. Both of those tables have related properties tables which allow any number of properties to be added to the records and collections. Another table allows tagging a set of categories for a record, and a sorting table helps to organize the collections of records.

To get started, I figured that I'd need, and want, to deploy a number of different technologies, API's, IDE's and related services. Among which are:

MySQL 5
Java 5
Eclipse 3.1
ANT
JDBC
Hibernate 3.1
Struts
Tomcat
Apache
mod_jk
jsvc (when I decide to do this all over again in a Unix environment)
and a templating engine to be decided.
I'd also like to use Lucene for searching

There will be more too, but this is a start.

I'm hoping that I can accomplish the following with this project.

  1. Create a solid, enterprise level, content management system
  2. Learn Struts
  3. Learn Hibernate
  4. Learn Eclipse
  5. To a lesser extent, become familiar with ANT
  6. Become more familiar with Transactions, triggers, and stored procedures.

So it's certainly a pedagogical practice, but I think it's going to be worth the effort. In the long run, I hope to turn it into something that can be sold to clients and repurposed efficiently. However, I have to admit, it's mostly just an educational endeavor. But I'm excited about it. I plan on keeping notes here as I begin to understand things.