简体   繁体   English

Spring:java.lang.NoClassDefFoundError:无法初始化类

[英]Spring: java.lang.NoClassDefFoundError: Could not initialize class

I am developing a little web application in Spring MVC. 我正在Spring MVC中开发一个小的Web应用程序。 I get the exception every time I try to get my custom class in any controller, in case if this class uses another custom class. 每次我尝试在任何控制器中获取自定义类时,我都会得到异常,以防该类使用另一个自定义类。 It is easier to show on example: 在示例中更容易显示:

Controller, where I'm trying to get an object of custom class WireTest: 控制器,我正在尝试获取自定义类WireTest的对象:

@Controller
@RequestMapping("/offices")
public class OfficesController {

  @Autowired
  private WireTest wt;

  @RequestMapping("")
  public String offices(Model model) {
    model.addAttribute("test", wt.getString());
    return "offices";
  }
}

The problem happens always, whether I'm creating an object directly or use @Autowired. 无论我是直接创建对象还是使用@Autowired,问题总会发生。 In code here, I'm showing the case of @Autowired, but that doesn't matter - I could write private WireTest wt = new WireTest() , and the exception would be the same. 在这里的代码中,我展示了@Autowired的情况,但这没关系 - 我可以编写private WireTest wt = new WireTest() ,并且异常将是相同的。

WireTest.java class: WireTest.java类:

@Service
public class WireTest {
  public String getString() {return (DBhelper.getString());}
}

Part of DBhelper.java class (There are also other static members, the full code is below): DBhelper.java类的一部分(还有其他静态成员,完整代码如下):

public class DBhelper {
    public static String getString() {return "Hi!";}
}

And the exception: 例外情况:

HTTP Status 500 - Handler processing failed; nested exception is         
java.lang.NoClassDefFoundError: Could not initialize class org.sher.wtpractice.dao.DBhelper

I also can use these classes without any problems in console application, so it works outside Spring. 我也可以在控制台应用程序中使用这些类而没有任何问题,因此它可以在Spring之外运行。

My Spring configuration: 我的Spring配置:

web.xml : web.xml

<?xml version="1.0" encoding="UTF-8"?>
<web-app version="2.5" xmlns="http://java.sun.com/xml/ns/javaee"
         xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
         xsi:schemaLocation="http://java.sun.com/xml/ns/javaee http://java.sun.com/xml/ns/javaee/web-app_2_5.xsd">

    <!-- Processes application requests -->
    <servlet>
        <servlet-name>dispatcher</servlet-name>
        <servlet-class>org.springframework.web.servlet.DispatcherServlet</servlet-class>
        <load-on-startup>1</load-on-startup>
    </servlet>

    <servlet-mapping>
        <servlet-name>dispatcher</servlet-name>
        <url-pattern>/</url-pattern>
    </servlet-mapping>

    <context-param>
        <param-name>contextConfigLocation</param-name>
        <param-value>/WEB-INF/dispatcher-servlet.xml</param-value>
    </context-param>

    <listener>
        <listener-class>
            org.springframework.web.context.ContextLoaderListener
        </listener-class>
    </listener>
</web-app>

dispatcher-servlet.xml : dispatcher-servlet.xml

<?xml version="1.0" encoding="UTF-8" ?>
<beans xmlns="http://www.springframework.org/schema/beans"
       xmlns:context="http://www.springframework.org/schema/context"
       xmlns:mvc="http://www.springframework.org/schema/mvc" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
       xsi:schemaLocation="
    http://www.springframework.org/schema/beans
    http://www.springframework.org/schema/beans/spring-beans.xsd
    http://www.springframework.org/schema/context
    http://www.springframework.org/schema/context/spring-context.xsd
    http://www.springframework.org/schema/mvc
    http://www.springframework.org/schema/mvc/spring-mvc.xsd">

<context:component-scan base-package="org.sher.wtpractice.spring, org.sher.wtpractice.dao" />
    <mvc:annotation-driven />
    <mvc:resources mapping="/css/**" location="/css/"/>
    <mvc:resources mapping="/js/**" location="/js/"/>
    <bean class="org.springframework.web.servlet.view.InternalResourceViewResolver">
        <property name="prefix">
            <value>/WEB-INF/jsp/</value>
        </property>
        <property name="suffix">
            <value>.jsp</value>
        </property>
    </bean>
</beans>

I'm using Maven for building and Tomcat 7 as a server, if that matters. 我正在使用Maven进行构建,将Tomcat 7用作服务器,如果这很重要的话。 Spring version is 4.0.1.RELEASE Spring版本是4.0.1.RELEASE

Update: Complete code of DBhelper.java 更新:DBhelper.java的完整代码

import org.hibernate.Session;
import org.hibernate.SessionFactory;
import org.hibernate.Transaction;
import org.hibernate.boot.registry.StandardServiceRegistryBuilder;
import org.hibernate.cfg.Configuration;
import org.hibernate.service.ServiceRegistry;

import java.util.Calendar;
import java.util.Date;
public class DBhelper {
    private static final SessionFactory sessionFactory = createSessionFactory();

    private static SessionFactory createSessionFactory() {
        Configuration configuration = new Configuration();
        configuration.configure();
        ServiceRegistry serviceRegistry = new StandardServiceRegistryBuilder().applySettings(
                configuration.getProperties()).build();
        return configuration.buildSessionFactory(serviceRegistry);
    }

    public static Object queryWrapper(DBoperation op) {
        Session session = sessionFactory.openSession();
        Transaction transaction = null;
        Object result = null;
        try {
            transaction = session.beginTransaction();
            result = op.operation(session);
            session.getTransaction().commit();
        } catch (Exception e) {
            if (transaction != null) {
                transaction.rollback();
            }
//            throw e;
        } finally {
            if (session != null && session.isOpen())
                session.close();
        }
        return result;
    }
    public static Date normalizeCal(Calendar cal) {
        cal.set(Calendar.MILLISECOND, 0);
        return cal.getTime();
    }
    public static String getString() {return "Hi!";}
}

Any help would be greatly appreciated! 任何帮助将不胜感激!

Try lazy-loading the session factory instead of initializing it statically by assigning to a final field. 尝试延迟加载会话工厂,而不是通过分配到final字段来静态初始化它。

For example, create a method such as the following, which returns the session factory, creating it if necessary. 例如,创建一个方法,如下所示,返回会话工厂,必要时创建它。 Whenever you want to use the session factory, call this method instead of referring directly to the field: 每当您想使用会话工厂时,请调用此方法而不是直接引用该字段:

private static SessionFactory getSessionFactory() {
    if (sessionFactory == null) {
        sessionFactory = createSessionFactory();
    }
    return sessionFactory;
}

Personally I dislike static initialization for anything non-trivial, as you're out of control of when it happens. 就个人而言,我不喜欢任何非平凡的静态初始化,因为你无法控制它何时发生。 With the above method you are in control: the session factory gets created the first time you need to use it. 使用上述方法,您可以控制:会话工厂在您第一次使用它时创建。

If you want to know what the problem is, I have two suggestions. 如果你想知道问题是什么,我有两个建议。 Firstly, restart your web application container and see if you get a different exception message first time. 首先,重新启动Web应用程序容器,看看是否第一次收到不同的异常消息。 (The 'first time' is important here: Could not initialize class means that the JVM has already tried and failed to initialize the class.) Secondly, try wrapping the contents of the createSessionFactory method in a try - catch block such as the following: ('第一次'在这里很重要: Could not initialize class意味着JVM已经尝试过并且无法初始化类。)其次,尝试将createSessionFactory方法的内容包装在try - catch块中,如下所示:

try {
    ...
} catch (Throwable e) {
    e.printStackTrace();
    throw new RuntimeException(e);
}

However, I can't guarantee that either approach will offer you much enlightenment. 但是,我不能保证这两种方法都能为你提供很多启示。

EDIT : rather than just speculate, I decided to actually try this out and see what happens. 编辑 :而不是仅仅推测,我决定尝试这一点,看看会发生什么。 So I knocked up a small web application using Spring and Hibernate and deployed it to Tomcat. 所以我使用Spring和Hibernate敲了一个小的Web应用程序并将它部署到Tomcat。 While attempting to get it working I encountered a few issues when attempting to read the Hibernate configuration, caused by me making the following mistakes: 在尝试使其工作时,我在尝试读取Hibernate配置时遇到了一些问题,这是由于我犯了以下错误:

  • I hadn't included the hibernate.cfg.xml file in the .war file, 我没有在.war文件中包含hibernate.cfg.xml文件,
  • I hadn't included the database's JDBC driver JAR in the .war file, 我没有在.war文件中包含数据库的JDBC驱动程序JAR,
  • the database I was trying to connect to was down. 我试图连接的数据库已关闭。

In each case my first approach worked. 在每种情况下我的第一种方法都有效 The first request made following a Tomcat restart gave me an ExceptionInInitializerError with further details below it. Tomcat重启后发出的第一个请求给了我一个ExceptionInInitializerError ,下面有更详细的信息。 The second and subsequent requests gave me NoClassDefFoundError s which didn't tell me much about the problem. 第二个和后续的请求给了我NoClassDefFoundError s,它没有告诉我很多关于这个问题的信息。

The problem is that once an ExceptionInInitializerError has been thrown for a class, the JVM blacklists this class and will refuse to do anything with it subsequently. 问题是,一旦为类抛出ExceptionInInitializerError ,JVM会将此类列入黑名单,并且随后将拒绝对其执行任何操作。 So you only get one chance to see what goes wrong in static initialization code. 所以你只有一次机会看到静态初始化代码出了什么问题。 If you initialized Hibernate lazily as I recommended above, you would get the detailed exception message every time. 如果您按照我上面的建议懒洋洋地初始化Hibernate,那么每次都会得到详细的异常消息。 Consider this another reason to avoid static initialization. 考虑避免静态初始化的另一个原因。

Check the static initialization of DBhelper . 检查DBhelper的静态初始化。

"NoClassDefFoundError: Could not initialize class" error “NoClassDefFoundError:无法初始化类”错误

In this case, instantiate sessionFactory as spring bean, and let the spring container assemble it to DBhelper . 在这种情况下,将sessionFactory实例化为spring bean,并让spring容器将它组装到DBhelper

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

相关问题 java.lang.NoClassDefFoundError:无法初始化类 - java.lang.NoClassDefFoundError: Could not initialize class java.lang.NoClassDefFoundError:无法初始化类 - java.lang.NoClassDefFoundError: Could not initialize class ECLIPSE:java.lang.NoClassDefFoundError:无法初始化类**** - ECLIPSE: java.lang.NoClassDefFoundError: Could not initialize class **** java.lang.NoClassDefFoundError:无法初始化类x - java.lang.NoClassDefFoundError: Could not initialize class x Tomcat java.lang.NoClassDefFoundError:无法初始化类 - Tomcat java.lang.NoClassDefFoundError: Could not initialize class java.lang.NoClassDefFoundError:无法初始化类DataLayer.HibernateAdapter - java.lang.NoClassDefFoundError: Could not initialize class DataLayer.HibernateAdapter java.lang.NoClassDefFoundError:无法初始化类business.HibernateUtil - java.lang.NoClassDefFoundError: Could not initialize class business.HibernateUtil java.lang.NoClassDefFoundError:无法初始化类 XXX - java.lang.NoClassDefFoundError: Could not initialize class XXX java.lang.NoClassDefFoundError: 无法初始化类 | 静态块 - java.lang.NoClassDefFoundError: Could not initialize class | static block java.lang.NoClassDefFoundError: 无法初始化 class - Kotlin Object - java.lang.NoClassDefFoundError: Could not initialize class - Kotlin Object
 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM