Question

Summary

Is that possible for webapps deployed on linux + tomcat5.5 to use/see all /usr/share/java/ jars automatically?

Details

I'm packaging my java webapp for Ubuntu (yet the question is related to any linux-based distro) and going to make it depend on tomcat.

I'm going to put context descriptor (an xml file) to /usr/share/tomcat5.5/conf/Catalina/localhost/ to make my app deployed. Having my web dir here: /usr/share/<appname>/web, how can I enable my app to use java jar libs installed in the system (/usr/share/java)?

I can't just symlink /usr/share/java -> <webdir>/WEB-INF/lib, since I have my custom jars need to be placed in lib dir.

Bad Solution

The solution I've found so far is to symlink each required jar to <webdir>/WEB-INF/lib/.

This is not so good, because I have to symlink a lot of jars and even worse to symlink all jars my direct dependency lib (jar) requires (and so on). In case my direct dependency lib changes its list of required jars I'll have to maintain that symlinks.

Was it helpful?

Solution

You should not do that. Java EE applications are the supposed to be self sufficient and not depend on any resources outside the deployment package other than those provided by the container. So you should take the libs you need from that directory and add it to your war or ear package.

This guarantees that your application will behave the same wherever you deploy it and you will not be subject to unexpected changes in the versions of the libs in /usr/share/java....

OTHER TIPS

According to the Tomcat classloading documentation, you need to put any shared libs that should be available to all Tomcat apps in the $CATALINA_BASE/shared/lib library -- so one way to do what you're looking to do is to move your libraries from /usr/share/java to $CATALINA_BASE/shared/lib.

BUt if I'm not misunderstanding that same documentation, Tomcat also makes the system-wide CLASSPATH variable's contents available to the classloader at launch, so if your directory -- /usr/share/java -- were included in the system-wide CLASSPATH variable, then that should work too. I've never done this, though; Tomcat's method of making the contents of $CATALINA_BASE/shared/lib available Tomcat-wide has always served me perfectly.

entzik's answer lead me to the following solution.

I'm going to use modified "bad solution" (see question).

Modifications are following:

  1. Depend on specific package version for all dependencies (affects "control" file while packaging for deb)
    example: libcommons-io-java ( = 1.3.1) instead of just libcommons-io-java
  2. Symlink to actual jar files in `/usr/share/java` and not "generalized" ones
    example:
    webdir/WEB-INF/lib/commons-io.jar -> /usr/share/java/commons-io-1.3.1.jar
    and not
    webdir/WEB-INF/lib/commons-io.jar -> /usr/share/java/commons-io.jar

This modifications ensure webapp is not broken if administrator installed new version of a library (commons-io for example).

The downside is this approach clearly inflates system with used-by-only-one-app versions of libraries and may lead to problem some other application/library can't install due to version conflict. I guess both potential problems are minor if we are speaking about libraries.

You have two options, one is to let the classloader provide the libraries to all java programs and the other is to let the classloader provide the libraries to all tomcat contexts.

Add your symlinks to /usr/lib/jvm/java-1.5.0-sun-1.5.0.11/jre/lib (note you may need to specify a different version in this path) to allow all java programs access to these libraries or add them to Tomcat's shared libraries at var/lib/tomcat5.5/shared/libs (again, the version number may be different) for access by all Tomcat contexts.

I should also note that these directory locations were taken from Ubuntu "Feisty".

Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top