Comment résoudre les erreurs « ClassNotFoundException » avec ma fonction Java Lambda ?

Dernière mise à jour : 07/01/2021

Lorsque j'exécute ma fonction AWS Lambda écrite en Java, je reçois des erreurs « ClassNotFoundException » ou « NoSuchMethodError ». Comment les éliminer ?

Brève description

L'erreur « ClassNotFoundException » se produit lorsqu'un environnement d'exécution Java charge une classe par son nom complet, mais ne la localise pas.

Remarque : le nom complet d'une classe inclut son package de déploiement et son nom de classe.

L'erreur « NosuchMethodeError » se produit lorsqu'une version de dépendance référencée est différente de la version packagée.

Pour plus d'informations sur la structure du package de déploiement de fonctions Java, consultez la rubrique Création d'un package de déploiement ZIP pour une fonction Java.

Résolution

Remarque : Si vous recevez des erreurs lors de l'exécution de commandes depuis l'interface de ligne de commande AWS (AWS CLI), vérifiez que vous utilisez la version la plus récente de l'interface.

Passez en revue la structure et le contenu du package de déploiement de votre fonction Lambda Java pour déterminer la cause de l'erreur. La bonne pratique consiste à utiliser zipinfo pour afficher le fichier Java de sortie de votre système de génération. Vous pouvez également télécharger le package en effectuant l'une des opérations suivantes :

  • Exécutez la commande Lambda get-function à partir de l'AWS CLI. La sortie de la commande affiche une URL pré-signée que vous pouvez utiliser pour télécharger le fichier. Pour plus d'informations, consultez la rubrique Récupérer une fonction Lambda.
    Remarque : si vous utilisez cette option, vérifiez également la configuration de la valeur du gestionnaire de votre fonction dans la sortie. Vous aurez besoin de cette valeur pour l'étape suivante.
  • Sur la page Functions (Fonctions) de la console Lambda, sélectionnez votre fonction, puis procédez comme suit :
    Sélectionnez Actions.
    Choisissez la fonction Export (Exporter).
    Dans la boîte de dialogue Export your function (Exporter votre fonction), choisissez Download deployment package (Télécharger le package de déploiement).

Recherchez l'un des problèmes suivants. Une fois que vous avez identifié et résolu les problèmes, regroupez et chargez manuellement votre fonction Lambda. Ensuite, vérifiez si vous obtenez toujours l'erreur.

Confirmer le nom de méthode du gestionnaire de fonction

Vérifiez le nom du gestionnaire de votre fonction Lambda en effectuant l'une des opérations suivantes :

Pour plus d'informations, consultez la rubrique Gestionnaire de fonctions AWS Lambda dans Java.

Afficher la structure du package de déploiement

Exécutez la commande suivante pour afficher la structure de fichier du package de déploiement de votre fonction Lambda :

Remarque : La commande suivante n'est valide que pour les systèmes Linux/Unix/macOS. Assurez-vous de remplacer my-deployment-package.zip par le nom de fichier de votre package de déploiement.

$ zipinfo my-deployment-package.zip

Vérifier la présence de problèmes lors de l'utilisation d'un pipeline CI/CD

Si vous utilisez un pipeline d'intégration et de livraison continues (CI/CD) pour empaqueter et déployer votre fonction, vérifiez les points suivants :

  • Toutes les dépendances requises ont été regroupées lors de l'empaquetage de la fonction.
  • Toutes les versions de dépendances référencées sont correctes.
  • Toute URL de compartiment Amazon Simple Storage Service (Amazon S3) requise existe et pointe vers la dernière version d'un fichier.
    Remarque : l'URL du compartiment Amazon S3 n'est requise que si vous utilisez une source de compartiment Amazon S3 et que le gestion des versions de compartiment est activé.
  • Les modifications de code ont été déployées avant le déploiement de la modification de configuration du gestionnaire.
    Remarque : Lambda ne dispose pas d'un mécanisme de mise à jour du code et ne peut être configuré en une modification atomique.

Vérifier les problèmes liés au fichier de classe

Vérifiez ce qui suit pour la classe nommée dans l'erreur « ClassNotFoundException » :

  • Elle est incluse dans le package de déploiement. Si vous ne trouvez pas la classe, elle n'a peut-être pas été regroupée lorsque vous avez créé le package de déploiement.
  • Son nom de classe groupée est identique à la valeur renseignée pour le gestionnaire de votre fonction. Par exemple, si la valeur du gestionnaire de votre fonction est « com.amazonaws.lambda.demo .LambdaFunctionHandler », Lambda attend un nom de classe « LambdaFunctionHandler.class » dans le répertoire de fonctions « /com/amazonaws/demo/ ». Pour plus d'informations, consultez la rubrique Gestionnaire de fonctions AWS Lambda dans Java.
  • Elle se trouve dans /lib ou dans le répertoire racine.
  • Son emplacement est spécifié dans une variable d'environnement Java CLASSPATH.
  • Si elle est référencée en tant que couche Lambda, son contenu n'a pas été extrait dans un répertoire autre que java/lib.
  • Il s'agit de la même version que la classe fournie avec votre fonction. Si ce n'est pas le cas, vérifiez si votre ordinateur local avait une version différente de celle que vous avez empaquetée.

Pour plus d'informations sur l'empaquetage des fonctions Java, consultez la rubrique Package de déploiement AWS Lambda dans Java.

Vérifier les problèmes liés au fichier JAR

Vérifiez si votre fonction s'exécute comme prévu sur un ordinateur local ou à partir d'une application AWS Serverless Application Model (AWS SAM). Si votre fonction échoue uniquement lorsqu'elle est appelée à partir de Lambda, il peut y avoir des problèmes avec les dépendances référencées (fichiers JAR).

Conseil : envisagez d'utiliser l'environnement de développement intégré (IDE) Eclipse pour créer vos fonctions Lambda Java. La création d'un projet à l'aide de plug-ins disponibles dans Eclipse configure automatiquement votre projet pour une compilation appropriée. Pour plus d'informations, consultez la rubrique Utilisation de Lambda avec AWS Toolkit for Eclipse.

Vérifiez ce qui suit pour les fichiers JAR situés dans un répertoire local et spécifiés dans une variable d'environnement Java CLASSPATH :

  • Les fichiers sont inclus dans le package de déploiement de votre fonction. Si vous ne trouvez pas de fichiers JAR référencés, ils n'ont peut-être pas été regroupés lorsque vous avez créé le package de déploiement.
  • Les versions de fichier sont les mêmes que les fichiers du package de déploiement.

Si des fichiers sont manquants ou si leurs versions sont incorrectes, copiez toutes les dépendances (fichiers JAR) dans /lib ou dans le répertoire racine. Assurez-vous que vous référencez les versions correctes. Chargez ensuite le contenu compressé.

Remarque : si vous utilisez un outil de construction tel que Apache Maven ou Gradle, assurez-vous d'utiliser les plugins requis lors de la création de l'artefact de déploiement. Par exemple, le plugin Apache Maven Shade.

Pour plus d'informations sur l'empaquetage des fonctions Java, consultez la rubrique Package de déploiement AWS Lambda dans Java.

Vérifier les problèmes d'autorisations

Lambda nécessite que les fichiers de package zip disposent d'autorisations de lecture globales. Pour plus d'informations, consultez la rubrique Comment résoudre les erreurs « permission denied » (autorisation refusée) ou « unable to import module » (impossible d'importer le module) dans Lambda lors du chargement d'un package de déploiement ?