Library quirk in the new Eclipse, and random framework musings

I’ve been working with Struts 2 recently, and like most frameworks it relies on a set of jar files.  I like to work with Eclipse as my primary IDE.  In that framework, my normal mode of operating is to create a User Library containing the jar files I need and then add it to my Dynamic Web Projects through the Java Build Path configuration.

It seems that the system has changed in Eclipse 3.3, aka Europa.  I’m working with the Web Tools Platform plugin, so at least I have dynamic web project capabilies.  I can also set up a Tomcat server easily.

What’s changed is that now, when I add a User Library to the build path, Eclipse warns me that it won’t be deployed to the server.  The warning is:

“Classpath entry org.eclipse.jdt.USER_LIBRARY/libname will not be exported or published.  Runtime ClassNotFoundExceptions may result.”

Yer darn tootin’ they’ll result.  I suppose this is a feature, not a bug, because I have had situations where the libraries were already added to my server’s classpath so I didn’t want to duplicate them in the war file.  Also, some war files become enormous because of all the libraries used.  (The last time I wrote a simple app that used JPA, Spring, and Hibernate the resulting war file was huge.  And the size of the war file that comes with a trivial Grails application is easily over 10 megs.)  Now Eclipse leaves the libraries out of the war by default.

I’m reminded of when the Collections framework for Java was created, and ArrayList turned out to be exactly like Vector but without the synchronization.  The theory seemed to be that you can always add synchronization later (Collections.synchronizedList(myList)), but that you couldn’t remove it from Vector when you didn’t need it.  This change has the same feel to it — you can always figure out a way to deploy the libraries, but you never had a way to get rid of them short of editing the resulting war file.

That’s not necessarily a good thing for me, though.  I’m always tempted to add libraries to my server’s classpath, partly to keep the size of the individual war files down, and partly because I tend to use the same libraries over and over and I hate packing them into every single application.  All those repeated files feel like a waste.

Still, it’s dangerous not to include the jar files in the web application itself.  Version problems can easily arise, especially because I tend to upgrade to the latest version of a given library whenever I can.  For that reason, I’ve resisted the temptation to, say, put Hibernate and Spring into my server’s lib directory.

So what do I do in Eclipse?  It turns out there are two solutions:

1. Declare the libraries to be module dependencies for the war.  That’s done by going into the project properties, then Properties –> J2EE Module Dependencies –> Select All.  Then Eclipse treats the libraries the same way it would any dependent project.

Eclipse Properties J2EE Module Dependencies

2. The other approach is to go on the file system and copy the jar files directly into the WEB-INF/lib directory of the project, then do a refresh.  Apparently Eclipse is smart enough to then add the jars to the classpath for my source code.

I’m not sure which way I’ll prefer in the future.  Eclipse does have a Navigator view which supports drag-and-drop copying, so that’s easy enough.  Still, I hate to leave the IDE when I’m in the middle of using it.

This is also one of the few situations where using MyEclipse wouldn’t make any difference.  Version 6 truly rocks, but it doesn’t have a predefined library for Struts 2.  Maybe Struts 2 was still too new when MyEclipse 6 was being developed.

As an aside, it should be interesting to see which way the framework wars will turn in 2008.  There’s still a huge installed base of Struts 1.* clients out there, but many of them are looking at other options.  The other page-based framework I’ve used is Spring Web MVC, which has its own learning curve.

JSF is part of the Java EE spec, but if you’re used to a page-based framework the switch to a component-based framework is not trivial.  Tapestry is still out there, and it has a few very fervent advocates, but I haven’t heard much growth in it.  I also haven’t gotten any calls about it in quite some time.  Seam is growing, too, but I expect that’ll be popular among the same crowd that likes JSF, since it’s based on JSF anyway.   Of course, there’s also Google Web Toolkit if you want to build a desktop application inside a browser.

Struts 2 is very interesting, and has the modern feel of interceptors and filters and POJOs (oh my!).  It has Spring-like dependency injection, though I think they use Guice by default rather than Spring, not that it really matters.  I never learned WebWork before the merger, so the learning curve has been pretty substantial for me.  Personally I feel that Struts 2 is so fundamentally different than Struts 1 that I’m surprised they kept the Struts name.  That marketing decision may make all the difference, however.

I’ll keep an eye on all of them, of course, but for my own applications, I like Grails. 😉

(Yes, I know that’s the same as saying Spring Web MVC.  We’ll see how that plays out, too.)

About Ken Kousen
I teach software development training courses. I specialize in all areas of Java and XML, from EJB3 to web services to open source projects like Spring, Hibernate, Groovy, and Grails. Find me on Google+ I am the author of "Making Java Groovy", a Java / Groovy integration book published by Manning in the Fall of 2013, and "Gradle Recipes for Android", published by O'Reilly in 2015.

8 Responses to Library quirk in the new Eclipse, and random framework musings

  1. Travis says:

    Good post… This is what I needed.

  2. I am running into a related but slightly different situation. In my case I have a bunch of JARs that I definitely do not want deployed to Tomcat, because I’m using the JARs only for unit testing. (For example, I wouldn’t want to deploy easymock-2.3.jar, spring-mock.jar, or gienah-testing-bin-E0.32.jar.) But Eclipse generates annoying warnings about these JARs. Ideally there would be some way to flag or otherwise indicate that these are not supposed to be deployed, and so no warning is necessary.

  3. Jason Whitaker says:

    This is great! Exactly what i was looking for.

  4. Jeff says:

    I’ve got the same warning, but for files that are no longer in the classpath. I had a JAR in an external place that I have since either (in one case) moved to WEB-INF/lib or (in another) removed from my project, yet the errors persist…

  5. struts says:

    this is so great!
    perfect.

    thanks a mil,
    Cheers,
    Chrissy

  6. Martin says:

    I’ve solved that differently (with Eclipse Helios SR1):

    Go to “Properties/Deployment Assembly”, click on “Add…”, select “JavaBuild Path Entries” and choose your jars 🙂

  7. Mario says:

    ..didnt work in my situation, but the advice from Martin solved the prob! Thanks a lot! 🙂

  8. Arvind Singh says:

    Martin’s solution works, thanks to both original author and Martin

Leave a Reply

Fill in your details below or click an icon to log in:

WordPress.com Logo

You are commenting using your WordPress.com account. Log Out / Change )

Twitter picture

You are commenting using your Twitter account. Log Out / Change )

Facebook photo

You are commenting using your Facebook account. Log Out / Change )

Google+ photo

You are commenting using your Google+ account. Log Out / Change )

Connecting to %s

%d bloggers like this: