-----BEGIN PGP SIGNED MESSAGE-----
Hash: SHA1

André,

On 12/16/11 5:13 AM, André Warnier wrote:
> Christopher Schultz wrote:
>> -----BEGIN PGP SIGNED MESSAGE----- The issue is that the tomcat5
>> install (or a related package, or even someone manually
>> installing tcnative)
> 
> It was the Debian "apt-get install tomcat5.5", I'm sure.

Are you sure? Debian is usually pretty good about using separate
packages for things like that. Looking at the "tomcat6" packages
(tomcat5.5 isn't available from the repo I'm tracking), no native
libraries are installed along with that package.

I checked, and in Lenny (where "tomcat5.5" *is* available at version
5.5.26-5lenny2), there is also no tcnative library.

Try running this from the command line:

$ dpkg -S /usr/lib/tcnative.so (or whatever the exact filename is)

That will tell you what package it came from, or it will tell you that
it's "not found" which means that it wasn't found in any installed
package. That would mean that it was installed manually by someone.

It's probably worth investigating moving that native library from
/usr/local into /path/to/tomcat5.5/bin. It will certainly make your
life (or the life of a future administrator) easier.

An aside about Tomcat in Debian:

I just checked, and on recently-built Debian Squeeze system, I can see
several packages for Tomcat 6:

tomcat6 - Servlet and JSP engine
tomcat6-user - Servlet and JSP engine -- tools to create user instances
tomcat6-common - Servlet and JSP engine -- common files
tomcat6-admin - Servlet and JSP engine -- admin web applications
tomcat6-docs - Servlet and JSP engine -- documentation
tomcat6-examples - Servlet and JSP engine -- example web applications

The "tomcat6" package contains startup scripts only for the
system-wide daemon, and depends upon "tomcat6-common" (which appears
to contain the actual "Tomcat" that we all know and love). The
"tomcat6-user" package looks like it contains those tools you'll need
to start Tomcat from the command line when not using it as a service.
The other projects seem obvious to me.

For those interested in seeing what the Debian folks have done with
their packages, here is a file listing of each package:

tomcat6:
http://packages.debian.org/squeeze/all/tomcat6/filelist

tomcat6-user:
http://packages.debian.org/squeeze/all/tomcat6-user/filelist

tomcat6-common:
http://packages.debian.org/squeeze/all/tomcat6-common/filelist

Looks like the tomcat6-user package contains some nice scripts like
"tomcat6-instance-create" which appears to automate the creation of a
CATALINA_BASE-style Tomcat instance. Someone's obviously been reading
the RUNNING.txt file :)

But I digress...

>> put the native library into /usr/lib, which is a very special
>> place. It's like someone parking their car in your "guest" space
>> -- it's rude and causes confusion, but it's not the end of the
>> world: you just have to park someplace else.
> 
> Right. That's one of the much-debated inconvenients of working
> with package managers. You never quite know where they will put
> things or why. And in this case, putting it in a common place like
> /usr/lib is really debatable, since I don't think that anything
> else but Tomcat uses that library.

I'm still dubious. Looks like the "libtcnative-1" package if anything:
http://packages.debian.org/search?suite=default&section=all&arch=any&searchon=names&keywords=tcnative

Looks like the latest version is 1.1.13 for Lenny, so it's time to
upgrade. (And if you're on Etch, like one of our aging servers, it's
REALLY time to upgrade!).

tcnative should (should!) be backward-compatible, so if you upgrade
the libtcnative-1 package to what Squeeze has available (1.1.20), then
tomcat5.5 should (should!) be okay.

>>> And finally, according to other recommendations on the list
>>> which appear to be worthy of trust, I believe that if, in the
>>> script which starts Tomcat6, I would add something like export 
>>> LD_LIBRARY_PATH=/opt/tomcat6/bin:$LD_LIBRARY_PATH that might do
>>> the trick as far as tc-native is concerned.
>> 
>> Probably, but it would be better (if possible) to move the
>> offending, outdated tcnative library into the tomcat5 deployment
>> so everyone is separate.
> 
> Yes, but then "uninstall" and "upgrade" and so on won't work
> anymore..

Well, it appears that you are on a system which doesn't (yet) support
Tomcat 6 (probably Lenny or even Etch), so there is bound to be a bit
of a struggle.

>> IIRC, Tomcat loads tcnative without a version number in it's name
>> even when it prefers a version that is of a certain level. That's
>> not a great practice, but I'm not sure there's anything that can
>> be done given that evidently there have been breaking-changes
>> with non-obviously-breaking version-number bumps.
> 
> Ok, so that indirectly explains another thing which I had
> separately been wondering about : why on all those *NIX systems,
> there are always a profusion of symlinks in the */lib directories,
> pointing to the same .so file, but with different names.

Yup, that's why. An application can ask the OS (okay, Chuck, the
/linker/) to load a library by it's base name (e.g. "tcnative") which
means "i don't care at all what version I get... just give me
something". Or, it can ask for "libtcnative-1" or even
"libtcnative-1.1.17". It's always best (as a program) to be as
accepting as possible, otherwise you risk failure when 1.1.17 gets
upgraded to 1.1.18. As long as they are API-compatible everything
should still work. As long as they are backward-compatible, everything
*will* work if the program requests "tcnative-1".

Now, let's say that tcnative goes to 2.0. If it is backward
compatible, you might end up with this:

libtcnative-2.0.0.so
libtcnative-2.0.so -> libtcnative-2.0.0.so
libtcnative-2.so   -> libtcnative-2.0.0.so
libtcnative-1.0.so -> libtcnative-2.0.0.so
libtcnative-1.so   -> libtcnative-2.0.0.so

If they're not compatible, you might end up with this (most likely
served by two separate packages, libtcnative-1 and libtcnative-2):

libtcnative-2.0.0.so
libtcnative-2.0.so -> libtcnative-2.0.0.so
libtcnative-2.so   -> libtcnative-2.0.0.so
libtcnative-1.0.0.so
libtcnative-1.0.so -> libtcnative-1.0.0.so
libtcnative-1.so   -> libtcnative-1.0.0.so

When an upgrade occurs to any of these packages, the most basic file
changes (in this case, libtcnative-2.0.0.so is deleted and
libtcnative-2.0.1.so is added) and the symlinks change to point to the
new version. Most programs that weren't picky about their version
number never notice the difference, which is as it should be IMO.

So, all this seems perfectly reasonable to me, but I experience
vertigo whenever I try to use CPAN. Go figure.

>>> And when native code under Linux is looking for a library, this
>>> is probably done through some other standard library providing 
>>> "library loading" functions.
>> 
>> This is a *NIX thing. I'm sure Microsoft Windows does things in
>> a similar way.
> 
> And that's where Chuck's (so to speak) dlopen() comes in. Slowly
> the dawn comes.

It's probably unreasonable to expect that someone not familiar with
"shared objects" (or DLLs in win32-speak) -- essentially shared code
libraries -- in general to make the leap from "this program blew up
and said it couldn't find library 'x'" to reading the UNIX manual page
for "dlopen". The only clue you have is that it might say something
about LD_LIBRARY_PATH. "man LD_LIBRARY_PATH" on my Debian system has
no man page, so Google is the answer, here, unfortunately. If you read
"java.library.path" in the error message, you'll have to wade through
enough JRE documentation to know that java.library.path (a Java system
property) is essentially the same thing as LD_LIBRARY_PATH (a POSIX
environment variable) ... though I suspect that the former is
prepended to the latter for the complete picture.

I was about to say "sadly, this is one of the places where the Java
magic yields to the harsh reality of the real world" but that's only
true because native code is involved. The wool-over-the-eyes world of
Java is in-tact until you make the decision to go native, and then you
have to dodge blow-darts while running through the jungle. That's just
the Way Things Are.

>> Tomcat does not do this by default. You must explicitly
>> configure java.library.path to point to CATALINA_HOME/bin if you
>> want it to load native libraries from there.
> 
> Ahaaa. /That/ was the key missing piece.

Yup -- see above for my coment re: java.library.path and LD_LIBRARY_PATH.

> So, if I compile the tc-native library, and put the resulting 
> libtcnative-1.so in (catalina_home)/bin, that by itself is not
> enough to have Tomcat find it there. Right ?

Correct. *NIX systems to not, by default, use the
current-working-directory as a valid search path for binaries of any
kind. That's too risky: a rogue library sitting in "." could turn
things like 'ls' into Trojan horses. *NIX gives you enough rope to
hang yourself, but you still have to tie the noose yourself, too: it
doesn't reach-out and strangle you. Instead, you need to modify that
path in one way (LD_LIBRARY_PATH) or another (java.library.path).
Using the Java system property is *much* safer, because then the JVM
won't try to load *other* libraries from Tomcat's bin directory...
only those that you try to load from within Java itself.

> And in order for Tomcat6 to find it there, I need to do either one
> of 2 things : 1) add an option
> "-Djava.library.path=$CATALINA_HOME/bin" to the command-line that
> starts the JVM which runs Tomcat OR 2) add a line export
> LD_LIBRARY_PATH=$CATALINA_HOME/bin:$LD_LIBRARY_PATH to the script
> which starts Tomcat, prior to the actual Tomcat start line.

Yes. Stick with java.library.path.

> and 1) gives the option to the JVM, and the JVM will then pass this
> to dl_open() when it calls it

dlopen does not take a search path as a parameter -- it always uses
LD_LIBRARY_PATH.

> or 2) is something that dl_open() itself will find and add to it's
> default search path when it is called by the JVM

I'm not sure exactly how the JVM does things. It could modify it's own
environment variable by constructing LD_LIBRARY_PATH from some default
(but how does it know the system default?) and then calling dlopen or
it could search the java.library.path itself, then call dlopen() with
the fill pathname to the library itself. I suspect the latter because
I launch Tomcat with CATALINA_HOME/bin as the java.library.path and
when I check the environment in /proc/[pid]/env, I can see the
LD_LIBRARY_PATH is being set to JRE-related paths only, and doesn't
include CATALINA_HOME/bin anywhere.

> Have I got it now ?

I think so.

- -chris
-----BEGIN PGP SIGNATURE-----
Version: GnuPG/MacGPG2 v2.0.17 (Darwin)
Comment: GPGTools - http://gpgtools.org
Comment: Using GnuPG with Mozilla - http://enigmail.mozdev.org/

iEYEARECAAYFAk7rx2gACgkQ9CaO5/Lv0PDeSwCeNBTSMEv8yjO1W7wOOH5I8MZD
uycAoKp+QRKCtocHKX2DvVFclU33Cs6t
=Jjwn
-----END PGP SIGNATURE-----

---------------------------------------------------------------------
To unsubscribe, e-mail: users-unsubscr...@tomcat.apache.org
For additional commands, e-mail: users-h...@tomcat.apache.org

Reply via email to