Gentoo Websites Logo
Go to: Gentoo Home Documentation Forums Lists Bugs Planet Store Wiki Get Gentoo!
Bug 333153 - www-servers/tomcat-6.0.26-r1, www-servers/tomcat-6.0.28: CLASSPATH set in the conf.d file is not passed to Java
Summary: www-servers/tomcat-6.0.26-r1, www-servers/tomcat-6.0.28: CLASSPATH set in the...
Status: RESOLVED FIXED
Alias: None
Product: Gentoo Linux
Classification: Unclassified
Component: [OLD] Server (show other bugs)
Hardware: All Linux
: High normal (vote)
Assignee: Mike Weissman
URL:
Whiteboard:
Keywords:
: 357391 441848 (view as bug list)
Depends on: 428002
Blocks: 322979
  Show dependency tree
 
Reported: 2010-08-17 13:30 UTC by Pavel Goran
Modified: 2012-12-07 17:26 UTC (History)
4 users (show)

See Also:
Package list:
Runtime testing required: ---


Attachments

Note You need to log in before you can comment on or make changes to this bug.
Description Pavel Goran 2010-08-17 13:30:46 UTC
The new init.d script (introduced since 6.0.26-r1) unsets CLASSPATH inherited from /etc/conf.d/tomcat-6, so I no more have a clean way to pass classpaths to the Java process that runs Tomcat.

The comment in ChangeLog states that "CLASSPATH is now unset in the init script, as global CLASSPATH is deprecated and should be set for tomcat specifically". But if this is about "global CLASSPATH" as in "CLASSPATH set for an entire system via /etc/env.d or something" - then this comment is misleading and wrong, since the conf.d file from the package *already* ignores the global CLASSPATH and composes it anew. Which is exactly what I would call "setting CLASSPATH for Tomcat specifically".

So, as far as I see, the init.d script unsetting CLASSPATH doesn't serve an intended purpose, breaks things and thus should be removed.


Reproducible: Always

Steps to Reproduce:
1. Install tomcat-6.0.28
2. Add something to CLASSPATH in /etc/conf.d/tomcat-6
3. Run Tomcat

Actual Results:  
Things added to CLASSPATH are not passed to Java.

Expected Results:  
CLASSPATH being passed to Java.

There is an easy fix, of course: just comment out the "unset CLASSPATH" line from the init.d script. But it may take hours to find this solution...
Comment 1 Pavel Goran 2010-08-17 13:43:03 UTC
Update.

In addition to commenting out "unset CLASSPATH", the line next to it should be changed to:

CLASSPATH="${CLASSPATH}:${JAVA_HOME}/lib/tools.jar"
Comment 2 Alexey Guzeev 2010-08-18 14:03:08 UTC
The question is, what the CLASSPATH in /etc/conf.d/tomcat-6 is for at all. If you add arbitrary classes into the global namespace, and a web application includes a different version of the same library, then chances are high the web application will end up broken - as system class loader has higher priority than web application class loader.

Instead, for really special configurations (that don't care about polluting web applications namespace, don't care about memory leaks, do not apply security manager for web applications) the special libraries could be dropped/linked into /usr/share/tomcat-6/lib or even better one of /usr/share/tomcat-6/shared/lib, /usr/share/tomcat-6/common/lib, or /usr/share/tomcat-6/server/lib (depending on which entities should get the added libraries into their namespaces). That's how tomcat is designed to support extension/common code.

And the tomcat CLASSPATH variable is better to be gone.
Comment 3 Pavel Goran 2010-08-18 16:33:49 UTC
The possibility to have additional server-wide jars in the namespace is useful when an application uses some big fat library. Having it in application's directory is annoying because each time I deploy the application to the remote server I'll have to uselessly transfer several megabytes of library files. (And yes, I know that mixing global and application-local JARs can be a major problem.)

Also, there is (at least) one specific case when the application's lib directory won't help at all: a JNDI-configured javax.mail.Session instance. It seems to require the JAR files to be made available to Tomcat globally, for some reason.

Regarding the "copy/link approach against CLASSPATH". Putting things into /usr/share/tomcat-6/lib doesn't look good to me. /usr/share/tomcat-6/server/lib etc. looks better, though I don't have these directories in my system. But overall, this approach is not the most convenient: with CLASSPATH I can write things like `java-config -p commons-dbcp` and always have the currently installed version available, whereas with copy/link I have to manually update the files after upgrades.

So the possibility to customize CLASSPATH still looks like a good thing for me...
Comment 4 Alexey Guzeev 2010-08-18 18:11:49 UTC
`java-config -p` is a nice gentoo feature indeed, and it is very effective on the workstation in Makefile that assembles web application archive. Then, well, upload the web application using rsync and forget about the megabytes.

So, yes, only libraries that define classes needed for the JNDI resources locally defined in tomcat config files are left. Even using the /usr/share/tomcat-6/lib directory is better than system class loader; but the absense of the other, more apropriate directories I mentioned should not stop you: just create them as needed, as tomcat simply looks for them in CATALINA_BASE which is /usr/share/tomcat-6/. Generally there aren't much libraries needed for the typical JNDI resources (dbcp, javamail, jaf... here the list ends?); and the good news that filepath there does not depend on a particular version of the library (like: /usr/share/commons-dbcp/lib/commons-dbcp.jar).

Not to mention that Tomcat JNDI implementation is not mandatory to use... for example with the help of Spring Framework (or quite a few others) the usual resources (and corresponding libraries) can be nicely defined totally within web application. Heck, even using a singleton class the resources can be brought completely into web application in a homegrownish way (quick and dirty, but in full conformance with relevant specs).

That all said, there is already a method to add trusted libraries globally: put JAVA_OPTS="-Xbootclasspath/a:/usr/share/commons-dbcp/lib/commons-dbcp.jar" into /etc/conf.d/tomcat. Not exactly the method I would recommend for wide use, but that's virtually the same as putting the same into CLASSPATH (boot classloader versus system classloader do not make much difference, considering that even tomcat code itself is loaded by non-system class loader, except for a couple of little bootstrap classes).

And the the CLASSPATH variable is better disappear completely from /etc/conf.d/tomcat. Who wants a hacky configuration will get it easily anyway (without even modifying a single portage-installed file outside /etc/conf.d/), but no need to invite people there.
Comment 5 William L. Thomson Jr. 2011-02-16 16:10:37 UTC
This needs to be closed as WONTFIX. The CLASSPATH was purposely set and removed, I need to see about the conf.d file. Tomcat is a class loader, it should not rely on a classpath for anything! Symlink what ever jars you need either at system level globally via /usr/share/tomcat-*/lib  or do it in your web apps lib directory. Enough said, close bug!

Additional comments are not necessary as they will not change my point of view. Gentoo Java Team has policies wrt to not setting a classpath anywhere. Any application that needs one creates it as it starts via init or wrapper/launcher script. Thus Tomcat unsetting any classpath and using its own pristine one.

Any mention of a classpath in the conf.d file is just a left over remnant.
Comment 6 Miroslav Šulc gentoo-dev 2011-02-16 16:29:35 UTC
Will, so though the following lines are both in tomcat 6 and 7 conf files in main tree, they should not be there? If so, they should be first removed before the bug is closed.

# Location of the Tomcat JARs and classes
CATALINA_LIBDIR=/usr/share/tomcat-6/lib/

# The CLASSPATH for Tomcat to use, plus any others you need.
CLASSPATH=${CATALINA_LIBDIR}
Comment 7 William L. Thomson Jr. 2011-02-17 06:30:36 UTC
Yes, it does not seem that CATALINA_LIBDIR is needed anywhere. I don't believe its an ENV variable tomcat needs, but that might be the only reason for that to remain. It is not used in the init script.

The classpath part can definitely be removed. Its created in the init script. The unset is really to catch any system/global set/hacked classpath. I overlooked that there was one in the conf.d file, otherwise would have removed it. Since that file is source before init script functions are invoked, and the unset will take that out as well.

Its not good or necessary for stuff to be in tomcats way when its starting or firing up. Everything else runs from within it, its not needed to start tomcat, therefore should come and be loaded after the fact.
Comment 8 William L. Thomson Jr. 2011-03-07 21:04:19 UTC
*** Bug 357391 has been marked as a duplicate of this bug. ***
Comment 9 damage 2011-04-07 13:16:46 UTC
Hi,
I would like to link custom jars into /usr/local/share/tomcat-6/lib.

The "local" signals that I have made the changes to the system. I dont want to touch the Gentoo system. I would like to diff between files that where created by Gentoo and files that where created by me.

regards
Daniel
Comment 10 Ralph Sennhauser (RETIRED) gentoo-dev 2012-12-07 17:22:49 UTC
While not documented in conf.d you can use TOMCAT_EXTRA_CLASSPATH for adding a free form classpath which will be added to the default classpath. There might be legitimate uses but I wouldn't recommend it.

For more info on the rewrite see https://wiki.gentoo.org/wiki/Apache_Tomcat. Thanks for the report.
Comment 11 Ralph Sennhauser (RETIRED) gentoo-dev 2012-12-07 17:26:56 UTC
*** Bug 441848 has been marked as a duplicate of this bug. ***