Notă interpretor Java, în cazul în care să caute clase
Notă interpret în cazul în care pentru a găsi clase
Interpretul trebuie să știe toate locurile unde se poate găsi clase. Ce este acest loc? Director și / sau o bibliotecă - borcan-fișier. Vă rugăm să acorde o atenție specială - acel fișier. Cu alte cuvinte, dacă fișierul javaee.jar este în directorul E: \ java \ lib \ - interpretul nevoie de calea completă la dosar, și anume - E: \ java \ lib \ javaee.jar. instrucțiuni simple director de ajuns!
Așa cum am spus, există mai multe modalități de a specifica sursele de clasă interpret. Acestea sunt discutate mai jos. (Clase de căutare în containerele de servlet și servere de aplicații, nu ating, este dincolo de domeniul de aplicare al acestui articol pentru începători.)
Metoda 1: CLASSPATH variabila de mediu
Metoda este simplă. PLANT CLASSPATH variabila de mediu, și printr-un separator ( „;“ pentru a câștiga, „:“ pentru * NIX) precizează toate căile complete la fișierele și directoarele de bibliotecă, care sunt copaci de clasă. Vă rugăm să rețineți că directorul - punctul în care se află rădăcina tuturor claselor compilate. Ie cu excepția cazului în pachetul de mypackage.test clasele compilate în directorul c: \ myproject \ clase, este în CLASSPATH ar trebui să apară este c: \ myproject \ clase, în loc de c: \ myproject clase \ mypackage \ sau c: \ myproject \ clase \ mypackage \ test.
Metoda simplă, cu toate acestea, are mai multe dezavantaje, pentru care eu nu-l plac foarte mult. În primul rând. Bine, deci biblioteca poate fi conectat. Și chiar și atunci cu rezerve. A se vedea mai jos. Și ce despre clasa curentă? Cu acestea, am scrie? Acestea trebuie să fie, de asemenea, conectate. Includeți toate? Unreal, am mai mult de 20 de proiecte pentru copacii din pădure nu va fi văzut în cazul în care, în fiecare caz în CLASSPATH pentru a specifica calea completă. Fii o rudă? El, de asemenea, este diferit. Sincer, eu nu sunt o soluție acceptabilă găsit.
În al doilea rând. Să presupunem că vreau să vă conectați biblioteci (borcan-fișiere) prin intermediul CLASSPATH. Întrebare. Și cât de multe am? Suprafata de căutare pe disc oferă. mai mult de 1.550! Ei bine, partea leului din ele - din aplicații. Dar cei care mă folosesc, în mod direct sau indirect, mai mult de 100 exact. Ce s-ar întâmpla dacă în CLASSPATH să se înregistreze pe toate? Vor exista suficiente dimensiuni de memorie alocată în sisteme de operare variabile de mediu? Și în cazul în care cererea se va face la fel?
În al treilea rând, cele mai neplăcute. Eu stau versiunile Log4j 1.2.8 și 1.3.0, Velocity 1.2, 1.3 și 1.4, Hibernate 2.1 și 3.0, Servlet 2.2, 2.3, 2.4 și JSP 1.1, 1.2 și 2.0, JDBC-MySQL trei versiuni diferite, nenumărat XML interpretoare, etc. etc. În unele proiecte, eu folosesc cel din cealaltă - cealaltă. Dacă aș include toate acestea în CLASSPATH - compilatorul va folosi întotdeauna prima clasă în ordinea bibliotecilor listare. Ce versiune? Nu știu. Dar, oricum - la fel. Și am nevoie de diferite. Și în cazul în care primele două puncte ar putea fi într-un fel supraviețui, atunci - nr.
Pentru că - nu am mai instalat la variabila de mediu CLASSPATH. Mai ales pentru că există.
Metoda 2: Tasta Indicație -classpath interpret (compilator)
Această metodă, în opinia mea, cel mai bun. Pot specifica exact biblioteca interpret pe care am nevoie. Și exact codul sursă, de care el trebuie să ia acest cod. Nici mai mult nici mai puțin.
Exemplu. Să presupunem că am un director in proiect directorul claselor subdirector, care conține clasele compilate, și subdirectorul lib, care sunt viteza-1.4.jar și Biblioteca-log4j 1.2.8.jar. Apoi, linia de comandă pentru a rula clasa ru.skipy.myproject.Main mea va arăta astfel:
java -classpath ./classes;./lib/velocity-1.4.jar;./lib/log4j-1.2.8.jar ru.skipy.myproject.Main
Punct cu punct: I punctul interpretul că această clasă ar trebui căutate în directorul ./classes - în biblioteca ./lib/log4j-1.2.8.jar ./lib/velocity-1.4.jar și o bibliotecă ( „“ directorul curent) , în ordinea indicată.
Dacă nu trebuie să utilizați o bibliotecă externă, linia de comandă este transformată în următoarele:
java -classpath ./classes ru.skipy.myproject.Main
Observați ./classes -classpath. Nu știu în cazul în care unele cărți provin de la proiectare Java ru.skipy.myproject.Main, fără a specifica CLASSPATH. Nu sunt leneș, el însuși set jdk1.1.8, dar chiar și acolo este necesar să se precizeze classpath. Este lipsa interpretului în parametrul CLASSPATH este sursa multor probleme. Dar, mai mult pe aceasta mai jos.
Pentru a fi corect să menționăm un al treilea mod de a conecta biblioteci:
3. Metoda Directory
Metoda este, probabil, cel mai ușor. Dar, trebuie să recunosc, este potrivit doar pentru conectarea jar-fișiere. Fișierul este plasat în directorul specificat. Totul. Când porniți o bibliotecă de mașină virtuală este conectată.
Dezavantajul este evident. Am în sistem, de exemplu, costurile de 6 mașini virtuale, nu de numărare cei care au mers impreuna cu aplicatii: 1.1.8 (pentru care această metodă nu funcționează), 1.3.1, 1.4.2, 1.5.0, JRockit 1.4 .2, JRockit 1.5.0. Biblioteca va trebui să pună fiecare. Întrebare. De ce?
Desigur, această metodă are și demnitate. Este bine atunci când ai nevoie de ceva pentru a pune pe masina client, în cazul în care există doar un singur JRE (și ce dacă este cazul). De asemenea, există mici diferențe în ceea ce privește siguranța (pentru acțiunile permise) între codul au fost descărcate prin intermediul classpath și codul descărcat de
Și ce se va întâmpla dacă nu se specifică după classpath, fie ca o variabilă de mediu sau ca un parametru la interpret? Și vor cunoaște toate bug-ul. Problema a ceea ce este, apare cel puțin o dată pe săptămână. Că printre altele, ma îndemnat să scriu acest articol. Aceasta se numește o eroare.
Excepție în firul java.lang.NoClassDefFoundError „principal“.
În loc de“. „Numele scris al clasei, care este o mașină virtuală nu a putut fi găsit. Această eroare înseamnă că definiția de clasă este găsit. În conformitate cu definiția unei mașini virtuale de clasă înțelege bytecode sale. Ie ea pur și simplu nu a putut găsi fișierul.
Uneori există o versiune mai sofisticată a acestei erori. Să presupunem clasa pe care doriți să rulați, numit test.Test. Unul dintre tipurile clasice de acțiuni: pentru a alcătui o clasă, apoi ajunge la directorul în care se află direct Test.class și rulați-l de acolo:
./test/Test.class fișier @rem creat
java -classpath. test
Eroarea în acest caz va fi:
Excepție în fir "principal" java.lang.NoClassDefFoundError: Test (nume greșit: încercare / test)
la java.lang.ClassLoader.defineClass0 (Metoda nativă)
la java.security.AccessController.doPrivileged (Metoda nativă)
Ce înseamnă acest lucru? Și este aici. Mașina virtuală a găsit o clasă pe care am încercat să ruleze - test. Ea a găsit doar pentru că am spus - uita-te în acest director numit clasa de test. Vă rugăm să acorde o atenție - testul numele complet. Aparatul găsit. Dar clasa este de fapt - test.Test. Aceasta este ceea ce spune ea - numele greșit: încercare / test
Un alt bug care a cauzat de apariția Excepție în fir „principal“ java.lang.NoClassDefFoundError: nume de clasă atunci când începeți să scrieți împreună cu fișierul extensia .class. În mod firesc mașina virtuală nu poate găsi această clasă, pentru că extinderea a declarat o parte a numelui, atributele numelui .class și începe să caute un fișier cu un nume care se termină în class.class
Pentru dezvoltatorii de avansate un membru existent al unui alt mod de a obține java.lang.NoClassDefFoundError. este după cum urmează: o aplicație care utilizează biblioteca terțe părți, care merg la borcan-fișier și rulați comanda java -jar <имя jar-файла>, și atunci există această eroare. Acest lucru se întâmplă din următorul motiv: atunci când rulați aplicația în acest fel, cu interpretul -jar cheie, classpath este inclus un singur fișier - cel care este specificat în linia de comandă. Toate celelalte biblioteci - descrierea în variabila CLASSPATH, printr-o cheie -classpath specificate - acestea sunt ignorate. Singura modalitate de a evita acest lucru (și a constatat că - pentru că este un fapt uimitor - din nou, în documentația) - pentru a specifica un fișier MANIFEST.MF atribut Class-Path - lista de căi relative (să acorde o atenție deosebită -! Relativă, în raport cu această bibliotki) La necesare biblioteci. Aceste căi sunt separate prin spații. Firește, munca și opțiunea de obicei - pentru a specifica în mod explicit classpath, inclusiv toate bibliotecile și numele executabil al clasei.
Un alt tip de eroare - compila mesajul „Nu se poate rezolva simbol.“ Cu referire la punctul în codul dvs. în cazul în care variabila este declarată, sau mai degrabă, tipul variabilei. Motivul este același - compilatorul nu poate găsi clasa specificat ca tipul acestei variabile din cauza lipsei acestei clase în classpath.
Poate că există încă unele erori tipice legate de classpath. Dacă vă amintiți - voi adăuga.