> -----Original Message-----
> From: Andreas Hirner [mailto:[EMAIL PROTECTED]]
> Sent: Tuesday, June 25, 2002 10:21 AM
> To: Tomcat Users List
> Subject: Re: Native library cannot be loaded twice
> 
> 
> Hi Charlie,
> 
> 
> > did you restart tomcat since your class is in common/classes?
> Yes, I did.
> 
> > you may want to wrap the loadlibrary() in a singleton. I'm not sure
> that you
> > can use Class.forName on a class with no methods or fields. You may
> also
> > want to see if the native functions are available even if the
> Class.forName
> > is throwing an error. The static block should be run automatically
> by the
> > classloader, but I'm not sure if it does this when the class is
> loaded, or
> > when it is first called.
> >
> > you do want your class in /common/classes so that it can only be
> loaded
> > once.
> 
> This is very important because I would like to access the library from
> several different applications.
> 
> > I have my library on the system path(win2k) and it works fine. If
> you had it
> > working before(if only the first time), then the library was in the
> right
> > place.
> 
> This is the part that's giving me a headache. I don't know why it
> makes a difference if initialise it in static block in a servlet or my
> InitMapserver class.

each webapp gets its own classloader. Therefore each
static(block,class,method,etc) is loaded in EACH classloader and is 'static'
only within that classloader. So when your library is loaded from a servlet
located in web-inf/lib(or classes), it is loaded for each webapp that
contains that .class file. But since native libraries can only be loaded
once, when it tries to load a second time you get the error. 

I believe the class loader is removed and replaced with a new one upon
reload. Since the old classloader loaded the native library, when the new
one tries to reload your updated class, it fails because the library is
already loaded.(A native library can only be loaded once in a jvm)

When you put the class that loads the library into \common\lib, then it is
loaded at tomcat startup, and the class is not unloaded until shutdown.
Classes in common\lib are available as one instance to all tomcat webapps in
all virtual hosts.

So if you wrap your loadlibrary in a singleton class that is located in
\common\classes, you can instantiate that class as many times as you need
to, but it only gets loaded once. keep in mind that this singleton will not
be able to reference any classes you have in any webapp, only the classes in
\common\classes(or lib).

this is the way that I load my library:
public class MySingleton
{
        static private MySingleton m_mySingleton = null;

        /** private constructor to enforce singleton use. */
         private MySingleton()
         {
         }

         static private void createInstance()
         {
                if (m_mySingleton == null)
                {
                        m_mySingleton = new MySingleton();
                        System.loadLibrary("mylibrary");
                }
         }
}

Charlie

> 
> Andreas
> 
> > > -----Original Message-----
> > > From: Andreas Hirner [mailto:[EMAIL PROTECTED]]
> > > Sent: Tuesday, June 25, 2002 7:41 AM
> > > To: Tomcat Users List
> > > Cc: [EMAIL PROTECTED]
> > > Subject: Re: Native library cannot be loaded twice
> > >
> > >
> > > Hi,
> > >
> > > > A bit off-topic (this goes into native programming), but there
> is
> > > something
> > > > whirling through my head:
> > > >
> > > > Static classes/members are instantiated once. But what happens
> if
> > > multiple
> > > > classloaders are used? Such as you have this one class static
> but
> > > use it in
> > > > several web applications?
> > > >
> > > > Seems like it MUST reside in common/lib instead of
> > > webapp/*/web-inf/lib?
> > > >
> > > > Hiran
> > >
> > > This is where my problem is. I was developing a servlet, which
> loaded
> > > a native library and subsequently called some native functions.
> > > Everything was working fine, but whenever I made changes to the
> > > servlet and reloaded the application with the manager/relaod call
> the
> > > native library was instanciated a second time and crashed. I had
> to
> > > stop and restart tomcat in order to see any changes made to the
> > > servlet.
> > >
> > > So I wrote and compiled a class called InitMapserver, which looks
> like
> > > that:
> > >
> > >  public class InitMapserver
> > >  {
> > >
> > >   static {
> > >    try {
> > >       System.loadLibrary("mapscript");
> > >       System.err.println("libmapscript.so loaded");
> > >    } catch (UnsatisfiedLinkError e) {
> > >       System.err.println("libmapscript.so not loaded: " + e);
> > >    }
> > >   }
> > >
> > >  }
> > >
> > > and put it into the common/classes directory. Then I try to load
> this
> > > class in a servlet
> > > doing:
> > >
> > >  public void init(ServletConfig config) throws ServletException
> > >  {
> > >   try
> > >   {
> > >      Class.forName("InitMapserver");
> > >   } catch (ClassNotFoundException ex) {
> > >      file://throw new ServletException(ex.getMessage() + "Class
> > > InitMapserver not     found");
> > >      System.err.println(ex.getMessage() + "Class InitMapserver not
> > > found");
> > >   }
> > >  }
> > >
> > > Unfortunately this does not work. Any suggestions???
> > >
> > > Thanks
> > > Andreas
> > >
> > > > > > Concerning the JDK documentation a native lib should be
> loaded
> > > in a
> > > > > static
> > > > > > scope. Static resources are processed differently, because
> the
> > > > > runtime
> > > > > > systems has to initialize all static resources at the
> beginning.
> > > > > After that
> > > > > > the runtime system tries to initialize objects and these
> objects
> > > > > can - of
> > > > > > course - use all static resources.
> > > > > >
> > > > > > A look into your code (InitMapserver) shows, that the
> runtime
> > > system
> > > > > cannot
> > > > > > initialize the static resource in the common way, because it
> > > first
> > > > > must
> > > > > > generate an object and this object contains code for doing
> some
> > > > > static
> > > > > > stuff. Maybe this is the reason for the strange behavior.
> > > > >
> > > > > I am sorry, but I am not a skilled Java Programmer and I don't
> > > quite
> > > > > understand what you mean. Can you try to explain it more
> > > explicitly or
> > > > > give some examples. I hope I am not asking to much....
> > >
> > >
> > >
> > >
> > > --
> > > To unsubscribe, e-mail:
> > > <mailto:[EMAIL PROTECTED]>
> > > For additional commands, e-mail:
> > > <mailto:[EMAIL PROTECTED]>
> > >
> >
> > --
> > To unsubscribe, e-mail:
> <mailto:[EMAIL PROTECTED]>
> > For additional commands, e-mail:
> <mailto:[EMAIL PROTECTED]>
> >
> >
> >
> 
> 
> 
> --
> To unsubscribe, e-mail:   
<mailto:[EMAIL PROTECTED]>
For additional commands, e-mail:
<mailto:[EMAIL PROTECTED]>

--
To unsubscribe, e-mail:   <mailto:[EMAIL PROTECTED]>
For additional commands, e-mail: <mailto:[EMAIL PROTECTED]>

Reply via email to