corecție Metode ssdeffounderror în Java J2EE


Translator este recunoscător Viktor Zhukovsky pentru editare valoroase și discutarea manuscrisului.

Cunoscut sub numele de neplăcut pentru a vedea java.lang.NoClassDefFoundError excepție firul „principal“. Mulți dezvoltatori petrec o mulțime de timp, mai ales încercând să înțeleagă ce a mers prost, ce clasa lipsește și care este esența problemei. În primul rând, ele sunt confundate între ele și ClassNotfoundException NoClassDefFoundError. când de fapt ele sunt două excepții complet diferite. În al doilea rând, ei utilizează metoda de „spear științifică“ pentru a rezolva problema în loc de NoClassDefFoundError o înțelegere clară a apărut eroarea și cum să-l corecteze. În acest articol, vom deschide pentru Java unele secrete NoClassDefFoundError de corectare a erorilor în Java, și va împărtăși experiențele lor în abordarea acestei probleme.

NoClassDefFoundError greșeală nu este ceva care nu poate fi eliminat sau ceva care este amovibilitate foarte dificil - nu, NoClassDefFoundError doar o manifestare a unui alt, eroare mai profundă care confundă majoritatea dezvoltatorilor Java. NoClassDefFoundError eroare cel mai frecvent în dezvoltarea Java, împreună cu java.lang.OutOfMemoroyError: spațiu heap Java și java.lang.OutOfMemoryError: spațiu PermGen. Să vedem de ce în Java există NoClassDefFoundError și ce să facă pentru a remedia problema.

Care este motivul pentru care NoClassDefFoundError în Java?

NoClassDefFoundError în Java are loc atunci când mașina virtuală Java în timpul executării codului nu poate găsi o anumită clasă, care era disponibil la momentul compilarii. De exemplu, dacă vom apela metoda a clasei sau a apela un membru static al unei clase, iar această clasă nu este disponibilă în timpul rulării, Java Virtual Machine aruncă NoClassDefFoundError. Este important să înțelegem că această eroare diferă de ClassNotFoundException excepție. care apare atunci când încercați să încărcați o clasă în timpul rulării, cu important ca acest nume de clasă a fost definit numai în timpul rulării, dar nu și în timpul codul de compilare. Mulți dezvoltatori Java au confundat aceste două greșeli și să ajungă la un capăt mort atunci când încearcă să rezolve problema.

Pe scurt, NoClassDefFoundError se întâmplă în cazul în care clasa a fost prezent la momentul compilării, dar nu și în classpath în timpul rulării. De obicei, în acest caz, veți vedea următoarea linie în jurnalul de eroare:

Excepție în firul java.lang.NoClassDefFoundError „principal“

Expresia excepție în fir „principal“ înseamnă că este fluxul de „principal“ nu poate găsi o anumită clasă. În loc de „principal“ poate fi orice flux. Diferența dintre care apare eroarea în fluxul de „principal“, iar într-un alt fir este în faptul că, în cazul în fluxul de „principal“, programul este oprit, iar în cazul într-un alt fir, pe de altă parte, continuă execuție după o eroare.

Diferența dintre ClassNotFoundException și java.lang.NoClassDefFoundError în Java

Înainte de a lua în considerare diferența dintre ClassNotFoundException și NoClassDefFoundError să vedem ce au în comun, și care duce la confuzie între aceste două erori:

  • Ambele erori sunt legate de lipsa de clasă în timpul rulării;
  • Ambele erori sunt legate de Java Classpath.

Acum, pentru diferențele.

  • ClassNotFoundException apare în Java, dacă vom încerca să încarce clasa în timpul rulării folosind Class.forName) metode (. ClassLoader.loadClass () sau ClassLoader.findSystemClass (). Mai mult decât atât, clasa necesară nu este disponibilă pentru Java. De multe ori, motivul este - greșit Classpath. Pentru cea mai mare parte ni se pare că folosim corect Classpath. dar se dovedește că aplicația utilizează un complet diferit Classpath - nu cel ne-am așteptat. De exemplu, Classpath. specificat în manifest fișierului jar, acesta suprascrie classpath în variabila de mediu CLASSPATH sau opțiunea -cp. predeterminate fișier jar de pornire. Spre deosebire de cazul ClassNotFoundException NoClassDefFoundError clasa problematică a participat la compilare, și, prin urmare, programul a fost compila cu succes, dar din anumite motive nu există nici o clasă în timpul rulării. În opinia mea, este mai ușor de rezolvat decât NoClassDefFoundError ClassNotFoundException. pentru că știi exact ce clasa a fost prezent în timpul asamblării, dar, în general, depinde foarte mult de mediul de dezvoltare. Dacă lucrați cu un mediu J2EE, puteți obține NoClassDefFoundError chiar dacă clasa este prezentă, deoarece poate fi invizibil pentru încărcător clasa corespunzătoare.
  • ClassNotFoundException este o excepție verificată, moștenită direct din clasa java.lang.Exception. necesită o prelucrare explicită, în timp ce NoClassDefFoundError java.lang.Error. moștenit de la java.lang.LinkageError.
  • ClassNotFoundException apare ca urmare a unor explicite de încărcare Class.forName metode de clasă (). ClassLoader.loadClass () sau ClassLoader.findSystemClass (). în timp ce NoClassDefFoundError - rezultatul unei sarcini de clasă implicită care apare atunci când încercați să apelați o metodă dintr-o altă clasă sau a avea acces la proprietățile sale.

NoClassDefFoundError în Java. Exemple și script-uri

Deci, motivul evident NoClassDefFoundError este că o anumită clasă nu este disponibilă în Classpath. așa că trebuie să-l adăugați la Classpath sau să înțeleagă de ce nu este în Classpath. deși ne așteptăm să-l găsim acolo. Acest lucru poate fi din mai multe motive:

  1. Clasa nu este specificat în mod direct în Classpath variabilă.
    • Tipărește System.getproperty valoare ( "java.classpath") într-un program Java.
    • Verificați dacă mediul script Classpath variabilă pentru a rula aplicații nu suprascrie. Executați programul cu opțiunea -classpath explicită. care specifică classpath. Cine crezi că va funcționa, iar în cazul în care, în acest caz, programul este de lucru, acesta este un semn bun că cineva perezatiraet classpath.
  2. Clasa nu este pe locul în variabila Classpath.
    • Verificați pentru a vedea dacă pentru a elimina pe cineva jar-fișier, sau poate fi redenumit.
  3. încărcător de clasă nu are permisiunea de a citi fișierul specificat în Classpath variabilă. la nivel de sistem de operare.
    • Utilizați același cod de utilizator pentru toate resursele aplicației: fișierele JAR, biblioteci și fișiere de configurare.
  4. Atributul de clasă nu este definit în CLASSPATH fișier manifest, atunci când începe programul utilizând comanda jar.
    • Dacă utilizați fișierul ANT construi pentru a crea un fișier JAR și un fișier manifest, cec primește ANT construi script-ul CLASSPATH valoarea corectă și o adaugă la fișierul MANIFEST.MF Do.
  5. Java mașină virtuală nu a fost găsit unul dintre dependențele, cum ar fi biblioteca nativă. Această eroare este aruncată, deoarece NoClassDefFoundError este succesorul java.lang.LinkageError.
    • Păstrați dll-ul, împreună cu jar-fișiere.
  6. Java mașină virtuală este în imposibilitatea de a finaliza o inițializare clasa statică.
    • Verificați pentru erori java.lang.ExceptionInInitializerError în jurnalul de erori.
  7. Încărcătorul clasa părinte nu vede clasa, deoarece el a fost deja încărcat încărcător filială. Dacă lucrați cu un mediu J2EE este clasa de vizibilitate în rândul classloaders configurat incorect poate duce, de asemenea, la java.lang.NoClassDefFoundError.
  8. Typo în configurația XML poate duce de asemenea la NoClassDefFoundError în Java. Majoritatea platformelor software, cum ar fi de primăvară și Struts folosi de configurare XML pentru definiții de fasole. Accidental amestecat numele de fasole, puteți obține java.lang.NoClassDefFoundError în timp ce încarcă o altă clasă, care depinde de fasole. Se întâmplă destul de des în platformele software Spring MVC și Apache Struts, în cazul în care veți obține o tona de erori de excepție în fir „principal“ java.lang.NoClassDefFoundError în timpul instalării sau WAR fișier EAR.
  9. Variabilele de mediu sau JDK instalat incorect.
    • Verificați calea și JAVA_HOME.
    • Pune-o altă versiune de JDK.

încărcătorul de clasă în Java

Pe scurt, ne amintim că încărcătorul de clasă utilizează cele trei principii de bază în activitatea lor: delegare, vizibilitatea și unicitatea.

  • Delegă înseamnă că fiecare cerere pentru a încărca o clasă este delegată încărcătorului de clasă părinte.
  • Vizibilitatea înseamnă că puteți găsi clasele încărcate de încărcător de clasă: toate copil incarcator de clasă pot vedea clase încărcate de către mamă încărcător, dar încărcătorul părinte nu poate vedea o filială clasa încărcată.
  • Unicitatea asigură că încărcătorul de clasă încărcat cu un părinte, un copil nu boot-ează din nou încărcător.

Fiecare instanță a încărcătorului de clasă are un încărcător de clasă părinte asociat. Să presupunem că aplicarea clasa încărcător dumneavoastră trebuie să se încarce clasa A. Primul lucru încărcător aplicație încearcă să delege căutarea pentru clasele A la încărcător de clasa părinte înainte de el încearcă să-l încarce. Puteți merge de-a lungul lanțului lung de downloader părinte până când ajunge la încărcător de pornire Java mașină virtuală.

Deci, care este problema? În cazul în care o clasă A este găsit și încărcate de orice părinte al încărcătorului, ceea ce înseamnă că încărcătorul de copil pentru a încărca va fi plecat, și s-ar putea doar că și de așteptare, ceea ce duce la NoClassDefFoundError.

Pentru o mai bună înțelegere a descrie întregul proces de încărcare în contextul platformei Java EE.

corecție Metode ssdeffounderror în Java J2EE

După cum puteți vedea când încercați să încărcați un încărcător de clasa copil (Web App # 1) încărcător delegat de boot-mamă (Java EE App # 1), care, la rândul său, și-a delegat său încărcător pornirea sistemului JVM. În cazul în care sistemul start-up încărcător de boot nu poate încărca clasa, returnează încărcătorul mamă și așa mai departe până lanțul până când clasa este încărcată de un încărcător.

Să considerăm un exemplu simplu, ceea ce duce la NoClassDefFoundError din cauza diferitelor clase de vedere între copil și încărcătorul-mamă. Asigurați-încărcător MyClassLoader. moștenitor al java.lang.Classloader, astfel încât să se încarce clasele cu extensia .class .test în loc. net.javacogito sunt în pachet. Rețineți că încărcătorul de boot standard, implicit încarcă datele numai din fișierele cu extensia .class. deci se descarca Bar.test el nu poate. Munca suplimentară a circuitului este după cum urmează:

  1. Bar JVM încarcă o clasă de fișier Bar.test.
  2. Class Bar imprimă încărcător de clasă. Acesta MyClassLoader.
  3. JVM sarcini clasa Foo din fișierul Foo.class.
  4. Clasa Foo imprimă încărcător de clasă. Acesta sun.misc.Launcher.AppClassLoader.
  5. Clasa de Foo este o printClassLoader metoda statică () în clasa Bar.

În acest moment, JVM dă NoClassDefFoundError. în ciuda faptului că Baroul a fost descărcat anterior, deoarece încărcătorul mamă AppClassLoader nu vezi clase încărcate de MyClassLoader încărcător filială.

Figura de mai jos ilustrează circuitul de sarcină delegare, rezultând în NoClassDefFoundError.

corecție Metode ssdeffounderror în Java J2EE

Codul sursă. Class Bar.

De la începutul rezultatelor arată că barul MyClassLoader clasa încărcate. și AppClassLoader (clasă abstractă moștenitor java.lang.Classloader) încărcate clasa Foo. clasa Bar este prezent în sistemul de fișiere și JVM încărcate său, dar încărcătorul ClassLoader mamă nu o vedea, ceea ce duce la NoClassDefFoundError.

NoClassDefFoundError în Java, din cauza unei excepții în blocul de inițializare statică