跳至主要内容

Class Not Found vs No Class Def Found

Class Not Found vs No Class Def Found

When we are working on JavaEE, we will always has multiple issues related to classes and ClassLoader.
We may struggle to find some strange memory leaks caused by ClassLoader; we may fail to run some applications because it fail to find some class; we may encounter cases when multiple versions of library conflict.
In order to solve all similar problems one for all, today we focus the understanding of two exception (to be precise, one exception and one error):

  • java.lang.ClassNotFoundException
  • java.lang.NoClassDefFoundError

ClassLoader

Before we get to solve the problem, we have to skim some basic knowledge of class loading.

In the world of Java, almost all things are abstracted into a class. Class is also a class, which organized by classpath and package structure. In order to load classes when suitable, JVM use the abstraction of ClassLoader to locate or generate data that constitutes a definition for the class.
The class loader use the a model called delegation, in which a class loader will delegate the search for class/resources to its parent before attempting to find them by itself. The most basic class, like class under java.* are all loaded by bootstrap class loader, which can’t be written in Java (or who will load this class?) and is the ancestor of all other class loaders. Other common class loaders are extension class loader and system class loader.

Class Not Found

From the doc of this ClassNotFoundException:

Thrown when an application tries to load in a class through its string name using:

  • The forName method in class Class.
  • The findSystemClass method in class ClassLoader .
  • The loadClass method in class ClassLoader.

but no definition for the class with the specified name could be found.

This doc sum up the three way to load a class in JVM, but it doesn’t tell us what does it mean and when it will be thrown.

The common way for class loader to work is to read a “class file” from directory specified by classpath, so this means that exception indicates the class was not found on the classpath. This indicates that we were trying to load the class definition, and the class did not exist on the classpath.

So, when this exception occurs, it may be means:

  • we have wrong class path specified;
  • we forget the full package name, which is required for class loader object to search in right directory;
  • we don’t have the permission on some directory or file

No Class Def Found

From NoClassDefFoundError:

Thrown if the Java Virtual Machine or a ClassLoader instance tries to load in the definition of a class (as part of a normal method call or as part of creating a new instance using the new expression) and no definition of the class could be found.
The searched-for class definition existed when the currently executing class was compiled, but the definition can no longer be found.

The docs points out the core of this error: this code can compile, but fail to run. It can have following possible reasons:

  • the lib required is provided in compile classpath, but not provided in runtime environment – this error should be caused by a ClassNotFoundException:
    • lib is not packaged into Jar/War
    • wrong class path settings in IDE and/or wrong class path environment variable
    • access class across different class loaders
  • this error is a subclass of LinkageError, so it will throw when:
    • when init class, i.e. init static variable or execute static code block and meet some errors with ExceptionInInitializerError
    • other verification error of class: illegal name, class file not match its binary name etc.

Ref

Written with StackEdit.

评论

此博客中的热门博文

Spring Boot: Customize Environment

Spring Boot: Customize Environment Environment variable is a very commonly used feature in daily programming: used in init script used in startup configuration used by logging etc In Spring Boot, all environment variables are a part of properties in Spring context and managed by Environment abstraction. Because Spring Boot can handle the parse of configuration files, when we want to implement a project which uses yml file as a separate config file, we choose the Spring Boot. The following is the problems we met when we implementing the parse of yml file and it is recorded for future reader. Bind to Class Property values can be injected directly into your beans using the @Value annotation, accessed via Spring’s Environment abstraction or bound to structured objects via @ConfigurationProperties. As the document says, there exists three ways to access properties in *.properties or *.yml : @Value : access single value Environment : can access multi...

Elasticsearch: Join and SubQuery

Elasticsearch: Join and SubQuery Tony was bothered by the recent change of search engine requirement: they want the functionality of SQL-like join in Elasticsearch! “They are crazy! How can they think like that. Didn’t they understand that Elasticsearch is kind-of NoSQL 1 in which every index should be independent and self-contained? In this way, every index can work independently and scale as they like without considering other indexes, so the performance can boost. Following this design principle, Elasticsearch has little related supports.” Tony thought, after listening their requirements. Leader notice tony’s unwillingness and said, “Maybe it is hard to do, but the requirement is reasonable. We need to search person by his friends, didn’t we? What’s more, the harder to implement, the more you can learn from it, right?” Tony thought leader’s word does make sense so he set out to do the related implementations Application-Side Join “The first implementation ...

Learn Spring Expression Language

When reading the source code of some Spring based projects, we can see some code like following: @Value( "${env}" ) private int value ; and like following: @Autowired public void configure (MovieFinder movieFinder, @ Value ("#{ systemProperties[ 'user.region' ] } ") String defaultLocale) { this.movieFinder = movieFinder; this.defaultLocale = defaultLocale; } In this way, we can inject values from different sources very conveniently, and this is the features of Spring EL. What is Spring EL? How to use this handy feature to assist our developments? Today, we are going to learn some basics of Spring EL. Features The full name of Spring EL is Spring Expression Language, which exists in form of Java string and evaluated by Spring. It supports many syntax, from simple property access to complex safe navigation – method invocation when object is not null. And the following is the feature list from Spring EL document : ...