Matt RaibleMatt Raible is a writer with a passion for software. Connect with him on LinkedIn.

The Angular Mini-Book The Angular Mini-Book is a guide to getting started with Angular. You'll learn how to develop a bare-bones application, test it, and deploy it. Then you'll move on to adding Bootstrap, Angular Material, continuous integration, and authentication.

Spring Boot is a popular framework for building REST APIs. You'll learn how to integrate Angular with Spring Boot and use security best practices like HTTPS and a content security policy.

For book updates, follow @angular_book on Twitter.

The JHipster Mini-Book The JHipster Mini-Book is a guide to getting started with hip technologies today: Angular, Bootstrap, and Spring Boot. All of these frameworks are wrapped up in an easy-to-use project called JHipster.

This book shows you how to build an app with JHipster, and guides you through the plethora of tools, techniques and options you can use. Furthermore, it explains the UI and API building blocks so you understand the underpinnings of your great application.

For book updates, follow @jhipster-book on Twitter.

10+ YEARS


Over 10 years ago, I wrote my first blog post. Since then, I've authored books, had kids, traveled the world, found Trish and blogged about it all.

[OSCON] Tuesday Afternoon

Creating Passionate Users
Presented by Kathy Sierra, OSCON 2005

How do you create passionate users? People will do anything and be enthusiastic about it if they're passionate about it. For example, Nikon.com teaches you how to be a better photographer. In their tutorials, they happen to mention that you might need a better camera to take better pictures. If you're going for passion, you have to provide a continuous path for becoming more knowledgeable about a product - and eventually becoming an expert in something. The beauty is the path or thing you provide doesn't even have to be related to the product. It simply has to provide users with enthusiasm about something you provide, which in turn supplies them with the path for that passionate experience.

"Things that look better actually work better." In other words, aesthetics matter.

When writing a book or documentation - you have to make what you're writing about matters to the user. It has to be so important to them that it gives them a queasy feeling. Naturally, the person won't be interested in what you're talking about - you need to be able to communicate the real core of why a person would have an emotional reaction and why it matters to them. "Well, why didn't you say that?" is the reaction you're looking for. If you're can answer that question w/o answering all the questions leading up to id - you're golden. You're supposed to try and scare them to the point that they're never going to have sex again, and then step back one level. What's the compelling meaningful benefit of the product?

You need to seduce your users and keep them interested and passionate by challenging them to learn more. Flow is the feeling when you have no sense of time - and you need to somehow figure out how to get your users into the flow. As long as you believe you're only one compile away from fixing it - you'll spend hours working on something. This is the flow state and comes from the perfect balance between a challenge and the skill+knowledge to solve that challenge.

One of the challenges to creating passionate users is to establish some sort of next level that your users can get to. First of all, you have to figure out what the next level is, followed by what "new powers" and abilities you can give to your users once they get to that level.

Tips for engaging users

When writing, use a conversational tone. The brain has a conversation with text when you read it and you'll have a 40% better retention rate by reading writing with a conversational tone. Also, use pictures whenever possible since they often make things easier to understand. Don't reveal everything - make your users curious.

What do film makers and novelists do? They tell stories.

Where there is community, there is legend, myth, passion and stories. Where there is passion, there are people. How can you propagate the stories and people from the project?

People don't care about you - all they care about is how they feel about themselves after interacting with your product or service.

This was a great session by Kathy and I was very impressed how she presented it. No laptop, just an overhead projector. Lots of group activities and lots of group discussions. I could easily see Kathy and Bert writing a book on Creating Passionate Users.

Posted in Open Source at Aug 03 2005, 12:30:10 AM MDT 1 Comment

[OSCON] Monday Afternoon

Ruby on Rails - Enjoying the ride of programming
Presented by David Heinemeier Hansson, OSCON 2005

About David: started doing Ruby in June 2003. Involuntary programmer of need, served 5 years in PHP. Spent 7 months in a Java shop.

Prerequisites of play: Ruby 1.8.2, dated December 25th. A database, pick one of 6. The RubyGems miner. Some gems called Active and Action.

Directory structure that Rails creates is more for convenience than anything. By picking conventions for you, it makes things easier. It might feel like flexibility is being ripped away from you - but you can change the defaults. However, by following the default settings, things will just work and life will be much easier for you as a developer.

I did a bit of playing on my PowerBook while listening to David's talk. I have Tiger installed, but found that Ruby 1.8.1 was installed on my machine (in /sw/bin/) thanks to Fink. My running "rm -r /sw/bin/ruby" and restarting iTerm, the default changed to /usr/bin/ruby, which is 1.8.2. From there, I downloaded and installed the Rails Installer.

I hate to admit it, but this talk is pretty boring so far. Probably because I've read David's blog for the past 6 months and watched most of the Rails videos. I haven't really learned a whole lot in the first 45 minutes of this talk. To be fair, the content of the talk seems to be properly targeted - there's been a fair amount of questions and everyone seems to be interested. Almost all of the seats are filled in the room; 3-4x as many folks as Dave Thomas's Ruby talk.

One interesting thing I've learned today is many features of Rails (i.e. Webrick) are actually a part of Ruby, not Rails. In addition, Ruby seems to have frequent releases and more features are added to the language each time. I guess that's the advantage of having a language that's not developed by committee.

When creating model objects in Rails, the default is to use a plural form of the object for the database table name. For example, a comment model will map to a comments table. Dave Thomas did mention in this morning's session that Rails isn't smart enough to figure out "sheep" - it gets maps to "sheeps". Apparently, you can easily override this behavior by specifying use_plurals=false somewhere. Another convention built-in to the framework is that the primary key is named "id" and its an auto-incrementing field.

"The database is a data bucket. I don't want any logic in my database, I want it all to be in my data model."

Rails doesn't handle composite primary keys. Rails is mostly designed for green-field development, where you get to control your database and its schema.

There are a number of key properties you can use in your database tables (a.k.a. your model objects) that will automatically get updated if you name them properly. Their names are created_at (datetime), created_on (date), updated_at and updated_on. There are also a number of time-related helpers, i.e. distance_of_time_in_words_to_now(date) » less than a minute ago.

Rails also has the concept of filters, which you can apply to a group of controllers. To use a filter, you define the filter method in controllers/application.rb and then you have to add a before_filter clause in each controller you want it to be applied. While it's cool that Rails has filters, it would be nice if you didn't have to configure the controllers that filters are applied to in the controller. To me, it seems more appropriate to be able to configure the where the filters are applied externally to the controllers. It seems more natural to me that you'd put something like apply_to_controller => { :controller1, :controller2 } in application.rb.

For doing page decoration with Rails (i.e. SiteMesh), you simply create a decorator in views/layouts. If you want a particular decorator to apply to a particular controller, you just name the file the same as the controller's URL. For example, if you have a posts controller (really a PostController.rb file), you'll create a decorator named posts.rhtml to decorate all the HTML rendered from the PostController - regardless of whether you're rendering from a method or from a view template. To have a decorator apply to all controllers, you can simply create a file named view/layouts/application.rhtml. This seems like something that SiteMesh could easily do as well - for example defaulting to /decorators/default.jsp (or something similar).

One thing I like about Rails is it's flash concept and how easy it makes it to display success messages. In my experience with Java web frameworks - many make this more difficult than it should be.

Testing Rails Applications

When running tests, Rails automates the creation of a test database instance that mirrors the schema of your development database. One slick thing in a Rails project's Rakefile is that you can run all the tests that you've touched in the last 10 minutes. I think one of the most unique thing about Rails/Ruby vs. Java is all that almost all of the files (Rakefile, code generation scripts, etc.) are written in Ruby.

Controller tests have a "mini-language" for simulating a browser when testing controllers. For example:

def test_login 
  get :login
  assert_response :success<
  assert_template "login" 
  
  post :login, :password => "secret!"
  assert_response :success
  assert !session[:authorized]
  
  post :login, :password => "secret"
  assert_response :redirect
  assert session[:authorized]
end

In the Controller tests, you can set cookies, parameters and mimic almost everything the browser can do. You can also test that your model objects have been manipulated appropriately. For example:

def test_create_post 
  post :create, :post => { :title => "This is my title", :body => "1" }
  assert_response :redirect
  assert_kind_of Post, Post.find_by_title("This is my title")
  
  post :create, :post => { :title => "", :body => "1" }
  assert_response :success # something was rendered, regardless of error messages
  assert_equal "don't leave me out", assigns(:post).errors.on(:title)
  #or assert_equal 1, assigns(:post).errors.count
end

The find_by_title method is a dynamic finder, where ActiveRecord creates find_by methods for each attribute of the model object. Another cool feature of testing is you can add a line with "breakpoint" in it - and the test will stop executing there - giving you access to all the variables at that point.

Ajax

The main reason for integrating JavaScript into Rails is so developers don't have to write JavaScript. For most developers, writing JavaScript is a pain because of browser incompatibilities and such. Rails ships with 4 JavaScript libraries, including Prototype and Script.aculo.us. It's easy to include the default JavaScript libraries in Rails:

<%= javascript_include_tag :defaults %> 

Both the link_to and form_tag methods have a "remote" equivalent (i.e. link_to_remote) that allows you to hook into Ajax, and by defining a :complete callback, you can call fade effects and the like. You can override many of the lifecycle stages of Ajax, but the most common is the :complete callback. In a Controller, it's easy to distinguish Ajax calls from non-Ajax calls using:

if request.xml_http_request?
  # do logic, for example rendering partials
end

Partials seem to be a pretty cool feature in Rails. They're actually just parts of a page that you include in a parent page with render :partial => "viewName". The slick thing about partials is you can actually populate their model and return them in a controller after an Ajax call.

The Ajax demos that David just showed are pretty cool. He was able to easily show how to delete a comment in his "weblog app", as well as add a new comment - w/o refreshing the page. The slick part of the add was he was easily able to add the new comment id to the Ajax response header, and then grab it in a callback and use the id to reference a <div> and use the yellow fade technique to highlight and fade the new comment.

That's the end of Dave's talk, and the first day at OSCON. Thanks to Dave and David for showing me the cool features of Ruby and Rails.

Posted in Open Source at Aug 01 2005, 05:02:31 PM MDT 5 Comments

[OSCON] Monday Morning

Facets of Ruby
Presented by Dave Thomas, OSCON 2005

I'm sitting in Dave Thomas's session on Intro to Ruby at the Oregon Convention Center. It looks like someone finally figured out the main problem with conferences - lack of power outlets. Kudos to O'Reilly - they've put power strips at the base of every table in this room. With the high-speed wireless and unlimited power, this conference is getting off to a great start.

Is programming still fun?

Round about 2000, programming started getting tedious for Dave - after having fun for the past 25 years. When we program, we combine all the problems of the artistic side of the race with all of the problems of the scientific side of the race. The only way to be successful at it is to enjoy doing it.

Is programming productive?

It has to be to enjoy it. The most satisfying thing about programming is watching it run. That's why scripting languages are so great - because you can see it run now. Myth: a good programmer can be a good programmer in any language. Language and tools make a difference - a good programmer knows which language to choose for a particular problem.

This session is not going to be a syntax session. Damn, sounds like I won't really learn how to program Ruby in this session.

Ruby, the Language

Born in Japan in 1994. Father: Invented by Yukihiro Matsumoto (Matz). Mother: Ada, Smalltalk, CLU, Perl, Lisp. Grew very rapidly in 2000, outpaced Python in 2000. Became international star in 2004.

Dave and Andy are language freaks and downloaded Ruby 1.4 shortly after finishing The Pragmatic Programmer. It passed the 5-minute test, the 1/2-hour test and Dave ended up playing with it all morning. The first Pickax book was 500+ pages long, and they wrote it because there wasn't much English-language documentation on Ruby. Ever since Rails, Ruby's adoption has grown exponentially.

Ruby is a multi-paradigm language: procedural, object-oriented, functional, meta-programming. You can write procedural code, but you'll be using OO concepts at the same time. You can do all of these at the same time.

Ruby code example:

# Generate Fibonacci numbers up to a given limit

def fib_up_to(max)
  f1, f2 = 1, 1
  while f1 <= max
    puts f1
    f1, f2 = f2, f1+f2
  end
end

fib_up_to(1000)

Methods start with def and end with end. The parenthesis around the method arguments are optional.

Now Dave is ragging on Java Programmers and how they discount Ruby because of its duck typing. In a Java program, most things are dynamically typed too. This is because most objects are stored in collections and whenever you pull things out of a collection - you have to cast from Object to the real type. The argument is that you don't have to have static typing. Dave hates Generics because he thinks they should've just done automatic casting.

The basic gist of Dave's argument is that we use dynamic typing (using casting) in Java all the time and you don't see Runtime exceptions all of the place. So the biggest proponents of static typing are actually using dynamic typing all of the place.

Back to the code: in Ruby, you don't need parenthesis around conditionals (for instance in the while statement above). The main reason we have parenthesis is because of Fortran. There's no reason for them. You can put parenthesis and semi-colons in your code, but you don't need to. In this code example, the variables are scoped for the duration of the method. puts (pronounced "put s") just prints the value of a variable to the console.

class Song
  def initialize(a_title)
    @title = a_title
  end
  def title
    @title
  end
end

Instance variables in Ruby start with an @ sign. The first time you use them, they spring into existence. If you access an instance variable and it's value hasn't been set - it's value is nil. Using the return keyword at the end of a method is optional - the default is to return the last line of a method. You can change the "title" method to use

attr_reader :title 

The attr_reader call is actually a method of Class:class. The attr_reader will dynamically add an accessor (that looks like the title method above). To create a setter, you can use attr_accessor and it'll create both a getter and setter.

Ruby is a single Inheritance language.

class KaraokeSong < Song

  attr_reader :lyric

  def initialize(a_title, a_lyric)
    super(a_title)
    @lyric = a_lyric
  end
end

Unlike Java, the super call can happen in any line, or not at all. To solve the single-inheritance problem, you can use mixins and apply them to any class.

Blocks and iterators are pervasive in Ruby, and look to be very easy to use.

3.times { puts "Ho!" }

hash.each { |key, value|
  puts "#{key} -> #{value}"
end

To do method calls with blocks, you use the yield keyword.

You can use blocks to simplify Resource Management and automatically close resources.

File.open("myfile.dat") do |f|
  name = f.gets
  # whatever
end

When the above code hits end, the file is automatically closed.

Duck Typing

Strongly-typed objects, untyped variables and methods. Types are implicitly determined by the things that an object can do. Duck typing is great for testing, refactoring and maintenance. This is very similar to concepts in Smalltalk. There is a strong commitment to unit testing in Ruby - which makes duck typing even easier to use. Duck typing makes things very easy. For example, you can have a method that takes a file as a parameter - and writes data to it. You can test this method by passing in a String (which also supports << for appending) and verify that your method's logic works.

Duck typing is useful in regular code for reducing coupling and increasing flexibility. Ruby community now differentiates the type (what it can do) of an object and the class (what generated it) of an object.

The Road to Metaprogramming

Metaprogramming is really, really powerful in Ruby. Library writers use it, but most developers don't use it. The ActiveRecord framework is an example of metaprogramming. Rather than being an O/R Mapping tool, it's more of a database table wrapper. The belongs_to, has_one, has_many and other validation_presence_of method calls can be written by you. Allowing you to write DSL (domain-specific languages) that appear to be a part of the Ruby language.

4 steps to metaprogramming:

  1. Classes are open: in Ruby, you can always add methods, attributes, etc. to existing classes. For example, you can add an encrypt() method to the String class. Isn't this dangerous? What if someone changes the logic of + for math expressions. No, because if one of your programmers overrides methods that breaks things - you take them out in the parking lot and beat them with a rubber hose! The language shouldn't prohibit us from doing powerful things.
  2. Definitions are active: code executes during what would normally be compilation. As the class if being defined, the code is being executed. For example, you can check if an environment variable is set - and create methods (i.e. log.debug()) accordingly. This can be great for caching.
  3. All method calls have a receiver: Methods are executed on objects. There's always a current object: self. Methods with no explicit receiver are executed on current object.
  4. Classes are objects too: You can easily add methods to classes.

Many more Ruby features: Reflection and ObjectSpace, Marshalling and Distributed Ruby, Tk, Gtk, Fox, networking, databases, etc. Garbage collection, Threads (like Java green threads), Modules and mixins. ObjectSpace - allows you to reflect on all of the objects that exist at runtime. Marshalling allows you to serialize into binary or text formats. No XML - uses YAML instead. Unlike XML, it's readable and looks more like a properties file. Modules (and their methods) can be easily included into a class simply by using "include ModuleName".

Now Dave is going to write a program to extract book sales ranks from Amazon pages, publish them as an RSS Feed, store them in a database, and access via a web application (using Rails). Since this is likely to involve a lot of live coding, I probably won't blog the code Dave writes.

Web Applications in Ruby can be done with Simple CGI, FastCGI, mod_ruby and frameworks (like Rails). Iowa, CGIKit, Nitro and Ruby on Rails are all web frameworks in Ruby. Iowa is a Ruby implementation of Apple's WebObjects. Dave's quote: "Apple really screwed up with WebObjects, they could've owned the market on web frameworks."

Summary

  • Use Ruby because it is Lightweight. A Ruby download is under 10 MB. Ruby Gems allows easy package management for downloading libraries and documentation.
  • Use Ruby is Transparent. It's nice and easy to read - and it only takes a couple of hours to learn its syntax.
  • Portable - runs on PDAs and Mainframes.
  • Open Source - MIT/Artistic style license. 1.8.3's regular expression engine is LGPL, 1.9's engine will be BSD-style license.
  • Easy to Learn - uses the Principle of Least Surprise. Things seem to work as you'd expect. Dave knows people that've downloaded Ruby and put web applications on line in the same morning - w/o any prior knowledge of Ruby.
  • Fun! It's enjoyable to program in.

Ruby Resources

Posted in Open Source at Aug 01 2005, 11:20:05 AM MDT 9 Comments

Fixing your java.net project's homepage

If you're hosting your open source project at java.net, you might be annoyed by the fact that you can't disable the forums or issue tracker. The forums pretty much suck, mainly because there's no "remember me" on the site and it's a pain to click 3 times just to answer someone's question. They also don't have the ability to quote a previous message. In addition to the less-than-adequate forums, the issue tracker doesn't hold a candle to JIRA.

For the longest time, I've been wanting to remove both the "Discussion forums" and "Project issues" links from the AppFuse homepage. I asked the java.net folks, and they didn't have a solution. Finally, I thought of one on my own.

In case you didn't know - you can create a project_tools.html file in your project's www directory - which allows you to append items to the menu on the left site. Add a little JavaScript action and you can manipulate or remove items as well. Here's what I'm using to remove the link for the Discussion forums, as well as change the Project issues to point to JIRA. If you find any issues with this script, please let me know.

<script type="text/javascript">

function replaceLinks() {
    try {
        var tools = document.getElementById("projecttools");
        var links = tools.getElementsByTagName("a");
        for (i=0; i < links.length; i++) {
            if (links[i].getAttribute("href").indexOf("ProjectIssues") > -1) {
                links[i].setAttribute("href", "http://issues.appfuse.org/browse/APF");
                links[i].innerHTML="JIRA Issue Tracker";
            }

            if (links[i].getAttribute("href").indexOf("ProjectForumView") > -1) {
                links[i].parentNode.style.display = "none";
            }
        }
    } catch (e) {}
}

window.onload=replaceLinks;
</script>

Related: AppFuse and Equinox get some FishEye lovin'.

Posted in Java at Jul 29 2005, 02:39:36 PM MDT Add a Comment

Site Status

Last weekend's crash made me change a few things on this site - all for the better. Instead of having a single server for hosting the AppFuse Wiki, there's now a read-only mirror at http://appfuse.org/wiki. Keith (of KGB Internet) has been kind enough to setup an rsynch cron that synchronizes from raibledesigns.com daily.

As part of the "fixing", I upgraded Roller and JSPWiki. Roller's search is still broken for the most part, but it seems to be due to some orphaned records, which I can hopefully fix soon. When upgrading JSPWiki, I broke the print as HTML feature, which I hope to fix today.

Last, but not least, I've enabled Roller's Planet feature. If you have a blog where you talk about AppFuse or it's related technologies, let me know and I'll add you. As far as contributing to Roller, I'm ashamed to admit that I haven't committed any code in months (maybe even a year). Integrating Acegi Security has been on my todo list for a couple of months now - and I hope to find some time soon. Unfortunately, life, AppFuse and Spring Live keep getting in the way. ;-)

5 minutes later: Print as HTML is fixed.

Posted in Roller at Jul 29 2005, 10:29:02 AM MDT 1 Comment

OSCON: Next week in Portland

I'm starting to get pretty pumped about OSCON next week in Portland. Unlike the rest of the conferences I attend, this one is close to home. My parents live in Salem, Oregon - which is a mere 40 miles south of Portland. I spent my last two years of high school in Salem, so I still have a few friends in the area too. To get the most out of the trip, I'm flying into Portland on Sunday and commuting from Salem to Portland for the first couple days.

On Monday, I'm going to do a Ruby-immersion day and spend it listening to Dave Thomas and David Heinemeier Hansson. I hope to come out of these sessions with enough knowledge to write a webapp in Rails. Since I'm aspiring to be an open source web frameworks expert, instead of Just Java - this seems like a good fit. In the next few months, I plan on learning more about Rails, as well as other open source web frameworks in general (any and all suggestions welcome).

Tuesday, I'm giving an AppFuse Tutorial and Wednesday I'll be duking it out with Matthew Porter. Other tutorials and sessions I hope to attend are Kathy Sierra's Creating Passionate Users, Joe Walnes' SiteMesh talk and I could probably stand to learn a bit more about Beehive.

Another reason this conference will be a lot of fun is because many of the SourceBeat Authors are attending. It's always a good time when you rendezvous with a bunch of smart developers. Last, but not least, if you're attending OSCON, you might want to check the New Sessions entry on O'Reilly's blog.

Posted in Java at Jul 28 2005, 11:53:56 AM MDT 12 Comments

Taming JSF 1.1

A couple weeks ago, I received an e-mail from Ray Davis of University of California, Berkeley. In the e-mail, he provided me a link to his team's Confluence Wiki - where he describes their experience and frustrations with JSF 1.1. I really like how Ray explains the problems they experienced, as well as how they fixed them. The "request thread" scope they created sounds similar to what Spring Web Flow does.

Our experience left us very happy with Spring, moderately happy with Hibernate, and not at all happy with JSF. We did manage to deliver a Pilot Gradebook that told us what we needed to know, but sacrificed reliability, consistency, and scalability to do so.

In January 2005, when we moved to full-time work on the official Sakai 2.0 Gradebook, JSF was our biggest concern.

It's a good read for those looking to jump into JSF. I think JSF 1.2 will solve a lot of problems, but who knows how long it will take to get a RI and MyFaces version of that.

Posted in Java at Jul 27 2005, 02:51:40 PM MDT 9 Comments

Tapestry 4.0 and AppFuse

It looks like someone might integrate Tapestry 4.0 into AppFuse before I get a chance. Now that Tapestry 4 has reached Beta 3, this seems like an excellent idea to me. My only request is to not make the initial Tapestry 4 integration depend on JDK 5. I plan to start working on AppFuse 2.0 in September and it would be nice to have Tapestry 4 in AppFuse 1.9 as well as 2.0. I'd love to start this next month, but I'm attending OSCON and working on Spring Live for most of the month.

P.S. The main reason I'm writing this post is to send a trackback to the developer who wants to do this work. I was unable to leave a comment on their site, nor find a contact e-mail address. ;-)

Posted in Java at Jul 26 2005, 05:33:08 PM MDT 1 Comment

What happens at my house when you're gone for a week

I was out of town last week and Julie architected and started building a deck while I was gone! We still have quite a bit more work to do - but she did the hard part. Her mom was in town all week, so apparently she was staying up until midnight working on it everyday. Of course I knew this before today, but didn't have any pictures to impress you with. ;-)

New Deck

Posted in General at Jul 25 2005, 10:20:33 AM MDT 1 Comment

Down all weekend - what happened?

Some of you might have noticed that this site was down all weekend. I didn't notice it until Saturday morning, at which point I was so beat from traveling last week that I didn't care. I tried to fix it for 5 minutes, then gave up figuring Keith (at KGB Internet) would be able to fix it. I sent him an e-mail asking for help - hoping he could kill a stray process or something. I didn't do any more investigating until Sunday - when it was still down. This site has been extremely stable for the last few months, so the fact that it all just stopped working really had (and still has) me puzzled.

I spent about an hour trying to get things to startup again, to no avail. The problem seemed to be related to the fact that the first time I'd try to hit Roller - it would peg the CPU and the number of database connections would start to skyrocket. Within seconds, the connection pool would become exhausted and Hibernate stack traces would begin to litter my logs. I spent hours doing this dance. At one point, I suspected a DOS attack - why else would the connections skyrocket for no reason?

While I was doing the site-fix dance, I created a read-only copy of the AppFuse Wiki at http://appfuse.org/wiki. When I tried to restart Tomcat on appfuse.org, I got stack traces from the JSPs. Upgrading to the latest stable release of JSPWiki (2.2.28) fixed the problem. However, when I'd start the "wiki" app, it would hang when I tried to request pages. Guessing that this was related to the data volume of pages (11.5 MB gzipped), I cleared out the wiki pages directory and started the wiki context with no data. That worked. I was then able to copy the pages back in and get everything back to normal.

Back to this site. I tried several things last night, including upgrading Roller to 1.2, upgrading Tomcat to 5.5.9 and upgrading the JDK to 5.0. Nothing worked, so I gave up and went to bed. This morning, I decided to try JDK 5 with Roller 1.2 and the instance of Tomcat (5.0.28) that's been working so well for the past few months. Still no dice. But I did manage to get the wiki to spit out the errors it did on appfuse.org. Remembering that this was caused by JDK 5, I went ahead and upgraded JSPWiki to 2.2.28 and did the empty directory dance to get the wiki started. Voila! - everything was fixed!

So that's my story. I still don't know the root cause, but I think the JDK 5 + JSPWiki 2.2.28 combination fixed the problem. I also suspect that something is different today than yesterday b/c the number of database connections didn't immediately spike like it did yesterday. I turned the search feature off as part of my site-fixing dance, so that's still off. I've been afraid to touch anything since I got it all working again. I'll try to turn it back on tonight. In the meantime, I need to figure out how to fix the startup problem with JSPWiki.

Update: I think I figured out the problem - particularly with JSPWiki. I was using JSPWiki's PageViewCountPlugin to track page hits. This file had grown to be just over 59 MB! Deleting the file allowed JSPWiki to start problem-free.

Posted in Roller at Jul 25 2005, 10:05:03 AM MDT 1 Comment