2016-02-10 1 views
0

J'essaie de configurer un système Akka où erreurs de désérialisation déclenchent un protocole dans lequel les classes manquantes sont échangées. J'utilise un de/sérialiseur personnalisé à cet effet, qui renvoie un certain message à l'acteur de l'application une fois qu'il attrape une exception liée aux classes manquantes. En termes simples, le système distant B envoie un objet au système A; Si, pendant la désérialisation, le système A obtient un ClassNotFoundError ou NoClassDefFoundError, le système A demande au système B le bytecode de la classe indéfinie. Lorsque A reçoit la réponse de B (qui est une paire de nom de classe plus un objet de type Array [Byte]), alors il peut enregistrer la classe, de sorte que le système suivant envoie l'objet au système A, A peut le désérialiser correctement.Désérialisation et chargement de classes dans Akka - NoClassDefFoundError

Maintenant, il y a deux approches

1) Système B envoie également toutes les classes liées à la classe

2) Système B envoie uniquement demandé le bytecode de la classe demandée (sans ses dépendances)

maintenant, concentrons-nous sur l'approche 2 et envisager le scénario suivant

  • 1) B === obj: X ==> A (B envoie objet de la classe X à A)
  • 2) Supposons que X dépend de Y, Z
  • 3) B < ==== X? ==== A (A demande la classe X à B)
  • 4) B ==== = X ====> B (B fournit la classe X à A; Une classe de registres X)
  • 5) B === obj: X ==> A (A reçoit l'erreur due à la dépendance manquant Y)
  • 6) B < ==== ==== Y A
  • ?
  • 7) B Y ===== ====> A (Une classe de registres Y)
  • 8) B === obj: X ==> A
  • 9) B < ==== Z? ==== A
  • 10) B ===== Z ====> A (A enregistre la classe Z)
  • 10) B === obj: X ==> A (OK, enfin A peut désérialiser l'objet de la classe X)

Je pense qu'un tel protocole devrait fonctionner, mais en pratique, je reçois une boucle dans les étapes 5-7, en raison de la

suivante

NoClassDefFoundError: Lexamples/DemoDecentralizedAkkaPlatformCmdLineMain2 $ AggregateProgram $$ anonfun $ 3 $ principale $$ anonfun $ applique 5 $;

je reçois pour enregistrer la classe suivante: examples.DemoDecentralizedAkkaPlatformCmdLineMain2 $ AggregateProgram $$ anonfun $ principale 5

appliquent $ de anonfun 3 $$ $ $ mais je continue à obtenir le NoClassDefFoundError.

Notez que je dépouille le "L" initial et le ";" du nom de classe, ainsi que de remplacer "/" par ".". Sinon, j'obtiendrais une erreur sur le système B.

Je suis désolé pour une formulation si compliquée de la question.

Répondre

0

De la liste abstraite:

Une fois que vous avez obtenu l'erreur « noClassDefFound Y » pour la classe de chargement « X », avez-vous assuré jeter le classloader de « X », et la charge « A » dans une nouvelle classe loader, qui inclut le code d'octet de 'Y'. Si une classe est chargée, mais ne parvient pas à charger, la machine virtuelle JVM se souvient de l'erreur et la relance simplement. Au moins pour certaines erreurs d'initialisation de classe. Vous devrez donc essayer le rechargement dans un nouveau chargeur de classe.

Recommandation la plus sincère: Si vous essayez de créer un système réparti fiable, évitez de vous fier au code octet partagé par octet exact ou à l'envoi de votre code d'octet. Cela rendra le système très fragile. Au mieux des erreurs de chargeur de classe bizarres, des erreurs de méthode non trouvées, des erreurs de sérialisation. Au pire, le système fonctionne de manière invisible, code inattendu: comme vous avez déployé une nouvelle version, mais il a chargé l'ancien code à partir d'une autre instance encore en cours d'exécution. Utilisez une sérialisation indépendante du code octet. Choisissez l'un des nombreux formats de sérialisation disponibles. Akka apporte déjà un protobuf serializer inclus. Et il est facile d'en inclure un autre.