J'ai essayé à la fois l'exemple du tutoriels Java d'Oracle. Ils compilent tous les deux bien, mais au moment de l'exécution, tous deux génèrent cette erreur:
Exception in thread "main" Java.lang.NoClassDefFoundError: graphics/shapes/Square
at Main.main(Main.Java:7)
Caused by: Java.lang.ClassNotFoundException: graphics.shapes.Square
at Java.net.URLClassLoader$1.run(URLClassLoader.Java:366)
at Java.net.URLClassLoader$1.run(URLClassLoader.Java:355)
at Java.security.AccessController.doPrivileged(Native Method)
at Java.net.URLClassLoader.findClass(URLClassLoader.Java:354)
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
Je pense que je pourrais avoir le fichier Main.Java
dans le mauvais dossier. Voici la hiérarchie des répertoires:
graphics
├ Main.Java
├ shapes
| ├ Square.Java
| ├ Triangle.Java
├ linepoint
| ├ Line.Java
| ├ Point.Java
├ spaceobjects
| ├ Cube.Java
| ├ RectPrism.Java
Et voici Main.Java
:
import graphics.shapes.*;
import graphics.linepoint.*
import graphics.spaceobjects.*;
public class Main {
public static void main(String args[]) {
Square s = new Square(2,3,15);
Line l = new Line(1,5,2,3);
Cube c = new Cube(13,32,22);
}
}
Qu'est-ce que je fais mal ici?
METTRE À JOUR
Après avoir placé la classe Main
dans le package graphics
(j'y ai ajouté package graphics;
), définissez le chemin d'accès aux classes sur "_test" (dossier contenant les graphiques), compilez-le et exécutez-le à l'aide de Java graphics.Main
(à partir de la ligne de commande), cela a fonctionné.
Très tard UPDATE # 2
Je n'utilisais pas Eclipse (uniquement Notepad ++ et le JDK) et la mise à jour ci-dessus a résolu mon problème. Cependant, il semble que bon nombre de ces réponses concernent Eclipse et IntelliJ, mais leurs concepts sont similaires.
Après avoir compilé votre code, vous vous retrouvez avec des fichiers .class
pour chaque classe de votre programme. Ces fichiers binaires sont le bytecode que Java interprète pour exécuter votre programme. La variable NoClassDefFoundError
indique que le chargeur de classes (dans ce cas, Java.net.URLClassLoader
), chargé du chargement dynamique des classes, ne peut pas trouver le fichier .class
de la classe que vous essayez d'utiliser.
Votre code ne serait pas compilé si les classes requises n'étaient pas présentes (sauf si les classes sont chargées de réflexion), cette exception signifie généralement que votre chemin d'accès aux classes n'inclut pas les classes requises. Rappelez-vous que le chargeur de classe (en particulier Java.net.URLClassLoader
) recherchera les classes du paquet a.b.c dans le dossier a/b/c/dans chaque entrée de votre chemin de classe. NoClassDefFoundError
peut également indiquer qu'il vous manque une dépendance transitive d'un fichier .jar contre lequel vous avez compilé et que vous essayez d'utiliser.
Par exemple, si vous aviez une classe com.example.Foo
, après la compilation, vous auriez un fichier de classe Foo.class
. Disons par exemple que votre répertoire de travail est .../project/
. Ce fichier de classe doit être placé dans .../project/com/example
et vous devez définir votre chemin de classe sur .../project/
.
Note latérale: Je vous recommanderais de tirer parti des outils étonnants qui existent pour les langages Java et JVM. Les IDE modernes comme Eclipse et IDEA et la construction d'outils de gestion comme Maven ou Gradle vous aideront à ne pas avoir à vous soucier des classpaths (autant) et à vous concentrer sur le code! Cela dit, ce lien explique comment définir le chemin d'accès aux classes lorsque vous l'exécutez sur la ligne de commande.
Je voudrais corriger le point de vue des autres sur NoClassDefFoundError
.
NoClassDefFoundError
peut se produire pour plusieurs raisons, telles que
Dans la question initiale, il s'agissait du premier cas pouvant être corrigé en définissant CLASSPATH dans le fichier jar des classes référencées ou dans son dossier de packages.
Qu'est-ce que cela signifie en disant "disponible dans le temps de compilation"?
Qu'est-ce que cela signifie en disant "non disponible au moment de la compilation"?
NoClassDefFoundError
signifie que la classe est présente dans le chemin d'accès aux classes à Compile time
mais qu'elle n'existe pas dans le chemin d'accès aux classes à Runtime
.
Si vous utilisez Eclipse, assurez-vous que vous avez les shapes
, linepoints
et le spaceobjects
comme entrées dans le fichier .classpath
.
si vous rencontrez l'une de ces erreurs lors de la compilation et de l'exécution:
* NoClassDefFoundError
* Error: Could not find or load main class hello
* Exception in thread "main" Java.lang.NoClassDefFoundError:javaTest/test/hello
(wrong name: test/hello)
at Java.lang.ClassLoader.defineClass1(Native Method)
at Java.lang.ClassLoader.defineClass(Unknown Source)
at Java.security.SecureClassLoader.defineClass(Unknown Source)
at Java.net.URLClassLoader.defineClass(Unknown Source)
at Java.net.URLClassLoader.access$100(Unknown Source)
at Java.net.URLClassLoader$1.run(Unknown Source)
at Java.net.URLClassLoader$1.run(Unknown Source)
at Java.security.AccessController.doPrivileged(Native Method)
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 Sun.launcher.LauncherHelper.checkAndLoadMain(Unknown Source)
--------------------------SOLUTIION------------- ----------
le problème est principalement dans l'organisation des paquets. Vous devriez organiser vos classes dans des dossiers concernant les classifications de paquets dans votre code source.
On Compiling process use this command:
javac -d . [FileName.Java]
To Run the class please use this command:
Java [Package].[ClassName]
Java.lang.NoClassDefFoundError
indique que quelque chose a été trouvé à compiletime mais pas à runtime . vous devez peut-être simplement l'ajouter au classpath.
Aucune exception de définition de classe se produit lorsque la classe voulue ne figure pas dans le chemin de la classe . Au moment de la compilation Classe: La classe a été générée à partir du compilateur Java, mais d'une manière ou d'une autreat La classe dépendante est introuvable. .
Passons à travers un exemple simple:
public class ClassA{
public static void main(String args[]){
//Some gibberish Code...
String text = ClassB.getString();
System.out.println("Text is :" + text);
}
}
public class ClassB{
public static String getString(){
return "Testing Some Exception";
}
}
Supposons maintenant que les deux codes source Java ci-dessus soient placés dans un dossier, disons "NoClassDefinationFoundExceptionDemo"
Maintenant, ouvrez un shell (en supposant que Java est déjà configuré correctement)
Si votre projet se trouve dans un package tel que com.blahcode
et que votre classe s'appelle Main
, les fichiers compilés peuvent apparaître dans une structure de répertoires telle que ./out/com/blahcode/Main.class
. Cela est particulièrement vrai pour IntelliJ IDEA.
Lorsque vous essayez de vous lancer depuis un shell ou une cmd, vous devez cd
à celui qui contient com
comme sous-répertoire.
cd out
Java -classpath . com.blahcode.Main
Après avoir travaillé sur un projet NetBeans pendant plusieurs mois, j'ai soudainement reçu le message NoClassDefFoundError peu de temps après avoir reçu une alerte "Mémoire faible". Faire une reconstruction complète n'a pas aidé, mais fermer Netbeans et rouvrir le projet n'a généré aucun rapport d'erreur.
NoClassDefFoundError en Java:
Définition:
NoClassDefFoundError viendra si une classe était présente lors de la compilation mais non disponible dans le chemin de classe Java lors de l'exécution. Normalement, vous verrez la ligne ci-dessous dans le journal lorsque vous obtenez NoClassDefFoundError: Exception dans le fil "principal" Java.lang.NoClassDefFoundError
Causes possibles:
La classe n'est pas disponible dans Java Classpath.
Vous exécutez peut-être votre programme avec la commande jar et la classe n'a pas été définie dans l'attribut ClassPath du fichier manifeste.
Tout script de démarrage remplace la variable d'environnement Classpath.
Comme NoClassDefFoundError est une sous-classe de Java.lang.LinkageError, elle peut également apparaître si l'une de ses dépendances, telle que la bibliothèque native, n'est pas disponible.
Recherchez Java.lang.ExceptionInInitializerError dans votre fichier journal. NoClassDefFoundError en raison de l'échec de l'initialisation statique est assez commun.
Si vous travaillez dans un environnement J2EE, la visibilité de Class entre plusieurs chargeurs de classe peut également entraîner Java.lang.NoClassDefFoundError. Pour plus de détails, reportez-vous à la section Exemples et scénario.
Résolutions possibles:
Vérifiez que toutes les classes Java requises sont incluses dans le chemin de classe de l’application. L'erreur la plus courante est de ne pas inclure toutes les classes nécessaires avant de commencer à exécuter une application Java dépendant de certaines bibliothèques externes.
Le classpath de l’application est correct, mais la variable d’environnement Classpath est remplacée avant l’exécution de l’application.
Vérifiez que l'exception ExceptionInInitializerError susmentionnée n'apparaît pas dans la trace de pile de votre application.
Ressources:
3 façons de résoudre Java.lang.NoClassDefFoundError en Java J2EE
Java.lang.NoClassDefFoundError - Comment résoudre aucune erreur de classe trouvée
J'ai fait face au problème aujourd'hui. J'ai un projet Android et après avoir activé multidex
, le projet ne démarre plus.
La raison en était que j'avais oublié d'appeler la méthode multidex spécifique qui devait être ajoutée au Application class
et appelée avant tout le reste.
MultiDex.install(this);
Suivez ce tutoriel pour activer multidex correctement. https://developer.Android.com/studio/build/multidex.html
Vous devriez ajouter ces lignes à votre classe d'application
@Override
protected void attachBaseContext(Context base) {
super.attachBaseContext(base);
MultiDex.install(this);
}
Cette réponse est spécifique à une erreur Java.lang.NoClassDefFoundError se produisant dans un service:
Mon équipe a récemment constaté cette erreur après la mise à niveau d'un RPM fournissant un service. Le rpm et le logiciel qu'il contenait avaient été conçus avec Maven, il nous semblait donc que nous avions une dépendance au temps de compilation qui n’avait tout simplement pas été incluse dans le rpm.
Toutefois, lors de l’examen, la classe non trouvée se trouvait dans le même module que plusieurs des classes de la trace de pile. De plus, ce module n’a pas été ajouté récemment à la construction. Ces faits indiquent qu’il ne s’agit peut-être pas d’un problème de dépendance Maven.
La solution éventuelle: Redémarrez le service!
Il semble que la mise à niveau rpm ait invalidé le descripteur de fichier du service sur le fichier jar sous-jacent. Le service a alors vu une classe qui n'avait pas été chargée en mémoire, l'a recherchée dans sa liste de descripteurs de fichier jar et n'a pas réussi à la trouver car le descripteur de fichier à partir duquel il pouvait charger la classe avait été invalidé. Le redémarrage du service l'a forcé à recharger tous ses descripteurs de fichiers, ce qui lui a ensuite permis de charger cette classe qui n'avait pas été trouvée en mémoire juste après la mise à niveau rpm.
J'espère que ce cas spécifique aide quelqu'un.
Mes deux cents dans cette chaîne:
Assurez-vous que le classpath contient full chemins (/home/user/lib/some_lib.jar
au lieu de ~/lib/some_lib.jar
), sinon vous pouvez toujours faire face à une erreur NoClassDefFoundError
.
J'ai eu le même problème avec mon développement Android en utilisant le studio Android . Les solutions fournies sont générales et ne m'a pas aidé (du moins pour moi) . Après des heures de recherche, j'ai trouvé la solution suivante et peut aider les développeurs Android qui sont en train de développer à l'aide d'Android studio . modifiez les paramètres comme suit Préférences -> Construire, Exécution, Déploiement -> Exécution instantanée -> Désélectionnez la première option.
Avec ce changement, je suis opérationnel. J'espère que cela aidera mes amis dev.
J'utilise le plugin FileSync pour Eclipse afin de pouvoir déboguer en direct sur Tomcat et j'ai reçu NoClassFoundError
car j'avais ajouté une entrée de synchronisation pour le répertoire bin
dans l'espace de travail Eclipse => classes
dans metadata
synchronisation de dossier pour le répertoire extlib
dans Eclipse =>
C:\Users\Stuart\Eclipse-workspace\.metadata\.plugins\org.Eclipse.wst.server.core\tmp0\webapps\myApp\WEB-INF\lib
si vous avez récemment ajouté la prise en charge multidex dans Android Studio, procédez comme suit:
// To Support MultiDex
implementation 'com.Android.support:multidex:1.0.1'
votre solution doit donc être étendue à partir de MultiDexApplication au lieu de Application.
public class MyApp extends MultiDexApplication {
Cela m'est arrivé dans Android Studio.
La solution qui a fonctionné pour moi: Il suffit de redémarrer le studio.
Vérifiez cela si vous avez un gestionnaire statique dans votre classe. Si c'est le cas, soyez prudent, car le gestionnaire statique ne peut être lancé que dans un thread avec une boucle, le crash pourrait être déclenché de cette façon
1. Tout d’abord, créez l’instance de classe dans un simple thread et attrapez le crash.
2.alors appelez la méthode de champ de la classe dans le fil principal, vous obtiendrez le NoClassDefFoundError.
voici le code de test:
public class MyClass{
private static Handler mHandler = new Handler();
public static int num = 0;
}
dans votre méthode d'activité principale OnCrete, ajoutez une partie de code de test:
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
//test code start
new Thread(new Runnable() {
@Override
public void run() {
try {
MyClass myClass = new MyClass();
} catch (Throwable e) {
e.printStackTrace();
}
}
}).start();
try {
Thread.sleep(1000);
} catch (InterruptedException e) {
e.printStackTrace();
}
MyClass.num = 3;
// end of test code
}
il existe un moyen simple de le réparer en utilisant un handlerThread pour init handler:
private static Handler mHandler;
private static HandlerThread handlerThread = new HandlerThread("newthread");
static {
handlerThread.start();
mHandler = new Handler(handlerThread.getLooper(), mHandlerCB);
}
Pour mon projet, le problème était que le navigateur Chrome et chromedriver n'étaient pas compatibles. J'avais une très ancienne version du pilote qui ne pouvait même pas ouvrir le navigateur. Je viens de télécharger la dernière version des deux et le problème a été résolu. Comment ai-je découvert le problème? Parce que j'ai exécuté mon projet en utilisant le pilote firefox natif Selenium avec une ancienne version de FF intégrée à mon application, j'ai alors réalisé que le problème était une incompatibilité entre le navigateur et le pilote.
J'espère que cela pourra aider quiconque ayant un problème similaire au mien, ayant généré le même message d'erreur.
Si vous utilisez plusieurs modules, vous devriez avoir
dexOptions {
preDexLibraries = false
}
dans votre fichier de construction.
Je développe une application basée sur Eclipse, également connue sous le nom RCP (Rich Client Platform) . Et je suis confrontée à ce problème après le refactoring (déplacement d'une classe d'un plugin vers un nouveau).
Nettoyer le projet et la mise à jour Maven n’a pas aidé.
Le problème provient de Bundle-Activator qui n'a pas été mis à jour automatiquement. La mise à jour manuelle de Bundle-Activator sous MANIFEST.MF dans le nouveau plug-in a corrigé mon problème.
Je reçois NoClassFoundError lorsque les classes chargées par le chargeur de classes d'exécution ne peuvent pas accéder aux classes déjà chargées par le rootloader Java. Étant donné que les différents chargeurs de classes se trouvent dans différents domaines de sécurité (selon Java), jvm ne permet pas aux classes déjà chargées par le rootloader d'être résolues dans l'espace adresse du chargeur d'exécution.
Exécutez votre programme avec 'Java -javaagent: tracer.jar [YOUR Java ARGS]'
Il génère une sortie montrant la classe chargée et l’environnement de chargement qui a chargé la classe. Il est très utile de déterminer pourquoi une classe ne peut pas être résolue.
// ClassLoaderTracer.Java
// From: https://blogs.Oracle.com/sundararajan/entry/tracing_class_loading_1_5
import Java.lang.instrument.*;
import Java.security.*;
// manifest.mf
// Premain-Class: ClassLoadTracer
// jar -cvfm tracer.jar manifest.mf ClassLoaderTracer.class
// Java -javaagent:tracer.jar [...]
public class ClassLoadTracer
{
public static void premain(String agentArgs, Instrumentation inst)
{
final Java.io.PrintStream out = System.out;
inst.addTransformer(new ClassFileTransformer() {
public byte[] transform(ClassLoader loader, String className, Class classBeingRedefined, ProtectionDomain protectionDomain, byte[] classfileBuffer) throws IllegalClassFormatException {
String pd = (null == protectionDomain) ? "null" : protectionDomain.getCodeSource().toString();
out.println(className + " loaded by " + loader + " at " + new Java.util.Date() + " in " + pd);
// dump stack trace of the thread loading class
Thread.dumpStack();
// we just want the original .class bytes to be loaded!
// we are not instrumenting it...
return null;
}
});
}
}
Une source d'erreur pour cette exception pourrait provenir de définitions incohérentes pour Proguard, par exemple. un manquant
-libraryJars "path.to.a.missing.jar.library".
Cela explique pourquoi la compilation et l’exécution fonctionnent bien, étant donné que le fichier jar est là, alors que le nettoyage et la construction échouent. N'oubliez pas de définir les bibliothèques de fichiers jar récemment ajoutées dans proguard setup!
Notez que les messages d'erreur de Proguard ne sont pas vraiment à la hauteur, car ils peuvent facilement être confondus avec des messages ant similaires qui arrivent lorsque le pot n'est pas du tout là. Tout en bas, il y aura un petit soupçon de proguard en difficulté. Par conséquent, il est tout à fait logique de commencer à rechercher les erreurs de classpath traditionnelles, etc., mais ce sera en vain.
À l’évidence, l’exception NoClassDefFound sera le résultat lors de l’exécution, par exemple. le fichier jar exécutable résultant est construit et basé sur un manque de cohérence de proguard. Certains l'appellent proguard "Hell"
Cela arrive souvent avec mes appareils Genymotion . Assurez-vous de disposer d’une bonne quantité de mémoire sur votre lecteur où Genymotion est installé.