Γιατί λαμβάνω ένα σφάλμα NoClassDefFoundError στη Java;

Λαμβάνω ένα σφάλμα NoClassDefFoundError όταν τρέχω την εφαρμογή μου Java. Ποια είναι συνήθως η αιτία αυτού του σφάλματος;

Ενώ είναι πιθανό αυτό να οφείλεται σε ασυμφωνία του classpath μεταξύ του χρόνου μεταγλώττισης και του χρόνου εκτέλεσης, δεν είναι απαραίτητα αλήθεια.

Είναι σημαντικό να κρατάμε δύο ή τρεις διαφορετικές εξαιρέσεις ευθυγραμμισμένες στο κεφάλι μας σε αυτή την περίπτωση:

  1. `java.lang.ClassNotFoundException Αυτή η εξαίρεση υποδεικνύει ότι η κλάση δεν βρέθηκε στο classpath. Αυτό δείχνει ότι προσπαθούσαμε να φορτώσουμε τον ορισμό της κλάσης και η κλάση δεν υπήρχε στο classpath.

  2. `java.lang.NoClassDefFoundError Αυτή η εξαίρεση υποδεικνύει ότι η JVM έψαξε στην εσωτερική δομή δεδομένων ορισμού κλάσης για τον ορισμό μιας κλάσης και δεν τον βρήκε. Αυτό είναι διαφορετικό από το να λέει ότι δεν μπόρεσε να φορτωθεί από το classpath. Συνήθως αυτό δείχνει ότι προηγουμένως προσπαθήσαμε να φορτώσουμε μια κλάση από το classpath, αλλά απέτυχε για κάποιο λόγο - τώρα προσπαθούμε να χρησιμοποιήσουμε ξανά την κλάση (και επομένως πρέπει να τη φορτώσουμε, αφού απέτυχε την προηγούμενη φορά), αλλά δεν πρόκειται καν να προσπαθήσουμε να τη φορτώσουμε, επειδή αποτύχαμε να τη φορτώσουμε νωρίτερα (και υποψιαζόμαστε εύλογα ότι θα αποτύχουμε ξανά). Η προηγούμενη αποτυχία θα μπορούσε να είναι ένα ClassNotFoundException ή ένα ExceptionInInitializerError (υποδεικνύοντας μια αποτυχία στο στατικό μπλοκ αρχικοποίησης) ή οποιοδήποτε άλλο πρόβλημα. Το θέμα είναι ότι ένα NoClassDefFoundError δεν είναι απαραίτητα ένα πρόβλημα του classpath.

Σχόλια (12)
Λύση

Αυτό προκαλείται όταν υπάρχει ένα αρχείο κλάσης από το οποίο εξαρτάται ο κώδικάς σας και το οποίο υπάρχει κατά τη μεταγλώττιση αλλά δεν βρίσκεται κατά την εκτέλεση. Ψάξτε για διαφορές στα μονοπάτια κλάσεων κατά τη στιγμή της δημιουργίας και της εκτέλεσης.

Σχόλια (7)

Έχω διαπιστώσει ότι μερικές φορές λαμβάνω ένα σφάλμα NoClassDefFound όταν ο κώδικας μεταγλωττίζεται με μια ασύμβατη έκδοση της κλάσης που βρέθηκε κατά την εκτέλεση. Η συγκεκριμένη περίπτωση που θυμάμαι είναι με τη βιβλιοθήκη apache axis. Υπήρχαν στην πραγματικότητα 2 εκδόσεις στο classpath του runtime μου και έπαιρνε την ξεπερασμένη και ασύμβατη έκδοση και όχι τη σωστή, προκαλώντας ένα σφάλμα NoClassDefFound. Αυτό συνέβη σε μια εφαρμογή γραμμής εντολών όπου χρησιμοποιούσα μια εντολή παρόμοια με αυτή.

set classpath=%classpath%;axis.jar

Κατάφερα να το κάνω να πάρει την κατάλληλη έκδοση χρησιμοποιώντας:

set classpath=axis.jar;%classpath%;
Σχόλια (2)