2016-09-17 3 views
0

Dernières je rencontrais un bogue dans l'environnement de production, qui est lorsque l'accès utilisateur une page de la liste des coupons, il avait en dessous de l'erreurcomment pourrait laisser NoClassDefFoundError exposée durant la phase de compilation

java.lang.NoClassDefFoundError: com/myapp/common/util/WrappedBeanCopier 

Et la dépendance Maven est comme ça

myapp 
    - coupon 
     - common 2.0 
    - common 1.0 

et WrappedBeanCopier que dans common 2.0 et monapp effectivement utilisé est common 1.0, donc causé cet accident se produise.

Je veux savoir pourquoi il peut être compilé et déployé sur tomcat avec succès? Avoir une certaine manière pourrait le laisser être exposé dès que possible? par exemple. la compilation a échoué.

+0

Le déploiement s'est déroulé avec succès car vous disposez des deux fichiers jar dont vous avez besoin. Donc les dépendances sont satisfaites. Mais à l'exécution, vous ne pouviez pas choisir dans quel ordre votre pot est chargé à partir du conteneur Web. Donc, si vous avez des classes avec le même nom, il se peut que vous chargiez la mauvaise classe et que vous trouviez un tel * NoClassDefFoundError *. Dans cette [page] (https://maven.apache.org/guides/introduction/introduction-to-optional-and-excludes-dependencies.html), il explique comment éviter ces situations en utilisant l'exclusion dans les dépendances maven. –

+0

La compilation a lieu dans un environnement; l'exécution se passe dans un autre. C'est à vous de vous assurer que le chemin de classe utilisé pendant la compilation est le même que le chemin de classe pendant l'exécution. – EJP

Répondre

1

Être informé des erreurs NoClassDefFoundError lors de la compilation est malheureusement impossible.

La raison est que l'erreur elle-même existe pour indiquer cette erreur:

(extrait du javadoc de la classe d'exception)

Thrown if the Java Virtual Machine or a ClassLoader instance tries to load in the definition of a class (as part of a normal method call or as part of creating a new instance using the new expression) and no definition of the class could be found.

The searched-for class definition existed when the currently executing class was compiled, but the definition can no longer be found.

donc il n'y a vraiment pas d'argent- bullet contre ce genre d'erreur. Les mesures que vous pouvez prendre pour éviter que cela se reproduise:

  • travail sur une structure plus de dépendance fiable à l'aide Maven
  • test plus approfondi (il devrait y avoir une phase de test, l'environnement, etc. entre la compilation et la production)
  • Encore plus de tests, car cette erreur peut se produire non seulement lorsqu'une définition de classe a changé, mais vous pouvez également avoir du mal avec NoClassDefFoundErrors si votre classe ne peut pas charger en raison d'une exception lors de l'initialisation d'une variable statique.

Exemple d'une classe qui ne charge:

private static Integer someThresholdValue = MyClass.calculateThreshold(); 

private static Integer calculateThreshold() { 
    throw new Exception("some error occured"); 
} 

Note: Il peut être super-méchant quand cette erreur ci-dessus ne se produit pas en permanence, mais seulement si la classe a été tenté de charger à un moment précoce dans la séquence d'amorçage d'une application, où disons que le contexte de printemps n'était pas encore prêt ... Donc vous obtiendrez une NoClassDefFoundError chaque fois que vous êtes trop impatient de tester, mais si vous attendez 10 secondes avant d'accéder à votre webapp, alors tout va bien ... Mauvais souvenir.

+0

Merci! myapp est uniquement une couche Web en tant que passerelle, tous les tests logiques et unitaires sont internes aux bibliothèques dépendantes, par ex. coupon.Donc, s'il existe un plugin maven pourrait résoudre ce problème, au moins pourrait vous avertir que la version de common externe est inférieure à la version de commun indirectement indépendant. – zhuguowei

+0

Comme je l'ai dit ci-dessus: il n'y a pas de balle d'argent. C'est un problème complexe, et vous ne serez pas en mesure de trouver une solution simple et globale. (un plugin maven intelligent, des drapeaux javac, etc) –