`
talentkep
  • 浏览: 100481 次
  • 性别: Icon_minigender_1
  • 来自: 武汉
社区版块
存档分类
最新评论

总结和对比一下(jboss,tomcat,jetty)容器的classloader机制

    博客分类:
阅读更多

 

总结和对比一下(jboss,tomcat,jetty)容器的classloader机制

容器 jboss(4.05) tomcat(6.0.30) jetty(7.1.20)
支持child/parent first设置(默认值) Java2ClassLoadingCompliance=false delegate=false _parentLoaderPriority=false
过滤package配置 FilteredPackages
默认值: javax.servlet,org.apache.commons.logging
packageTriggers
默认配置:org.apache.commons.logging
systemClasses
默认配置:java. 
javax.
org.xml.
org.w3c.
org.apache.commons.logging.
org.eclipse.jetty.continuation.
org.eclipse.jetty.jndi.
org.eclipse.jetty.plus.jaas.
org.eclipse.jetty.websocket.
org.eclipse.jetty.servlet.DefaultServlet.
特殊性

1. UseJBossWebLoader=false时,过滤packages才能生效

2. UseJBossWebLoader=true时,不支持过滤packages

3. jboss 5.0以后UseJBossWebLoader参数将不支持

1. 在执行child/parent判断之前,会委托system classloader装载系统class,比如jdk的lib库

1. 多了一个serverclass配置,如果是serverclass优先采用child first

2. systemclass默认的配置,多了javax,org.xml,org.w3c配置。

相关文档 svn url : http://anonsvn.jboss.org/repos/jbossas/tags/JBoss_4_0_5_GA_CP18
jboss社区classloader文档: http://community.jboss.org/wiki/ClassLoadingConfiguration

svn url : http://svn.apache.org/repos/asf/tomcat/tc6.0.x/trunk

官方classloader机制: http://tomcat.apache.org/tomcat-6.0-doc/class-loader-howto.html

svn url : http://dev.eclipse.org/svnroot/rt/org.eclipse.jetty/jetty/tags/jetty-7.2.0.v20101020/

classloader 官方文档: http://docs.codehaus.org/display/JETTY/Classloading

 
 

 

最后(相关问题分析)

 

问题1:

  是一个jar sealed问题, 官方说明: http://download.oracle.com/javase/tutorial/deployment/jar/sealman.html

 

Html代码 复制代码
  1. Package Sealing: A package within a JAR file can be optionally sealed, which means that all classes defined in that package must be archived in the same JAR file.    
  2. A package might be sealed to ensure version consistency among the classes in your software or as a security measure.   
  3. To seal a package, a Name header needs to be added for the package, followed by a Sealed header, similar to this:   
  4. Name: myCompany/myPackage/   
  5. Sealed: true   
  6.   
  7. The Name header's value is the package's relative pathname. Note that it ends with a '/' to distinguish it from a filename.    
  8. Any headers following a Name header, without any intervening blank lines, apply to the file or package specified in the Name header.    
  9. In the above example, because the Sealed header occurs after the Name: myCompany/myPackage header,    
  10. with no blank lines between, the Sealed header will be interpreted as applying (only) to the package myCompany/myPackage.    
  11.   
  12. This code doesn't work.  
Package Sealing: A package within a JAR file can be optionally sealed, which means that all classes defined in that package must be archived in the same JAR file. 
A package might be sealed to ensure version consistency among the classes in your software or as a security measure.
To seal a package, a Name header needs to be added for the package, followed by a Sealed header, similar to this:
Name: myCompany/myPackage/
Sealed: true

The Name header's value is the package's relative pathname. Note that it ends with a '/' to distinguish it from a filename. 
Any headers following a Name header, without any intervening blank lines, apply to the file or package specified in the Name header. 
In the above example, because the Sealed header occurs after the Name: myCompany/myPackage header, 
with no blank lines between, the Sealed header will be interpreted as applying (only) to the package myCompany/myPackage. 

This code doesn't work.

 

说白了就是jdk在jar层面上做的一层控制,避免出现两个不同版本的实现类同时在应用中被装载。

理清了sealed的含义,再看一下出错的堆栈:com.sun.media.jai.util,这个类是jai相关处理

  • jai_core.jar
  • jai_codec.jar
  • jai_imageio.jar

几个jar包的META-INF/MANIFEST.MF中都定义了sealed :true。而我们的应用中刚好有两个jar包,那为什么在jboss运行中没问题,jetty运行却出了问题。

 

最后的原因:

1. 我们使用的是javax.media.jai.JAI.create(String opName,ParameterBlock args),该类刚好依赖了com.sun.media.jai.util.ImagingListenerImpl等相关类。

2. 意看jetty的特殊性,针对javax.media.jai.JAI是属于systemclass,所以会优先使用jdk去装载,而com.sun则通过应用容器装载,很巧的是公司的jdk下的jre/lib/ext下刚好增加了jai的相关jar,最终导致了sealed冲突。

 

解决方案:

   处理起来相对暴力,增加配置systemclass配置,添加jai的相关package,所有的jai都采取parent first加载。

Java代码 复制代码
  1. <!--for jai_code.jar , jai_codec.jar -->   
  2. <Item>com.sun.media.jai.</Item>   
  3. <!--for jai_imageio.jar -->   
  4. <Item>com.sun.media.imageio.</Item>   
  5. <Item>com.sun.media.imageioimpl.</Item>   
  6. <Item>jj2000.j2k.</Item>  
<!--for jai_code.jar , jai_codec.jar -->
<Item>com.sun.media.jai.</Item>
<!--for jai_imageio.jar -->
<Item>com.sun.media.imageio.</Item>
<Item>com.sun.media.imageioimpl.</Item>
<Item>jj2000.j2k.</Item>


问题2

xml加载的问题,原因也跟jetty的特殊性相关。大家都知道xml解析类有很多种

  • xerces
  • crimson
  • jdk rt.jar
  • j2ee.jar

真TMD令人纠结啊,应用容器中一旦同时依赖了这几个xml类库,那麻烦问题就来了。这个SAXParserFactory.newInstance(String factoryClassName, ClassLoader classLoader)在jdk1.6.18版本中有,而在其他的几个包中却没有该接口方法。

 

该问题的原因:

  1. 原先应用运行的是tomca,也因为tomcat容器的特殊性,会优先通过system classloader优先装载,正好SAXParserFactory类属于jdk的库,所以也正好装载了jdk的类
  2. jetty容器因为特殊systemclass配置,针对javax.打头的package采用parent first,所以这时装载了jdk SAXParserFactory
  3. 最后jboss运行时,因为我们使用的是UseJbossWebLoader=true,所以会优先装载应用中的lib,至于用哪个那就看概率了,一般按classpath装载lib的顺序。所以这时没有该方法,就抛出了对应的错误

 

解决方案:

处理方式也比较粗暴,如果该方法存在歧义,那干脆不用这方法不就得了,最后换用了无参的newInstance()方法。但这时得注意了,不同xml类库,对应的xml impl默认配置不一样。比如jdk的配置:就会以他自己的为默认值

 

Java代码 复制代码
  1. return (SAXParserFactory) FactoryFinder.find(   
  2.                 /* The default property name according to the JAXP spec */  
  3.                 "javax.xml.parsers.SAXParserFactory",   
  4.                 /* The fallback implementation class name */  
  5.                 "com.sun.org.apache.xerces.internal.jaxp.SAXParserFactoryImpl");  
return (SAXParserFactory) FactoryFinder.find(
                /* The default property name according to the JAXP spec */
                "javax.xml.parsers.SAXParserFactory",
                /* The fallback implementation class name */
                "com.sun.org.apache.xerces.internal.jaxp.SAXParserFactoryImpl");

 

所以最后为了统一使用,通过设置环境变量:

Java代码 复制代码
  1. -Djavax.xml.parsers.SAXParserFactory=org.apache.xerces.jaxp.SAXParserFactoryImpl  
-Djavax.xml.parsers.SAXParserFactory=org.apache.xerces.jaxp.SAXParserFactoryImpl

 

问题3:

 该问题是由问题2引出的,正因为设置了xml解析器为xerces,导致在jetty启动的时候出现了一些问题。这次主要的原因就跟共享lib库有关了。

 

最终原因分析:

  1. 因为通过环境变量设置了xml解析器的实现类,所以不同的xml类库在创建xml parse时,都会尝试去载入对应的lib库。
  2. jetty启动时,其自身需要解析xml文件,这时候就出现问题了,jetty默认是没有xerces xml的解析类的,所以启动就出错了。

 

解决方案:

  1. 参照jboss的共享lib的配置,在jetty的ext库里添加了xercesImpl-2.9.1.jar,xml-apis-1.3.04.jar,xml-resolver-1.2.jar
  2. 因为我使用的是外部ext库,不想放到jetty软件的lib库下,所以需要通过手工指定,在start.ini中添加:
    Java代码 复制代码
    1. lib=${jettyserverhome}/ext  
    lib=${jettyserverhome}/ext


问题4:

是一个mail邮件发送时发现的问题,从堆栈信息描述看也很见到,对应的javax.mail.event.TransportListener没找到

mail的lib库也是挺让人纠结的

1. xml一样有多个lib库:j2ee.jar,javamail。

2. 但有一点又不同的是j2ee.jar中只有接口申明没有对应的实现类

3. 更纠结的是j2ee-1.4新版本和老的javamail版本接口上还存在差异性(这个是别人告诉我的,个人没仔细验证)

 

看到这,各位看官需要多淡定一下,真是很让人纠结啊

 

最终原先分析:

  1. 原先jboss容器运行没问题,主要是和其默认的lib库有关,jboss 4.05在默认的server/default/lib下有个jboss-j2ee.jar,所以即使容器中没有javamail的包也能正常运行。
  2. 换成jetty以后,因默认在jetty下没有j2ee这个lib库,所以很悲惨,抛异常了。

 

解决方案:

1. 没必要参合j2ee.jar,直接在原先的工程里添加javamail的依赖,最后在应用中引入javamail的包。

 

 

 

 

 结尾

在这次的jetty使用过程,还是遇到了比较多的问题,大部分还是在classloader机制上,希望通过这篇文章能对大家有所帮助,少走弯路。
分享到:
评论

相关推荐

    Tomcat-JBoss-Weblogic-Jetty的区别和介绍

    Tomcat应用也算非常广泛的web 服务器,支持部分j2ee,免费...JBoss和WebLogic都含有Jsp和Servlet容器,也就可以做web容器, JBoss和WebLogic也包含EJB容器,是完整的J2EE应用服务器 tomcat 只能做jsp和servlet的container

    Servlet引擎:JBoss与Tomcat、Jetty协同工作

    其中,JBoss、Tomcat和Jetty是最为广泛使用的Servlet容器,它们各自拥有独特的架构和工作原理,但同时也具备协同工作的能力。 **一、JBoss的基本架构与工作原理** JBoss是一个功能强大的企业级Java应用服务器,其...

    jboss 5 原理 2 classloader

    随着OSGi(Open Services Gateway Initiative)风格的类加载机制逐渐流行,以及新的Java模块和类加载规范的出现,JBoss对自身的类加载层进行了重构,以适应这些新的需求。在JBoss Microcontainer中,类加载层扮演着...

    apache 集成 jboss、tomcat

    1. **Apache mod_jk模块**:这是Apache的一个模块,专门用于连接Apache和Tomcat或者JBoss。mod_jk负责通信协议,将HTTP请求转发到应用服务器,并将响应返回给客户端。它通过JKMount指令配置,将URL映射到特定的应用...

    Jetty和tomcat比较.docx

    - **Servlet引擎**: Tomcat和Jetty都是基于Java的Servlet容器,支持标准的servlet规范和JavaEE的规范。这意味着开发者可以在这些容器中部署和运行Java Web应用。 #### 不同点 1. **架构比较** - **Jetty**: ...

    JBOSS+TOMCAT集成开发环境。完整版

    【JBOSS+TOMCAT集成开发环境】是一种常见的企业级应用服务器组合,它结合了JBOSS的全面中间件服务和TOMCAT的轻量级Servlet容器特性,为开发者提供了一个高效且灵活的开发与部署平台。在这个“完整版”中,用户可以...

    Apache Tomcat JBOSS Nginx区别

    JBoss 是一个管理 EJB 的容器和服务器,但 JBoss 核心服务不包括支持 servlet/JSP 的 WEB 容器,一般与 Tomcat 或 Jetty 绑定使用。JBoss 与 Web 服务器在同一个 Java 虚拟机中运行,Servlet 调用 EJB 不经过网络,...

    Apache+Jboss(Tomcat)集群配置

    Apache+Jboss(Tomcat)集群配置是一种常见的高可用性和负载均衡解决方案,它通过在前端部署Apache服务器,中间层配置多个Jboss或Tomcat应用服务器,后端连接统一的数据库来实现系统的扩展性和稳定性。以下是配置这个...

    tomcate和jetty虚拟目录配置方法

    在Java Web开发中,Tomcat和Jetty是两种常见的应用服务器。它们都支持虚拟目录配置,使得我们可以将多个Web应用程序部署在同一服务器上,而无需更改全局服务器配置。虚拟目录允许我们为每个应用设置一个独立的URL...

    TOMCAT移植到JBOSS

    ### 知识点详解:“TOMCAT移植到JBOSS” ...通过以上步骤和注意事项的详述,我们可以看到从TOMCAT移植到JBOSS不仅是一个技术性的转换过程,也是一个涉及系统架构、配置管理和性能优化的综合性项目。

    J2EE应用服务器Jboss+Tomcat安装攻略

    J2EE应用服务器是企业级Java应用程序开发和部署的核心平台,而Jboss和Tomcat的组合提供了一种开源且稳定的选择。Jboss是一款强大的J2EE应用服务器,它支持多种J2EE规范,如EJB(Enterprise JavaBeans)、JMS(Java ...

    JBOSS\Tomcat最大连接数配置和jvm内存配置.docx

    【JBOSSTomcat最大连接数配置和JVM内存配置】 在JBOSSTomcat服务器的性能优化中,最大连接数配置和JVM内存配置是两个至关重要的环节,它们直接影响到服务器的响应速度和稳定性,尤其对于处理大量并发请求的场景。 ...

    tomcat_Jboss_weblogic区别、容器的作用

    "Tomcat、Jboss、Weblogic区别、容器的作用" Tomcat是一种免费的开放源代码的Web应用服务器,它是Apache软件基金会(Apache Software Foundation)的Jakarta项目中的一个核心项目,由Apache、Sun和其他一些公司及...

    tomcat-and-jboss.rar_jboss_tomcat

    【标题】:“Tomcat与JBoss的对比分析” 【描述】:在IT行业中,Tomcat和JBoss都是广泛使用的应用程序服务器,它们各自有着独特的特性和优势。Tomcat以其轻量级、高效能和对Servlet及JavaServer Pages(JSP)的良好...

    CXF发布WebService,jboss和tomcat都能发布

    - **tomcat**:Tomcat是Apache软件基金会的项目,是一款轻量级的Servlet容器,支持Servlet和JSP标准。 - **cxf**:Apache CXF是一个用于构建和部署Web服务的开源框架,支持多种协议,包括SOAP和REST。 - **...

    WebLogic、WebSphere、JBOSS、Tomcat之间的区别

    因为 JBoss 和 Tomcat 都是开源免费的,所以它们也就没有任何商业服务和技术支持,而 WebLogic 和 WebSphere 的技术文档和相关服务还是很到位,如果你的服务器哪一天出问题了,只要你能出的起钱,他们的技术工程师...

    tomcat、weblogic、jboss的区别,容器的作用

    【描述】:本文将详细探讨三个著名Java应用服务器——Tomcat、WebLogic和JBoss之间的差异,同时解析它们作为容器的主要功能。 【标签】:Tomcat、WebLogic、JBoss、Java应用服务器、容器 【正文】: 在Java世界中...

    java项目tomcat迁移到jboss

    Java 项目从 Tomcat 迁移到 JBoss 的解决方案 在 Java 项目中,迁移到 JBoss 可能会出现各种问题,例如版本兼容问题、设置问题等。本文将介绍如何解决这些问题,包括如何配置 JBoss,使得 Spring 项目能够正常运行...

    Tomcat容器

    Tomcat容器,全称为Apache Tomcat,是一款开源且免费的Java Web应用服务器,由Apache软件基金会的Jakarta项目开发和维护。它是实现Java Servlet和JavaServer Pages(JSP)规范的主要容器之一,是Java EE(现更名为...

    Apache Jboss/Tomcat集群(手稿)

    总结来说,Apache JBoss/Tomcat集群的搭建涉及多个组件的配置和集成,包括前端的Apache服务器、后端的应用服务器和中间的连接器。通过这种方式,系统能够有效地处理高流量,提高服务的可用性和响应时间,同时通过...

Global site tag (gtag.js) - Google Analytics