虚拟主机同时运行多个使用 ImageMagick +Jmagick的网站

       Tomcat虚拟主机同时运行多个使用 ImageMagick +Jmagick的网站,遇到了这个错误:Native Library C:\WINDOWS\system32\jmagick.dll already loaded in another classloader

-----------------------------------------------------

环境说明:

中间件:tomcat6.0.18

开发环境:winXP

服务器:CentOS5.3

         在一个tomcat下,有多个虚拟主机, 运行了多个网站,每个网站都使用 ImageMagick +Jmagick 来处理图片, 须要使用JNI调用本地*.dll文件来处理图片,  每个网站(web应用程序)都有自己的lib,在WebContent\WEB-INF\lib下面.  这样就有重复的jar包, 如jmagick.jar,servlet-api.jar, ***等好多jar包, 在每个网站(web应用程序)都有一份.

-----------------------------------------------------

结果在启动tomcat时会报:

1 忽略了servlet-api.jar .  (具体日志信息没有复制)

2 一个web应用程序处理完图片后,第二个web应用程序再处理图片时会出错:Native Library C:\WINDOWS\system32\jmagick.dll already loaded in another classloader

3 A C3P0Registry mbean is already registered

-----------------------------------------------------

 

我搜索到了  http://jbossweek.iteye.com/blog/138903的一篇文章:

1、症状 

如果JBoss上的两个web应用需要使用相同的JNI本地库,当第二个web应用加载JNI本地库时,就会出现Native Library xxx.so already loaded in another classloader错误

2、原因 

 Java虚拟机为了在JNI本地库中确保基于classloader的命名空间隔离,因而不允许一个JNI本地库被两个不同的classloader加载。而JBoss中web应用的classloader是独立的,也就是说每个web应用都有一个专属的classloader,这样就出现两个classloader加载同一JNI本地库的情况

3、解决方法 

在JBoss AS中,虽然不同的web应用使用不同的classloader,但是web应用classloader的父classloader是相同的,这样根据双亲委托模型只要让父classloader加载JNI本地库就可以避免被多个classloader加载。父classloader的classpath为JBoss AS配置(default、all或minimal)的lib目录,因而只要将JNI class单独发布成jar包,并放在配置(default、all或minimal)的lib目录中,问题就可以解决

 以上说明了问题的原因, 上面说 "因而只要将JNI class单独发布成jar包"  , 我使用了 jmagick.jar是在这里调用了JNI ,  所以把jmagick.jar 从WebContent\WEB-INF\lib下 移动到了E:\tomcat-6.0.18\lib下, 就不会被重复加载了.

 

----------------------------------------------------

Tomcat6的类加载顺序

1、最先是$JAVA_HOME/jre/lib/ext/下的jar文件。
2、环境变量CLASSPATH中的jar和class文件。

3、$CATALINA_HOME/lib 下的jar文件。

4、各自具体的webapp /WEB-INF/classes下的class文件。
5、各自具体的webapp /WEB-INF/lib下的jar文件。

 

 

你可能感兴趣的:(ImageMagick)