Win a copy of TDD for a Shopping Website LiveProject this week in the Testing forum!
  • Post Reply Bookmark Topic Watch Topic
  • New Topic
programming forums Java Mobile Certification Databases Caching Books Engineering Micro Controllers OS Languages Paradigms IDEs Build Tools Frameworks Application Servers Open Source This Site Careers Other Pie Elite all forums
this forum made possible by our volunteer staff, including ...
Marshals:
  • Campbell Ritchie
  • Paul Clapham
  • Ron McLeod
  • Jeanne Boyarsky
  • Tim Cooke
Sheriffs:
  • Liutauras Vilda
  • paul wheaton
  • Henry Wong
Saloon Keepers:
  • Tim Moores
  • Tim Holloway
  • Stephan van Hulst
  • Carey Brown
  • Frits Walraven
Bartenders:
  • Piet Souris
  • Himai Minh

Native Library XXX.so already loaded in another classloader

 
Greenhorn
Posts: 14
  • Mark post as helpful
  • send pies
    Number of slices to send:
    Optional 'thank-you' note:
  • Quote
  • Report post to moderator
Hi,

I'm developing a web page to monitor the movements of a stepper motor, using Phidgets, which uses a native library. I'm running Tomcat 10 on a Raspberry Pi.

When I first boot the pi and start the server, it all works. But if I update the war file and upload it to the pi, I get an unsatisfied link error:

java.lang.ExceptionInInitializerError: Native Library /usr/lib/libphidget22java.so.0.0.0 already loaded in another classloader

So it looks like in the process of updating the war file, libphidget22java.so isn't being unloaded and so isn't free to be reloaded.

I can get round it by rebooting the pi every time I want to upload a new war file, but I have a lot of development to do! Is there a way to release the libphidget22java.so from the classloader?

Thanks,

John
 
Saloon Keeper
Posts: 25461
180
Android Eclipse IDE Tomcat Server Redhat Java Linux
  • Mark post as helpful
  • send pies
    Number of slices to send:
    Optional 'thank-you' note:
  • Quote
  • Report post to moderator
Well, welcome to the Ranch, John!

The first question is "are you stopping and restarting Tomcat, or just re-deploying the webapp?" A re-deploy would be more likely to leave the library hanging around. A full halt of the Tomcat JVM very definitely should close the library except perhaps in cases where Tomcat was shut down by brute force.

At the OS level, the dlopen function loads/opens a Shared Object, the corresponding dlclose decrements its open count (it can unload when the shared user count reaches 0). So a properly-implemented Java native library should either have explicit open/close methods or call dlclose in its finalization method.
 
John Peders
Greenhorn
Posts: 14
  • Mark post as helpful
  • send pies
    Number of slices to send:
    Optional 'thank-you' note:
  • Quote
  • Report post to moderator
Thanks Tim.

I'm just redeploying the webapp. I guess I can just stop and restart the server each time I replace the war file.

I don't know if the library calls close int he finalization method - it's above my pay grade, but I'll take a look if stopping/starting becomes too  onerous.

Thanks for the helpful reply.

John
 
Tim Holloway
Saloon Keeper
Posts: 25461
180
Android Eclipse IDE Tomcat Server Redhat Java Linux
  • Mark post as helpful
  • send pies
    Number of slices to send:
    Optional 'thank-you' note:
  • Quote
  • Report post to moderator
Tomcat went through a phase where it was worse than that. The JVM had something called "permgen" memory. It tended to hold things like class variables, and didn't purge when you re-deployed, so usually after 3-4 deployments, permgen memory was all exhausted and you had no choice but to restart Tomcat. Fortunately Tomcat is a fast-starting system.

Permgen memory no longer exists, thank goodness.
 
John Peders
Greenhorn
Posts: 14
  • Mark post as helpful
  • send pies
    Number of slices to send:
    Optional 'thank-you' note:
  • Quote
  • Report post to moderator


If I want bad code, I can produce it myself with ease.
 
Sheriff
Posts: 22645
123
Eclipse IDE Spring VI Editor Chrome Java Windows
  • Mark post as helpful
  • send pies
    Number of slices to send:
    Optional 'thank-you' note:
  • Quote
  • Report post to moderator
This is probably the reason why it's strongly discouraged to use native code in servlet or JEE/Jakarta containers.

I assume that you put the native library not in your WAR but in Tomcat itself. However, the loading must still be done in your application, because I don't know any way to hook into Tomcat itself and execute code on behalf of Tomcat and not your application. If there were unload functionality, you could use a {{ServletContextListener}} and unload when the application is undeployed. However, I've checked and there isn't. I'm afraid that means that you're stuck with reboots for now.
 
Tim Holloway
Saloon Keeper
Posts: 25461
180
Android Eclipse IDE Tomcat Server Redhat Java Linux
  • Mark post as helpful
  • send pies
    Number of slices to send:
    Optional 'thank-you' note:
  • Quote
  • Report post to moderator
It's strongly discouraged in Java to use native code anywhere. Write-once/run-anywhere.

Ideally in Linux, a custom device would be implemented as an OS device and at that point regular Java code could talk to it. I think there are also I²C and SPI classes for the Pi, though.

It would indeed be appropriate to load/unload an application-bound .so in a ServletContextListener. Its methods are invoked when a webapp is deployed/undeployed.

Tomcat itself can also add hooks for odd things (it is, after all a wired-together collection of POJOs), but there'd be no point for it here.
 
I'm gonna teach you a lesson! Start by looking at this tiny ad:
free, earth-friendly heat - a kickstarter for putting coin in your pocket while saving the earth
https://coderanch.com/t/751654/free-earth-friendly-heat-kickstarter
reply
    Bookmark Topic Watch Topic
  • New Topic