Wednesday, October 25, 2006

Debugging Maven and Spring

I wanted to share an error I received with the following configuration

New application using
  • Maven 2.0.4
  • Eclipse 3.1.2
  • Spring 2.0
  • Spring-ldap 1.1
I was porting an existing LDAP application to use Spring-Ldap, because it looked like a really good solution to what I saw as really ugly programming using an old netscape ldap api.

For a bunch of reasons - mainly because my company needed to standardize development lifecycle, release management and deployment - I need to use Maven 2.0.4.

I took the sample code included in the spring-ldap distribution, and created an Eclipse project. Using the Maven plugin for Eclipse. Everything would compile fine, but when I would run "mvn test" on the command line, I sporadically get this error:

Results :
[surefire] Tests run: 4, Failures: 0, Errors: 4

Error creating bean with name 'com.example.PersonDaoSpringLdapTest': Unsatisfied dependency expressed through bean property 'personDao': Set this property value or disable dependency checking for this bean.


Hmm, let me clean my Eclipse project and then run "mvn clean" and let's see what happens.

Results :
[surefire] Tests run: 4, Failures: 0, Errors: 0


Hmm. I didn't change anything. Anyway, I did some more coding and then ran the mvn test again:

Results :
[surefire] Tests run: 4, Failures: 0, Errors: 4


Error creating bean with name 'com.example.PersonDaoSpringLdapTest': Unsatisfied dependency expressed through bean property 'personDao': Set this property value or disable dependency checking for this bean.

Oh, c'mon now, what's going on! Being that there was a little lull at work and I was 100% on this project without being spread to thin on other projects, I dedicated an inordinate amount of time to debugging this - in total about 14 hours (ok, with email and lunch padding the time a little).

So I broke all the code down to the bare minimum and still got these errors. Back and forth, clean and test, I could never get a reproducible condition. Argh!!!! Google searches on the "Error creating..." message above never really revealed much.

Without bogging you down (as if I haven't already) with debugging details, here's what I found.

It hit me during a long walk that there is some class-loading conflict.

Using spring's AbstractDependencyInjectionSpringContextTests class for loading spring files, I was wondering whether maven was having a problem finding the file

protected String[] getConfigLocations() {

return new String[] {
"classpath:/**/applicationContext-springldap.xml"
};
}


Here are the conditions:
  • If no file is found, you will not get an error saying "file not found", and instead will get the "Error creating bean..." error.
  • If the file is found, everything should work
The first drove me nuts for a little, but then in the mvn stdout, I did finally see that it was saying "no beans set", so I figured out that it was not finding the file.

To alleviate this, try using more defined criteria for finding the file

protected String[] getConfigLocations() {

return new String[] {
"classpath:/com/example/applicationContext-springldap.xml"
};
}


Now, if the file is not found, you will get this (note, I intentionally renamed the file:

IOException parsing XML document from class path resource [comm/example/applicationContext-springldap.xml]; nested exception is java.io.FileNotFoundException: class path resource [comm/example/applicationContext-springldap.xml] cannot be opened because it does not exist


Ok, so I began to realize that Maven did something with "resources". After never getting very far with Maven (see many of my previous posts), I forgot that Maven used this src/main/resources directory to store configuration files like the Spring xml file.

Going back and using Clean in eclipse, then mvn clean, my tests again failed. Looking in target/classes, I realized that it was not finding my applicationContext-springldap.xml file.

I looked in the project properties under "build path" in eclipse and expected to see the default project/bin directory set up for classes. No! After enabling the project for Maven using the plugin, apparently it changes it from project/bin to project/test-classes. Argh! Ok, so I switched it to project/bin.

Now I've got the class loading separate between eclipse and maven so there should be no interference. In my src/main/java, I kept the applicationContext-springldap.xml amongst the java classes because well ... that's how example was packaged. For compilation, Eclipse brings this xml file to project/bin, but Maven doesn't.

In order for the Spring config file to be loaded, you need to put the Spring file in src/main/resources. And if you want to still use this:

protected String[] getConfigLocations() {

return new String[] {
"classpath:/com/example/applicationContext-springldap.xml"
};
}


Then your file needs to be in src/main/resources/com/example/applicationContext-springldap.xml.

After doing this, all is well. It turns out the error had nothing to do with Spring-Ldap, as I originally thought.

Sorry for being long-winded, but I wanted to give the error message some context, since context is the one thing I couldn't get in my builds or in any google searching.

Tuesday, September 19, 2006

Paying more for good Java hosting

A recent article on OnJava.com asked why Java hosting is so expensive.

After I decided a few years ago to focus on making Java sites and move away from php/perl. Every time I would place an order for java hosting - while still a nascent freelancer and a frugal hobbyist - I did ask the same question about why the price was still higher than the basic packages offered.

I struggled with some hosts initially, and others I was strapped into using (by my client), but my recommended host and a few of my hobby sites are now safely on one good java host.

There's no way a post like this can avoid being somewhat of an ad, so I will mention that this host is Kattare. So far their features are excellent, their support (imho) is terrific and I'm happy with every aspect except the price.

In the comments to the OnJava.com link above, there were very good remarks saying the price is probably due to supply and demand. This makes sense. Java is prevalent in big enterprise companies, but these are not the same companies looking for hosting for $20 a month like most of us are. The number of freelance developers using Java for their small projects (small = $1000-$2000? you tell me) is probably the minority and that's where the high pricing structure comes into play.

But there one sole reason why I am able to say I'm fully satisfied with my host and I'm willing to disregard the high cost:
Some hosting companies that offer java have no fucking clue how to support it!
Although I'm tempted to name the hosts, here are two case studies over the past few years summarizing my experiences with two industry-leading hosts and the java sites I hosted with them.

1. Being first sometimes gives you a scary feeling

While converting a static site to a dynamic java site a few years ago, I asked my host if they supported Java and what app servers they provided. The response I received was this:
We offer PHP and Perl, why would you want to build a site using Java?
Uh ... three reasons: a) because I want to, b) because I should be able to and c) can you just answer my first question!

I was then told that yes, for a $50 setup fee, they would install Tomcat. Here are some of the many things that went horribly wrong:
  • They tied the start/stop scripts into that horrible Ensim hosting manager, and it never picked up any common/lib, environment variables or anything in the classpath properly. Lost 2 weeks of my life debugging that one.
  • As the host's clientele increased, eventually my java process - all the measily 128Mb or RAM I was given - is often exhausted and the box routinely freezes up
  • I was told that if I wanted to have multiple apps (like a /webapps) directory, that would be $25 change fee. So now I'm relegated to one App and it's right at the docroot of my static filesystem directory. sigh.
  • Using struts, my URLs used *.do extensions. Because my host couldn't figure it out I remarkably figured out how to modify the site-specific apache config for this domain myself (avoiding permissions issues), and the *.do to the Tomcat proxy configuration.
  • To add onto the last point, every time I added or deleted a host in my reseller plan, it robotically re-createdthe custom Tomcat proxy configurations and removed my *.do mapping! Sometimes sites would stop working at random times because of virtual host configurations.
The common thread between all these bullet points is that I was always using my own research and not the help of customer service - which I'm essentially paying for. Nothing is more frustrating then talking to a customer service agent - in any industry - that doesn't understand the product they're supporting. I would get really interesting lines like "It seems like your Java packages are taking up too much memory". What? And then there was "Why is the java process taking up so much memory?". I didn't pay this host for them to be asking the questions.

The site with these problems is still live but hanging by a thread. It goes down about 3-4 times a month. I'm about a week away from re-deploying a re-engineered version of the site on Kattare and hope to never have these problems again.

Moral of the story: If you get the impression that you're the first or one of the first clients to host a java site on that host, run. Run far away and find a host with experience.

2. Big Daddy, Little Options

Ok, from the title, you can probably figure out from that title what host I'm talking about. But a client of mine bought into all their bells and whistles and I am building a java site for them to host on *cough*daddy.com.

Every host handles deployment differently, so I asked my client to contact the host's support contact to find out how to deploy java applications as war files. Here's the response they got - and this was written by them, not translated by my client:
Put your jar file into the WEB-INF directory in your docroot.
Hehe. Snicker. Lol. Guffaw. Insert your own chuckling mechanism here.

I told my non-technical client that this statement was akin to someone saying:
If you want to learn to play baseball, go buy a football and kick it in a goal.
He then received another reply saying:
Put your *.war file in your docroot and Tomcat will unpack it once-a-day when the server does a nightly restart. Clients are not allowed to stop/start the server. Keep in mind the server is in Arizona on Pacific Daylight Time.
For the price he's paying, this java hosting service is very limiting. Once a day? No stop/start? C'mon. The server sounds like it's in China, not Arizona.

Moral of the story: A host can offer every feature in the web world - including java hosting - but if it's all half-assed service, the money you saved is now costing you in delivery and features.

Summary

I currently pay $29 or so a month for the level of service I choose with Kattare. Thanks to a referral program, each month that number seems to be going down.

For the great service that a knowledgeable host provides, I am more than willing to pay a premium for this service then have to waste my valuable e-time debugging classic issues created by poor configuration and lack of knowledge from hosts that only wish they knew how to host java applications.

Friday, May 05, 2006

What is Time?

I just wanted to point out the irony that I didn't create a blog for a long time because I thought it would interfere with the other programming work in needed to do. However, I blogged the most when I was at my least productive point. Now, I'm hopefully at the end of my least productive period, and I realized I haven't blogged once in that time period. hrmmmmm.

Thursday, February 23, 2006

Neat things

Another product from 37 Signals for chatting. Looks neat!
Campfire - Business Chat
A Tag Library for displaying lists

DisplayTag TLD

Friday, February 10, 2006

Universe of Maven 2 Archetypes

Maven 2 has this really neat feature called "archtypes" useful for creating a skeleton directory structure for a project. It allows you to specify an "archetype type" that identifies the project as an api (default), webapp or other types.

For example, you could start a brand new project like this:
mvn archetype:create              -DgroupId=com.mycompany.app              -DartifactId=my-app

Maven then creates a directory structure that Maven can understand:
my-app
|-- pom.xml
`-- src
|-- main
| `-- java
| `-- com
| `-- mycompany
| `-- app
| `-- App.java
`-- test
`-- java
`-- com
`-- mycompany
`-- app
`-- AppTest.java


This directory structure is used when your app is a jar, i.e. an API, or application.

Maven also hints that there are other types of archetypes for other types of applications, but then they don't explain anywhere what these are!

You can create a web-app project by specifying the web-app archetype:
mvn archetype:create -DgroupId=com.mycompany.app -DartifactId=my-webapp -DarchetypeArtifactId=maven-archetype-webapp
The only problem is that the Apache Maven group doesn't seem to realize that when users see this neat feature, the first questions are "Great! What types of archtypes are offered?" or "Where can I find in the documentation the list of available archetypes?". The result is that the documentation (well, "mini guides") show some examples of different archtypes used, describe an introduction to archetypes, and even show you how to create your own archetype. (Worse yet, is that "How to create archteypes" is listed before, "Introduction to Archteypes" ... duh!) . But programmers are lazy, and we want to know what archetypes have you created for us!!

To find the answer, I did a little google searching and found two links that pointed me in very unobvious directions:

One link pointed me to the unobvious subdirectories of the build distribution for Maven 2 found here: http://www.ibiblio.org/maven2/org/apache/maven/archetypes/

From here, you can see the possible archetypes are:
maven-archetype-marmalade-mojo
maven-archetype-mojo
maven-archetype-quickstart
maven-archetype-site
maven-archetype-webapp
Another site pointed me to the SVN repository for Maven. Drilling down to the archetypes, it looks like there are a few more available:
maven-archetype-j2ee
maven-archetype-mojo
maven-archetype-portlet
maven-archetype-profiles
maven-archetype-quickstart
maven-archetype-site
maven-archetype-webapp
The directory structure that these archetypes actually create is up to you to try. I've used the default (i.e., don't specify one) API archetype and the web-app and am happy with the directory structure that it creates.

Maybe one day I will report on the directory structures of these archetypes, but really that should be done in the Maven documentation ... (Hint!!!)

Tuesday, February 07, 2006

JCoverage Eclipse Plugin?

Has anyone every tried installing the jcoverage plugin for eclipse? I tried but it doesn't seem to work. I followed this step to "Add jcoverage nature" and Eclipse does nothing. Doesn't move, no change, nada. Then it says to complete the license information screen. Umm. What license information screen? I can't do anything after this. The view opens, but that's it. No pretty jcoverage charts =( Anyone ever have any luck?

Upgrading Eclipse?

Ever upgrade eclipse? Seems to not be a smart move. When trying to use the jcoverage plugin for maven, I saw that jcoverage comes as an eclipse plugin! After going through the install guide, it didn't seem to work properly. I looked at teh compatible versions and I just had plain old 3.1, not 3.1 M2. Ok, let's upgrade.

Bad idea.

Why does eclipse make it so easy to upgrade its own plugins, but doesn't allow for an upgrade of the product itself. Now I have to do a fresh install and go install all the plugins all over again.

Pain in my ass!!

Working with Maven 2

I had not used Maven 1.X. I remember giving it a test drive, but a lot of it made me shiver. It seemed like a lot of learning and a lot of quirky behavior for something that was supposed to help me.

Looking at Maven 2, it seemed like a good place to start. I heard "total rewrite" and was a little scared, but I figured that the Apache folks had their shit together. The quick start guide was helpful and it did what I needed it to do right off the bat.

My whole point was that I wanted to put no effort into the build process. I am doing almost everything myself and I didn't want shit like the package process to hold me up. Here is what I needed m2 to do:

- run my junit tests
- package the APIs as JARs
- package the web-apps as WARs

I even sacrificed setting up the deployment of my WARs to my app server web-apps directory. Simply, I knew Windows would poke it's ugly head and I'd be pullying my hair over backslashed backslashes, or spaces in file paths or something terrible like that. I figured a drag and drop of a WAR was the least of my hold-ups.

Also, one nice feature of m2 is setting up dependencies, and since the app1-core was packaged as a JAR, that meant in the app1-webapp pom.xml, I could set up that JAR as a dependency meaning I just add to package app1-core and not deploy it anywhere.

Getting tests tested quickly, JARs built quickly and WARs built quickly was easily achieved. Here are some things that really screwed me up.

Downloading of dependencies and plugins. When you first run mvn, it needs to download all the plugins and dependencies. Well jaysus, I just fuckin downloaded the program, why didn't the plugins come with it? You watch line after line after line of new plugin being downloaded which is sort of a drag.

Then I started adding dependencies like junit, spring, struts and hibernate. This was pretty easy, although when m2 sets up its repository, it also downloads all the dependencies that *those* jars have. Again, you watch your screen flicker with new downloads and wonder if it is all working properly. You also have the problem of Sun Jars not being stored on the Maven JAR repository.

Can't find a jar? don't know it's heirarchy or version? Easy browsing here.

One problem with m2 is that it seems to have little patience if it doesn't find a jar that you have double-checked is in the repository. I got hung up on the struts jar for 3-4 tries running mvn, and it finally was able to download it. A better message than "download it manually yourself" would have been better.

This was all I needed to get started though. I don't really need m2 to build me a project site or documentation yet. But knowing that it can do that is fabulous. Now, I get away with these few basic commands

Test:
mvn test

package the API into a jar:
mvn package

package the web-apps into WARs
mvn package

(yes, the same, in the POM you just declare what the package type is)

I may be skipping over some other headaches I had with m2, but I think they mostly had to do with poor documentation. The topics for the documentation don't really follow and rhyme or reason, and they really vary from complete to scant to the obscure. They go from "getting started" right to "mini-guides". Not good, not good. Documentation should be more procedural, especially something as big as maven.

Overally, i give m2 a 8.5 out of 10 for "suiting my needs with minimal headaches".

Setting up code with Maven 2 and SVN

Ok, it has been a long time since my first post, but let's act like it never happened.

I decided to use Maven 2 for my code management and building. Ant was easy, but from what I had experienced, there were 841 ways to write a build script, and that always made me uneasy. Plus, I liked the bonus of what maven appeared to give: documentation perks, site creation, and library management.

Did I have any experience with Maven 1.X? No. I wasn't sure if that was a pro or a con. The docs on maven.apache.org seemed pretty good, and I did the getting started guide with relative ease.

The notion of "archtypes" really got me charged up. I was stuck at a place to start, and when you use the different create types to organize your code, I loved how it did that work for me. But how was this going to fit in with the best practices tags/, trunk/ branches/ directory structure of subversion? Time to put two directory layout conventions together like chocolate and peanut butter.

For my project, I was developing two APIs and two webapps - the APIs would be packaged as jars and the webapps would be packaged as WARs. Therefore, I decided to do create four specific code projects.

Couple this with SVN!! Oy, now how do I integrate one into the other. I decided to combine both and do this:

app1-core
/trunk
/tags
/branches

app2-webapp
/trunk
/tags
/branches

app2-core
/trunk
/tags
/branches

app2-webapp
/trunk
/tags
/branches

Now, within trunk is where the maven part starts. So within each trunk/ directory, there is another named directory after the trunk, so each project goes like this:

app1-core/trunk/app1-core
app1-core/trunk/app1-webapp
app2-core/trunk/app2-core
app2-webapp/trunk/app2-webapp

each of these directories contains the main src/ and pom.xml pieces for Maven. Was it overkill? I don't think so. Was it a lot of switching around of directories? At first, yes, but that is why we have bash profile and windows properties for setup aliases. 99% of the time I was bouncing around to each project home so doing "cd $app1core" was a lot easier than doing "cd ~/app1-core/trunk/app1-core".

So when I was done I was happy. I felt like my project setup was like the 2-person horse costume. The high level directories were the horse's rear for subversion - project names followed by the trunk/, tags/ branches/ convention. And the horse's front part (wink, where the brains are) are the project directories for maven.

More catching up to do. The next entry will be on the fine balance of the pros and cons of maven 2.

Wednesday, January 04, 2006

The Origins of a Web Application

I'm developing a new website from scratch. If you're a web programmer, you know this isn't just a folder of HTML files or CGI scripts anymore, that would be too easy. This is Java, and it's real frickin cool but really complicated. If I didn't have the experience I have, I wouldn't understand a lick of it, but thank God I do.

It's amazing the choices you have for each component of an application, and it's a total buzzkill to take the time to pick your programs and frameworks, because it takes time away from architecting.

For this project, the basic requirement is that there is a business process that needs persistence (thus an admin interface) with a publishing process (for in-progress work parallel to public delivery) and a public read-only interface for the data. Not brain surgery.

Here are the software and frameworks I've chosen for the project:

  • Java 5 - all programming logic
  • Struts Framework - application controller
  • Spring Framework - Dependency injection for chosen implementations
  • Hibernate 3 - persistence ORM
  • Mysql 5 - Database
  • Apache Commons - for all the utils I need that I shouldn't have to write
  • Tiles/JSP - presentation layer
  • JSTL - presentation logic
  • XHTML/CSS2.0/JavaScript - presentation implementation
  • Maven 2.0 - project management, building, packaging, deploying
  • Subversion - source control
  • Eclipse IDE - client IDE
  • Resin/Tomcat - servlet container (still weighing)

Unless you have an existing app with the stuff you want in it, getting to this point is sometimes unbearable. In my opinion you should never start coding unless you have a HelloWorld type example working with all the components talking properly to each other. Another solution is to have a starter app, and a great one is Appfuse.

Here are a list (in no order) of some of my design decisions:

Maven 2 over Ant (and over Maven 1.x) - I was never a huge fan of Ant, the build files were just to messy. THere was a lot of documentation on maven 1.X, but Maven 2.X seemed like the way to go. The initial project setup using creation based on ArcheTypes is liberating. There is also a good guide to getting started and also a Maven 2 Plugin which helps manage the POM and dependencies.

Struts over JSF - I have a lot of experience with Struts and although JSF might be the framework of the future, I just didn't have time to learn it

Mysql - with Hibernate3, the database is almost an afterthought. Mysql is proven and free. 'Nuff said.

Spring - Spring was new to me ...well, not new ... but i was using it previously without really knowing how it worked and how useful it really was. After reading the O'Reilly Developer's Notebook on it (in about 2 days), I'm a Spring disciple.

JSTL was chosen over velocity and struts tags just to go with something that seems like it has staying power and is tied into the core technologies. Also I like how there is the word "Standard" in the acronym =)

Tiles/JSP - This also had to do with the Struts decision, that if a better template system is available, I will upgrade to it in the future, but for now Tiles does what I want it to do. In my opinion, it is more difficult to configure when you have a lot of master templates, but what I've done to compensate for that is to make my designs simpler so that Tiles management is easier. Is that a compromise? I don't think so. Sometimes making something simpler for you to manager makes for a better user experience because the layout is more consistent.

CSS/XHTML - using complete separation of formatting between the XHTML and CSS. All HTML is contained within DIV tags with standard formatting. So far individual elements are not using the class attribute. To me, if you want to go the whole nine yards, using class attributes ties what's in your DIV tags to the CSS and when you have an application like mine where content editors will be entering simple HTML articles, you do not want to have them entering in class attributes. Most of the layouts are designed through amazing CSS tutorials such as the Floattutorial and CSS Zen Garden

Subversion - best version control system out there. I had a decision between using Subclipse (Subversion Plugin for Eclipse) or use TortoiseSVN with Windows Explorer and I chose to use Tortoise. I felt Subclipse was still a little buggy and it really made the Package Explorer view messy with the modified SVN icons.

You can see from all this description how much is really involved in setting up a software project. I know mine is also a drop in the bucket compared to large enterprise projects but for now I am the sole developer on a project, which I'm sure applies to a lot of developers out there.

I have a backlog of small solutions to all of these pieces mentioned above which I hopefully will knock off the queue for reference, but I wanted to set the foundation for the decisions to use a lot of these products, because, ya never know when you might switch and seeing these trends might cause someone some headaches in the future.