My "User Libraries" in Eclipse are not deployed with Vaadin app

I have libraries such as "
Joda Time
" configured as “User Libraries” in Eclipse’s Prefs > Java > Build Path.

My problem: → These libraries are not available to my Vaadin app.

I know my library is configured properly in Eclipse because:

(a) I see the libraries listed in the Project Explorer > myproject > Java Resources > Libraries.

(b) Code like this is recognized by the Eclipse IDE and compiles:

org.joda.time.DateTime now = new org.joda.time.DateTime();

(c) That same code works in a plain simple Java app.

But when I add that line to the simple Vaadin app (buttonClick listener) built according to the the Tutorial, I get this error at runtime when I click the button:

java.lang.ClassNotFoundException: org.joda.time.DateTime

Perhaps I need to turn on some setting in Eclipse. I’ve done some Swing programming with these same libraries in Eclipse. But I’m new to web development like Vaadin in Eclipse.

Using: Eclipse Java EE IDE for Web Developers, Version: Indigo Release, Build id: 20110615-0604, on Mac OS X 10.6.7, with Tomcat 7.0.21.

I’ve found the temporary Tomcat deployment folders and files here:

…/workspace/.metadata/.plugins/org.eclipse.wst.server.core/tmp0/wtpwebapps/myproject/WEB-INF/

Sure enough, the vaadin-6.7.0.beta1.jar file is being deployed to:

…/workspace/.metadata/.plugins/org.eclipse.wst.server.core/tmp0/wtpwebapps/myproject/WEB-INF/lib/

but not my User Libraries.

When a web app is deployed, only the stuff inside the [tt]
WebContent
[/tt] folder in Eclipse is deployed. Moreover, the servlet containers require that they can find the libraries from under [tt]
WEB-INF/lib
[/tt].

You therefore need to put any libraries needed by your application to [tt]
WebContent/WEB-INF/lib
[/tt]. They are listed in Eclipse in Project Explorer under
Java Resources → Libraries → Web App Libraries
.

You don’t even need to add such Jars individually to the project, as everything under the WEB-INF/lib is included automatically.

Libraries that are used only during compilation, such as GWT libraries, can be located elsewhere.

So, the upshot is that the web tools in Eclipse do not work with the usual “User Libraries” defined in Eclipse’s preferences?

I already have a dozen such “User Libraries” defined in Eclipse for Java Swing development. But to build a web app, I need to redundantly define those libraries as “Web App Libraries”?

For posterity, the exact steps to do this (defining “Web App Libraries”) seems to be:

  1. Create your Vaadin project.
  2. Locate this folder in your project’s folder: WebContent/WEB-INF/lib
  3. Drag your library’s jar to that ‘lib’ folder.
  4. In Eclipse, context-click on your project to choose Refresh.
  5. In the “Project Explorer” of Eclipse, navigate to: Java Resources → Libraries → Web App Libraries
  6. Verify your library’s jar is there.

At that point you should be ready to write code, compile, and deploy using that library.

Optionally, you can specify your library’s source code (for debugging) and JavaDoc (for help in the code editor).

  1. In the “Project Explorer” of Eclipse, navigate to: Java Resources → Libraries → Web App Libraries
  2. Context-click to choose Properties
  3. Click the “Java Source Attachment” tab to link to source code.
  4. Click the “JavaDoc Location” tab to link to JavaDoc jar or folder.

Yes, that’s the way it goes. It is redundant, but that’s how web applications are packaged and deployed.

Some servers or portals, such as Liferay, can be an exception and have a lib dir shared by all portlets.

They do and they don’t…

Eclipse should be able to use all kinds of build path entries, although it might be that e.g. widgetset compilation does not take into account libraries in certain places (like referenced projects). However, when you build the WAR that will actually be deployed to the server, only the Web App Libraries are included by default. You can customize this (for your Eclipse workspace) using Project Properties → Deployment Assembly, but I would recommend simply using the standard WEB-INF/lib.

If you are using shared libraries on the server, note that they might get loaded with a different classloader instance than that used for your application.