今天在做Annotation扫描的时候发现的。。java.lang.NoClassDefFoundError: org/hibernate/Session
at java.lang.Class.forName0(Native Method)
at java.lang.Class.forName(Class.java:169)
at jax.commons.ScanClass.getAllClassName(ScanClass.java:53)
at jax.commons.ScanClass.getClasses(ScanClass.java:23)
at jax.commons.ScanClass.getClasses(ScanClass.java:21)
at jax.commons.ScanClass.getClasses(ScanClass.java:21)调试发现时 实例化jax.service.AbstractServiceImpl的Class时抛的异常jax.service.AbstractServiceImpl源码大概是这样的package jax.service;import org.hibernate.Session;
import org.hibernate.SessionFactory;
import org.hibernate.cfg.Configuration;public abstract class AbstractServiceImpl<T> implements EntityService<T,Integer>{

private Class<T> clz;
public SessionFactory sf;
public Session session;
}
为什么我获取AbstractServiceImpl.class的时候会抛NoClassDefFoundError: org/hibernate/Session求解。

解决方案 »

  1.   


      把Class<?> clz = Class.forName(sb.toString());
    改为Class<?> clz = ScanClass.class.getClassLoader().loadClass(sb.toString());
    就可以了但是原理还是不懂
      

  2.   

    唉。。原来我没把hibernate的包放到web目录的lib下。。但是放到lib跟没放有什么区别呢?
      

  3.   


    。。没导入jar包public class NoClassDefFoundError
    extends LinkageError
    当 Java 虚拟机或 ClassLoader 实例试图在类的定义中加载
    (作为通常方法调用的一部分或者作为使用 new 表达式创建的新实例的一部分),
    但无法找到该类的定义时,抛出此异常。 当前执行的类被编译时,所搜索的类定义存在,但无法再找到该定义。 
      

  4.   

    你的问题跟虚拟机类加载的原理有关。
    类加载的原理比较复杂,这里一时半会也陈述不清,我只能告诉你,你当前调用Class.forName方法的类加载器与ScanClass.class.getClassLoader()所获得的加载器是不同的,前者不能找到你指定的Class源数据(这个跟类加载器具体实现有关,你可以自己实现类加载器,数据源可能是个.class文件,也可能是某个网络流),而后者可以找到你指定的Class数据源。
    而调用Class.forName单参数方法的类加载器是你调用这个方法的类的类加载器,这个类加载器可以如此获得:
    this.getClass.getClassLoader();
    如果这个方法返回的是个null,则说明这个类加载器是java虚拟机的初始化类加载器。
    而你使用的ScanClass.class.getClassLoader().loadClass(sb.toString())
    说明ScanClass类的类加载器可以加载你所传入参数的类,而且往往是同一个类加载器。
      

  5.   

    当调用:Class <?> clz = Class.forName(sb.toString())时,实际上是调用
    Class.forName("XXX.XXX", true, ScanClass.class.getClassLoader());
    第二个true表示立即初始化.
    而Class <?> clz = ScanClass.class.getClassLoader().loadClass(sb.toString());
    实际上是Class.forName("XXX.XXX", false, ScanClass.class.getClassLoader());
    只有在clz .newInstance()才初始化的.
      

  6.   


     public static Class<?> forName(String className) 
                    throws ClassNotFoundException {
            return forName0(className, true, ClassLoader.getCallerClassLoader());
        }// 这是Class.forName,调用的是ClassLoader.getCallerClassLoader() static ClassLoader getCallerClassLoader() {
            // NOTE use of more generic Reflection.getCallerClass()
            Class caller = Reflection.getCallerClass(3);
            // This can be null if the VM is requesting it
            if (caller == null) {
                return null;
            }
            // Circumvent security check since this is package-private
            return caller.getClassLoader0();
        } //实际返回空或者调用.getClassLoader0()public ClassLoader getClassLoader() {
            ClassLoader cl = getClassLoader0();
            if (cl == null)
                return null;
            SecurityManager sm = System.getSecurityManager();
            if (sm != null) {
                ClassLoader ccl = ClassLoader.getCallerClassLoader();
                if (ccl != null && ccl != cl && !cl.isAncestor(ccl)) {
                    sm.checkPermission(SecurityConstants.GET_CLASSLOADER_PERMISSION);
                }
            }
            return cl;
        }//这个是xxx.class.getClassLoader(),返回也是getClassLoader0().楼上能具体说明么?