RichFaces for JSF Use

Russell Bateman
11 February 2011
last update:

Table of Contents

Preface
JSF and Facelets are a long in the tooth?
Prerequistites
Cool, promising tutorial
Create a new Eclipse Dynamic Web Project
Differences with the tutorial
Those JARs!
The world of JSTL
MyFaces
Unknown tag warning solved?
The definitive JAR list
JSTL library and filter statements
web.xml
Second project: a Rich datatable
Third project: Rich AJAX
web.xml
faces-config.xml
BankAccountBean.java
ajax.jsp
Summary
Where from here?
Appendix: Useful links
Appendix: Whence JAR downloads

Preface

Apache MyFaces has fallen on hard times. It's questionable sometimes whether it's even maintained as a viable, stand-alone solution, but for certain, everything written about it is hopelessly inaccurate and/or out of date. It's impossible to get help solving problems: server start-up (well, I can usually help there), occasional, inexplicable missing tag errors, crashes for lack of something, lack of specificity as to what tag libraries should accompany it, how to do Facelets using it, etc. For this reason, I'm abandoning this library. Too bad. I liked it a lot; it was my introduction to JavaServer Faces.

The objective of this article or tutorial review is to establish a solid, working set of libraries with which to undertake web applications in JavaServer Faces and Facelets.

A secondary objective is to redo these projects using Maven. You may find this undertaking full of drudgery because I'm carefully studying the effects of using different JARs and combinations of JARs as I go. It's very incremental; I need to be able to retrace my steps in case I have to back up and go down a different path.

A higher objective is for me to be able to help others sort out their troubles. I had some kind help from different circles (especially stackOverflow and Java Ranch), but nothing really clicked.

But, JavaServer Faces and Facelets are a little long in the tooth, no?

I'm a late-comer to JEE. I can skip everything all the way up to JBoss Seam or Spring—where this world had just arrived when I got on board. But, I have a really hard time understanding things without peeling the onion. Out there I'm still getting recruiters calling wanting experience in truly dinosaur frameworks like Enterprise Java Beans and Struts. I do draw the line there. But as soon as I learned JSP, I heard about how JSF was the new cool solution beginning a couple of years before that.

A big problem has been getting over the nastiness that is sorting out a set of libraries to use. I can't seem to carry my original set very far because a lot has changed: JSF has moved on, developers are building with Maven, there's a lot of structural overhead that needs to be set down for those following me.

Anyway, let's move on...

Prerequisites

If you haven't figured this out already, you must understand that a prerequisite to this article is the setting up of Eclipse for web application development. If you need help with this, visit Setting Up Eclipse—a Summary. You'll need to set up the Eclipse IDE for Java EE Developers, a Sun JDK and Apache Tomcat.

Cool, promising tutorial

This document represents the hope that I can solve the problems I discussed in the preface using RichFaces. Things start off well. I'm especially impressed with the graphic on this page (click it to see the tutorial). How else would I learn that RichFaces depends on MyFaces? Old, dependable MyFaces!

Create a new Eclipse Dynamic Web Project

Before we get too much further, be sure to create each new project implied in this article using the wizard for new Dynamic Web Projects, and when you establish Configuration on the first page, use JavaServer Faces v1.2 Project, later in the wizard, you'll have to set up the libraries to some degree in order to get past the wizard (which won't proceed until you set at least something up). For your workspace, once you work through this aspect of things, which is explained in more detail below, you'll find them already in place the next time you run the wizard.

So, it would appear that, besides RichFaces, we need Apache MyFaces and Common, on which MyFaces depends as we already know. I've rarely read a JSF (or other) tutorial in which any attempt was made to lay the exact JAR dependency list out.

Following this information, an entire web.xml. (Scroll the page in that tutorial just a bit if you are following along.)

Differences with the tutorial

I can't say exactly when this tutorial was published, but it must be at least a couple of years ago (2008-2009), maybe sooner still. I'm going to update to the latest libraries that I can get and still get things working.

I'm going to use Tomcat alone and not JBoss to do this work. I have nothing against JBoss, I just want always to be able to get along without it. This tutorial is a sort of JBoss advertisement. I get it, but I want to see if I can just use Tomcat.

Also, I'm not going to use MyEclipse. Instead, I'll use standard Eclipse. A few years back when Eclipse Web Tools Platform was very young or non-existent, MyEclipse made a great deal of sense. However, today it's just paying for something that's done much better in modern Eclipse by a much wider audience. And, it tends to get you to do things in a certain way, just as does NetBeans, rather than stay out of your way and let you make the decisions. I don't like my IDE dictating what approaches I take (not that MyEclipse absolute dictates, but...).

Those JARs!

This is the tedious part I told you about.

Doing this tutorial, I found that I also need a JavaServer Pages Standard Tags library. Not sure why the tutorial didn't show that. It likely stems from JBoss already having JSTL within while Tomcat doesn't? As I don't use JBoss, I don't know how that solved the need in Eclipse. Hmmmm... much more to learn here. Anyway, if you're following me here, you must add these to the library suite. Here is my library suite:

commons-beanutils-1.8.3.jar commons-codec-1.4.jar commons-collections-3.2.1.jar commons-digester-2.1.jar commons-discovery-0.4.jar commons-logging-1.1.1.jar jstl-api-1.2.jar jstl-impl-1.2.jar myfaces-api-1.2.8.jar myfaces-impl-1.2.8.jar richfaces-api-3.3.3.Final.jar richfaces-impl-3.3.3.Final.jar richfaces-ui-3.3.3.Final.jar

The world of JSTL

Where do you get jstl-xxx-1.2.jar? Yeah, that's hard now. You have to cast around. I finally went back into an old Eclipse project I had and got it from there. I haven't completely sorted out the confusion that the world (Sun, mostly) has made of this library and others like it. Because when you go a modern one from Sun, you end up missing stuff, or it breaks when you try to run. Someday I hope to make a rock-solid inventory of the world of JSTL libraries. In the meantime, it just has to work.

MyFaces

Optionally, I also tried this other set of MyFaces which the Eclipse Dynamic Web Project wizard wanted to bring in sort of automatically (via download, actually, see Download Library illustration. When you establish Configuration as JavaServer Faces v1.2 Project, later in the wizard, you reach the JSF Capabilities dialog where you click on the Download library... button. You are presented with JSF 1.2 (Apache Myfaces JSF Core-1.2 API 1.2.9) from the Apache Software Foundation. This is what comes with that:

commons-beanutils-1.7.0.jar commons-codec-1.3.jar commons-collections-3.2.jar commons-digester-1.8.jar commons-discovery-0.4.jar commons-logging-1.1.1.jar myfaces-api-1.2.9.jar myfaces-impl-1.2.9.jar

Strangely, MyFaces is a later revision than what I had been using (1.2.8), but Apache Commons is much further behind for some of its JARs over what you can lay your hands on at the Apache site. So, I'm going to move ahead there too.

Moreover, I sometimes got actual (red) errors in test.jsp on the taglib ... prefix="h", etc. definitions at the top of this file. I don't get this with MyFaces 1.2.9, but I do get the individual Unknown tag warnings. Never fear, http://localhost:8080/RichFacesTutorial/faces/test.jsp does indeed work.

So, here is my latest set of libraries that give me a) a running state, b) warnings for <f:____ /> and <h:____ /> tags in test.jsp, but no c) errors.

commons-beanutils-1.8.3.jar commons-codec-1.4.jar commons-collections-3.2.1.jar commons-digester-2.1.jar commons-discovery-0.4.jar commons-logging-1.1.1.jar jstl-api-1.2.jar jstl-impl-1.2.jar myfaces-api-1.2.9.jar myfaces-impl-1.2.9.jar richfaces-api-3.3.3.Final.jar richfaces-impl-3.3.3.Final.jar richfaces-ui-3.3.3.Final.jar

As I have even later versions of Apache MyFaces, I tried those. They shipped with the same "out-of-date" Apache Commons JARs as MyFaces 1.2.9 (with one exception: commons-beanutils-1.8.3.jar). So, I keep my own later versions. Now my latest set of libraries is below. And, I still get the unknown tag warnings. But, test.jsp runs nevertheless.

commons-beanutils-1.8.3.jar commons-codec-1.4.jar commons-collections-3.2.1.jar commons-digester-2.1.jar commons-discovery-0.4.jar commons-logging-1.1.1.jar jstl-api-1.2.jar jstl-impl-1.2.jar myfaces-api-2.0.4.jar myfaces-bundle-2.0.4.jar myfaces-impl-2.0.4.jar richfaces-api-3.3.3.Final.jar richfaces-impl-3.3.3.Final.jar richfaces-ui-3.3.3.Final.jar

So, at this point, I'm asking how to rid myself of the JSP validation warnings?

Unknown tag warning solved?

The answer is that as I moved on to create my next project using these JARs, I discovered that myfaces-bundle-2.0.4.jar is both the API and implementation bundled together. Because of that, I was unable to create the second project (the wizard would not allow me to do it). So, I returned to the first project to remove this JAR in favor of keeping the two individual ones. once I had done that, the JSP validation warnings disappeared. Though still dim, the conclusion I reached is that a) you can thwart the wizard's warning by later duplicating stuff and getting away with it; b) the duplication may lead the JSP validator to the conclusion that one or more tags aren't known.

The definitive JAR list

Apache Commons commons-beanutils-1.8.3.jar commons-codec-1.4.jar commons-collections-3.2.1.jar commons-digester-2.1.jar commons-discovery-0.4.jar commons-logging-1.1.1.jar JSTL 1.2 jstl-api-1.2.jar jstl-impl-1.2.jar MyFaces 2.0.4 myfaces-api-2.0.4.jar myfaces-impl-2.0.4.jar RichFaces 3.3.3 richfaces-api-3.3.3.Final.jar richfaces-impl-3.3.3.Final.jar richfaces-ui-3.3.3.Final.jar

See Appendix: Whence JAR downloads for whence to get some of these libraries.

Reporting on needing the JSTL library and filter statements

We've already announced that this combination of JARs works minus the unknown tag warnings. This is to cap off the symptoms of it not working and what we did to fix that (since that's in fact the most important part of this write-up).

At some point, you look and observe that the JSP file will have warnings such as Unknown tag (f:view) or Unknown tag (h:form) This is very annoying as the application works and isn't in fact missing those definitions. What's more, the taglib ... prefix="h", etc. definitions at the top aren't flagged as errors.

web.xml:

This is what I came up with for Tomcat (and not JBoss) use.

<?xml version="1.0" encoding="UTF-8"?>
<web-app xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
       xmlns="http://java.sun.com/xml/ns/javaee"
       xmlns:web="http://java.sun.com/xml/ns/javaee/web-app_2_5.xsd"
       xsi:schemaLocation="http://java.sun.com/xml/ns/javaee
                       http://java.sun.com/xml/ns/javaee/web-app_2_5.xsd"
       id="WebApp_ID"
       version="2.5">
  <display-name>RichFacesTutorial</display-name>

  <filter>
    <display-name>RichFaces Filter</display-name>
    <filter-name>richfaces</filter-name>
    <filter-class>org.ajax4jsf.Filter</filter-class>
  </filter>
  <filter-mapping>
    <filter-name>richfaces</filter-name>
    <servlet-name>Faces Servlet</servlet-name>
    <dispatcher>REQUEST</dispatcher>
    <dispatcher>FORWARD</dispatcher>
    <dispatcher>INCLUDE</dispatcher>
  </filter-mapping>

  <servlet>
      <servlet-name>Faces Servlet</servlet-name>
      <servlet-class>javax.faces.webapp.FacesServlet</servlet-class>
      <load-on-startup>1</load-on-startup>
  </servlet>
  <servlet-mapping>
      <servlet-name>Faces Servlet</servlet-name>
      <url-pattern>/faces/*</url-pattern>
  </servlet-mapping>

  <listener>
      <listener-class>
          org.apache.myfaces.webapp.StartupServletContextListener
      </listener-class>
  </listener>

  <context-param>
      <param-name>org.richfaces.SKIN</param-name>
      <param-value>blueSky</param-value>
  </context-param>
  <context-param>
      <param-name>javax.servlet.jsp.jstl.fmt.localizationContext</param-name>
      <param-value>resources.application</param-value>
  </context-param>
  <context-param>
      <param-name>javax.faces.STATE_SAVING_METHOD</param-name>
      <param-value>client</param-value>
  </context-param>
  <context-param>
      <param-name>org.apache.myfaces.ALLOW_JAVASCRIPT</param-name>
      <param-value>true</param-value>
  </context-param>
  <context-param>
      <param-name>org.apache.myfaces.PRETTY_HTML</param-name>
      <param-value>true</param-value>
  </context-param>
  <context-param>
      <param-name>org.apache.myfaces.DETECT_JAVASCRIPT</param-name>
      <param-value>false</param-value>
  </context-param>
  <context-param>
      <param-name>org.apache.myfaces.AUTO_SCROLL</param-name>
      <param-value>true</param-value>
  </context-param>

  <welcome-file-list>
      <welcome-file>index.html</welcome-file>
      <welcome-file>index.htm</welcome-file>
      <welcome-file>index.jsp</welcome-file>
      <welcome-file>default.html</welcome-file>
      <welcome-file>default.htm</welcome-file>
      <welcome-file>default.jsp</welcome-file>
  </welcome-file-list>
</web-app>

Note on <welcome-file-list ... />: You only need list your specific web site's expectations. In testing, as long as you're willing to include the exact name of the start-up file, you do not need to list it in this section of web.xml in order for your example to work.

The result was as seen in the tutorial. There were some runtime errors until JSTL libraries and the <filter /> section was added.

This is the runtime result when the JavaServer Pages Standard Tag Library is missing. Why is this not listed in the tutorial? Perhaps this is a function of what's missing from Tomcat, but offered in JBoss. The give-away of the solution is in green, which isn't in the original Tomcat output of course.

... INFO: Server startup in 2057 ms Feb 11, 2011 5:27:03 PM javax.faces.webapp._ErrorPageWriter handleThrowable SEVERE: An exception occurred java.lang.NoClassDefFoundError: javax/servlet/jsp/jstl/core/Config at org.apache.myfaces.application.jsp.JspViewHandlerImpl.renderView(JspViewHandlerImpl.java:335) at org.ajax4jsf.application.ViewHandlerWrapper.renderView(ViewHandlerWrapper.java:100) at org.ajax4jsf.application.AjaxViewHandler.renderView(AjaxViewHandler.java:176) at org.apache.myfaces.lifecycle.RenderResponseExecutor.execute(RenderResponseExecutor.java:41) at org.apache.myfaces.lifecycle.LifecycleImpl.render(LifecycleImpl.java:140) at javax.faces.webapp.FacesServlet.service(FacesServlet.java:187)

This is what happens in the absence of the <filter /> statements in web.xml. For me, the solution suggested was a) seeing the AJAX-related filter stuff in the tutorial and then seeing AJAX again in the Tomcat output.

... INFO: Server startup in 2033 ms Feb 11, 2011 5:20:25 PM javax.faces.webapp._ErrorPageWriter handleThrowable SEVERE: An exception occurred javax.faces.FacesException: Exception while calling encodeEnd on component : {Component-Path : \ [Class: org.ajax4jsf.component.AjaxViewRoot,ViewId: /test.jsp][Class: javax.faces.component.html.HtmlForm,\ Id: j_id_jsp_914825448_1][Class: org.richfaces.component.html.HtmlSpacer,Id: j_id_jsp_914825448_2]} at javax.faces.component.UIComponentBase.encodeEnd(UIComponentBase.java:652) at javax.faces.component.UIComponent.encodeAll(UIComponent.java:261) at javax.faces.component.UIComponent.encodeAll(UIComponent.java:257) at javax.faces.component.UIComponent.encodeAll(UIComponent.java:257) at org.apache.myfaces.application.jsp.JspViewHandlerImpl.actuallyRenderView(JspViewHandlerImpl.java:427)

Second project: a Rich datatable

We'll create a second project, RichFacesDataTable for this in order to preserve the first. I found that having eliminated myfaces-bundle-2.0.4.jar enabled me to complete the wizard.

(We've clicked the next link at the bottom of the first page of the original tutorial.)

As I usually do (because I'm squeamish about the clean state of originally auto-generated files), I replaced the new web.xml with the one from the RichFacesTutorial (first) project.

Predictably, the tutorial doesn't name the JSP (hope it's a JSP) file. So, we'll just call it test.jsp again. And (just as predictably) the <style ... /> tag is out of place in the file.

I take great care in implementing the code for this sample. In the first place, things are badly formatted. Second, the backing bean is mismanaged in faces-config.xml. The standard for the identifier representing the bean (in test.jsp) is to drop "Bean" from the end and drop the first letter to lower case as it appears as if a local variable. This is what Spring and many others consider best practice.

I also correct the English; it's a small matter. Otherwise, I get the same output, still no errors or warnings. I think this is a keeper.

Third project: Rich AJAX

Just to make certain we're not getting too far off track, here are our principal files, which are different from the tutorial's by a) enactment of best practices for naming and b) for the slight difference that using Tomcat and other limits we've artificially placed on our work here.

web.xml:

This file, except for the display-name element, remains identical to what we've been using in the preceeding projects. Here, we've retained the comments that the Eclipse new Dynamic Web Project wizard inserts.

<?xml version="1.0" encoding="UTF-8"?>
<web-app xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
       xmlns="http://java.sun.com/xml/ns/javaee"
       xmlns:web="http://java.sun.com/xml/ns/javaee/web-app_2_5.xsd"
       xsi:schemaLocation="http://java.sun.com/xml/ns/javaee
                       http://java.sun.com/xml/ns/javaee/web-app_2_5.xsd"
       id="WebApp_ID"
       version="2.5">
  <display-name>RichFacesAjax</display-name>

	<filter>
		<display-name>RichFaces Filter</display-name>
		<filter-name>richfaces</filter-name>
		<filter-class>org.ajax4jsf.Filter</filter-class>
	</filter>
	<filter-mapping>
		<filter-name>richfaces</filter-name>
		<servlet-name>Faces Servlet</servlet-name>
		<dispatcher>REQUEST</dispatcher>
		<dispatcher>FORWARD</dispatcher>
		<dispatcher>INCLUDE</dispatcher>
	</filter-mapping>

	<servlet>
		<servlet-name>Faces Servlet</servlet-name>
		<servlet-class>javax.faces.webapp.FacesServlet</servlet-class>
		<load-on-startup>1</load-on-startup>
	</servlet>
	<servlet-mapping>
		<servlet-name>Faces Servlet</servlet-name>
		<url-pattern>/faces/*</url-pattern>
	</servlet-mapping>

	<listener>
		<listener-class>org.apache.myfaces.webapp.StartupServletContextListener</listener-class>
	</listener>

	<context-param>
		<param-name>org.richfaces.SKIN</param-name>
		<param-value>blueSky</param-value>
	</context-param>
	<context-param>
		<param-name>javax.servlet.jsp.jstl.fmt.localizationContext</param-name>
		<param-value>resources.application</param-value>
	</context-param>
	<context-param>
		<description>
		State saving method: 'client' or 'server' (=default). See JSF Specification 2.5.2.
		</description>
		<param-name>javax.faces.STATE_SAVING_METHOD</param-name>
		<param-value>client</param-value>
	</context-param>
	<context-param>
		<description>
		This parameter tells MyFaces if JavaScript code should be allowed in
		the rendered HTML output.
		If JavaScript is allowed, command_link anchors will have JavaScript code
		that submits the corresponding form.
		If JavaScript is not allowed, the state saving info and nested parameters
		will be added as URL parameters.
		Default is 'true'
		</description>
		<param-name>org.apache.myfaces.ALLOW_JAVASCRIPT</param-name>
		<param-value>true</param-value>
	</context-param>
	<context-param>
		<description>
		If true, rendered HTML code will be formatted, so that it is
		'human-readable' i.e. additional line separators and whitespace will be
		written, that do not influence the HTML code.
		Default is 'true'
		</description>
		<param-name>org.apache.myfaces.PRETTY_HTML</param-name>
		<param-value>true</param-value>
	</context-param>
	<context-param>
		<param-name>org.apache.myfaces.DETECT_JAVASCRIPT</param-name>
		<param-value>false</param-value>
	</context-param>
	<context-param>
		<description>
		If true, a JavaScript function will be rendered that is able to restore
		the former vertical scroll on every request. Convenient feature if you
		have pages with long lists and you do not want the browser page to always
		jump to the top if you trigger a link or button action that stays on the
		same page.
		Default is 'false'
		</description>
		<param-name>org.apache.myfaces.AUTO_SCROLL</param-name>
		<param-value>true</param-value>
	</context-param>

	<welcome-file-list>
	    <welcome-file>index.html</welcome-file>
	    <welcome-file>index.htm</welcome-file>
	    <welcome-file>index.jsp</welcome-file>
	    <welcome-file>default.html</welcome-file>
	    <welcome-file>default.htm</welcome-file>
	    <welcome-file>default.jsp</welcome-file>
	</welcome-file-list>
</web-app>
faces-config.xml:

See that we've slightly renamed the backing bean as well as the variable by which it will be referenced in JSF. The naming relationship here is held by Spring and many developers to be "best practice".

<?xml version="1.0" encoding="UTF-8"?>
<faces-config
    xmlns="http://java.sun.com/xml/ns/javaee"
    xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
    xsi:schemaLocation="http://java.sun.com/xml/ns/javaee http://java.sun.com/xml/ns/javaee/web-facesconfig_1_2.xsd"
    version="1.2">

	<managed-bean>
		<managed-bean-name>bankAccount</managed-bean-name>
		<managed-bean-class>com.sample.BankAccountBean</managed-bean-class>
		<managed-bean-scope>session</managed-bean-scope>
	</managed-bean>

</faces-config>
BankAccountBean.java:

See that we've slightly renamed the backing bean as already noted.

package com.sample;

public class BankAccountBean
{
	private String name;
	private String account;

	public String getAccount()	{ return account; }
	public String getName()		{ return name; }

	public void setAccount( String account )	{ this.account = account; }
	public void setName( String name )			{ this.name = name; }

	public void searchAccount() { account = name + "1234X"; }
}
ajax.jsp:

Again, the variable representing the backing bean is bankAccount by convention.

<%@ taglib uri="http://richfaces.org/a4j" prefix="a4j"%>
<%@ taglib uri="http://richfaces.org/rich" prefix="rich"%>
<%@ taglib uri="http://java.sun.com/jsf/html" prefix="h"%>
<%@ taglib uri="http://java.sun.com/jsf/core" prefix="f"%>

<html>
<body>
<f:view>
	<a4j:form>
		<h:panelGrid columns="3">
			<h:outputText value="Name:" />
			<h:inputText value="#{bankAccount.name}" />
			<a4j:commandLink reRender="out" action="#{bankAccount.searchAccount}">
				<h:outputText value="Enter name" />
			</a4j:commandLink>
		</h:panelGrid>
	</a4j:form>

	<rich:spacer height="7" />
	<br />
	<h:panelGroup id="out">
		<h:outputText value="Your account is " rendered="#{not empty bankAccount.account}" />
		<h:outputText value="#{bankAccount.account}" />
		<h:outputText value="!" rendered="#{not empty bankAccount.account}" />
	</h:panelGroup>

</f:view>
</body>
</html>

Invoke this application

In the Eclipse Server view (tab), right-click Tomcat v6.0 Server at localhost and start it. Then, use this URI in a browser http://localhost:8080/RichFacesAjax/ajax.faces or right-click ajax.jsp and choose Run As. Here it is after a name has been filled in and "Enter name" clicked. (The point to this example in any AJAX tutorial is that the only thing changed on the page after clicking "Enter name" is the addition of "Your account is..." since AJAX practice is not to re-get the entire page, but only the bits that change.)

Summary

What have we learned here?

I've learned how to set up JARs, web.xml and faces-config.xml to implement a small web application. I've learned how to detect and solve a couple of missing JAR problems. I now have a definitive, modern set of JARs with which to do JavaServer Faces.

Where from here?

From here I'm going to tackle Facelets in a separate article. Facelets are the next step beyond JavaServer Faces in that they begin providing standard views or templates that reduce the amoung of work you have to do to standardize views and implement large-scale web sites. Facelets allow you to dump JavaServer Pages technology completely in favor of XHTML. In fact, as I've already been doing JSF for some time, this article was really to solve the shifting JAR sands under me in preparation to move forward on Facelets.

Why are Facelets interesting? XHTML documents are completely editable in web page creation tools such as Dreamweaver. This means that your web-layout and -graphics folks don't have to have any programming understanding.

As noted in this article, another goal is to integrate Maven builds. Now that I have a definitive JAR list, I can go find which Maven repositories provide them. I have the goal to come back here and add an appendix to this article on this topic.


Appendix: Useful links


Appendix: Whence JAR downloads

Here's where I've found downloads for all or most of the JARs in this article.