`
ruruhuang
  • 浏览: 193060 次
  • 性别: Icon_minigender_1
  • 来自: 广州
社区版块
存档分类
最新评论

Tomcat类装载的问题.

阅读更多
昨天发布一个web application的时候发现一个奇怪的问题, 明明jar包里面有的类说找不到, 真是奇怪. 不过要下班了. 明天再说吧.

java.lang.NoClassDefFoundError: com/netsboss/util/dbobject/GeneralEntity
java.lang.ClassLoader.defineClass1(Native Method)
java.lang.ClassLoader.defineClass(ClassLoader.java:620)
java.lang.ClassLoader.defineClass(ClassLoader.java:465)
com.netsboss.util.proxy.ProxyClassLoader.defineClass(ProxyClassLoader.java:75)
com.netsboss.util.proxy.Proxy.getProxyClass(Proxy.java:216)
com.netsboss.util.dbobject.DatabaseManager.generateClass(DatabaseManager.java:1161)
com.netsboss.util.dbobject.DatabaseManager.<init>(DatabaseManager.java:240)
com.netsboss.util.dbobject.DatabaseManager.getDatabaseManager(DatabaseManager.java:98)
com.aft.constants.SystemConstants.getDefaultAFTDatabaseManager(SystemConstants.java:258)
com.aft.database.retrieve.CAFTDBGetWebUserInfo.<init>(CAFTDBGetWebUserInfo.java:64)
com.aft.database.retrieve.CAFTDBGetWebUserInfo.getCAFTDBGetWebUserInfo(CAFTDBGetWebUserInfo.java:51)
com.aft.servlets.actions.RegisterAction.perform(RegisterAction.java:43)
org.apache.struts.action.Action.execute(Action.java:420)
org.apache.struts.action.RequestProcessor.processActionPerform(RequestProcessor.java:484)
org.apache.struts.action.RequestProcessor.process(RequestProcessor.java:274)
org.apache.struts.action.ActionServlet.process(ActionServlet.java:1482)
org.apache.struts.action.ActionServlet.doPost(ActionServlet.java:525)
javax.servlet.http.HttpServlet.service(HttpServlet.java:709)
javax.servlet.http.HttpServlet.service(HttpServlet.java:802)

上面的是异常的信息, 我明明把含有这个类的jar包放到了WEB-INF/lib下面. 怎么办,还能这么办, trace code.
结果发现在了一个自定义的类装载器com.netsboss.util.proxy.ProxyClassLoader,他在构着函数里面没有传他的parent classloader(tomcat Webapp classloader)进去, 所以他的parent classloader是systemclassloader, 我想假如ProxyClassLoader的构着函数里面调用了super(ProxyClassLoader.class.getClassLoader());的话,
 应该能解决这个问题的. 我想这个就是这个java.lang.NoClassDefFoundError异常的原因吧.

这里有篇介绍类装载的问题, 也介绍了Tomcat类装器的机制.
http://blog.csai.cn/blog/number01/2005628165135.html
添加一些: 
这个是自定义的classloader, 他在构着函数里面没有传他的parent classloader(tomcat Webapp classloader)进去, 所以他的parent classloader是systemclassloader,
具体代码看java.lang.ClassLoader. 
    /**
* Creates a new class loader using the specified parent class loader for
* delegation.
*
*

If there is a security manager, its {@link
* SecurityManager#checkCreateClassLoader()
* checkCreateClassLoader} method is invoked. This may result in
* a security exception.


*
* @param parent
* The parent class loader
*
* @throws SecurityException
* If a security manager exists and its
* checkCreateClassLoader method doesn&apost allow creation
* of a new class loader.
*
* @since 1.2
*/
protected ClassLoader(ClassLoader parent) {
SecurityManager security = System.getSecurityManager();
if (security != null) {
security.checkCreateClassLoader();
}
this.parent = parent;
initialized = true;
}
    /**
* Creates a new class loader using the ClassLoader returned by
* the method {@link #getSystemClassLoader()
* getSystemClassLoader()} as the parent class loader.
*
*

If there is a security manager, its {@link
* SecurityManager#checkCreateClassLoader()
* checkCreateClassLoader} method is invoked. This may result in
* a security exception.


*
* @throws SecurityException
* If a security manager existsand its
* checkCreateClassLoader method doesn&apost allow creation
* of a new class loader.
*/
protected ClassLoader() {
SecurityManager security = System.getSecurityManager();
if (security != null) {
security.checkCreateClassLoader();
}
this.parent = getSystemClassLoader();
initialized = true;
}
 
package com.netsboss.util.proxy;
 
import java.io.File;
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.UnsupportedEncodingException;
import java.net.URL;
import java.net.URLDecoder;
import java.net.URLEncoder;
import java.util.HashMap;
import java.util.Locale;
import org.apache.log4j.Category;
 
public class ProxyClassLoader extends ClassLoader {
 
 private static Category log = Category.getInstance(ProxyClassLoader.class);
 private HashMap classes = new HashMap();
 private boolean saveToClassPath = false;
 
 public ProxyClassLoader(boolean saveToClassPath){
  this.saveToClassPath = saveToClassPath;
 }
 
 /**
  * @see ClassLoader#findClass(String)
  */
 protected Class findClass(String name) throws ClassNotFoundException {
 
  Class find = super.findClass(name);
  if(find != null) return find;
 
  find = (Class)classes.get(name);
  if(find != null) return find;
  else throw new ClassNotFoundException(name);
 
 }
 
 public void defineClass(byte classfile[], String classname){
 
  Class clazz = defineClass(classname, classfile,0, classfile.length);
  classes.put(classname,clazz);
 
  if(saveToClassPath){
   saveToClassPath(classfile, classname);
  }
 
 }
 
 /**
  * return a class which implements all the interfaces or inherit from one of class
  * currently, just return null.
  */
 public Class search(Class interfaces[]){
  return null;
 }
 
 private void saveToClassPath(byte classfile[], String classname){
  String filename = classname + ".class";
 
  URL url = getClass().getProtectionDomain().getCodeSource().getLocation();
  if( "file".equals(url.getProtocol()) && (url.getHost() == null || url.getHost().equals("")) ){
      String dir = null;
      try{
dir = URLDecoder.decode(url.getFile(), "UTF-8");
}catch(UnsupportedEncodingException ex){
log.error("Encoding not supported", ex);
}
 
   File classpath = new File(dir);
   if(classpath.isDirectory() == false){
    log.info("Classpath error for ProxyClassLoader:" + dir + " not a directory");
    return;
   }
   File file = new File(classpath, filename);
   try {
    FileOutputStream os = new FileOutputStream(file);
    os.write(classfile);
    os.close();
   }
   catch(IOException ex){
log.error("Error writing Proxy Class file", ex);
ex.printStackTrace();
   }
  }
 
 }
 
}
参考这篇文章
http://www.cjsdn.net/post/view?bid=29&id=162060&sty=1&tpg=1&age=0

分享到:
评论

相关推荐

    how tomcat works中文版.pdf百度网盘下载地址

    掌握这些知识不仅有助于开发者更好地使用Tomcat进行Java Web应用开发,还能在遇到问题时快速定位原因并采取有效措施解决。希望本文能帮助您建立起对Tomcat工作原理的深刻理解。 最后,如果您希望通过文档进一步深入...

    tomcat常见问题及解决方法

    6. 在 Tomcat 下使用 JNI 时我遇到了类装载器的问题 在 Tomcat 中使用 JNI 时,需要了解类装载器的问题。不能将本地库或者他们的 JNI 接口放在应用程序的 WEB-INF/lib 或者 WEB-INF/classes 目录下,否则可能会导致...

    Tomcat中间件监控配置&指标.doc

    10. 类加载信息:包括已装载类的总数、已卸载类总数和当前装载类数等信息。 11. 垃圾回收器信息:包括垃圾回收器名称、回收总次数和回收消耗总时间等信息。 通过监控这些信息,可以实时了解Tomcat的运行状态和性能...

    JAVA虚拟机的类装载机制的原理分析与应用研究.pdf

    - **隔离模块**:不同的类装载器可以加载相同类的不同版本,实现类的隔离,比如Tomcat容器中的Web应用隔离。 - **安全性**:验证机制能防止恶意代码的注入,保障系统的安全运行。 了解并熟练掌握Java虚拟机的类装载...

    tomcat源码基于6.0

    4. **生命周期管理**:Tomcat通过`Lifecycle`接口和`LifeCycleListener`机制来管理Servlet的生命周期,包括装载、初始化、启动、停止和卸载等阶段。 5. **JSP编译**:Jasper会监控JSP文件的改动,自动重新编译。JSP...

    jconsole+tomcat配置说明 附加Tomcat内存说明(基于jdk5.0).docx )

    5. **类面板**: 显示已加载类的数量和统计信息,有助于理解类装载行为。 6. **Garbage Collector和Memory面板**: 监控垃圾收集活动和内存使用情况,优化内存配置。 7. **CPU面板**: 统计CPU使用率,帮助识别性能...

    tomcat源码 tomcat本来就是开源的

    4. **参与社区讨论**:加入Tomcat的技术论坛或者邮件列表,与其他开发者交流心得体验,解决遇到的问题。 5. **实践应用**:将所学知识应用于实际项目中,不断巩固和提升自己的技能水平。 #### 五、Tomcat核心组件...

    tomcat的工作原理

    2. **容器(Containers)**:容器是Tomcat的核心,用于装载和管理Web应用程序。容器可以分为四个层次:Engine、Host、Context和Wrapper,分别对应整个服务器、虚拟主机、Web应用程序和具体的Servlet或JSP页面。 - ...

    Tomcat 6.0启动过程分析

    `Bootstrap` 类作为 Tomcat 的启动入口,承担着构建一个独立的类加载器的任务,用于装载 `Catalina` 的内部类,以此来确保这些内部类与系统的 classpath 相隔离,避免与应用级别的类产生冲突。 - **主函数 main** ...

    apache-tomcat-7.0.75

    描述中提到的"可以装载dubbo-admin项目"表明Tomcat 7.0.75能够支持Dubbo管理控制台的部署和运行。Dubbo是一个高性能、轻量级的服务治理框架,广泛应用于分布式系统。Dubbo-admin是一个用于监控和管理Dubbo服务的Web...

    apache和tomcat的区别

    Apache是一个卡车,可以装载静态网页等,而Tomcat是一个桶,可以装载JSP、Servlet等动态网页。如果我们想装载水(JSP、Servlet等),我们需要一个卡车(Apache)和一个桶(Tomcat)。 Apache和Tomcat的区别还可以...

    tomcat启动服务运行servlet

    6. 装载Servlet:根据`web.xml`中的配置,Tomcat实例化Servlet类,并调用其`init()`方法进行初始化。 7. 服务器开始监听并处理请求:一旦启动完成,Tomcat就开始接受HTTP请求,将请求分发给相应的Servlet进行处理。 ...

    Tomcat教程-JVM相关工具.docx

    jconsole是一个图形化界面工具,可以实时监控Java应用的性能和资源使用情况,包括JVM指标、线程、类装载、内存、垃圾收集等。 8. **jvisualvm (Java VisualVM)**: jvisualvm是另一个功能强大的Java应用性能分析...

    How Tomcat Work Source

    总结,通过对Apache Tomcat 4.1.40源码的深度学习,我们可以更全面地了解其工作原理,这对于优化性能、排查问题、自定义扩展都具有极大的帮助。在实际开发中,结合文档和源码,可以提高我们对Tomcat的理解和应用能力...

    Tomcat中间件监控配置&amp;指标.doc

    - JMX提供了一种标准的方式来管理和监控Java应用程序,可以获取到详细的运行时信息,如类装载、线程池、Garbage Collection等。 4. **错误和异常**: - **日志分析**:定期分析`catalina.out`和其他日志文件,找...

    tomcat内存溢出

    3. **类加载器问题**:如果类加载器没有被正确地卸载,其所加载的类及对应的资源就会一直占用内存,形成所谓的“类装载器内存泄漏”。 4. **JVM配置不当**:错误的JVM内存设置,如初始堆大小(Xms)和最大堆大小...

Global site tag (gtag.js) - Google Analytics