java - ClassNotFoundException vs NoClassDefFoundError
class not found php (10)
Bueno ... ClassNotFoundException
ocurre cuando el tiempo de ejecución está tratando de encontrar la clase nombrada por alguna String
por ejemplo, el método Class.forName(java.lang.String)
toma un argumento de cadena e intenta encontrar la clase con este nombre. En este caso, el nombre de la clase es una picadura y solo se puede verificar en tiempo de ejecución. aquí la excepción dice claramente ... esta "clase" no se encuentra. Entonces ... puede suceder por dos razones:
Razón 1. El nombre de clase no es una clase java válida (ejemplo - "java.bang.kiting").
// Example
Class cdef = Class.forName( "java.bang.kiting" );
Razón 2. El nombre de la clase era una clase válida ... pero de alguna manera no estaba empaquetado con el jar o no se resolvió en la ruta de la clase. Por lo que el tiempo de ejecución sabe ... puede ser un nombre de clase incorrecto ... similar al caso 1.
// Example
Class cdef =Class.forName( "apache.some.SomeLegitClass" );
Donde como NoClassDefFoundError
para casos donde se usó la referencia de clase real,
// example
import apache.some.SomeLegitClass
SomeLegitClass i = (SomeLegitClass) instanceOfSomeLegitClass;
Así que, básicamente, todo fue correcto, pero de alguna manera la clase no está empaquetada con el archivo jar (o más generalmente, no se resuelve en la ruta de clase). En este caso obtenemos NoClassDefFoundError
.
Aquí el tiempo de ejecución sabe que la clase es válida ya que se compiló con éxito ... pero no puede encontrar la "definición de clase".
He pasado por este hilo ¿Qué causa y cuáles son las diferencias entre NoClassDefFoundError y ClassNotFoundException? Esto es lo que uno de los ans, que tiene max ups, en el hilo es: NoClassDefFoundError : "Entonces, parece que NoClassDefFoundError ocurre cuando la fuente se compiló con éxito, pero en el tiempo de ejecución, no se encontraron los archivos de clase requeridos . Esto puede ser algo que puede suceder en la distribución o producción de archivos JAR, donde no se incluyeron todos los archivos de clase requeridos ".
ClassNotFoundException : En cuanto a ClassNotFoundException, parece que puede surgir al intentar hacer llamadas reflexivas a las clases en tiempo de ejecución, pero las clases a las que el programa está tratando de llamar no existe.
Hice un pequeño experimento. Creé una clase principal, clase A y traté de llamar a otra clase, clase B , compilada exitosamente.
Luego eliminé la clase B que se llama en la clase A. Obtuve la excepción java.lang.ClassNotFoundException, pero de acuerdo con la respuesta en la banda de rodadura, debería haber obtenido NoClassDefFoundError (la fuente se compiló con éxito pero no se encontraron los archivos de clase en tiempo de ejecución) ¿Podría alguien explicar lo que me falta en la interpretación de los ans en el hilo?
package com.random;
public class A {
public static void main(String[] args) {
B b= new B();
}
}
package com.random;
public class B {
}
ClassNotFoundException y NoClassDefFoundError ocurren cuando una clase particular no se encuentra en el tiempo de ejecución. Sin embargo, ocurren en diferentes escenarios.
La excepción ClassNotFoundException es una excepción que se produce cuando intenta cargar una clase en tiempo de ejecución utilizando los métodos Class.forName () o loadClass () y las clases mencionadas no se encuentran en el classpath.
public class MainClass
{
public static void main(String[] args)
{
try
{
Class.forName("oracle.jdbc.driver.OracleDriver");
}catch (ClassNotFoundException e)
{
e.printStackTrace();
}
}
}
java.lang.ClassNotFoundException: oracle.jdbc.driver.OracleDriver
at java.net.URLClassLoader.findClass(Unknown Source)
at java.lang.ClassLoader.loadClass(Unknown Source)
at sun.misc.Launcher$AppClassLoader.loadClass(Unknown Source)
at java.lang.ClassLoader.loadClass(Unknown Source)
at java.lang.Class.forName0(Native Method)
at java.lang.Class.forName(Unknown Source)
at pack1.MainClass.main(MainClass.java:17)
NoClassDefFoundError es un error que se produce cuando una clase en particular está presente en el momento de la compilación, pero se perdió en el tiempo de ejecución.
class A
{
// some code
}
public class B
{
public static void main(String[] args)
{
A a = new A();
}
}
Cuando compile el programa anterior, se generarán dos archivos .class. Uno es A.class y otro es B.class. Si elimina el archivo A.class y ejecuta el archivo B.class, Java Runtime System lanzará NoClassDefFoundError como a continuación:
Exception in thread "main" java.lang.NoClassDefFoundError: A
at MainClass.main(MainClass.java:10)
Caused by: java.lang.ClassNotFoundException: A
at java.net.URLClassLoader.findClass(URLClassLoader.java:381)
at java.lang.ClassLoader.loadClass(ClassLoader.java:424)
at sun.misc.Launcher$AppClassLoader.loadClass(Launcher.java:331)
at java.lang.ClassLoader.loadClass(ClassLoader.java:357)
Como se mencionó en las respuestas anteriores, NoClassDefFoundError ocurrirá cuando la clase estuvo presente durante el tiempo de compilación y no esté disponible durante el tiempo de ejecución por algunas razones.
Hay otro escenario que deseo agregar, que también podría resultar en NoClassDefFoundError.
Cuando intenta cargar una clase que no se pudo cargar debido a alguna excepción, como un error en el bloque de inicialización estática, el sistema le lanzará ExceptionInInitializerError. Si intenta volver a cargar la misma clase (que no se cargó anteriormente), el sistema lanzará NoClassDefFoundError
Vamos a explorarla con una muestra.
ClassWithStaticBlock.java
public class ClassWithStaticBlock {
static {
int total = 1/0;
}
}
Main.java
public class Main {
public static void main(String[] args) {
ClassWithStaticBlock cs;
try {
cs = new ClassWithStaticBlock();
}catch(Throwable e){
e.printStackTrace();
}
}
}
Resultado:
java.lang.ExceptionInInitializerError
at Main.main(Main.java:6)
at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:39)
at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:25)
at java.lang.reflect.Method.invoke(Method.java:597)
at com.intellij.rt.execution.application.AppMain.main(AppMain.java:140)
Caused by: java.lang.ArithmeticException: / by zero
at ClassWithStaticBlock.<clinit>(ClassWithStaticBlock.java:7)
... 6 more
Permite modificar Main.java.
public class Main {
public static void main(String[] args) {
ClassWithStaticBlock cs;
try {
cs = new ClassWithStaticBlock();
}catch(Throwable e){
e.printStackTrace();
}
cs = new ClassWithStaticBlock(); //try to use ClassWithStaticBlock again
}
}
Resultado:
java.lang.ExceptionInInitializerError
at Main.main(Main.java:6)
at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:39)
at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:25)
at java.lang.reflect.Method.invoke(Method.java:597)
at com.intellij.rt.execution.application.AppMain.main(AppMain.java:140)
Caused by: java.lang.ArithmeticException: / by zero
at ClassWithStaticBlock.<clinit>(ClassWithStaticBlock.java:7)
... 6 more
Exception in thread "Main Thread" java.lang.NoClassDefFoundError: ClassWithStaticBlock
at Main.main(Main.java:10)
at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:39)
at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:25)
at java.lang.reflect.Method.invoke(Method.java:597)
at com.intellij.rt.execution.application.AppMain.main(AppMain.java:140)
Cuando intentamos usar ClassWithStaticBlock nuevamente (que no se pudo inicializar antes), el sistema está lanzando NoClassDefFoundError.
Encontré la muestra de ¿Por qué obtengo un NoClassDefFoundError en Java?
La diferencia depende de quién le pidió a la clase que se cargue :
-
ClassNotFoundException
produce cuando el código intenta cargar directamente una clase , pasando el argumentoString
que representa un nombre totalmente calificado de la clase.- por ejemplo,
Class.forName(String)
, oClassLoader.loadClass(String)
.
- por ejemplo,
-
NoClassDefFoundError
se lanza cuando se le pide a la JVM que cargue una clase indirectamente .- por ejemplo, cuando la clase A está utilizando la clase B y la clase B no está en la ruta de
NoClassDefFoundError
, seNoClassDefFoundError
.
- por ejemplo, cuando la clase A está utilizando la clase B y la clase B no está en la ruta de
Las otras respuestas en este hilo son correctas, solo quiero agregar algo que pasé horas tratando de averiguar. Incluso si
Class.forName("apache.some.SomeLegitClass")
trabajos,
Class.forName("apache.some.somelegitclass")
resultará en un NoClassDefFoundError. El Class.forName () distingue entre mayúsculas y minúsculas. Resultará en diferentes excepciones si el nombre de clase está mal escrito o simplemente tiene una carcasa incorrecta.
Uno de los casos en los que ocurre NoClassDefFoundError es cuando la clase JVM está intentando acceder, no se encuentra en classpath. Pero si la clase está presente en classpath, resultará en ClassNotFoundException.
En resumen, NoClassDefFoundError vendrá si una clase estuvo presente durante el tiempo de compilación pero no estuvo disponible en java classpath durante el tiempo de ejecución.
Solo intente ejecutar con la opción -classpath explícita donde la ruta de clase no contenga la clase B.
Todo sobre el artículo ClassNotFoundException Vs NoClassDefFoundError explica la diferencia entre ClassNotFoundException Vs NoClassDefFoundError muy claramente con el ejemplo y de acuerdo con él.
ClassNotFoundException
Es una excepción marcada que ocurre cuando le decimos a JVM que cargue una clase por su nombre de cadena usando los métodos Class.forName () o ClassLoader.findSystemClass () o ClassLoader.loadClass () y la clase mencionada no se encuentra en el classpath.
La mayoría de las veces, esta excepción se produce cuando intenta ejecutar una aplicación sin actualizar la ruta de clase con los archivos JAR necesarios. Por ejemplo, es posible que haya visto esta excepción al hacer el código JDBC para conectarse a su base de datos, por ejemplo, MySQL, pero su classpath no tiene el jar para ello.
public class Test {
public static void main(String[] args) throws Exception {
// Provide any class name to Class.forName() which does not exist
// Or compile Test.java and then manually delete Person.class file so Person class will become unavailable
// Run the program using java Test
Class clazz = Class.forName("Person");
Person person = (Person) clazz.newInstance();
person.saySomething();
}
}
class Person {
void saySomething() {
System.out.println("Hello");
}
}
No Error Clase Def Encontrado
Es un subtipo de java.lang.Error y la clase Error indica un comportamiento anormal que realmente no debería ocurrir con una aplicación, pero los desarrolladores de aplicaciones no deberían intentar atraparlo, está ahí solo para uso de JVM.
NoClassDefFoundError ocurre cuando JVM intenta cargar una clase particular que es parte de su ejecución de código (como parte de una llamada de método normal o como parte de crear una instancia usando la nueva palabra clave) y esa clase no está presente en su ruta de clase pero sí estaba presente en tiempo de compilación porque para ejecutar su programa necesita compilarlo y si está intentando usar una clase que no está presente, el compilador generará un error de compilación.
public class Test {
public static void main(String[] args) throws Exception {
// Do javac on Test.java,
// Program will compile successfully because Empoyee class exits
// Manually delete Employee.class file
// Run the program using java Test
Employee emp = new Employee();
emp.saySomething();
}
}
class Employee {
void saySomething() {
System.out.println("Hello");
}
}
NoClassDefFoundError
se llama NoClassDefFoundError
cuando está utilizando una biblioteca (por ejemplo, Guava, Gson, CommonsIO). Coloca la biblioteca en la ruta de clase de su proyecto, pero no la exportó en conjunto, obtendrá un NoClassDefFoundError
cuando la aplicación se está ejecutando.
Cómo obtener NoClassDefFoundError
:
Crea un nuevo proyecto, con esta clase.
public class A
{
public void do()
{
System.out.println("Do!");
}
}
Exportarlo como un archivo .jar
.
Ahora crea otro proyecto. Agregue el archivo jar exportado a classpath.
import ???.A;
public class Main
{
public static void main(String[] args)
{
A a = new A();
a.do();//NoClassDefFoundError thrown at here.
}
}
Exporte el proyecto, asegúrese de no incluir el archivo jar (con clase A
). Ejecute el archivo jar recién exportado, verá ese error!
1) ClassNotFoundException
- Esto ocurre cuando intentamos cargar una clase en tiempo de ejecución utilizando los métodos
Class.forName()
oClassLoader.loadClass()
oClassLoader.findSystemClass()
y no se pudo encontrar la clase requerida en la ruta de la clase . - En este caso, deberíamos verificar la
class path
laclass path
y agregar la clase en la ruta de la clase si falta. - Esta es una excepción marcada , que se deriva de la clase java.lang.Exception .
- Esto viene bajo carga explícita .
2) NoClassDefFoundError
Esto ocurre cuando la clase estuvo presente durante el
compile time
y no está disponible durante elrun time
por algunas razones. Significa que la clase que se está cargando estápresent
enclasspath
, pero uno de losclasse(s)
dependientes que requiere esta clase se eliminó o el compilador no pudo cargarlo.En este caso, solo necesitamos verificar las
classes which are dependent on this class
.- Este es un error , que se deriva de java.lang.LinkageError .
- Esto viene bajo carga implícita .
No Error Clase Def Encontrado
Se lanza si la instancia de Java Virtual Machine o ClassLoader intenta cargar en la definición de una clase (como parte de una llamada de método normal o como parte de la creación de una nueva instancia usando la nueva expresión) y no se puede encontrar una definición de la clase.
La definición de la clase buscada existía cuando se compiló la clase que se está ejecutando actualmente, pero la definición ya no se puede encontrar.
ClassNotFoundException
Se lanza cuando una aplicación intenta cargar en una clase a través de su nombre de cadena usando: El método forName en la clase Class. El método findSystemClass en la clase ClassLoader. El método loadClass en la clase ClassLoader.
Debe comprender que la JVM
no puede darse cuenta de que no se puede encontrar la definición de la class
que eliminó, ya que no se puede encontrar la class
sí misma que lanza automáticamente la ClassNotFoundException
.
Esta excepción ocurre en el runtime
de runtime
por lo que no importa si compiló primero o no, eliminó el archivo, por lo tanto, no se puede encontrar y lanzar la exception
.
Tenga en cuenta que NoClassDefFoundError
no es en realidad una excepción, es un Error
derivado de LinkageError
mientras que ClassNotFoundException
deriva directamente de java.lang.Exception
.
Para reanudar, NoClassDefFoundError
nivel global simplemente significa que la JVM
intentó acceder en runtime
de runtime
algo que, según el código compiled
, debería existir, pero en realidad no existe (o no está en el classpath).
Ejemplo para reproducir la excepción ClassNotFoundException
public class ClassNotFoundExceptionExample {
private static final String CLASS_TO_LOAD = "main.java.Utils";
public static void main(String[] args) {
try {
Class loadedClass = Class.forName(CLASS_TO_LOAD);
System.out.println("Class " + loadedClass + " found successfully!");
}
catch (ClassNotFoundException ex) {
System.err.println("A ClassNotFoundException was caught: " + ex.getMessage());
ex.printStackTrace();
}
}
}
Ejemplo para reproducir NoClassDefFoundError
Crear una Test
clase simple
public class Test {
public Test() {
System.out.println("A new instance of the Test class was created!");
}
}
Y una clase NoClassDefFoundErrorExample
public class NoClassDefFoundErrorExample {
private static Test test = new Test();
public static void main(String[] args) {
System.out.println("The definition of Test was found!");
}
}
Ahora crea un archivo .jar
ejecutable que ejecute el método main
. Puede especificarlo en el archivo Manifest.txt
dentro de .jar
Main-Class: NoClassDefFoundErrorExample
Ahora ejecuta los siguientes comandos
javac Test.java
javac NoClassDefFoundErrorExample.java
jar cfm NoClassDefFoundErrorExample.jar Manifest.txt NoClassDefFoundErrorExample.class
java -jar NoClassDefFoundErrorExample.jar
Observe el NoClassDefFoundError
Exception in thread "main" java.lang.NoClassDefFoundError: TestClass
at NoClassDefFoundErrorExample.(NoClassDefFoundErrorExample.java:2)
Caused by: java.lang.ClassNotFoundException: TestClass
at java.net.URLClassLoader$1.run(URLClassLoader.java:372)
at java.net.URLClassLoader$1.run(URLClassLoader.java:361)
at java.security.AccessController.doPrivileged(Native Method)
at java.net.URLClassLoader.findClass(URLClassLoader.java:360)
at java.lang.ClassLoader.loadClass(ClassLoader.java:424)
at sun.misc.Launcher$AppClassLoader.loadClass(Launcher.java:308)
at java.lang.ClassLoader.loadClass(ClassLoader.java:357)
... 1 more