197 votes

Java.lang.NoClassDefFoundError: Impossible d'initialiser la classe XXX

public class PropHolder {
  public static Properties prop;

  static {
    //code for loading properties from file
  }
}

// Référencement de la classe ailleurs :
Properties prop = PropHolder.prop;

class PropHolder est une classe de ma propre création. La classe réside dans le même fichier JAR que la classe principale. Donc cela ne devrait pas être dû à un JAR manquant dans le classpath.

Quand je regarde dans le fichier JAR avec jar tf monfichierjar, je peux voir le PropHolder.class répertorié là-bas.

À propos : le code fonctionne parfaitement sur ma machine locale. Mais il ne fonctionne pas lorsque je le déploie avec un script sur un serveur Linux. Je pense donc que ce n'est pas un problème de code. Mais pour une raison quelconque, le processus de déploiement est très difficile à suivre.

Quel pourrait être le problème ?

0 votes

Est-ce que la structure de répertoire appropriée dans votre jar correspond au package de classe ?

0 votes

Besoin de voir certaines sources, de nombreuses choses peuvent causer cela. par exemple, une déclaration 'package' mais le fichier ne réside pas réellement dans le chemin correspondant

4 votes

Une cause est une exception pendant l'initialisation--y a-t-il une autre sortie d'erreur?

246voto

John Vint Points 19804

Ma meilleure hypothèse est qu'il y a un problème ici :

static {
    //code for loading properties from file
}

Il semblerait qu'une exception non attrapée s'est produite et a été propagée jusqu'au ClassLoader réel essayant de charger la classe. Nous aurions besoin d'une trace de la pile pour confirmer cela cependant.

Soit cela s'est produit lors de la création de la variable statique PropHolder.prop.

0 votes

J'ai été confronté au même problème maintes et maintes fois. Je suis sûr que c'est à cause de l'issue static. Que faire pour résoudre le problème ?

1 votes

Vous devrez identifier quelle exception est lancée à partir du bloc static. Pour le déboguer, placez un try/catch (Exception e) autour de tout le bloc et enregistrez l'exception. Vous devrez corriger cette exception. En général, l'exception sera enregistrée mais il peut être difficile de la trouver car elle est enregistrée pendant le chargement de la classe, ce qui peut se produire très tôt.

0 votes

Oui, j'ai gardé le code dans le bloc try catch et il a affiché Echec d'initialisation de la ClassA. Je pense que c'est le problème du JVM. J'ai redémarré mon système et ensuite tout a fonctionné correctement. Comment puis-je résoudre ce problème à l'avenir sans redémarrer mon système et le résoudre avec une solution simple.

140voto

jeha Points 5463

Vous obtenez une java.lang.NoClassDefFoundError ce qui ne signifie PAS que votre classe est manquante (dans ce cas, vous obtiendriez une java.lang.ClassNotFoundException). Le ClassLoader a rencontré une erreur lors de la lecture de la définition de la classe lors de la tentative de lecture de la classe.

Ajoutez un try/catch à l'intérieur de votre initialiseur statique et regardez l'exception. Si vous lisez des fichiers là-bas et que cela diffère de votre environnement local, c'est très probablement la cause du problème (peut-être que le fichier ne peut pas être trouvé, pas de permissions, etc.).

1 votes

Une clarification est que même si NoClassDefFoundError n'implique pas une ClassNotFoundException, c'est toujours une cause possible de NoClassDefFoundError.

1 votes

Buf si vous aviez une ClassNotFoundException alors le ClassLoader ne pourrait / ne pourrait jamais essayer de charger la classe, n'est-ce pas?

4 votes

Une classe peut charger une autre classe qui n'a pas été trouvée. La cause dans ce cas est toujours une ClassNotFoundException.

36voto

Mark Hansen Points 420

La NoClassDefFoundError ne donne pas beaucoup d'indications sur ce qui s'est mal passé à l'intérieur du bloc statique. Il est bon de toujours avoir un bloc comme celui-ci à l'intérieur du code d'initialisation static { ... } :

static {
  try {

    ... votre code d'initialisation ici

  } catch (Throwable t) {
    LOG.error("Échec lors de l'initialisation statique", t);
    throw t;
  }
}

0 votes

Comment faire cela en kotlin?

0 votes

Merci pour avoir donné l'astuce. Dans mon cas, j'obtenais une NPE lors de l'initialisation de la ligne statique.

3voto

user3190140 Points 11

J'ai eu la même exception, voici comment j'ai résolu le problème :

Préconditions :

  1. Classe Junit (et test), qui étendait une autre classe.

  2. ApplicationContext initialisé en utilisant Spring, qui initialise le projet.

  3. L'application context a été initialisée dans la méthode @Before

Solution :

Initialiser le contexte de l'application depuis la méthode @BeforeClass, puisque la classe parent nécessitait également certaines classes qui étaient initialisées depuis le contexte de l'application.

J'espère que cela vous aidera.

2voto

TriMix Points 11

Comme mentionné ci-dessus, cela pourrait être plusieurs choses. Dans mon cas, j'avais une variable initialisée de manière statique qui dépendait d'une entrée manquante dans mon fichier de propriétés. J'ai ajouté l'entrée manquante au fichier de propriétés et le problème a été résolu.

Prograide.com

Prograide est une communauté de développeurs qui cherche à élargir la connaissance de la programmation au-delà de l'anglais.
Pour cela nous avons les plus grands doutes résolus en français et vous pouvez aussi poser vos propres questions ou résoudre celles des autres.

Powered by:

X