OSGi: comment assurer classpath de cohérence?
Selon la OSGi documentation, OSGi est conçu pour aider à prévenir le ClassPath problèmes.
Par exemple, de "OSGi dans l'action":
ClassNotFoundExceptions lors du démarrage de votre application, car l'
chemin de classe n'était pas correct. OSGi peut aider à garantir que le code
les dépendances sont satisfaites, avant d'autoriser le code à exécuter.
Cependant, depuis que nous sommes passés de notre application java pour OSGi, je vois plus de ClassNotFoundExceptions et surtout NoClassDefFoundErrors que jamais. Les Classes qui ont été précédemment chargement fine ne sont pas plus trouvée par OSGI chargeur de classe, et le pire: vous obtenez le message d'erreur au moment de l'exécution, ce qui signifie que vous ne pouvez pas facilement vérifier, à l'exception de manuellement les tests de tous les coins de votre application.
Par exemple, notre demande était en cours d'exécution heureusement sous OSGi, mais nous avons reçu des rapports de bêta-testeurs qu'ils ne pouvaient pas exporter des documents au format PDF plus. En effet, quand j'ai regardé, j'ai trouvé que cette fonctionnalité a provoqué une exception à être connecté:
java.lang.NoClassDefFoundError: org/w3c/dom/Node
Donc, OSGi est en fait la création de plus de classpath de problèmes qu'elle n'en résout?
et plus important encore: Comment puis-je tester que mon chemin de classe est compatible avec tous les Import-Package déclarations etc. avant I lire à leur sujet dans les rapports de bug?
Pour ceux à la recherche de ce débordement de pile lors de la recherche OSGi NoClassDefFound.... le garder à l'esprit que l'Java thread d'exécution OSGi bundle code détermine l' "active" ClassLoader aka Contexte de Thread chargeur de classe (TCCL). Les "actifs" chargeur de classe peut-être pas le chargeur de classe le conteneur OSGi crée pour l'ensemble du code. Donc, pour faire fonctionner le tout, parfois, vous devez changer manuellement le fil du TCCL.
Voir 2012. Neil Bartlett. "Le Redoutable Contexte de Thread Chargeur de Classe", blogs.paremus.com/2012/10/....
OriginalL'auteur amarillion | 2011-09-19
Vous devez vous connecter pour publier un commentaire.
Une application OSGi sera pas jeter ClassNotFoundExceptions et NoClassDefFoundErrors si votre manifeste est correct. Qui est, vous devez dire à OSGi qui les packages de votre bundle utilise; si vous ne le faites pas correctement ou honnêtement, alors OSGi ne peut pas vous aider. En d'autres termes: GIGO (Garbage In, Garbage Out).
Par exemple, vous pouvez utiliser le package
org.w3c.dom
mais vous ne liste pas dans votreImport-Package
déclaration. Donc OSGi ne sait pas que vous devez avoir accès à ce package, et donc en fait, quand vous essayez de charger les classes de ce package, ils ne sont pas disponibles.Ainsi, vous devez vous assurer que votre
Import-Package
déclaration est exacte à l'égard de vos paquets de faisceaux réellement utiliser. La bonne nouvelle, c'est que le "bnd" outil peut faire pour vous en produisant le faisceau de manifester, à l'aide de pseudo-code binaire de l'analyse pour trouver toutes les statiquement référencé paquets.Mise à jour:
Votre dernière question demande comment vérifier que vos bottes sont compatibles avant de découvrir des problèmes lors de l'exécution. Bnd a une "vérifier", qui fait exactement cela. En fait, si vous utilisez Bnd pour générer le manifeste en premier lieu, alors vous n'aurez pas besoin de vérifier la fonctionnalité. Cependant, je ne sais rien au sujet de votre processus de construction de sorte que vous pourriez trouver qu'il est difficile de passer à un Bnd génération basé sur le court terme... dans ce cas, il serait relativement simple d'ajouter la tâche de vérification après l'étape de traitement après la construction. Cependant, je voudrais encore vous recommandons d'essayer d'utiliser Bnd plus tôt dans le processus de construction.
"si votre manifeste est correct" .... de sens que si votre manifeste est exactement comme la mise en oeuvre particulière que vous utilisez s'attend à ce qu'il soit et tu ne fais rien de la OSGI les concepteurs et les programmeurs de la mise en oeuvre particulière que vous utilisez n'ont pas pensé. Je suis d'accord avec amarillion - OSGI est un cauchemar de classe pas trouvé de problèmes, avec d'un côté aucun dépannage des mécanismes disponibles. Il peut être utile aux utilisateurs d'avoir plus de souplesse de déploiement, mais c'est l'ENFER pour les développeurs.
Il est facile pour les lâches à l'élingue sur les insultes sur internet. Si vous calmer et de vous décider à apprendre quelque chose, vous savez où trouver des gens raisonnables qui peuvent vous aider.
Veuillez noter que si vous spécifiez manuellement un "Import-Package" déclaration dans votre onglet Source (à l'aide de bndtools) le bnd ne sera pas ajouter automatiquement tous les paquets à la "Import-Package". M'a fallu un peu de temps à comprendre.
Bndtools ne explicitement, de vous avertir à ce sujet, et dites-vous d'ajouter les attraper tous modèle "*" à la fin de votre Import-Package liste.
OriginalL'auteur Neil Bartlett
Je pense que le problème ici est que vous ne spécifiez pas le bon ensemble de paquets/les classes utilisées par votre bundle (à l'aide de l'Importation de Paquets de la directive dans le MANIFESTE). À moins d'OSGi sait à propos de celles-ci, il ne peut pas vraiment aider!
Pas sûr de savoir comment vous construisez votre bundles OSGi, mais vous devriez vérifier le
Maven bundle plugin
, qui résout les problèmes de spécifier explicitement l'Importation de Paquets (au moins pour le moment de la compilation). Voir http://wso2.org/library/tutorials/develop-osgi-bundles-using-maven-bundle-plugin#Importing%20packages.OriginalL'auteur Saket
Je ne suis pas répondre à la question centrale, mais la prestation de ma solution pour un problème similaire.
Dans mon cas, j'ai eu cette structure de classe:
interface javax.script.ScriptEngineFactory
class pkga.A implements ScriptEngineFactory
class pkgb.B extends A
Mon premier projet de code était dans la classe
B
et cette étendue de classeA
dans une situation de dépendance Jar. À l'aide deétait pas suffisante, j'ai reçu une erreur se plaindre du manque de
javax.script.ScriptEngineFactory
. C'est bizarre qu'il fait partie de la norme du JDK 8, notez que le code dans le paquetpkgb
n'a pas explicitement référencejavax.script.*
; peut-être le Manifeste de l'écrivain ne savais pas que cette interface nécessaire pour être exportés?J'ai trouvé cet ajout à l'Export-Package directive résolu le problème
OriginalL'auteur AndrewL